Add 'update user' endpoint

This commit is contained in:
2023-05-14 00:43:31 +02:00
parent e615d58262
commit fcb6bb063a
4 changed files with 107 additions and 2 deletions

View File

@@ -1,19 +1,48 @@
package net.kapcake.bankingservice.controllers;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import net.kapcake.bankingservice.exceptions.ValidationException;
import net.kapcake.bankingservice.model.dtos.UserUpdateDTO;
import net.kapcake.bankingservice.security.UserDetailsImpl;
import net.kapcake.bankingservice.services.UserService;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import static net.kapcake.bankingservice.controllers.ControllerUtils.getErrorString;
@RestController
@Slf4j
public class AuthController {
private final UserService userService;
public AuthController(UserService userService) {
this.userService = userService;
}
@PostMapping("/login")
public void login(HttpServletRequest request) {
Authentication auth = (Authentication) request.getUserPrincipal();
UserDetailsImpl user = (UserDetailsImpl) auth.getPrincipal();
log.info("User {} logged in.", user.getUsername());
}
@PutMapping("/update-user")
public void updateUser(HttpServletRequest request, @AuthenticationPrincipal UserDetailsImpl authenticatedUser, @RequestBody @Valid UserUpdateDTO userUpdateDTO, BindingResult bindingResult) throws ServletException {
if (bindingResult.hasErrors()) {
String errorString = getErrorString(bindingResult);
throw new ValidationException("User update request invalid: " + errorString);
}
boolean needsLogout = userService.updateUser(authenticatedUser, userUpdateDTO);
if (needsLogout) {
request.logout();
}
}
}

View File

@@ -1,8 +1,7 @@
package net.kapcake.bankingservice.model.domain;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.*;
import lombok.experimental.Accessors;
import java.util.List;
@@ -12,6 +11,9 @@ import java.util.List;
@Accessors(chain = true)
@Getter
@Setter
@Builder(toBuilder = true)
@AllArgsConstructor
@NoArgsConstructor
public class User {
@Id
@GeneratedValue

View File

@@ -0,0 +1,21 @@
package net.kapcake.bankingservice.model.dtos;
import jakarta.validation.constraints.Pattern;
import lombok.Data;
import lombok.experimental.Accessors;
import net.kapcake.bankingservice.validation.AtLeastOneFieldNotEmpty;
import java.io.Serializable;
@Data
@Accessors(chain = true)
@AtLeastOneFieldNotEmpty(fieldNames = {"password", "street", "number", "numberExtension", "postalCode", "country"})
public class UserUpdateDTO implements Serializable {
@Pattern(regexp = "^[^\\s]+$")
private String password;
private String street;
private Integer number;
private String numberExtension;
private Integer postalCode;
private String country;
}

View File

@@ -0,0 +1,53 @@
package net.kapcake.bankingservice.services;
import net.kapcake.bankingservice.model.domain.User;
import net.kapcake.bankingservice.model.dtos.UserUpdateDTO;
import net.kapcake.bankingservice.repositories.UserRepository;
import net.kapcake.bankingservice.security.UserDetailsImpl;
import org.modelmapper.ModelMapper;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository userRepository;
private final ModelMapper modelMapper;
private final PasswordEncoder passwordEncoder;
public UserService(UserRepository userRepository, ModelMapper modelMapper, PasswordEncoder passwordEncoder) {
this.userRepository = userRepository;
this.modelMapper = modelMapper;
this.passwordEncoder = passwordEncoder;
}
public boolean updateUser(UserDetailsImpl authenticatedUser, UserUpdateDTO userUpdateDTO) {
boolean needsLogout = false;
User user = userRepository.findByUsername(authenticatedUser.getUsername()).orElseThrow();
User.UserBuilder builder = user.toBuilder();
if (userUpdateDTO.getCountry() != null) {
builder.country(userUpdateDTO.getCountry());
}
if (userUpdateDTO.getStreet() != null) {
builder.street(userUpdateDTO.getStreet());
}
if (userUpdateDTO.getPostalCode() != null) {
builder.postalCode(userUpdateDTO.getPostalCode());
}
if (userUpdateDTO.getNumber() != null) {
builder.number(userUpdateDTO.getNumber());
}
if (userUpdateDTO.getNumberExtension() != null) {
builder.numberExtension(userUpdateDTO.getNumberExtension());
}
if (userUpdateDTO.getPassword() != null) {
builder.password(passwordEncoder.encode(userUpdateDTO.getPassword()));
needsLogout = true;
}
User updatedUser = builder.build();
userRepository.save(updatedUser);
return needsLogout;
}
}