-
Notifications
You must be signed in to change notification settings - Fork 526
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f2caba5
commit 60ee12c
Showing
9 changed files
with
293 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 46 additions & 38 deletions
84
starter_code/src/main/java/com/example/demo/controllers/UserController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,61 @@ | ||
package com.example.demo.controllers; | ||
|
||
import java.util.Optional; | ||
|
||
import com.example.demo.model.persistence.Cart; | ||
import com.example.demo.model.persistence.User; | ||
import com.example.demo.model.persistence.repositories.CartRepository; | ||
import com.example.demo.model.persistence.repositories.UserRepository; | ||
import com.example.demo.model.requests.CreateUserRequest; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import com.example.demo.model.persistence.Cart; | ||
import com.example.demo.model.persistence.User; | ||
import com.example.demo.model.persistence.repositories.CartRepository; | ||
import com.example.demo.model.persistence.repositories.UserRepository; | ||
import com.example.demo.model.requests.CreateUserRequest; | ||
|
||
@RestController | ||
@RequestMapping("/api/user") | ||
public class UserController { | ||
|
||
@Autowired | ||
private UserRepository userRepository; | ||
|
||
@Autowired | ||
private CartRepository cartRepository; | ||
|
||
@GetMapping("/id/{id}") | ||
public ResponseEntity<User> findById(@PathVariable Long id) { | ||
return ResponseEntity.of(userRepository.findById(id)); | ||
} | ||
|
||
@GetMapping("/{username}") | ||
public ResponseEntity<User> findByUserName(@PathVariable String username) { | ||
User user = userRepository.findByUsername(username); | ||
return user == null ? ResponseEntity.notFound().build() : ResponseEntity.ok(user); | ||
} | ||
|
||
@PostMapping("/create") | ||
public ResponseEntity<User> createUser(@RequestBody CreateUserRequest createUserRequest) { | ||
User user = new User(); | ||
user.setUsername(createUserRequest.getUsername()); | ||
Cart cart = new Cart(); | ||
cartRepository.save(cart); | ||
user.setCart(cart); | ||
userRepository.save(user); | ||
return ResponseEntity.ok(user); | ||
} | ||
|
||
|
||
|
||
@Autowired | ||
private UserRepository userRepository; | ||
|
||
@Autowired | ||
private CartRepository cartRepository; | ||
|
||
@Autowired | ||
private BCryptPasswordEncoder bCryptPasswordEncoder; | ||
|
||
@GetMapping("/id/{id}") | ||
public ResponseEntity<User> findById(@PathVariable Long id) { | ||
return ResponseEntity.of(userRepository.findById(id)); | ||
} | ||
|
||
@GetMapping("/{username}") | ||
public ResponseEntity<User> findByUserName(@PathVariable String username) { | ||
User user = userRepository.findByUsername(username); | ||
return user == null ? ResponseEntity.notFound().build() : ResponseEntity.ok(user); | ||
} | ||
|
||
@PostMapping("/create") | ||
public ResponseEntity<User> createUser(@RequestBody CreateUserRequest createUserRequest) { | ||
|
||
User user = new User(); | ||
user.setUsername(createUserRequest.getUsername()); | ||
Cart cart = new Cart(); | ||
cartRepository.save(cart); | ||
|
||
user.setCart(cart); | ||
if (createUserRequest.getPassword().length() < 7 || | ||
!createUserRequest.getPassword().equals(createUserRequest.getConfirmPassword())) { | ||
return ResponseEntity.badRequest().build(); | ||
} | ||
user.setPassword(bCryptPasswordEncoder.encode(createUserRequest.getPassword())); | ||
userRepository.save(user); | ||
return ResponseEntity.ok(user); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
starter_code/src/main/java/com/example/demo/security/JWTAuthenticationFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package com.example.demo.security; | ||
|
||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.Date; | ||
|
||
import javax.servlet.FilterChain; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
|
||
import org.springframework.security.authentication.AuthenticationManager; | ||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.core.AuthenticationException; | ||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | ||
|
||
import com.auth0.jwt.JWT; | ||
import com.example.demo.model.persistence.User; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
|
||
import static com.auth0.jwt.algorithms.Algorithm.HMAC512; | ||
|
||
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter { | ||
|
||
private AuthenticationManager authenticationManager; | ||
|
||
public JWTAuthenticationFilter(AuthenticationManager authenticationManager) { | ||
this.authenticationManager = authenticationManager; | ||
} | ||
|
||
@Override | ||
public Authentication attemptAuthentication(HttpServletRequest req, | ||
HttpServletResponse res) throws AuthenticationException { | ||
try { | ||
User credentials = new ObjectMapper() | ||
.readValue(req.getInputStream(), User.class); | ||
|
||
return authenticationManager.authenticate( | ||
new UsernamePasswordAuthenticationToken( | ||
credentials.getUsername(), | ||
credentials.getPassword(), | ||
new ArrayList<>())); | ||
} catch (IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
@Override | ||
protected void successfulAuthentication(HttpServletRequest req, | ||
HttpServletResponse res, | ||
FilterChain chain, | ||
Authentication auth) throws IOException, ServletException { | ||
|
||
String token = JWT.create() | ||
.withSubject(((org.springframework.security.core.userdetails.User) auth.getPrincipal()).getUsername()) | ||
.withExpiresAt(new Date(System.currentTimeMillis() + SecurityConstants.EXPIRATION_TIME)) | ||
.sign(HMAC512(SecurityConstants.SECRET.getBytes())); | ||
res.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX + token); | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
starter_code/src/main/java/com/example/demo/security/JWTAuthenticationVerficationFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package com.example.demo.security; | ||
|
||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
|
||
import javax.servlet.FilterChain; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
|
||
import org.springframework.security.authentication.AuthenticationManager; | ||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | ||
import org.springframework.security.core.context.SecurityContextHolder; | ||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; | ||
import org.springframework.stereotype.Component; | ||
|
||
import com.auth0.jwt.JWT; | ||
|
||
import static com.auth0.jwt.algorithms.Algorithm.HMAC512; | ||
|
||
@Component | ||
public class JWTAuthenticationVerficationFilter extends BasicAuthenticationFilter { | ||
|
||
public JWTAuthenticationVerficationFilter(AuthenticationManager authManager) { | ||
super(authManager); | ||
} | ||
|
||
@Override | ||
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) | ||
throws IOException, ServletException { | ||
String header = req.getHeader(SecurityConstants.HEADER_STRING); | ||
|
||
if (header == null || !header.startsWith(SecurityConstants.TOKEN_PREFIX)) { | ||
chain.doFilter(req, res); | ||
return; | ||
} | ||
|
||
UsernamePasswordAuthenticationToken authentication = getAuthentication(req); | ||
|
||
SecurityContextHolder.getContext().setAuthentication(authentication); | ||
chain.doFilter(req, res); | ||
} | ||
|
||
private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest req) { | ||
String token = req.getHeader(SecurityConstants.HEADER_STRING); | ||
if (token != null) { | ||
String user = JWT.require(HMAC512(SecurityConstants.SECRET.getBytes())).build() | ||
.verify(token.replace(SecurityConstants.TOKEN_PREFIX, "")) | ||
.getSubject(); | ||
if (user != null) { | ||
return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>()); | ||
} | ||
return null; | ||
} | ||
return null; | ||
} | ||
|
||
} |
10 changes: 10 additions & 0 deletions
10
starter_code/src/main/java/com/example/demo/security/SecurityConstants.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.example.demo.security; | ||
|
||
public class SecurityConstants { | ||
|
||
public static final String SECRET = "oursecretkey"; | ||
public static final long EXPIRATION_TIME = 864_000_000; // 10 days | ||
public static final String TOKEN_PREFIX = "Bearer "; | ||
public static final String HEADER_STRING = "Authorization"; | ||
public static final String SIGN_UP_URL = "/api/user/create"; | ||
} |
28 changes: 28 additions & 0 deletions
28
starter_code/src/main/java/com/example/demo/security/UserDetailsServiceImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.example.demo.security; | ||
|
||
import java.util.Collections; | ||
|
||
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 com.example.demo.model.persistence.User; | ||
import com.example.demo.model.persistence.repositories.UserRepository; | ||
|
||
@Service | ||
public class UserDetailsServiceImpl implements UserDetailsService { | ||
|
||
@Autowired | ||
private UserRepository userRepository; | ||
|
||
@Override | ||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { | ||
User user = userRepository.findByUsername(username); | ||
if (user == null) { | ||
throw new UsernameNotFoundException(username); | ||
} | ||
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), Collections.emptyList()); | ||
} | ||
} |
Oops, something went wrong.