diff --git a/shoppingcart/pom.xml b/shoppingcart/pom.xml index 1a2d4e3a..692f3012 100644 --- a/shoppingcart/pom.xml +++ b/shoppingcart/pom.xml @@ -76,6 +76,23 @@ 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 + 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..519059ba --- /dev/null +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/AuthorizationServerConfig.java @@ -0,0 +1,58 @@ +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 { + + static final String CLIENT_ID = System.getenv("OAUTHCLIENTID"); + static final String CLIENT_SECRET = System.getenv("OAUTHCLIENTSECRET"); + + static final String GRANT_TYPE_PASSWORD = "password"; + static final String AUTHORIZATION_CODE = "authorization_code"; + + static final String SCOPE_READ = "read"; + static final String SCOPE_WRITE = "write"; + static final String TRUST = "trust"; + + static final int ACCESS_TOKEN_VALIDITY_SECONDS = -1; //doesn't expire + + + @Autowired + private TokenStore tokenStore; + + @Autowired + private AuthenticationManager authenticationManager; + + @Autowired + private PasswordEncoder encoder; + + + @Override + public void configure(ClientDetailsServiceConfigurer client) throws Exception + { + client.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); + } + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + endpoints.tokenStore(tokenStore) + .authenticationManager(authenticationManager); + 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..4cc451b7 --- /dev/null +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/ResourceServerConfig.java @@ -0,0 +1,57 @@ +package com.lambdaschool.shoppingcart.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +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) + { + resources.resourceId(RESOURCE_ID) + .stateless(false); + } +// +// For the routes /carts/** +// All authenticated users can access /carts/*** +// Remove the user/{userid} path variable from all the routes +// Use the authenticated as the user to work with + + @Override + public void configure(HttpSecurity http) throws Exception + { + http.authorizeRequests() + .antMatchers("/", + "/h2-console/**", + "/swagger-resources/**", + "/swagger-resource/**", + "/swagger-ui.html", + "/v2/api-docs", + "/webjars/**") + .permitAll() + .antMatchers("/roles/**", "/products/**") + .hasAnyRole("ADMIN") + .antMatchers(HttpMethod.POST, "/users/**", "/oauth/revoke-token", "/logout") + .authenticated() + .and() + .exceptionHandling() + .accessDeniedHandler(new OAuth2AccessDeniedHandler()); + + http.csrf().disable(); + + http.headers().frameOptions().disable(); + + 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..6fde07be --- /dev/null +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SecurityConfig.java @@ -0,0 +1,50 @@ +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 SecurityConfig extends WebSecurityConfigurerAdapter +{ + @Override + @Bean + public AuthenticationManager authenticationManagerBean() throws Exception + { + return super.authenticationManagerBean(); + } + + @Autowired + private UserDetailsService securityUserService; + + @Autowired + public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception + { + auth.userDetailsService(securityUserService) + .passwordEncoder(encoder()); + } + + @Bean + public TokenStore tokenStore() + { + return new InMemoryTokenStore(); + } + + @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..2cb9bf68 --- /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); + } + } +} 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..5b88cad4 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 @@ -25,7 +26,9 @@ public ResponseEntity listCartItemsByUserId( @PathVariable long userid) { - User u = userService.findUserById(userid); + User u = userService.findByName(SecurityContextHolder.getContext() + .getAuthentication() + .getName()); return new ResponseEntity<>(u, HttpStatus.OK); } @@ -33,11 +36,13 @@ public ResponseEntity listCartItemsByUserId( @PutMapping(value = "/add/user/{userid}/product/{productid}", produces = {"application/json"}) public ResponseEntity addToCart( - @PathVariable - long userid, @PathVariable long productid) { + // pulls current user through context and sets as long userId (security) + long userid = userService.findByName(SecurityContextHolder.getContext() + .getAuthentication().getName()).getUserid(); + CartItem addCartTtem = cartItemService.addToCart(userid, productid, "I am not working"); @@ -45,14 +50,14 @@ public ResponseEntity addToCart( HttpStatus.OK); } - @DeleteMapping(value = "/remove/user/{userid}/product/{productid}", + @DeleteMapping(value = "/remove/user/{userid}/product/{procductid}", 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"); 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..f6741ad0 --- /dev/null +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/controllers/LogoutController.java @@ -0,0 +1,33 @@ +package com.lambdaschool.shoppingcart.controllers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +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.GetMapping; + +import javax.servlet.http.HttpServletRequest; + +@Controller +public class LogoutController +{ + @Autowired + private TokenStore tokenStore; + + @GetMapping(value = {"/oauth/revoke-token", "/logout"}, produces = "application/json") + public ResponseEntity 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); + } + + return new ResponseEntity<>(HttpStatus.OK); + } + +} 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..ea0daec9 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,8 @@ public class UserController * @return JSON list of all users with a status of OK * @see UserService#findAll() UserService.findAll() */ + @PreAuthorize("hasAnyRole('ADMIN')") + // without this any authenticated user has access bnecause of the cfg file, use to restrict access to just admin @GetMapping(value = "/users", produces = "application/json") public ResponseEntity listAllUsers() @@ -70,6 +74,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 +94,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 +117,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 +155,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( @@ -174,6 +182,7 @@ public ResponseEntity updateFullUser( * @return A status of OK * @see UserService#update(User, long) UserService.update(User, long) */ + // handle this restriction in the service itself @PatchMapping(value = "/user/{id}", consumes = "application/json") public ResponseEntity updateUser( @@ -194,6 +203,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 +212,14 @@ public ResponseEntity deleteUserById( userService.delete(id); return new ResponseEntity<>(HttpStatus.OK); } + + // No restriction needed since it is only returning information about the currently logged in user (line 221) + @GetMapping(value = "/myinfo", produces = "application/json") + public ResponseEntity getUserInfo() + { + User u = userService.findByName(SecurityContextHolder.getContext() + .getAuthentication() // this is in spring and tells us who is the current user that is logged in + .getName()); + return new ResponseEntity<>(u, HttpStatus.OK); + } } \ No newline at end of file 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..34b17225 100644 --- a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/models/User.java +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/models/User.java @@ -1,11 +1,17 @@ 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 org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; import javax.persistence.*; import javax.validation.constraints.Email; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; /** @@ -88,7 +94,7 @@ public User( String comments) { setUsername(username); - setPassword(password); + setPassword(password); // do instead of this.password = password so it is forced to be encrypted this.primaryemail = primaryemail; this.comments = comments; } @@ -168,11 +174,18 @@ public String getPassword() * * @param password the new password (String) for the user */ + public void setPassword(String password) { - this.password = password; + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + this.password = passwordEncoder.encode(password); // this encrypts the password } + public void setPasswordNoEncrypt(String password) + { + this.password = password; + } //this is to call when no encrypt needed + /** * Getter for user role combinations * @@ -212,4 +225,19 @@ 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; + } } diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/HelperFunctions.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/HelperFunctions.java index 164b08d0..91c31249 100644 --- a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/HelperFunctions.java +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/HelperFunctions.java @@ -18,4 +18,8 @@ public interface HelperFunctions */ List getConstraintViolation(Throwable cause); + + default boolean isAuthorizedToMakeChange(String username) { + return false; + } } diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/HelperFunctionsImpl.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/HelperFunctionsImpl.java index d7b91930..598032cb 100644 --- a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/HelperFunctionsImpl.java +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/HelperFunctionsImpl.java @@ -1,13 +1,18 @@ package com.lambdaschool.shoppingcart.services; +import com.lambdaschool.shoppingcart.exceptions.ResourceNotFoundException; import com.lambdaschool.shoppingcart.models.ValidationError; import org.hibernate.exception.ConstraintViolationException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.validation.FieldError; import org.springframework.web.bind.MethodArgumentNotValidException; import java.util.ArrayList; import java.util.List; +import java.util.Locale; @Service(value = "helperFunctions") public class HelperFunctionsImpl @@ -67,4 +72,24 @@ public List getConstraintViolation(Throwable cause) } return listVE; } + + @Override + public boolean isAuthorizedToMakeChange(String username) + { + Authentication authentication = SecurityContextHolder.getContext() + .getAuthentication(); //gets current user authenticated + if (username.equalsIgnoreCase(authentication.getName().toLowerCase()) + //if you are the one trying to edit, you can make change + || + authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_ADMIN"))) + // if you are admin, you can change any user + { + return true; + } else + { + throw new ResourceNotFoundException(authentication.getName() + " isn't authorized to make this change"); + // or else STOP! + } + + } } diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/SecurityUserServiceImpl.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/SecurityUserServiceImpl.java new file mode 100644 index 00000000..db2a21d0 --- /dev/null +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/SecurityUserServiceImpl.java @@ -0,0 +1,34 @@ +package com.lambdaschool.shoppingcart.services; + +import com.lambdaschool.shoppingcart.exceptions.ResourceFoundException; +import com.lambdaschool.shoppingcart.models.User; +import com.lambdaschool.shoppingcart.repository.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Locale; + +@Service(value = "securityUserService") +public class SecurityUserServiceImpl implements UserDetailsService +{ + @Autowired + private UserRepository userrepos; + + @Transactional + @Override + public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException + { + User user = userrepos.findByUsername(s.toLowerCase()); + if(user == null) + { + throw new ResourceFoundException("Invalid Username or Password."); + } + return new org.springframework.security.core.userdetails. + User(user.getUsername(), user.getPassword(), user.getAuthority()); + + } +} diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserAuditing.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserAuditing.java index 725dcee1..777875d3 100644 --- a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserAuditing.java +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserAuditing.java @@ -1,17 +1,17 @@ package com.lambdaschool.shoppingcart.services; - import org.springframework.data.domain.AuditorAware; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; - import java.util.Optional; - /** * Spring Boot needs to know what username to use for the auditing fields CreatedBy and ModifiedBy - * For now, a default name will be used + * Checks to see if there is an authenticated user. If so use that user, + * if not which happens when seeding the database, use a default value */ @Component public class UserAuditing - implements AuditorAware + implements AuditorAware { /** * The current user @@ -22,7 +22,15 @@ public class UserAuditing public Optional getCurrentAuditor() { String uname; - uname = "SYSTEM"; + Authentication authentication = SecurityContextHolder.getContext() + .getAuthentication(); + if (authentication != null) + { + uname = authentication.getName(); + } else + { + uname = "SYSTEM"; + } return Optional.of(uname); } -} +} \ No newline at end of file diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserServiceImpl.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserServiceImpl.java index d84fad84..6b5fc6a6 100755 --- a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserServiceImpl.java +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserServiceImpl.java @@ -6,6 +6,8 @@ import com.lambdaschool.shoppingcart.models.User; import com.lambdaschool.shoppingcart.models.UserRoles; import com.lambdaschool.shoppingcart.repository.UserRepository; +import net.bytebuddy.implementation.bytecode.Throw; +import org.hibernate.id.uuid.Helper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; @@ -34,19 +36,33 @@ public class UserServiceImpl @Autowired private RoleService roleService; + @Autowired + private HelperFunctions helperFunctions; + public User findUserById(long id) throws ResourceNotFoundException { - return userrepos.findById(id) - .orElseThrow(() -> new ResourceNotFoundException("User id " + id + " not found!")); + User currentUser = userrepos.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("User id " + id + " not found!")); + + if (helperFunctions.isAuthorizedToMakeChange(currentUser.getUsername())) + { + return currentUser; + } else + { + throw new ResourceNotFoundException("This user isn't authorized to make that change!"); + } } + + @Override public List findByNameContaining(String username) { return userrepos.findByUsernameContainingIgnoreCase(username.toLowerCase()); } + @Override public List findAll() { @@ -101,7 +117,7 @@ public User save(User user) newUser.setUsername(user.getUsername() .toLowerCase()); - newUser.setPassword(user.getPassword()); + newUser.setPasswordNoEncrypt(user.getPassword()); newUser.setPrimaryemail(user.getPrimaryemail() .toLowerCase()); @@ -141,7 +157,7 @@ public User update( if (user.getPassword() != null) { - currentUser.setPassword(user.getPassword()); + currentUser.setPasswordNoEncrypt(user.getPassword()); } if (user.getPrimaryemail() != null) diff --git a/shoppingcart/src/main/resources/data.sql b/shoppingcart/src/main/resources/data.sql index a1159b8b..46147fd1 100644 --- a/shoppingcart/src/main/resources/data.sql +++ b/shoppingcart/src/main/resources/data.sql @@ -18,9 +18,9 @@ INSERT INTO ROLES(ROLEID, NAME, CREATEDBY, CREATEDDATE, LASTMODIFIEDBY, LASTMODI (2, 'USER', 'SYSTEM', CURRENT_TIMESTAMP, 'SYSTEM', CURRENT_TIMESTAMP); INSERT INTO USERS(USERID, USERNAME, PRIMARYEMAIL, PASSWORD, COMMENTS, CREATEDBY, CREATEDDATE, LASTMODIFIEDBY, LASTMODIFIEDDATE) - VALUES (1, 'barnbarn', 'barnbarn@host.local', 'LambdaLlama', '', 'SYSTEM', CURRENT_TIMESTAMP, 'SYSTEM', CURRENT_TIMESTAMP), - (2, 'cinnamon', 'cinnamon@host.local', 'LambdaLlama', '', 'SYSTEM', CURRENT_TIMESTAMP, 'SYSTEM', CURRENT_TIMESTAMP), - (3, 'stumps', 'stumps@host.local', 'LambdaLlama', '', 'SYSTEM', CURRENT_TIMESTAMP, 'SYSTEM', CURRENT_TIMESTAMP); + VALUES (1, 'barnbarn', 'barnbarn@host.local', '$2y$12$k3LlmPBgJCfYm2QHQ5Qy2.DHn/QoxBUNKahQAltBkTI8XXYngqTUm', '', 'SYSTEM', CURRENT_TIMESTAMP, 'SYSTEM', CURRENT_TIMESTAMP), + (2, 'cinnamon', 'cinnamon@host.local', '$2y$12$k3LlmPBgJCfYm2QHQ5Qy2.DHn/QoxBUNKahQAltBkTI8XXYngqTUm', '', 'SYSTEM', CURRENT_TIMESTAMP, 'SYSTEM', CURRENT_TIMESTAMP), + (3, 'stumps', 'stumps@host.local', '$2y$12$k3LlmPBgJCfYm2QHQ5Qy2.DHn/QoxBUNKahQAltBkTI8XXYngqTUm', '', 'SYSTEM', CURRENT_TIMESTAMP, 'SYSTEM', CURRENT_TIMESTAMP); INSERT INTO USERROLES(ROLEID, USERID, CREATEDBY, CREATEDDATE, LASTMODIFIEDBY, LASTMODIFIEDDATE) VALUES (1, 1, 'SYSTEM', CURRENT_TIMESTAMP, 'SYSTEM', CURRENT_TIMESTAMP),