From a929a4ee482ea0cd04d935952014f2ccd4f98434 Mon Sep 17 00:00:00 2001 From: Rainnny7 Date: Wed, 18 Sep 2024 18:23:18 -0400 Subject: [PATCH] return the user as well as the session when authenticating --- .gitea/workflows/deploy.yml | 6 ++--- .../cc/pulseapp/api/common/StringUtils.java | 2 +- .../api/controller/v1/AuthController.java | 10 +++---- .../model/user/response/UserAuthResponse.java | 26 +++++++++++++++++++ .../cc/pulseapp/api/service/AuthService.java | 23 ++++++++-------- .../pulseapp/api/service/CaptchaService.java | 3 ++- 6 files changed, 49 insertions(+), 21 deletions(-) create mode 100644 src/main/java/cc/pulseapp/api/model/user/response/UserAuthResponse.java diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 50f4559..5380ade 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -2,7 +2,7 @@ name: Deploy API on: push: - branches: ["master"] + branches: [ "master" ] paths-ignore: - README.md - LICENSE @@ -11,8 +11,8 @@ jobs: deploy: strategy: matrix: - arch: ["ubuntu-latest"] - git-version: ["2.44.0"] + arch: [ "ubuntu-latest" ] + git-version: [ "2.44.0" ] runs-on: ${{ matrix.arch }} # Steps to run diff --git a/src/main/java/cc/pulseapp/api/common/StringUtils.java b/src/main/java/cc/pulseapp/api/common/StringUtils.java index b3ec8a9..43bb2a9 100644 --- a/src/main/java/cc/pulseapp/api/common/StringUtils.java +++ b/src/main/java/cc/pulseapp/api/common/StringUtils.java @@ -18,7 +18,7 @@ public final class StringUtils { private static final SecureRandom RANDOM = new SecureRandom(); private static final Pattern EMAIL_PATTERN = Pattern.compile("^[A-Za-z0-9+_.-]+@(.+)$"); - private static final Pattern USERNAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_.]*$"); + private static final Pattern USERNAME_PATTERN = Pattern.compile("^[a-z0-9_.]*$"); /** * Check if the given email is valid. diff --git a/src/main/java/cc/pulseapp/api/controller/v1/AuthController.java b/src/main/java/cc/pulseapp/api/controller/v1/AuthController.java index 668fb96..13beba5 100644 --- a/src/main/java/cc/pulseapp/api/controller/v1/AuthController.java +++ b/src/main/java/cc/pulseapp/api/controller/v1/AuthController.java @@ -1,9 +1,9 @@ package cc.pulseapp.api.controller.v1; import cc.pulseapp.api.exception.impl.BadRequestException; -import cc.pulseapp.api.model.user.Session; import cc.pulseapp.api.model.user.input.UserLoginInput; import cc.pulseapp.api.model.user.input.UserRegistrationInput; +import cc.pulseapp.api.model.user.response.UserAuthResponse; import cc.pulseapp.api.service.AuthService; import jakarta.servlet.http.HttpServletRequest; import lombok.NonNull; @@ -39,11 +39,11 @@ public final class AuthController { * * @param request the http request * @param input the registration input - * @return the session for the registered user + * @return the user auth response * @throws BadRequestException if the registration fails */ @PostMapping("/register") @ResponseBody @NonNull - public ResponseEntity register(@NonNull HttpServletRequest request, UserRegistrationInput input) throws BadRequestException { + public ResponseEntity register(@NonNull HttpServletRequest request, UserRegistrationInput input) throws BadRequestException { return ResponseEntity.ok(authService.registerUser(request, input)); } @@ -52,11 +52,11 @@ public final class AuthController { * * @param request the http request * @param input the login input - * @return the session for the login user + * @return the user auth response * @throws BadRequestException if the login fails */ @PostMapping("/login") @ResponseBody @NonNull - public ResponseEntity login(@NonNull HttpServletRequest request, UserLoginInput input) throws BadRequestException { + public ResponseEntity login(@NonNull HttpServletRequest request, UserLoginInput input) throws BadRequestException { return ResponseEntity.ok(authService.loginUser(request, input)); } } \ No newline at end of file diff --git a/src/main/java/cc/pulseapp/api/model/user/response/UserAuthResponse.java b/src/main/java/cc/pulseapp/api/model/user/response/UserAuthResponse.java new file mode 100644 index 0000000..acb7841 --- /dev/null +++ b/src/main/java/cc/pulseapp/api/model/user/response/UserAuthResponse.java @@ -0,0 +1,26 @@ +package cc.pulseapp.api.model.user.response; + +import cc.pulseapp.api.model.user.Session; +import cc.pulseapp.api.model.user.UserDTO; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NonNull; +import lombok.ToString; + +/** + * The response for successfully logging in. + * + * @author Braydon + */ +@AllArgsConstructor @Getter @ToString +public final class UserAuthResponse { + /** + * The created session for the user. + */ + @NonNull private final Session session; + + /** + * The user logging in. + */ + @NonNull private final UserDTO user; +} \ No newline at end of file diff --git a/src/main/java/cc/pulseapp/api/service/AuthService.java b/src/main/java/cc/pulseapp/api/service/AuthService.java index 8406500..f2a80c5 100644 --- a/src/main/java/cc/pulseapp/api/service/AuthService.java +++ b/src/main/java/cc/pulseapp/api/service/AuthService.java @@ -7,12 +7,10 @@ import cc.pulseapp.api.exception.impl.BadRequestException; import cc.pulseapp.api.exception.impl.ResourceNotFoundException; import cc.pulseapp.api.model.Feature; import cc.pulseapp.api.model.IGenericResponse; -import cc.pulseapp.api.model.user.Session; -import cc.pulseapp.api.model.user.User; -import cc.pulseapp.api.model.user.UserFlag; -import cc.pulseapp.api.model.user.UserTier; +import cc.pulseapp.api.model.user.*; import cc.pulseapp.api.model.user.input.UserLoginInput; import cc.pulseapp.api.model.user.input.UserRegistrationInput; +import cc.pulseapp.api.model.user.response.UserAuthResponse; import cc.pulseapp.api.repository.SessionRepository; import cc.pulseapp.api.repository.UserRepository; import jakarta.servlet.http.HttpServletRequest; @@ -64,11 +62,11 @@ public final class AuthService { * * @param request the http request * @param input the registration input - * @return the registered user's auth token + * @return the user auth response * @throws BadRequestException if the input has an error */ @NonNull - public Session registerUser(@NonNull HttpServletRequest request, UserRegistrationInput input) throws BadRequestException { + public UserAuthResponse registerUser(@NonNull HttpServletRequest request, UserRegistrationInput input) throws BadRequestException { // Ensure user registration is enabled if (!Feature.USER_REGISTRATION_ENABLED.isEnabled()) { throw new BadRequestException(Error.REGISTRATION_DISABLED); @@ -83,11 +81,12 @@ public final class AuthService { // Create the user and return it byte[] salt = HashUtils.generateSalt(); Date now = new Date(); - return generateSession(request, userRepository.save(new User( + User user = userRepository.save(new User( snowflakeService.generateSnowflake(), input.getEmail(), input.getUsername().toLowerCase(), HashUtils.hash(salt, input.getPassword()), Base64.getEncoder().encodeToString(salt), null, UserTier.FREE, 0, now - ))); + )); + return new UserAuthResponse(generateSession(request, user), UserDTO.asDTO(user, now)); } /** @@ -95,11 +94,11 @@ public final class AuthService { * * @param request the http request * @param input the login input - * @return the logged in user's auth token + * @return the user auth response * @throws BadRequestException if the input has an error */ @NonNull - public Session loginUser(@NonNull HttpServletRequest request, UserLoginInput input) throws BadRequestException { + public UserAuthResponse loginUser(@NonNull HttpServletRequest request, UserLoginInput input) throws BadRequestException { validateLoginInput(input); // Ensure the input is valid // Lookup the user by the email or username and ensure the user exists @@ -112,7 +111,9 @@ public final class AuthService { throw new BadRequestException(Error.PASSWORDS_DO_NOT_MATCH); } user.setLastLogin(new Date()); - return generateSession(request, userRepository.save(user)); + user = userRepository.save(user); + return new UserAuthResponse(generateSession(request, user), + UserDTO.asDTO(user, new Date(snowflakeService.extractCreationTime(user.getSnowflake())))); } /** diff --git a/src/main/java/cc/pulseapp/api/service/CaptchaService.java b/src/main/java/cc/pulseapp/api/service/CaptchaService.java index bdc3d79..299dbef 100644 --- a/src/main/java/cc/pulseapp/api/service/CaptchaService.java +++ b/src/main/java/cc/pulseapp/api/service/CaptchaService.java @@ -1,5 +1,6 @@ package cc.pulseapp.api.service; +import cc.pulseapp.api.common.EnvironmentUtils; import cc.pulseapp.api.exception.impl.BadRequestException; import cc.pulseapp.api.model.IGenericResponse; import com.google.gson.JsonObject; @@ -33,7 +34,7 @@ public final class CaptchaService { .header(HttpHeaders.CONTENT_TYPE, "application/json") .body(body) .asJson(); - if (!response.getBody().getObject().getBoolean("success")) { + if (EnvironmentUtils.isProduction() && !response.getBody().getObject().getBoolean("success")) { throw new BadRequestException(Error.CAPTCHA_INVALID); } }