Add 'update user' endpoint
This commit is contained in:
@@ -1,19 +1,48 @@
|
|||||||
package net.kapcake.bankingservice.controllers;
|
package net.kapcake.bankingservice.controllers;
|
||||||
|
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
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.security.UserDetailsImpl;
|
||||||
|
import net.kapcake.bankingservice.services.UserService;
|
||||||
import org.springframework.security.core.Authentication;
|
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.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import static net.kapcake.bankingservice.controllers.ControllerUtils.getErrorString;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class AuthController {
|
public class AuthController {
|
||||||
|
private final UserService userService;
|
||||||
|
|
||||||
|
public AuthController(UserService userService) {
|
||||||
|
this.userService = userService;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/login")
|
@PostMapping("/login")
|
||||||
public void login(HttpServletRequest request) {
|
public void login(HttpServletRequest request) {
|
||||||
Authentication auth = (Authentication) request.getUserPrincipal();
|
Authentication auth = (Authentication) request.getUserPrincipal();
|
||||||
UserDetailsImpl user = (UserDetailsImpl) auth.getPrincipal();
|
UserDetailsImpl user = (UserDetailsImpl) auth.getPrincipal();
|
||||||
log.info("User {} logged in.", user.getUsername());
|
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;
|
package net.kapcake.bankingservice.model.domain;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import lombok.Getter;
|
import lombok.*;
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -12,6 +11,9 @@ import java.util.List;
|
|||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
|
@Builder(toBuilder = true)
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
public class User {
|
public class User {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue
|
@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