From 0d9e9ea6ac138062cce156942e87c5bb4fea83ce Mon Sep 17 00:00:00 2001 From: Simone Ballard Date: Tue, 15 Dec 2020 20:49:40 -0700 Subject: [PATCH 1/6] config files added --- .../config/AuthorizationServerConfig.java | 131 ++++++++++++++++++ .../config/ResourceServerConfig.java | 90 ++++++++++++ .../shoppingcart/config/SecurityConfig.java | 86 ++++++++++++ .../shoppingcart/config/SimpleCorsFilter.java | 67 +++++++++ 4 files changed, 374 insertions(+) create mode 100644 shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/AuthorizationServerConfig.java create mode 100644 shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/ResourceServerConfig.java create mode 100644 shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SecurityConfig.java create mode 100644 shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SimpleCorsFilter.java diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/AuthorizationServerConfig.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/AuthorizationServerConfig.java new file mode 100644 index 00000000..3ec0b069 --- /dev/null +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/AuthorizationServerConfig.java @@ -0,0 +1,131 @@ +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; + +/** + * This class enables and configures the Authorization Server. The class is also responsible for granting authorization to the client. + * This class is responsible for generating and maintaining the access tokens. + */ +@Configuration +@EnableAuthorizationServer +public class AuthorizationServerConfig + extends AuthorizationServerConfigurerAdapter +{ + /** + * Client Id is the user name for the client application. It is read from the environment variable OAUTHCLIENTID + */ + static final String CLIENT_ID = System.getenv("OAUTHCLIENTID"); + + /** + * Client secret is the password for the client application. It is read from the environment variable OAUTHCLIENTSECRET + */ + static final String CLIENT_SECRET = System.getenv("OAUTHCLIENTSECRET"); // read from environment variable + + /** + * We are using username and password to authenticate a user + */ + static final String GRANT_TYPE_PASSWORD = "password"; + + /** + * We are using the client id and client security combination to authorize the client. + * The client id and security can be base64 encoded into a single API key or code + */ + static final String AUTHORIZATION_CODE = "authorization_code"; + + /** + * Scopes are meant to limit what a user can do with the application as a whole. + * Here we allow the user to read from the application. + * Currently we are not implementing scope in our applications. We are just setting up the framework to do so. + */ + static final String SCOPE_READ = "read"; + + /** + * Scopes are meant to limit what a user can do with the application as a whole. + * Here we allow the user to write to the application. + * Currently we are not implementing scope in our applications. We are just setting up the framework to do so. + */ + static final String SCOPE_WRITE = "write"; + + /** + * Scopes are meant to limit what a user can do with the application as a whole. + * Here we say the user is trusted. + * Currently we are not implementing scope in our applications. We are just setting up the framework to do so. + */ + static final String TRUST = "trust"; + + /** + * Tells how long in seconds the access code should be kept valid. After this timeout, the user has to sign on again. + * set to -1 if you want the token to be valid forever. 1 * 60 * 60 would give us 1 hour. + */ + static final int ACCESS_TOKEN_VALIDITY_SECONDS = -1; + + /** + * The token store is configured in Security Config. However, the authorization server manages it + */ + @Autowired + private TokenStore tokenStore; + + /** + * The authentication server authenticates a user to that user user gets assigned an access token that is managed by the authorization server + */ + @Autowired + private AuthenticationManager authenticationManager; + + /** + * The authorization server must encrypt the client secret so needs to know what password encoder is in use. + */ + @Autowired + private PasswordEncoder encoder; + + /** + * Method to configure the Client Details Service for our application. This is created and managed by Spring. + * We just need to give it our custom configuration. + * + * @param configurer The ClientDetailsServiceConfigurer used in our application. Spring Boot Security created this for us. + * We just use it. + * @throws Exception if the configuration fails + */ + @Override + public void configure(ClientDetailsServiceConfigurer configurer) + throws + Exception + { + configurer.inMemory() + .withClient(CLIENT_ID) + .secret(encoder.encode(CLIENT_SECRET)) + .authorizedGrantTypes(GRANT_TYPE_PASSWORD, + AUTHORIZATION_CODE) + .scopes(SCOPE_READ, + SCOPE_WRITE, + TRUST) + .accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS); + } + + /** + * Connects are endpoints to our custom authentication server and token store. + * We can also rename the endpoints for certain oauth functions + * + * @param endpoints The Authorization Server Endpoints Configurer is created and managed by Spring Boot Security. + * We give the configurer some custom configuration and let it work! + * @throws Exception if the configuration fails + */ + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) + throws + Exception + { + endpoints.tokenStore(tokenStore) + .authenticationManager(authenticationManager); + // here instead of our clients requesting authentication at the endpoint /oauth/token, they request it at the endpoint /login + endpoints.pathMapping("/oauth/token", + "/login"); + } +} diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/ResourceServerConfig.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/ResourceServerConfig.java new file mode 100644 index 00000000..a0b39529 --- /dev/null +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/ResourceServerConfig.java @@ -0,0 +1,90 @@ +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; + +/** + * Once the client has gained authorization, users need to gain authentication. This class is response for handling that. + * It also configures which roles have access to which endpoints. So controls the users' access! + */ +@Configuration +@EnableResourceServer +public class ResourceServerConfig + extends ResourceServerConfigurerAdapter +{ + private static final String RESOURCE_ID = "resource_id"; + + @Override + public void configure(ResourceServerSecurityConfigurer resources) + { + resources.resourceId(RESOURCE_ID) + .stateless(false); + } + + /** + * This method configures which roles can access which endpoints + * + * @param http Our HttpSecurity object that is maintains by Spring + * @throws Exception in case the configurations fails + */ + @Override + public void configure(HttpSecurity http) + throws + Exception + { + // our antMatchers control which roles of users have access to which endpoints + // we must order our antmatchers from most restrictive to least restrictive. + // So restrict at method level before restricting at endpoint level. + // permitAll = everyone and their brother + // authenticated = any authenticated, signed in, user + // hasAnyRole = must be authenticated and be assigned this role! + http.authorizeRequests() + .antMatchers("/", + "/h2-console/**", + "/swagger-resources/**", + "/swagger-resource/**", + "/swagger-ui.html", + "/v2/api-docs", + "/webjars/**") + .permitAll() + .antMatchers("/users/**", + "/roles/**", + "/products/**") + .hasAnyRole("ADMIN") + .antMatchers("/users/**", + "/oauth/revoke-token", + "/logout") + .authenticated() + .and() + .exceptionHandling() + .accessDeniedHandler(new OAuth2AccessDeniedHandler()); + + // http.requiresChannel().anyRequest().requiresSecure(); required for https + + // disable the creation and use of Cross Site Request Forgery Tokens. + // These tokens require coordination with the front end client that is beyond the scope of this class. + // See https://www.yawintutor.com/how-to-enable-and-disable-csrf/ for more information + http.csrf() + .disable(); + + // this disables all of the security response headers. This is necessary for access to the H2 Console. + // Normally, Spring Security would include headers such as + // Cache-Control: no-cache, no-store, max-age=0, must-revalidate + // Pragma: no-cache + // Expires: 0 + // X-Content-Type-Options: nosniff + // X-Frame-Options: DENY + // X-XSS-Protection: 1; mode=block + http.headers() + .frameOptions() + .disable(); + + // This application implements its own logout procedure so disable the one built into Spring Security + http.logout() + .disable(); + } +} diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SecurityConfig.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SecurityConfig.java new file mode 100644 index 00000000..28728364 --- /dev/null +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SecurityConfig.java @@ -0,0 +1,86 @@ +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; + +/** + * This class allows us to set standard security protocols to be used throughout the application, + * such as password encoding, location of token store, our implementation of users, among others + */ +@Configuration +@EnableWebSecurity +// This allows us to further restrict access to an endpoint inside of a controller. +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class SecurityConfig + extends WebSecurityConfigurerAdapter +{ + /** + * Allows us to customize the Authentication Manager. Normally, as we do here, we just take the defaults. + * + * @return The configured authentication manager + * @throws Exception In case our custom configurations do not work. + */ + @Override + @Bean + public AuthenticationManager authenticationManagerBean() + throws + Exception + { + return super.authenticationManagerBean(); + } + + /** + * Connects the user details used by Spring Security to our implementation of it + */ + @Autowired + private UserDetailsService securityUserService; + + /** + * Ties our implementation of user details and password encoding to the Authentication Manager + * + * @param auth the connection to our authentication manager + * @throws Exception in case our custom configuration does not work + */ + @Autowired + public void globalUserDetails(AuthenticationManagerBuilder auth) + throws + Exception + { + auth.userDetailsService(securityUserService) + .passwordEncoder(encoder()); + } + + + /** + * We will store our token in memory. This way when the application exists all access tokens are invalidated. + * + * @return A token store configured to be used in memory + */ + @Bean + public TokenStore tokenStore() + { + return new InMemoryTokenStore(); + } + + /** + * Set our preferred encoder for our password + * + * @return A password will be encoded using the standard BCrypt method + */ + @Bean + public PasswordEncoder encoder() + { + return new BCryptPasswordEncoder(); + } +} diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SimpleCorsFilter.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SimpleCorsFilter.java new file mode 100644 index 00000000..82083d40 --- /dev/null +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SimpleCorsFilter.java @@ -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); + } + } +} From 69165627e9de6d7f1603cba7d3b537eeb0096755 Mon Sep 17 00:00:00 2001 From: Simone Ballard Date: Tue, 15 Dec 2020 20:51:33 -0700 Subject: [PATCH 2/6] security dependencies added to pom.xml --- shoppingcart/pom.xml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/shoppingcart/pom.xml b/shoppingcart/pom.xml index 1a2d4e3a..8d26c626 100644 --- a/shoppingcart/pom.xml +++ b/shoppingcart/pom.xml @@ -76,6 +76,26 @@ 2.9.2 + + + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.security + spring-security-test + test + + + + org.springframework.security.oauth + spring-security-oauth2 + 2.3.6.RELEASE + + From 7f90d0448da64e6866f81e971a833b752776e786 Mon Sep 17 00:00:00 2001 From: Simone Ballard Date: Tue, 15 Dec 2020 20:57:49 -0700 Subject: [PATCH 3/6] Logout Controller added --- .../controllers/LogoutController.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 shoppingcart/src/main/java/com/lambdaschool/shoppingcart/controllers/LogoutController.java diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/controllers/LogoutController.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/controllers/LogoutController.java new file mode 100644 index 00000000..29209304 --- /dev/null +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/controllers/LogoutController.java @@ -0,0 +1,35 @@ +package com.lambdaschool.shoppingcart.controllers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.provider.token.TokenStore; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseStatus; + +import javax.servlet.http.HttpServletRequest; + +@Controller +public class LogoutController +{ + @Autowired + private TokenStore tokenStore; + + @RequestMapping(value = {"/oauth/revoke-token", "/logout"}, + method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + public void logoutSelf(HttpServletRequest request) + { + String authHeader = request.getHeader("Authorization"); + if (authHeader != null) + { + String tokenValue = authHeader.replace("Bearer", + "") + .trim(); + OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue); + tokenStore.removeAccessToken(accessToken); + } + } +} From 9f0c58c788364abfc0b1a323aba65dd131d5552b Mon Sep 17 00:00:00 2001 From: Simone Ballard Date: Tue, 15 Dec 2020 21:03:01 -0700 Subject: [PATCH 4/6] User Controller routes updated --- .../controllers/UserController.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/controllers/UserController.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/controllers/UserController.java index 50737ff4..0d3931e7 100755 --- a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/controllers/UserController.java +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/controllers/UserController.java @@ -6,6 +6,8 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; @@ -34,6 +36,7 @@ public class UserController * @return JSON list of all users with a status of OK * @see UserService#findAll() UserService.findAll() */ + @PreAuthorize("hasAnyRole('ADMIN')") @GetMapping(value = "/users", produces = "application/json") public ResponseEntity listAllUsers() @@ -70,6 +73,7 @@ public ResponseEntity getUserById( * @return JSON object of the user you seek * @see UserService#findByName(String) UserService.findByName(String) */ + @PreAuthorize("hasAnyRole('ADMIN')") @GetMapping(value = "/user/name/{userName}", produces = "application/json") public ResponseEntity getUserByName( @@ -89,6 +93,7 @@ public ResponseEntity getUserByName( * @return A JSON list of users you seek * @see UserService#findByNameContaining(String) UserService.findByNameContaining(String) */ + @PreAuthorize("hasAnyRole('ADMIN')") @GetMapping(value = "/user/name/like/{userName}", produces = "application/json") public ResponseEntity getUserLikeName( @@ -111,6 +116,7 @@ public ResponseEntity getUserLikeName( * @throws URISyntaxException Exception if something does not work in creating the location header * @see UserService#save(User) UserService.save(User) */ + @PreAuthorize("hasAnyRole('ADMIN')") @PostMapping(value = "/user", consumes = "application/json") public ResponseEntity addNewUser( @@ -148,6 +154,7 @@ public ResponseEntity addNewUser( * @return status of OK * @see UserService#save(User) UserService.save(User) */ + @PreAuthorize("hasAnyRole('ADMIN')") @PutMapping(value = "/user/{userid}", consumes = "application/json") public ResponseEntity updateFullUser( @@ -194,6 +201,7 @@ public ResponseEntity updateUser( * @param id the primary key of the user you wish to delete * @return Status of OK */ + @PreAuthorize("hasAnyRole('ADMIN')") @DeleteMapping(value = "/user/{id}") public ResponseEntity deleteUserById( @PathVariable @@ -202,4 +210,15 @@ public ResponseEntity deleteUserById( userService.delete(id); return new ResponseEntity<>(HttpStatus.OK); } + + @GetMapping(value = "/myinfo", + produces = "application/json") + public ResponseEntity getUserInfo() + { + User u = userService.findByName(SecurityContextHolder.getContext() + .getAuthentication() + .getName()); + return new ResponseEntity<>(u, + HttpStatus.OK); + } } \ No newline at end of file From e6ed14870ca87c6a1b273a35a6583bb145571eec Mon Sep 17 00:00:00 2001 From: Simone Ballard Date: Tue, 15 Dec 2020 21:09:56 -0700 Subject: [PATCH 5/6] findByUsername method included in UserRepository --- .../shoppingcart/models/User.java | 111 +++++------------- 1 file changed, 29 insertions(+), 82 deletions(-) diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/models/User.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/models/User.java index fcc02f61..0fbb835e 100644 --- a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/models/User.java +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/models/User.java @@ -1,47 +1,37 @@ package com.lambdaschool.shoppingcart.models; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import javax.persistence.*; import javax.validation.constraints.Email; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; -/** - * The entity allowing interaction with the users table - */ @Entity @Table(name = "users") public class User extends Auditable { - /** - * The primary key (long) of the users table. - */ @Id @GeneratedValue(strategy = GenerationType.AUTO) private long userid; - /** - * The username (String). Cannot be null and must be unique - */ @Column(nullable = false, unique = true) private String username; - /** - * The password (String) for this user. Cannot be null. Never get displayed - */ @Column(nullable = false) @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) private String password; private String comments; - /** - * Primary email account of user. Could be used as the userid. Cannot be null and must be unique. - */ @Column(nullable = false, unique = true) @Email @@ -54,10 +44,7 @@ public class User allowSetters = true) private Set carts = new HashSet<>(); - /** - * Part of the join relationship between user and role - * connects users to the user role combination - */ + @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) @@ -65,22 +52,10 @@ public class User allowSetters = true) private Set roles = new HashSet<>(); - /** - * Default constructor used primarily by the JPA. - */ public User() { } - /** - * Given the params, create a new user object - *

- * userid is autogenerated - * - * @param username The username (String) of the user - * @param password The password (String) of the user - * @param primaryemail The primary email (String) of the user - */ public User( String username, String password, @@ -93,101 +68,57 @@ public User( this.comments = comments; } - /** - * Getter for userid - * - * @return the userid (long) of the user - */ public long getUserid() { return userid; } - /** - * Setter for userid. Used primary for seeding data - * - * @param userid the new userid (long) of the user - */ public void setUserid(long userid) { this.userid = userid; } - /** - * Getter for username - * - * @return the username (String) lowercase - */ public String getUsername() { return username; } - /** - * setter for username - * - * @param username the new username (String) converted to lowercase - */ public void setUsername(String username) { this.username = username.toLowerCase(); } - /** - * getter for primary email - * - * @return the primary email (String) for the user converted to lowercase - */ public String getPrimaryemail() { return primaryemail; } - /** - * setter for primary email - * - * @param primaryemail the new primary email (String) for the user converted to lowercase - */ public void setPrimaryemail(String primaryemail) { this.primaryemail = primaryemail.toLowerCase(); } - /** - * Getter for the password - * - * @return the password (String) of the user - */ public String getPassword() { return password; } - /** - * Setter for password - * - * @param password the new password (String) for the user - */ - public void setPassword(String password) + public void setPasswordNoEncrypt(String password) { this.password = password; } - /** - * Getter for user role combinations - * - * @return A list of user role combinations associated with this user - */ + public void setPassword(String password) + { + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + this.password = passwordEncoder.encode(password); + } + public Set getRoles() { return roles; } - /** - * Setter for user role combinations - * - * @param roles Change the list of user role combinations associated with this user to this one - */ public void setRoles(Set roles) { this.roles = roles; @@ -212,4 +143,20 @@ public void setCarts(Set carts) { this.carts = carts; } + + @JsonIgnore + public List getAuthority() + { + List rtnList = new ArrayList<>(); + + for (UserRoles r : this.roles) + { + String myRole = "ROLE_" + r.getRole() + .getName() + .toUpperCase(); + rtnList.add(new SimpleGrantedAuthority(myRole)); + } + + return rtnList; + } } From 8845cf217c2a16f30dc6bb9dd78ffa4b715ffc1f Mon Sep 17 00:00:00 2001 From: Simone Ballard Date: Tue, 15 Dec 2020 21:20:55 -0700 Subject: [PATCH 6/6] Cart controller updated --- .../controllers/CartController.java | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/controllers/CartController.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/controllers/CartController.java index bd0d26e7..d71ee197 100644 --- a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/controllers/CartController.java +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/controllers/CartController.java @@ -7,6 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; @RestController @@ -19,25 +20,28 @@ public class CartController @Autowired private UserService userService; - @GetMapping(value = "/user/{userid}", + @GetMapping(value = "/user", produces = {"application/json"}) - public ResponseEntity listCartItemsByUserId( - @PathVariable - long userid) + public ResponseEntity listCartItemsByUserId() { - User u = userService.findUserById(userid); + User u = userService.findByName(SecurityContextHolder.getContext() + .getAuthentication() + .getName()); return new ResponseEntity<>(u, HttpStatus.OK); } - @PutMapping(value = "/add/user/{userid}/product/{productid}", + @PutMapping(value = "/add/product/{productid}", produces = {"application/json"}) public ResponseEntity addToCart( - @PathVariable - long userid, @PathVariable long productid) { + long userid = userService.findByName(SecurityContextHolder.getContext() + .getAuthentication() + .getName()) + .getUserid(); + CartItem addCartTtem = cartItemService.addToCart(userid, productid, "I am not working"); @@ -45,14 +49,17 @@ public ResponseEntity addToCart( HttpStatus.OK); } - @DeleteMapping(value = "/remove/user/{userid}/product/{productid}", + @DeleteMapping(value = "/remove/product/{productid}", produces = {"application/json"}) public ResponseEntity removeFromCart( - @PathVariable - long userid, @PathVariable long productid) { + long userid = userService.findByName(SecurityContextHolder.getContext() + .getAuthentication() + .getName()) + .getUserid(); + CartItem removeCartItem = cartItemService.removeFromCart(userid, productid, "I am still not working");