Added user preferences endpoints.

This commit is contained in:
Andrew Lalis 2023-02-06 10:17:50 +01:00
parent 9218a38850
commit e69008a582
6 changed files with 96 additions and 34 deletions

View File

@ -68,29 +68,6 @@ public class AuthController {
return tokenService.regenerateAccessToken(auth); return tokenService.regenerateAccessToken(auth);
} }
/**
* Gets information about the user, as determined by the provided access
* token.
* @param user The user that requested information.
* @return The user data.
*/
@GetMapping(path = "/auth/me")
public UserResponse getMyUser(@AuthenticationPrincipal User user) {
return new UserResponse(user);
}
/**
* Endpoint for updating one's own password.
* @param user The user that's updating their password.
* @param payload The payload with the new password.
* @return An empty 200 OK response.
*/
@PostMapping(path = "/auth/me/password")
public ResponseEntity<Void> updateMyPassword(@AuthenticationPrincipal User user, @RequestBody PasswordUpdatePayload payload) {
userService.updatePassword(user.getId(), payload);
return ResponseEntity.ok().build();
}
/** /**
* <strong>Public endpoint</strong> for requesting a reset code to be sent * <strong>Public endpoint</strong> for requesting a reset code to be sent
* to an account with the given email address. * to an account with the given email address.

View File

@ -1,10 +1,9 @@
package nl.andrewlalis.gymboard_api.domains.auth.controller; package nl.andrewlalis.gymboard_api.domains.auth.controller;
import nl.andrewlalis.gymboard_api.domains.auth.dto.UserPersonalDetailsPayload; import nl.andrewlalis.gymboard_api.domains.auth.dto.*;
import nl.andrewlalis.gymboard_api.domains.auth.dto.UserPersonalDetailsResponse;
import nl.andrewlalis.gymboard_api.domains.auth.dto.UserResponse;
import nl.andrewlalis.gymboard_api.domains.auth.model.User; import nl.andrewlalis.gymboard_api.domains.auth.model.User;
import nl.andrewlalis.gymboard_api.domains.auth.service.UserService; import nl.andrewlalis.gymboard_api.domains.auth.service.UserService;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -19,16 +18,52 @@ public class UserController {
this.userService = userService; this.userService = userService;
} }
/**
* Gets information about the user, as determined by the provided access
* token.
* @param user The user that requested information.
* @return The user data.
*/
@GetMapping(path = "/auth/me")
public UserResponse getMyUser(@AuthenticationPrincipal User user) {
return new UserResponse(user);
}
/**
* Endpoint for updating one's own password.
* @param user The user that's updating their password.
* @param payload The payload with the new password.
* @return An empty 200 OK response.
*/
@PostMapping(path = "/auth/me/password")
public ResponseEntity<Void> updateMyPassword(@AuthenticationPrincipal User user, @RequestBody PasswordUpdatePayload payload) {
userService.updatePassword(user.getId(), payload);
return ResponseEntity.ok().build();
}
@GetMapping(path = "/auth/me/personal-details") @GetMapping(path = "/auth/me/personal-details")
public UserPersonalDetailsResponse getMyPersonalDetails(@AuthenticationPrincipal User user) { public UserPersonalDetailsResponse getMyPersonalDetails(@AuthenticationPrincipal User user) {
return userService.getPersonalDetails(user.getId()); return userService.getPersonalDetails(user.getId());
} }
@PostMapping(path = "/auth/me/personal-details") @PostMapping(path = "/auth/me/personal-details")
public UserResponse updateMyPersonalDetails( public UserPersonalDetailsResponse updateMyPersonalDetails(
@AuthenticationPrincipal User user, @AuthenticationPrincipal User user,
@RequestBody UserPersonalDetailsPayload payload @RequestBody UserPersonalDetailsPayload payload
) { ) {
return userService.updatePersonalDetails(user.getId(), payload); return userService.updatePersonalDetails(user.getId(), payload);
} }
@GetMapping(path = "/auth/me/preferences")
public UserPreferencesResponse getMyPreferences(@AuthenticationPrincipal User user) {
return userService.getPreferences(user.getId());
}
@PostMapping(path = "/auth/me/preferences")
public UserPreferencesResponse updateMyPreferences(
@AuthenticationPrincipal User user,
@RequestBody UserPreferencesPayload payload
) {
return userService.updatePreferences(user.getId(), payload);
}
} }

View File

@ -0,0 +1,9 @@
package nl.andrewlalis.gymboard_api.domains.auth.dao;
import nl.andrewlalis.gymboard_api.domains.auth.model.UserPreferences;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserPreferencesRepository extends JpaRepository<UserPreferences, String> {
}

View File

@ -0,0 +1,6 @@
package nl.andrewlalis.gymboard_api.domains.auth.dto;
public record UserPreferencesPayload(
boolean accountPrivate,
String locale
) {}

View File

@ -0,0 +1,17 @@
package nl.andrewlalis.gymboard_api.domains.auth.dto;
import nl.andrewlalis.gymboard_api.domains.auth.model.UserPreferences;
public record UserPreferencesResponse(
String userId,
boolean accountPrivate,
String locale
) {
public UserPreferencesResponse(UserPreferences p) {
this(
p.getUserId(),
p.isAccountPrivate(),
p.getLocale()
);
}
}

View File

@ -3,10 +3,7 @@ package nl.andrewlalis.gymboard_api.domains.auth.service;
import jakarta.mail.MessagingException; import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage; import jakarta.mail.internet.MimeMessage;
import nl.andrewlalis.gymboard_api.domains.api.model.WeightUnit; import nl.andrewlalis.gymboard_api.domains.api.model.WeightUnit;
import nl.andrewlalis.gymboard_api.domains.auth.dao.PasswordResetCodeRepository; import nl.andrewlalis.gymboard_api.domains.auth.dao.*;
import nl.andrewlalis.gymboard_api.domains.auth.dao.UserActivationCodeRepository;
import nl.andrewlalis.gymboard_api.domains.auth.dao.UserPersonalDetailsRepository;
import nl.andrewlalis.gymboard_api.domains.auth.dao.UserRepository;
import nl.andrewlalis.gymboard_api.domains.auth.dto.*; import nl.andrewlalis.gymboard_api.domains.auth.dto.*;
import nl.andrewlalis.gymboard_api.domains.auth.model.PasswordResetCode; import nl.andrewlalis.gymboard_api.domains.auth.model.PasswordResetCode;
import nl.andrewlalis.gymboard_api.domains.auth.model.User; import nl.andrewlalis.gymboard_api.domains.auth.model.User;
@ -38,6 +35,7 @@ public class UserService {
private final UserRepository userRepository; private final UserRepository userRepository;
private final UserPersonalDetailsRepository userPersonalDetailsRepository; private final UserPersonalDetailsRepository userPersonalDetailsRepository;
private final UserPreferencesRepository userPreferencesRepository;
private final UserActivationCodeRepository activationCodeRepository; private final UserActivationCodeRepository activationCodeRepository;
private final PasswordResetCodeRepository passwordResetCodeRepository; private final PasswordResetCodeRepository passwordResetCodeRepository;
private final ULID ulid; private final ULID ulid;
@ -49,7 +47,9 @@ public class UserService {
public UserService( public UserService(
UserRepository userRepository, UserRepository userRepository,
UserPersonalDetailsRepository userPersonalDetailsRepository, UserActivationCodeRepository activationCodeRepository, UserPersonalDetailsRepository userPersonalDetailsRepository,
UserPreferencesRepository userPreferencesRepository,
UserActivationCodeRepository activationCodeRepository,
PasswordResetCodeRepository passwordResetCodeRepository, PasswordResetCodeRepository passwordResetCodeRepository,
ULID ulid, ULID ulid,
PasswordEncoder passwordEncoder, PasswordEncoder passwordEncoder,
@ -57,6 +57,7 @@ public class UserService {
) { ) {
this.userRepository = userRepository; this.userRepository = userRepository;
this.userPersonalDetailsRepository = userPersonalDetailsRepository; this.userPersonalDetailsRepository = userPersonalDetailsRepository;
this.userPreferencesRepository = userPreferencesRepository;
this.activationCodeRepository = activationCodeRepository; this.activationCodeRepository = activationCodeRepository;
this.passwordResetCodeRepository = passwordResetCodeRepository; this.passwordResetCodeRepository = passwordResetCodeRepository;
this.ulid = ulid; this.ulid = ulid;
@ -228,7 +229,7 @@ public class UserService {
} }
@Transactional @Transactional
public UserResponse updatePersonalDetails(String id, UserPersonalDetailsPayload payload) { public UserPersonalDetailsResponse updatePersonalDetails(String id, UserPersonalDetailsPayload payload) {
User user = userRepository.findById(id) User user = userRepository.findById(id)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
var pd = user.getPersonalDetails(); var pd = user.getPersonalDetails();
@ -249,7 +250,7 @@ public class UserService {
pd.setCurrentMetricWeight(currentMetricWeight); pd.setCurrentMetricWeight(currentMetricWeight);
pd.setSex(UserPersonalDetails.PersonSex.parse(payload.sex())); pd.setSex(UserPersonalDetails.PersonSex.parse(payload.sex()));
user = userRepository.save(user); user = userRepository.save(user);
return new UserResponse(user); return new UserPersonalDetailsResponse(user.getPersonalDetails());
} }
@Transactional(readOnly = true) @Transactional(readOnly = true)
@ -258,4 +259,21 @@ public class UserService {
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
return new UserPersonalDetailsResponse(pd); return new UserPersonalDetailsResponse(pd);
} }
@Transactional(readOnly = true)
public UserPreferencesResponse getPreferences(String id) {
var p = userPreferencesRepository.findById(id)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
return new UserPreferencesResponse(p);
}
@Transactional
public UserPreferencesResponse updatePreferences(String id, UserPreferencesPayload payload) {
var p = userPreferencesRepository.findById(id)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
p.setAccountPrivate(payload.accountPrivate());
p.setLocale(payload.locale());
p = userPreferencesRepository.save(p);
return new UserPreferencesResponse(p);
}
} }