Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MVP #21

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open

MVP #21

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions shoppingcart/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,23 @@
<version>2.9.2</version>
</dependency>
<!-- Swagger Dependencies End -->

<!-- Security Dependencies Start -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.6.RELEASE</version>
</dependency>
<!-- Security Dependencies End -->
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.lambdaschool.shoppingcart.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
private static final String CLIENT_ID = System.getenv("OAUTHCLIENTID");
private static final String CLIENT_SECRET = System.getenv("OAUTHCLIENTSECRET");

private static final String GRANT_TYPE_PASSWORD = "password";
private static final String AUTHORIZATION_CODE = "authorization_code";
private static final String SCOPE_READ = "read";
private static final String SCOPE_WRITE = "write";
private static final String SCOPE_TRUST = "trust";

private static final int ACCESS_TOKEN_VALIDITY_SECONDS = -1;

@Autowired
private TokenStore tokenStore;

@Autowired
private AuthenticationManager authenticationManager;

@Autowired
private PasswordEncoder passwordEncoder;

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore)
.authenticationManager(authenticationManager);
endpoints.pathMapping("/oauth/token", "/login");
}

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient(CLIENT_ID)
.secret(passwordEncoder.encode(CLIENT_SECRET))
.authorizedGrantTypes(GRANT_TYPE_PASSWORD, AUTHORIZATION_CODE)
.scopes(SCOPE_READ, SCOPE_WRITE, SCOPE_TRUST)
.accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.lambdaschool.shoppingcart.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "resource_id";

@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID)
.stateless(false);//Does not need username for testing
}

@Override
public void configure(HttpSecurity http) throws Exception {//which roles has access to which endpoints
http.authorizeRequests()
.antMatchers("/", "/h2-console/**",
"/swagger-resources/**",
"/swagger-resource/**",
"/swagger-ui.html",
"/v2/api-docs",
"/webjars/**",
"/createnewuser",
"/signup",
"/login")
.permitAll()
.antMatchers("/roles/**")
.hasAnyRole("ADMIN", "ANALYST")
.antMatchers("/users/**", "/logout")
.authenticated()
.antMatchers("/carts/**")
.hasAnyRole("ADMIN", "ANALYST")
.and()
.exceptionHandling()
.accessDeniedHandler(new OAuth2AccessDeniedHandler());

http.csrf().disable();
http.headers().frameOptions().disable(); //Allows h2 console to work
http.logout().disable(); //We will write a custom logout
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.lambdaschool.shoppingcart.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityServerConfig extends WebSecurityConfigurerAdapter {

@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

@Bean
public TokenStore tokenStore(){
return new InMemoryTokenStore();
}

@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}

@Autowired
private UserDetailsService securityUserDetails;

@Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(securityUserDetails)
.passwordEncoder(passwordEncoder());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.lambdaschool.shoppingcart.config;

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
* Spring uses filters to manage web traffic. Here we manually add a CORS (Cross-Origin Resource Sharing) filter to the chain.
* Using the Order annotation, we tell Spring this is the most important filter. If this filter blocks a request,
* don't do anything else. Just block the request.
*/
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCorsFilter
implements Filter
{
@Override
public void doFilter(
ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain)
throws
IOException,
ServletException
{
// Convert our request and response to Http ones. If they are not Http ones, an
// exception would be thrown
// that would handled by our exception handler!
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest) servletRequest;
// white list domains that can access this API. * says let everyone access it.
// To restrict access use something like
// response.setHeader("Access-Control-Allow-Origin",
// "https://lambdaschool.com/");
response.setHeader("Access-Control-Allow-Origin",
"*");
// white list http methods that can be used with this API. * says lets them all work!
// To restrict access use something like
// response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Allow-Methods",
"*");
// while list access headers that can be used with this API. * says lets them all work!
// To restrict access use something like
// response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization,
// content-type, access_token");
response.setHeader("Access-Control-Allow-Headers",
"*");
// maximum seconds results can be cached
response.setHeader("Access-Control-Max-Age",
"3600");
if (HttpMethod.OPTIONS.name()
.equalsIgnoreCase(request.getMethod()))
{
response.setStatus(HttpServletResponse.SC_OK);
} else
{
filterChain.doFilter(servletRequest,
servletResponse);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.lambdaschool.shoppingcart.controllers;

import com.lambdaschool.shoppingcart.exceptions.ResourceFoundException;
import com.lambdaschool.shoppingcart.exceptions.ResourceNotFoundException;
import com.lambdaschool.shoppingcart.models.*;
import com.lambdaschool.shoppingcart.repository.RoleRepository;
import com.lambdaschool.shoppingcart.repository.UserRepository;
import com.lambdaschool.shoppingcart.services.RoleService;
import com.lambdaschool.shoppingcart.services.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

@RestController
public class NewUserController {

@Autowired
private UserRepository userrepos;

@Autowired
private RoleRepository rolerepos;


@PostMapping(value = "/createnewuser",
consumes = {"application/json"},
produces = {"application/json"})
public ResponseEntity<?> addSelf(
HttpServletRequest httpServletRequest,
@Valid
@RequestBody
UserMinimum checkuser) throws URISyntaxException {
if (checkuser.getUsername().isBlank() || checkuser.getPassword().isBlank() ){
throw new ResourceNotFoundException("Username, and/or password cannot be blank");
}
if (userrepos.findByUsername(checkuser.getUsername()) != null) {
throw new ResourceFoundException("Username already exists!");
}
User newuser = new User();
newuser.setUsername(checkuser.getUsername().toLowerCase());
newuser.setPassword(checkuser.getPassword());
newuser.setPrimaryemail(checkuser.getPrimaryemail().toLowerCase());
newuser.getRoles().clear();
for (UserRoles ur : newuser.getRoles())
{
Role addRole = rolerepos.findByNameIgnoreCase(("USER"));
newuser.getRoles()
.add(new UserRoles(newuser,
addRole));
}
newuser = userrepos.save(newuser);

HttpHeaders responseHeaders = new HttpHeaders();
URI newUserURI = ServletUriComponentsBuilder.fromUriString(httpServletRequest.getServerName() + ":" + httpServletRequest.getLocalPort() + "/users/user/{userId}")
.buildAndExpand(newuser.getUserid())
.toUri();
responseHeaders.setLocation(newUserURI);

RestTemplate restTemplate = new RestTemplate();
String requestURI = "http://localhost" + ":" + httpServletRequest.getLocalPort() + "/login";

List<MediaType> acceptableMediaTypes = new ArrayList<>();
acceptableMediaTypes.add(MediaType.APPLICATION_JSON);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.setAccept(acceptableMediaTypes);
headers.setBasicAuth(System.getenv("OAUTHCLIENTID"),
System.getenv("OAUTHCLIENTSECRET"));

MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("grant_type",
"password");
map.add("scope",
"read write trust");
map.add("username",
checkuser.getUsername());
map.add("password",
checkuser.getPassword());

HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map,
headers);

String theToken = restTemplate.postForObject(requestURI,
request,
String.class);

return new ResponseEntity<>(theToken,
responseHeaders,
HttpStatus.CREATED);
}
}
Loading