NCP-3 Add logic update user fields,change password
This commit is contained in:
@@ -0,0 +1,41 @@
|
|||||||
|
package ru.soune.no_copy.configuration;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Primary;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class JacksonConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Primary
|
||||||
|
public ObjectMapper objectMapper() {
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
|
||||||
|
JavaTimeModule javaTimeModule = new JavaTimeModule();
|
||||||
|
|
||||||
|
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(
|
||||||
|
DateTimeFormatter.ofPattern("dd-MM-yyyy")));
|
||||||
|
|
||||||
|
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(
|
||||||
|
DateTimeFormatter.ofPattern("dd-MM-yyyy")));
|
||||||
|
|
||||||
|
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(
|
||||||
|
DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss")));
|
||||||
|
|
||||||
|
mapper.registerModule(javaTimeModule);
|
||||||
|
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||||
|
|
||||||
|
return mapper;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import org.springframework.http.ResponseEntity;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import ru.soune.no_copy.dto.ChangePasswordRequest;
|
import ru.soune.no_copy.dto.ChangePasswordRequest;
|
||||||
import ru.soune.no_copy.dto.UserDTO;
|
import ru.soune.no_copy.dto.UserDTO;
|
||||||
|
import ru.soune.no_copy.dto.UserRequest;
|
||||||
import ru.soune.no_copy.entity.AuthToken;
|
import ru.soune.no_copy.entity.AuthToken;
|
||||||
import ru.soune.no_copy.entity.User;
|
import ru.soune.no_copy.entity.User;
|
||||||
import ru.soune.no_copy.exception.InvalidUserEmail;
|
import ru.soune.no_copy.exception.InvalidUserEmail;
|
||||||
@@ -35,7 +36,7 @@ public class UserController {
|
|||||||
List<UserDTO> allUsers = userRepository.findAll().stream()
|
List<UserDTO> allUsers = userRepository.findAll().stream()
|
||||||
.map(u -> new UserDTO(u.getFullName(), u.getCompany(), u.getEmail(), u.getIsActive(),
|
.map(u -> new UserDTO(u.getFullName(), u.getCompany(), u.getEmail(), u.getIsActive(),
|
||||||
u.getPhone(), u.getGenderType(),
|
u.getPhone(), u.getGenderType(),
|
||||||
u.getBirthday(), u.getCreatedAt()))
|
u.getBirthday(), u.getCreatedAt(), u.getSubscriptionType()))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
return ResponseEntity.ok(allUsers);
|
return ResponseEntity.ok(allUsers);
|
||||||
@@ -61,4 +62,18 @@ public class UserController {
|
|||||||
|
|
||||||
return ResponseEntity.ok(userMapper.toDTO(updateUser));
|
return ResponseEntity.ok(userMapper.toDTO(updateUser));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PatchMapping("/user-update")
|
||||||
|
public ResponseEntity<UserDTO> updateUser(@RequestBody UserRequest userRequest,
|
||||||
|
@RequestHeader("Authorization") String tokenHeader) {
|
||||||
|
String token = tokenHeader.replace("Bearer ", "");
|
||||||
|
|
||||||
|
Optional<AuthToken> tokenOptional = authTokenRepository.findByToken(token);
|
||||||
|
|
||||||
|
AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found"));
|
||||||
|
|
||||||
|
User user = authToken.getUser();
|
||||||
|
|
||||||
|
return ResponseEntity.ok(userService.updateUser(userRequest, user));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,4 +2,9 @@ package ru.soune.no_copy.dto;
|
|||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
public record AuthResponse (boolean success, String message, String token, LocalDateTime expiresAt) {}
|
public record AuthResponse (
|
||||||
|
boolean success,
|
||||||
|
String message,
|
||||||
|
String token,
|
||||||
|
LocalDateTime expiresAt
|
||||||
|
) {}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package ru.soune.no_copy.dto;
|
|||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import jakarta.validation.constraints.Email;
|
import jakarta.validation.constraints.Email;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Past;
|
||||||
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
import ru.soune.no_copy.entity.GenderType;
|
import ru.soune.no_copy.entity.GenderType;
|
||||||
@@ -27,6 +28,7 @@ public record RegisterRequest(
|
|||||||
|
|
||||||
@DateTimeFormat(pattern = "dd-MM-yyyy")
|
@DateTimeFormat(pattern = "dd-MM-yyyy")
|
||||||
@JsonFormat(pattern = "dd-MM-yyyy")
|
@JsonFormat(pattern = "dd-MM-yyyy")
|
||||||
|
@Past
|
||||||
LocalDate birthday,
|
LocalDate birthday,
|
||||||
|
|
||||||
@NotBlank(message = "error.not.blank")
|
@NotBlank(message = "error.not.blank")
|
||||||
|
|||||||
@@ -3,7 +3,13 @@ package ru.soune.no_copy.dto;
|
|||||||
import jakarta.validation.constraints.Email;
|
import jakarta.validation.constraints.Email;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
|
||||||
public record UserContentRequest(@NotBlank @Email String userEmail, @NotBlank String fileName,
|
public record UserContentRequest(
|
||||||
@NotBlank String originalFilename, @NotBlank String fileType,
|
@NotBlank @Email String userEmail,
|
||||||
@NotBlank String fileExtension, @NotBlank Long fileSize,
|
@NotBlank String fileName,
|
||||||
@NotBlank String filePath, Integer protectionLevel) {}
|
@NotBlank String originalFilename,
|
||||||
|
@NotBlank String fileType,
|
||||||
|
@NotBlank String fileExtension,
|
||||||
|
@NotBlank Long fileSize,
|
||||||
|
@NotBlank String filePath,
|
||||||
|
Integer protectionLevel
|
||||||
|
) {}
|
||||||
|
|||||||
@@ -3,8 +3,14 @@ package ru.soune.no_copy.dto;
|
|||||||
import jakarta.validation.constraints.Email;
|
import jakarta.validation.constraints.Email;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
|
||||||
public record UserContentUpdateRequest(@NotBlank @Email String userEmail, @NotBlank String fileName,
|
public record UserContentUpdateRequest(
|
||||||
@NotBlank String originalFilename, @NotBlank String fileType,
|
@NotBlank @Email String userEmail,
|
||||||
@NotBlank String fileExtension, @NotBlank Long fileSize,
|
@NotBlank String fileName,
|
||||||
@NotBlank String filePath, Integer protectionLevel, Long id) {
|
@NotBlank String originalFilename,
|
||||||
}
|
@NotBlank String fileType,
|
||||||
|
@NotBlank String fileExtension,
|
||||||
|
@NotBlank Long fileSize,
|
||||||
|
@NotBlank String filePath,
|
||||||
|
Integer protectionLevel,
|
||||||
|
Long id
|
||||||
|
) {}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package ru.soune.no_copy.dto;
|
package ru.soune.no_copy.dto;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import ru.soune.no_copy.entity.GenderType;
|
import ru.soune.no_copy.entity.GenderType;
|
||||||
|
import ru.soune.no_copy.entity.SubscriptionType;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@@ -11,6 +13,7 @@ import java.time.LocalDateTime;
|
|||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
public class UserDTO {
|
public class UserDTO {
|
||||||
private String fullName;
|
private String fullName;
|
||||||
private String company;
|
private String company;
|
||||||
@@ -20,4 +23,5 @@ public class UserDTO {
|
|||||||
private GenderType genderType;
|
private GenderType genderType;
|
||||||
private LocalDate birthday;
|
private LocalDate birthday;
|
||||||
private LocalDateTime createdAt;
|
private LocalDateTime createdAt;
|
||||||
|
private SubscriptionType subscriptionType;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package ru.soune.no_copy.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import jakarta.validation.constraints.Email;
|
||||||
|
import jakarta.validation.constraints.Past;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
import ru.soune.no_copy.entity.GenderType;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class UserRequest {
|
||||||
|
@Size(min = 2)
|
||||||
|
private String fullName;
|
||||||
|
private String company;
|
||||||
|
@Email
|
||||||
|
private String email;
|
||||||
|
private String phone;
|
||||||
|
private GenderType genderType;
|
||||||
|
@Past
|
||||||
|
@JsonFormat(pattern = "dd-MM-yyyy")
|
||||||
|
private LocalDate birthday;
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package ru.soune.no_copy.handler;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class JwtTokenProvider {
|
||||||
|
}
|
||||||
@@ -3,9 +3,14 @@ package ru.soune.no_copy.service;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import ru.soune.no_copy.dto.ChangePasswordRequest;
|
import ru.soune.no_copy.dto.ChangePasswordRequest;
|
||||||
|
import ru.soune.no_copy.dto.UserDTO;
|
||||||
|
import ru.soune.no_copy.dto.UserRequest;
|
||||||
import ru.soune.no_copy.entity.User;
|
import ru.soune.no_copy.entity.User;
|
||||||
|
import ru.soune.no_copy.exception.InvalidUserEmail;
|
||||||
import ru.soune.no_copy.exception.NotValidationPasswordException;
|
import ru.soune.no_copy.exception.NotValidationPasswordException;
|
||||||
|
import ru.soune.no_copy.exception.UserNotFoundException;
|
||||||
import ru.soune.no_copy.repository.UserRepository;
|
import ru.soune.no_copy.repository.UserRepository;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -16,6 +21,7 @@ public class UserService {
|
|||||||
|
|
||||||
private final PasswordEncoder passwordEncoder;
|
private final PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
|
@Transactional
|
||||||
public User changePassword(User user, ChangePasswordRequest request) {
|
public User changePassword(User user, ChangePasswordRequest request) {
|
||||||
if (!passwordEncoder.matches(request.getCurrentPassword(), user.getPassword())) {
|
if (!passwordEncoder.matches(request.getCurrentPassword(), user.getPassword())) {
|
||||||
throw new NotValidationPasswordException("Current password is incorrect");
|
throw new NotValidationPasswordException("Current password is incorrect");
|
||||||
@@ -25,4 +31,56 @@ public class UserService {
|
|||||||
|
|
||||||
return userRepository.save(user);
|
return userRepository.save(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public UserDTO updateUser(UserRequest userRequest, User currentUser) {
|
||||||
|
User user = userRepository.findById(currentUser.getId())
|
||||||
|
.orElseThrow(() -> new UserNotFoundException("User not found with id: " + currentUser.getId()));
|
||||||
|
|
||||||
|
updateUserFromRequest(user, userRequest);
|
||||||
|
|
||||||
|
User updatedUser = userRepository.save(user);
|
||||||
|
|
||||||
|
return mapToDTO(updatedUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateUserFromRequest(User user, UserRequest request) {
|
||||||
|
if (request.getFullName() != null) {
|
||||||
|
user.setFullName(request.getFullName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.getCompany() != null) {
|
||||||
|
user.setCompany(request.getCompany());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.getEmail() != null && !request.getEmail().equals(user.getEmail())) {
|
||||||
|
if (userRepository.existsByEmail(request.getEmail())) {
|
||||||
|
throw new InvalidUserEmail("Email already exists: " + request.getEmail());
|
||||||
|
}
|
||||||
|
user.setEmail(request.getEmail());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.getPhone() != null) {
|
||||||
|
user.setPhone(request.getPhone());
|
||||||
|
}
|
||||||
|
if (request.getGenderType() != null) {
|
||||||
|
user.setGenderType(request.getGenderType());
|
||||||
|
}
|
||||||
|
if (request.getBirthday() != null) {
|
||||||
|
user.setBirthday(request.getBirthday());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserDTO mapToDTO(User user) {
|
||||||
|
return UserDTO.builder()
|
||||||
|
.fullName(user.getFullName())
|
||||||
|
.email(user.getEmail())
|
||||||
|
.company(user.getCompany())
|
||||||
|
.phone(user.getPhone())
|
||||||
|
.genderType(user.getGenderType())
|
||||||
|
.birthday(user.getBirthday())
|
||||||
|
.subscriptionType(user.getSubscriptionType())
|
||||||
|
.createdAt(user.getCreatedAt())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user