Add 'update user' endpoint
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user