user login border crossing
All checks were successful
Deploy API / deploy (ubuntu-latest, 2.44.0) (push) Successful in 48s

This commit is contained in:
Braydon 2024-09-19 08:15:42 -04:00
parent 7bee1d38b3
commit 8e47214257
2 changed files with 32 additions and 13 deletions

@ -22,6 +22,11 @@ public final class UserLoginInput {
*/ */
private final String password; private final String password;
/**
* The TFA pin of the user to login with.
*/
private final String tfaPin;
/** /**
* The captcha response token to validate. * The captcha response token to validate.
*/ */

@ -43,6 +43,11 @@ public final class AuthService {
*/ */
@NonNull private final SnowflakeService snowflakeService; @NonNull private final SnowflakeService snowflakeService;
/**
* Thw two-factor auth service to use.
*/
@NonNull private final TFAService tfaService;
/** /**
* The repository to store and retrieve users. * The repository to store and retrieve users.
*/ */
@ -55,9 +60,11 @@ public final class AuthService {
@Autowired @Autowired
public AuthService(@NonNull CaptchaService captchaService, @NonNull SnowflakeService snowflakeService, public AuthService(@NonNull CaptchaService captchaService, @NonNull SnowflakeService snowflakeService,
@NonNull UserRepository userRepository, @NonNull SessionRepository sessionRepository) { @NonNull TFAService tfaService, @NonNull UserRepository userRepository,
@NonNull SessionRepository sessionRepository) {
this.captchaService = captchaService; this.captchaService = captchaService;
this.snowflakeService = snowflakeService; this.snowflakeService = snowflakeService;
this.tfaService = tfaService;
this.userRepository = userRepository; this.userRepository = userRepository;
this.sessionRepository = sessionRepository; this.sessionRepository = sessionRepository;
} }
@ -115,6 +122,17 @@ public final class AuthService {
if (!HashUtils.hash(Base64.getDecoder().decode(user.getPasswordSalt()), input.getPassword()).equals(user.getPassword())) { if (!HashUtils.hash(Base64.getDecoder().decode(user.getPasswordSalt()), input.getPassword()).equals(user.getPassword())) {
throw new BadRequestException(Error.PASSWORDS_DO_NOT_MATCH); throw new BadRequestException(Error.PASSWORDS_DO_NOT_MATCH);
} }
// Handle the two-factor auth pin if the user has it enabled
if (user.hasFlag(UserFlag.TFA_ENABLED)) {
String pin = input.getTfaPin();
if (pin == null || (pin.isBlank())) { // No TFA pin received
throw new BadRequestException(Error.BORDER_CROSSING);
}
// Incorrect TFA pin
if (pin.length() != 6 || (!tfaService.getPin(user.getTfa().getSecret()).equals(pin))) {
throw new BadRequestException(Error.TFA_PIN_INVALID);
}
}
user.setLastLogin(new Date()); user.setLastLogin(new Date());
user = userRepository.save(user); user = userRepository.save(user);
return new UserAuthResponse(generateSession(request, user), return new UserAuthResponse(generateSession(request, user),
@ -194,20 +212,16 @@ public final class AuthService {
* @throws BadRequestException if the input has an error * @throws BadRequestException if the input has an error
*/ */
private void validateRegistrationInput(UserRegistrationInput input) throws BadRequestException { private void validateRegistrationInput(UserRegistrationInput input) throws BadRequestException {
// Ensure the input was provided if (input == null || (!input.isValid())) { // Ensure the input was provided
if (input == null || (!input.isValid())) {
throw new BadRequestException(Error.MALFORMED_REGISTRATION_INPUT); throw new BadRequestException(Error.MALFORMED_REGISTRATION_INPUT);
} }
// Ensure the email is valid if (!StringUtils.isValidEmail(input.getEmail())) { // Ensure the email is valid
if (!StringUtils.isValidEmail(input.getEmail())) {
throw new BadRequestException(Error.EMAIL_INVALID); throw new BadRequestException(Error.EMAIL_INVALID);
} }
// Ensure the username is valid if (!StringUtils.isValidUsername(input.getUsername())) { // Ensure the username is valid
if (!StringUtils.isValidUsername(input.getUsername())) {
throw new BadRequestException(Error.USERNAME_INVALID); throw new BadRequestException(Error.USERNAME_INVALID);
} }
// Password and confirmed password must match if (!input.getPassword().equals(input.getPasswordConfirmation())) { // Ensure passwords match
if (!input.getPassword().equals(input.getPasswordConfirmation())) {
throw new BadRequestException(Error.PASSWORDS_DO_NOT_MATCH); throw new BadRequestException(Error.PASSWORDS_DO_NOT_MATCH);
} }
// The password must meet the requirements // The password must meet the requirements
@ -226,12 +240,10 @@ public final class AuthService {
* @throws BadRequestException if the input has an error * @throws BadRequestException if the input has an error
*/ */
private void validateLoginInput(UserLoginInput input) throws BadRequestException { private void validateLoginInput(UserLoginInput input) throws BadRequestException {
// Ensure the input was provided if (input == null || (!input.isValid())) { // Ensure the input was provided
if (input == null || (!input.isValid())) {
throw new BadRequestException(Error.MALFORMED_LOGIN_INPUT); throw new BadRequestException(Error.MALFORMED_LOGIN_INPUT);
} }
// Ensure the email is valid if (!StringUtils.isValidEmail(input.getEmail())) { // Ensure the email is valid
if (input.getEmail() != null && (!StringUtils.isValidEmail(input.getEmail()))) {
throw new BadRequestException(Error.EMAIL_INVALID); throw new BadRequestException(Error.EMAIL_INVALID);
} }
// Finally validate the captcha // Finally validate the captcha
@ -249,6 +261,8 @@ public final class AuthService {
USERNAME_INVALID, USERNAME_INVALID,
USER_NOT_FOUND, USER_NOT_FOUND,
PASSWORDS_DO_NOT_MATCH, PASSWORDS_DO_NOT_MATCH,
BORDER_CROSSING,
TFA_PIN_INVALID,
EMAIL_ALREADY_USED, EMAIL_ALREADY_USED,
USER_DISABLED USER_DISABLED
} }