implement registration validity checks
	
		
			
	
		
	
	
		
	
		
			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:
		| @@ -7,11 +7,14 @@ import org.springframework.security.authentication.AuthenticationManager; | ||||
| import org.springframework.security.authentication.AuthenticationProvider; | ||||
| import org.springframework.security.authentication.dao.DaoAuthenticationProvider; | ||||
| import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; | ||||
| import org.springframework.security.core.userdetails.UserDetails; | ||||
| import org.springframework.security.core.userdetails.UserDetailsService; | ||||
| import org.springframework.security.core.userdetails.UsernameNotFoundException; | ||||
| import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | ||||
| import wtf.beatrice.releasehive.repositories.UserRepository; | ||||
|  | ||||
| import java.util.function.Supplier; | ||||
|  | ||||
| @Configuration | ||||
| public class ApplicationConfiguration | ||||
| { | ||||
| @@ -24,7 +27,7 @@ public class ApplicationConfiguration | ||||
|  | ||||
|     @Bean | ||||
|     UserDetailsService userDetailsService() { | ||||
|         return email -> userRepository.findByEmail(email) | ||||
|         return authParameter -> userRepository.findByEmail(authParameter) | ||||
|                 .orElseThrow(() -> new UsernameNotFoundException("User not found")); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -0,0 +1,8 @@ | ||||
| package wtf.beatrice.releasehive.config; | ||||
|  | ||||
| public class InternalConfiguration | ||||
| { | ||||
|     public static final String EMAIL_REGEX_RCF = "(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"; | ||||
|     public static final String USERNAME_REGEX = "^[a-zA-Z0-9_-]{3,16}$"; | ||||
|     public static final String PASSWORD_REGEX = "^.{6,128}$"; | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| package wtf.beatrice.releasehive.exceptions; | ||||
|  | ||||
| public class HiveException extends Exception | ||||
| { | ||||
|     public HiveException(String message, Throwable cause) { | ||||
|         super(message, cause); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,6 +1,7 @@ | ||||
| package wtf.beatrice.releasehive.exceptions; | ||||
|  | ||||
| import io.jsonwebtoken.ExpiredJwtException; | ||||
| import org.apache.coyote.BadRequestException; | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.springframework.http.HttpStatusCode; | ||||
| @@ -25,6 +26,11 @@ public class RestExceptionHandler | ||||
|  | ||||
|         LOGGER.error(exception); | ||||
|  | ||||
|         if(exception instanceof BadRequestException) { | ||||
|             errorDetail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(400), exception.getMessage()); | ||||
|             errorDetail.setProperty(DESCRIPTION_PROPERTY, "Bad request"); | ||||
|         } | ||||
|  | ||||
|         if (exception instanceof BadCredentialsException) { | ||||
|             errorDetail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(401), exception.getMessage()); | ||||
|             errorDetail.setProperty(DESCRIPTION_PROPERTY, "Invalid email or password"); | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| package wtf.beatrice.releasehive.resources; | ||||
| 
 | ||||
| import org.apache.coyote.BadRequestException; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.http.ResponseEntity; | ||||
| import org.springframework.web.bind.annotation.PostMapping; | ||||
| import org.springframework.web.bind.annotation.RequestBody; | ||||
| @@ -15,12 +17,12 @@ import wtf.beatrice.releasehive.services.JWTService; | ||||
| 
 | ||||
| @RestController | ||||
| @RequestMapping("/api/v1/auth") | ||||
| public class AccountResource { | ||||
| public class AuthResource { | ||||
| 
 | ||||
|     private final AccountService accountService; | ||||
|     private final JWTService jwtService; | ||||
| 
 | ||||
|     public AccountResource( | ||||
|     public AuthResource( | ||||
|             @Autowired AccountService accountService, | ||||
|             @Autowired JWTService jwtService) { | ||||
|         this.accountService = accountService; | ||||
| @@ -30,8 +32,7 @@ public class AccountResource { | ||||
|     @PostMapping( | ||||
|             value="/register", | ||||
|             produces="application/json") | ||||
|     public ResponseEntity<User> register(@RequestBody RegisterUserDto userDto) | ||||
|     { | ||||
|     public ResponseEntity<User> register(@RequestBody RegisterUserDto userDto) throws BadRequestException { | ||||
|         User user = accountService.register(userDto); | ||||
|         return ResponseEntity.ok(user); | ||||
|     } | ||||
| @@ -1,5 +1,6 @@ | ||||
| package wtf.beatrice.releasehive.services; | ||||
|  | ||||
| import org.apache.coyote.BadRequestException; | ||||
| import wtf.beatrice.releasehive.dtos.LoginUserDto; | ||||
| import wtf.beatrice.releasehive.dtos.RegisterUserDto; | ||||
| import wtf.beatrice.releasehive.models.User; | ||||
| @@ -7,7 +8,7 @@ import wtf.beatrice.releasehive.models.User; | ||||
| public interface AccountService | ||||
| { | ||||
|  | ||||
|     User register(RegisterUserDto user); | ||||
|     User register(RegisterUserDto user) throws BadRequestException; | ||||
|  | ||||
|     User login(LoginUserDto user); | ||||
| } | ||||
|   | ||||
| @@ -1,12 +1,17 @@ | ||||
| package wtf.beatrice.releasehive.services; | ||||
|  | ||||
| import org.apache.coyote.BadRequestException; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.http.ResponseEntity; | ||||
| import org.springframework.security.authentication.AuthenticationManager; | ||||
| import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | ||||
| import org.springframework.security.crypto.password.PasswordEncoder; | ||||
| import org.springframework.stereotype.Service; | ||||
| import wtf.beatrice.releasehive.config.InternalConfiguration; | ||||
| import wtf.beatrice.releasehive.dtos.LoginUserDto; | ||||
| import wtf.beatrice.releasehive.dtos.RegisterUserDto; | ||||
| import wtf.beatrice.releasehive.exceptions.HiveException; | ||||
| import wtf.beatrice.releasehive.models.User; | ||||
| import wtf.beatrice.releasehive.repositories.UserRepository; | ||||
|  | ||||
| @@ -28,7 +33,37 @@ public class AccountServiceImpl implements AccountService { | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public User register(RegisterUserDto userDto) { | ||||
|     public User register(RegisterUserDto userDto) throws BadRequestException { | ||||
|  | ||||
|         if (userDto.getEmail() == null || | ||||
|                 userDto.getEmail().isEmpty() || | ||||
|                 userDto.getPassword() == null || | ||||
|                 userDto.getPassword().isEmpty() || | ||||
|                 userDto.getUsername() == null || | ||||
|                 userDto.getUsername().isEmpty()) { | ||||
|  | ||||
|             throw new BadRequestException("Please provide a valid email, password, and username"); | ||||
|         } | ||||
|  | ||||
|         if(!userDto.getEmail().matches(InternalConfiguration.EMAIL_REGEX_RCF)) { | ||||
|             throw new BadRequestException("Invalid email format"); | ||||
|         } | ||||
|  | ||||
|         if(!userDto.getUsername().matches(InternalConfiguration.USERNAME_REGEX)) { | ||||
|             throw new BadRequestException("Username contains invalid characters"); | ||||
|         } | ||||
|  | ||||
|         if(!userDto.getPassword().matches(InternalConfiguration.PASSWORD_REGEX)) { | ||||
|             throw new BadRequestException("Invalid password format"); | ||||
|         } | ||||
|  | ||||
|         if (userRepository.findByEmail(userDto.getEmail()).isPresent()) { | ||||
|             throw new BadRequestException("An account already exists with this email"); | ||||
|         } | ||||
|  | ||||
|         if(userRepository.findByUsername(userDto.getUsername()).isPresent()) { | ||||
|             throw new BadRequestException("Username already in use"); | ||||
|         } | ||||
|  | ||||
|         User user = new User(); | ||||
|         user.setUsername(userDto.getUsername()); | ||||
|   | ||||
| @@ -1,31 +1,15 @@ | ||||
| package wtf.beatrice.releasehive.services; | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.security.core.userdetails.UsernameNotFoundException; | ||||
| import org.springframework.stereotype.Service; | ||||
| import wtf.beatrice.releasehive.models.User; | ||||
| import wtf.beatrice.releasehive.repositories.UserRepository; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| @Service | ||||
| public class UserService | ||||
| public interface UserService | ||||
| { | ||||
|     private final UserRepository userRepository; | ||||
|     List<User> getAllUsers(); | ||||
|  | ||||
|     public UserService(@Autowired UserRepository userRepository) { | ||||
|         this.userRepository = userRepository; | ||||
|     } | ||||
|     User loadUserByUsername(String username) throws UsernameNotFoundException; | ||||
|  | ||||
|     public List<User> getAllUsers() { | ||||
|         return userRepository.findAll(); | ||||
|     } | ||||
|  | ||||
|     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)); | ||||
|     } | ||||
|     User loadUserByEmail(String email) throws UsernameNotFoundException; | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,34 @@ | ||||
| package wtf.beatrice.releasehive.services; | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.security.core.userdetails.UsernameNotFoundException; | ||||
| import org.springframework.stereotype.Service; | ||||
| import wtf.beatrice.releasehive.models.User; | ||||
| import wtf.beatrice.releasehive.repositories.UserRepository; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| @Service | ||||
| public class UserServiceImpl implements UserService | ||||
| { | ||||
|     private final UserRepository userRepository; | ||||
|  | ||||
|     public UserServiceImpl(@Autowired UserRepository userRepository) { | ||||
|         this.userRepository = userRepository; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<User> getAllUsers() { | ||||
|         return userRepository.findAll(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public User loadUserByUsername(String username) throws UsernameNotFoundException { | ||||
|         return userRepository.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException(username)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public User loadUserByEmail(String email) throws UsernameNotFoundException { | ||||
|         return userRepository.findByEmail(email).orElseThrow(() -> new UsernameNotFoundException(email)); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user