diff --git a/shoppingcart/pom.xml b/shoppingcart/pom.xml
index 1a2d4e3a..7e16c495 100644
--- a/shoppingcart/pom.xml
+++ b/shoppingcart/pom.xml
@@ -35,6 +35,20 @@
runtime
true
+
+ 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
+
com.h2database
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..d16b0d98
--- /dev/null
+++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/AuthorizationServerConfig.java
@@ -0,0 +1,56 @@
+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");
+
+ 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 SCOPE_TRUST = "trust";
+
+ 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_TRUST,SCOPE_WRITE)
+ .accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS);
+
+
+ }
+}
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..47f7b876
--- /dev/null
+++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/ResourceServerConfig.java
@@ -0,0 +1,45 @@
+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);
+ }
+
+ @Override
+ public void configure(HttpSecurity http) throws Exception {
+ http.authorizeRequests()
+ .antMatchers("/", "/h2-console/**",
+ "/swagger-resources/**",
+ "/swagger-resource/**",
+ "/swagger-ui.html",
+ "/v2/api-docs",
+ "/webjars/**",
+ "/createnewuser")
+ .permitAll()
+ .antMatchers("/roles/**","/products/**","/users/**")
+ .hasAnyRole("ADMIN")
+ .antMatchers("/carts/**")
+ .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/SecurityServiceConfig.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SecurityServiceConfig.java
new file mode 100644
index 00000000..8daaf6b0
--- /dev/null
+++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SecurityServiceConfig.java
@@ -0,0 +1,46 @@
+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 SecurityServiceConfig 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());
+ }
+}
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..bdb19bf4
--- /dev/null
+++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SimpleCorsFilter.java
@@ -0,0 +1,52 @@
+package com.lambdaschool.shoppingcart.config;
+
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.HttpMethod;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+@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..cb4e4317 100644
--- a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/controllers/CartController.java
+++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/controllers/CartController.java
@@ -5,8 +5,11 @@
import com.lambdaschool.shoppingcart.services.CartItemService;
import com.lambdaschool.shoppingcart.services.UserService;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.*;
@RestController
@@ -16,21 +19,24 @@ public class CartController
@Autowired
private CartItemService cartItemService;
+
@Autowired
private UserService userService;
- @GetMapping(value = "/user/{userid}",
+ @GetMapping(value = "/user/products",
produces = {"application/json"})
- public ResponseEntity> listCartItemsByUserId(
- @PathVariable
- long userid)
+ public ResponseEntity> listCartItemsByUserId()
{
- User u = userService.findUserById(userid);
- return new ResponseEntity<>(u,
+ String uname = SecurityContextHolder.getContext().getAuthentication().getName();
+
+ User user = userService.findByName(uname);
+
+
+ return new ResponseEntity<>(user,
HttpStatus.OK);
}
- @PutMapping(value = "/add/user/{userid}/product/{productid}",
+ @PutMapping(value = "/add/user/product/{productid}",
produces = {"application/json"})
public ResponseEntity> addToCart(
@PathVariable
@@ -45,7 +51,7 @@ public ResponseEntity> addToCart(
HttpStatus.OK);
}
- @DeleteMapping(value = "/remove/user/{userid}/product/{productid}",
+ @DeleteMapping(value = "/remove/user/product/{productid}",
produces = {"application/json"})
public ResponseEntity> removeFromCart(
@PathVariable
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..c554b561 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,7 @@
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
@@ -51,13 +52,13 @@ public ResponseEntity> listAllUsers()
* @return JSON object of the user you seek
* @see UserService#findUserById(long) UserService.findUserById(long)
*/
- @GetMapping(value = "/user/{userId}",
+ @GetMapping(value = "/user"
produces = "application/json")
- public ResponseEntity> getUserById(
- @PathVariable
- Long userId)
+ public ResponseEntity> getUserById()
{
- User u = userService.findUserById(userId);
+ String uname = SecurityContextHolder.getContext().getAuthentication().getName();
+
+ User u = userService.findByName(uname);
return new ResponseEntity<>(u,
HttpStatus.OK);
}
@@ -148,7 +149,7 @@ public ResponseEntity> addNewUser(
* @return status of OK
* @see UserService#save(User) UserService.save(User)
*/
- @PutMapping(value = "/user/{userid}",
+ @PutMapping(value = "/user",
consumes = "application/json")
public ResponseEntity> updateFullUser(
@Valid
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..27a2b4aa 100644
--- a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/models/User.java
+++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/models/User.java
@@ -1,12 +1,14 @@
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.HashSet;
-import java.util.Set;
+import java.util.*;
/**
* The entity allowing interaction with the users table
@@ -122,12 +124,17 @@ public String getUsername()
{
return username;
}
+ public void setPassword(String password)
+ {
+ BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
+ this.password = passwordEncoder.encode(password);
+ }
+
+ public void setPasswordNoEncrypt(String password)
+ {
+ this.password = password;
+ }
- /**
- * setter for username
- *
- * @param username the new username (String) converted to lowercase
- */
public void setUsername(String username)
{
this.username = username.toLowerCase();
@@ -168,10 +175,6 @@ public String getPassword()
*
* @param password the new password (String) for the user
*/
- public void setPassword(String password)
- {
- this.password = password;
- }
/**
* Getter for user role combinations
@@ -212,4 +215,14 @@ public void setCarts(Set carts)
{
this.carts = carts;
}
+
+ @JsonIgnore
+ public List getAuthority(){
+ List rtnList = new ArrayList<>();
+ for (UserRoles ur: this.roles){
+ String myRole = "ROLE_" + ur.getRole().getName().toUpperCase();
+ rtnList.add(new SimpleGrantedAuthority(myRole));
+ }
+ return rtnList;
+ }
}
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..91f093d0
--- /dev/null
+++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/SecurityUserServiceImpl.java
@@ -0,0 +1,36 @@
+package com.lambdaschool.shoppingcart.services;
+
+import com.lambdaschool.shoppingcart.exceptions.ResourceNotFoundException;
+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 javax.transaction.Transactional;
+import java.util.Locale;
+
+@Transactional
+@Service(value = "securityUserDetails")
+public class SecurityUserServiceImpl implements UserDetailsService {
+
+ @Autowired
+ private UserRepository userrepos;
+
+ @Transactional
+ @Override
+ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+ User user = userrepos.findByUsername(username.toLowerCase());
+
+ if (user == null) {
+ throw new ResourceNotFoundException("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..6d482a78 100644
--- a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserAuditing.java
+++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserAuditing.java
@@ -1,6 +1,8 @@
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;
@@ -11,18 +13,24 @@
*/
@Component
public class UserAuditing
- implements AuditorAware
-{
+ implements AuditorAware {
/**
* The current user
*
* @return Optional(String) of current user
*/
@Override
- public Optional getCurrentAuditor()
- {
+ public Optional getCurrentAuditor() {
String uname;
- uname = "SYSTEM";
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ if (authentication == null) {
+ uname = "SYSTEM";
+ }else{
+ uname = authentication.getName();
+
+
+ }
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..03564a32 100755
--- a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserServiceImpl.java
+++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserServiceImpl.java
@@ -101,7 +101,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 +141,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..d372b3a0 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$xbqvAmGbfuOlUEE3Y3P2y.arKWqMFyyCNZegUu25VYzjv785auV7K', '', 'SYSTEM', CURRENT_TIMESTAMP, 'SYSTEM', CURRENT_TIMESTAMP),
+ (2, 'cinnamon', 'cinnamon@host.local', '$2y$12$xbqvAmGbfuOlUEE3Y3P2y.arKWqMFyyCNZegUu25VYzjv785auV7K', '', 'SYSTEM', CURRENT_TIMESTAMP, 'SYSTEM', CURRENT_TIMESTAMP),
+ (3, 'stumps', 'stumps@host.local', '$2y$12$xbqvAmGbfuOlUEE3Y3P2y.arKWqMFyyCNZegUu25VYzjv785auV7K', '', 'SYSTEM', CURRENT_TIMESTAMP, 'SYSTEM', CURRENT_TIMESTAMP);
INSERT INTO USERROLES(ROLEID, USERID, CREATEDBY, CREATEDDATE, LASTMODIFIEDBY, LASTMODIFIEDDATE)
VALUES (1, 1, 'SYSTEM', CURRENT_TIMESTAMP, 'SYSTEM', CURRENT_TIMESTAMP),