From 7bee1d38b3ea6129048683d8b73570be61a447c0 Mon Sep 17 00:00:00 2001 From: Rainnny7 Date: Thu, 19 Sep 2024 07:36:52 -0400 Subject: [PATCH] add the logout endpoint --- .../java/cc/pulseapp/api/common/Tuple.java | 16 ++++++++++++++++ .../api/controller/v1/UserController.java | 18 ++++++++++++++++++ .../cc/pulseapp/api/service/AuthService.java | 14 +++++++++++++- .../cc/pulseapp/api/service/UserService.java | 18 +++++++++++++++++- 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 src/main/java/cc/pulseapp/api/common/Tuple.java diff --git a/src/main/java/cc/pulseapp/api/common/Tuple.java b/src/main/java/cc/pulseapp/api/common/Tuple.java new file mode 100644 index 0000000..99b3079 --- /dev/null +++ b/src/main/java/cc/pulseapp/api/common/Tuple.java @@ -0,0 +1,16 @@ +package cc.pulseapp.api.common; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +/** + * A simple tuple utility. + * + * @author Braydon + */ +@AllArgsConstructor @Setter @Getter +public final class Tuple { + private L left; + private R right; +} \ No newline at end of file diff --git a/src/main/java/cc/pulseapp/api/controller/v1/UserController.java b/src/main/java/cc/pulseapp/api/controller/v1/UserController.java index 6fdbd84..5d35e9a 100644 --- a/src/main/java/cc/pulseapp/api/controller/v1/UserController.java +++ b/src/main/java/cc/pulseapp/api/controller/v1/UserController.java @@ -84,8 +84,26 @@ public final class UserController { return ResponseEntity.ok(userService.setupTwoFactor()); } + /** + * A POST endpoint to enable TFA for a useer. + * + * @param input the input to process + * @return the raw backup codes + * @throws BadRequestException if enabling fails + */ @PostMapping("/enable-tfa") @ResponseBody @NonNull public ResponseEntity> enableTwoFactor(EnableTFAInput input) throws BadRequestException { return ResponseEntity.ok(userService.enableTwoFactor(input)); } + + /** + * A POST endpoint to logout the user. + * + * @return the logout response + */ + @PostMapping("/logout") @ResponseBody @NonNull + public ResponseEntity> logout() { + userService.logout(); + return ResponseEntity.ok(Map.of("success", true)); + } } \ 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 75ae8ef..5f79de0 100644 --- a/src/main/java/cc/pulseapp/api/service/AuthService.java +++ b/src/main/java/cc/pulseapp/api/service/AuthService.java @@ -2,6 +2,7 @@ package cc.pulseapp.api.service; import cc.pulseapp.api.common.HashUtils; import cc.pulseapp.api.common.StringUtils; +import cc.pulseapp.api.common.Tuple; import cc.pulseapp.api.exception.impl.BadRequestException; import cc.pulseapp.api.exception.impl.ResourceNotFoundException; import cc.pulseapp.api.model.Feature; @@ -128,8 +129,19 @@ public final class AuthService { */ @NonNull public User getAuthenticatedUser() throws ResourceNotFoundException { + return getSessionAndUser().getRight(); + } + + /** + * Get the authenticated session and associated user. + * + * @return the authenticated session and user + * @throws ResourceNotFoundException if the user doesn't exist + */ + @NonNull + public Tuple getSessionAndUser() throws ResourceNotFoundException { Session session = (Session) SecurityContextHolder.getContext().getAuthentication().getCredentials(); - return getUserFromSnowflake(session.getUserSnowflake()); + return new Tuple<>(session, getUserFromSnowflake(session.getUserSnowflake())); } /** diff --git a/src/main/java/cc/pulseapp/api/service/UserService.java b/src/main/java/cc/pulseapp/api/service/UserService.java index c3f5ea2..8dbec01 100644 --- a/src/main/java/cc/pulseapp/api/service/UserService.java +++ b/src/main/java/cc/pulseapp/api/service/UserService.java @@ -139,7 +139,8 @@ public final class UserService { } /** - * Start setting up TFA for a user. + * Start setting up TFA for the + * currently authenticated user. * * @return the setup response * @throws BadRequestException if the setup fails @@ -155,6 +156,14 @@ public final class UserService { return new UserSetupTFAResponse(secret, tfaService.generateQrCodeUrl(user.getUsername(), secret)); } + /** + * Enable two-factor auth for the + * currently authenticated user. + * + * @param input the input to process + * @return the raw backup codes + * @throws BadRequestException if enabling fails + */ @NonNull public List enableTwoFactor(EnableTFAInput input) throws BadRequestException { if (input == null || (!input.isValid())) { // Ensure the input was provided @@ -195,6 +204,13 @@ public final class UserService { return originalBackupCodes; } + /** + * Logout the user. + */ + public void logout() { + sessionRepository.delete(authService.getSessionAndUser().getLeft()); + } + /** * User errors. */