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),