implement users resource and email based auth
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			This commit is contained in:
		| @@ -36,8 +36,7 @@ public class Main { | ||||
|         transaction.commit(); | ||||
|  | ||||
|         users.forEach(user -> LOGGER.info("ID: {}, Name: {}", user.getUuid(), user.getUsername())); | ||||
|  | ||||
|     } | ||||
| } | ||||
|  | ||||
|     private static final Thread shutdownHook = new Thread(() -> { | ||||
|         HibernateManager.shutdown(); | ||||
|   | ||||
| @@ -24,7 +24,7 @@ public class ApplicationConfiguration | ||||
|  | ||||
|     @Bean | ||||
|     UserDetailsService userDetailsService() { | ||||
|         return username -> userRepository.findByEmail(username) | ||||
|         return email -> userRepository.findByEmail(email) | ||||
|                 .orElseThrow(() -> new UsernameNotFoundException("User not found")); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -9,13 +9,13 @@ import org.springframework.lang.NonNull; | ||||
| import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | ||||
| import org.springframework.security.core.Authentication; | ||||
| import org.springframework.security.core.context.SecurityContextHolder; | ||||
| import org.springframework.security.core.userdetails.UserDetails; | ||||
| import org.springframework.security.core.userdetails.UserDetailsService; | ||||
| import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; | ||||
| import org.springframework.stereotype.Component; | ||||
| import org.springframework.web.filter.OncePerRequestFilter; | ||||
| import org.springframework.web.servlet.HandlerExceptionResolver; | ||||
| import wtf.beatrice.releasehive.model.User; | ||||
| import wtf.beatrice.releasehive.service.JWTService; | ||||
| import wtf.beatrice.releasehive.service.UserDetailsExtendedService; | ||||
|  | ||||
| import java.io.IOException; | ||||
|  | ||||
| @@ -25,11 +25,11 @@ public class JWTAuthenticationFilter extends OncePerRequestFilter | ||||
|     private final HandlerExceptionResolver handlerExceptionResolver; | ||||
|  | ||||
|     private final JWTService jwtService; | ||||
|     private final UserDetailsService userDetailsService; | ||||
|     private final UserDetailsExtendedService userDetailsService; | ||||
|  | ||||
|     public JWTAuthenticationFilter( | ||||
|             @Autowired JWTService jwtService, | ||||
|             @Autowired UserDetailsService userDetailsService, | ||||
|             @Autowired UserDetailsExtendedService userDetailsService, | ||||
|             @Autowired HandlerExceptionResolver handlerExceptionResolver) { | ||||
|         this.jwtService = jwtService; | ||||
|         this.userDetailsService = userDetailsService; | ||||
| @@ -52,12 +52,12 @@ public class JWTAuthenticationFilter extends OncePerRequestFilter | ||||
|  | ||||
|         try { | ||||
|             final String jwt = authHeader.substring(7); | ||||
|             final String userEmail = jwtService.extractUsername(jwt); | ||||
|             final String email = jwtService.extractEmail(jwt); | ||||
|  | ||||
|             Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); | ||||
|  | ||||
|             if (userEmail != null && authentication == null) { | ||||
|                 UserDetails userDetails = this.userDetailsService.loadUserByUsername(userEmail); | ||||
|             if (email != null && authentication == null) { | ||||
|                 User userDetails = this.userDetailsService.loadUserByEmail(email); | ||||
|  | ||||
|                 if (jwtService.isTokenValid(jwt, userDetails)) { | ||||
|                     UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken( | ||||
|   | ||||
| @@ -11,4 +11,6 @@ import java.util.UUID; | ||||
| public interface UserRepository extends JpaRepository<User, UUID> { | ||||
|  | ||||
|     Optional<User> findByEmail(String email); | ||||
|  | ||||
|     Optional<User> findByUsername(String username); | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,46 @@ | ||||
| package wtf.beatrice.releasehive.resource; | ||||
|  | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.ResponseEntity; | ||||
| import org.springframework.security.core.Authentication; | ||||
| import org.springframework.security.core.context.SecurityContextHolder; | ||||
| import org.springframework.web.bind.annotation.GetMapping; | ||||
| import org.springframework.web.bind.annotation.RequestMapping; | ||||
| import org.springframework.web.bind.annotation.RestController; | ||||
| import wtf.beatrice.releasehive.model.User; | ||||
| import wtf.beatrice.releasehive.service.UserService; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| @RestController | ||||
| @RequestMapping("/api/v1/users") | ||||
| public class UserResource | ||||
| { | ||||
|     private final UserService userService; | ||||
|  | ||||
|     public UserResource(@Autowired UserService userService) | ||||
|     { | ||||
|         this.userService = userService; | ||||
|     } | ||||
|  | ||||
|     @GetMapping( | ||||
|             value = "/me", | ||||
|             produces = "application/json") | ||||
|     public ResponseEntity<User> authenticatedUser() { | ||||
|  | ||||
|         Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); | ||||
|         User currentUser = (User) authentication.getPrincipal(); | ||||
|  | ||||
|         return ResponseEntity.ok(currentUser); | ||||
|     } | ||||
|  | ||||
|     @GetMapping( | ||||
|             value = "/all", | ||||
|             produces = "application/json") | ||||
|     public ResponseEntity<List<User>> getAllUsers() { | ||||
|         List<User> users = userService.getAllUsers(); | ||||
|         return ResponseEntity.ok(users); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -6,8 +6,8 @@ import io.jsonwebtoken.SignatureAlgorithm; | ||||
| import io.jsonwebtoken.io.Decoders; | ||||
| import io.jsonwebtoken.security.Keys; | ||||
| import org.springframework.beans.factory.annotation.Value; | ||||
| import org.springframework.security.core.userdetails.UserDetails; | ||||
| import org.springframework.stereotype.Service; | ||||
| import wtf.beatrice.releasehive.model.User; | ||||
|  | ||||
| import java.security.Key; | ||||
| import java.util.Date; | ||||
| @@ -24,7 +24,7 @@ public class JWTService | ||||
|     @Value("${security.jwt.expiration-time}") | ||||
|     private long jwtExpiration; | ||||
|  | ||||
|     public String extractUsername(String token) { | ||||
|     public String extractEmail(String token) { | ||||
|         return extractClaim(token, Claims::getSubject); | ||||
|     } | ||||
|  | ||||
| @@ -33,11 +33,11 @@ public class JWTService | ||||
|         return claimsResolver.apply(claims); | ||||
|     } | ||||
|  | ||||
|     public String generateToken(UserDetails userDetails) { | ||||
|     public String generateToken(User userDetails) { | ||||
|         return generateToken(new HashMap<>(), userDetails); | ||||
|     } | ||||
|  | ||||
|     public String generateToken(Map<String, Object> extraClaims, UserDetails userDetails) { | ||||
|     public String generateToken(Map<String, Object> extraClaims, User userDetails) { | ||||
|         return buildToken(extraClaims, userDetails, jwtExpiration); | ||||
|     } | ||||
|  | ||||
| @@ -47,22 +47,22 @@ public class JWTService | ||||
|  | ||||
|     private String buildToken( | ||||
|             Map<String, Object> extraClaims, | ||||
|             UserDetails userDetails, | ||||
|             User userDetails, | ||||
|             long expiration | ||||
|     ) { | ||||
|         return Jwts | ||||
|                 .builder() | ||||
|                 .setClaims(extraClaims) | ||||
|                 .setSubject(userDetails.getUsername()) | ||||
|                 .setSubject(userDetails.getEmail()) | ||||
|                 .setIssuedAt(new Date(System.currentTimeMillis())) | ||||
|                 .setExpiration(new Date(System.currentTimeMillis() + expiration)) | ||||
|                 .signWith(getSignInKey(), SignatureAlgorithm.HS256) | ||||
|                 .compact(); | ||||
|     } | ||||
|  | ||||
|     public boolean isTokenValid(String token, UserDetails userDetails) { | ||||
|         final String username = extractUsername(token); | ||||
|         return (username.equals(userDetails.getUsername())) && !isTokenExpired(token); | ||||
|     public boolean isTokenValid(String token, User userDetails) { | ||||
|         final String email = extractEmail(token); | ||||
|         return (email.equals(userDetails.getEmail())) && !isTokenExpired(token); | ||||
|     } | ||||
|  | ||||
|     private boolean isTokenExpired(String token) { | ||||
|   | ||||
| @@ -0,0 +1,25 @@ | ||||
| package wtf.beatrice.releasehive.service; | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.security.core.userdetails.UsernameNotFoundException; | ||||
| import org.springframework.stereotype.Service; | ||||
| import wtf.beatrice.releasehive.model.User; | ||||
| import wtf.beatrice.releasehive.repository.UserRepository; | ||||
|  | ||||
| @Service | ||||
| public class UserDetailsExtendedService { | ||||
|  | ||||
|     private final UserRepository userRepository; | ||||
|  | ||||
|     public UserDetailsExtendedService(@Autowired UserRepository userRepository) { | ||||
|         this.userRepository = userRepository; | ||||
|     } | ||||
|  | ||||
|     public User loadUserByUsername(String username) throws UsernameNotFoundException { | ||||
|         return userRepository.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException(username)); | ||||
|     } | ||||
|  | ||||
|     public User loadUserByEmail(String email) throws UsernameNotFoundException { | ||||
|         return userRepository.findByEmail(email).orElseThrow(() -> new UsernameNotFoundException(email)); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,23 @@ | ||||
| package wtf.beatrice.releasehive.service; | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.stereotype.Service; | ||||
| import wtf.beatrice.releasehive.model.User; | ||||
| import wtf.beatrice.releasehive.repository.UserRepository; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| @Service | ||||
| public class UserService | ||||
| { | ||||
|     private final UserRepository userRepository; | ||||
|  | ||||
|     public UserService(@Autowired UserRepository userRepository) { | ||||
|         this.userRepository = userRepository; | ||||
|     } | ||||
|  | ||||
|     public List<User> getAllUsers() { | ||||
|         return userRepository.findAll(); | ||||
|     } | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user