add the logout endpoint
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 07:36:52 -04:00
parent b88e512aae
commit 7bee1d38b3
4 changed files with 64 additions and 2 deletions

@ -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<L, R> {
private L left;
private R right;
}

@ -84,8 +84,26 @@ public final class UserController {
return ResponseEntity.ok(userService.setupTwoFactor()); 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 @PostMapping("/enable-tfa") @ResponseBody @NonNull
public ResponseEntity<List<String>> enableTwoFactor(EnableTFAInput input) throws BadRequestException { public ResponseEntity<List<String>> enableTwoFactor(EnableTFAInput input) throws BadRequestException {
return ResponseEntity.ok(userService.enableTwoFactor(input)); return ResponseEntity.ok(userService.enableTwoFactor(input));
} }
/**
* A POST endpoint to logout the user.
*
* @return the logout response
*/
@PostMapping("/logout") @ResponseBody @NonNull
public ResponseEntity<Map<String, Object>> logout() {
userService.logout();
return ResponseEntity.ok(Map.of("success", true));
}
} }

@ -2,6 +2,7 @@ package cc.pulseapp.api.service;
import cc.pulseapp.api.common.HashUtils; import cc.pulseapp.api.common.HashUtils;
import cc.pulseapp.api.common.StringUtils; 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.BadRequestException;
import cc.pulseapp.api.exception.impl.ResourceNotFoundException; import cc.pulseapp.api.exception.impl.ResourceNotFoundException;
import cc.pulseapp.api.model.Feature; import cc.pulseapp.api.model.Feature;
@ -128,8 +129,19 @@ public final class AuthService {
*/ */
@NonNull @NonNull
public User getAuthenticatedUser() throws ResourceNotFoundException { 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<Session, User> getSessionAndUser() throws ResourceNotFoundException {
Session session = (Session) SecurityContextHolder.getContext().getAuthentication().getCredentials(); Session session = (Session) SecurityContextHolder.getContext().getAuthentication().getCredentials();
return getUserFromSnowflake(session.getUserSnowflake()); return new Tuple<>(session, getUserFromSnowflake(session.getUserSnowflake()));
} }
/** /**

@ -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 * @return the setup response
* @throws BadRequestException if the setup fails * @throws BadRequestException if the setup fails
@ -155,6 +156,14 @@ public final class UserService {
return new UserSetupTFAResponse(secret, tfaService.generateQrCodeUrl(user.getUsername(), secret)); 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 @NonNull
public List<String> enableTwoFactor(EnableTFAInput input) throws BadRequestException { public List<String> enableTwoFactor(EnableTFAInput input) throws BadRequestException {
if (input == null || (!input.isValid())) { // Ensure the input was provided if (input == null || (!input.isValid())) { // Ensure the input was provided
@ -195,6 +204,13 @@ public final class UserService {
return originalBackupCodes; return originalBackupCodes;
} }
/**
* Logout the user.
*/
public void logout() {
sessionRepository.delete(authService.getSessionAndUser().getLeft());
}
/** /**
* User errors. * User errors.
*/ */