From c2ffe08e7dd55a17258f3e41aa35ee0f2ce67181 Mon Sep 17 00:00:00 2001 From: vladp Date: Wed, 10 Dec 2025 02:37:31 +0700 Subject: [PATCH 01/12] NCBACK-9 add Validator,Add new enums with codes --- .../no_copy/controller/ApiController.java | 116 ++++++++++++++++++ .../no_copy/controller/AuthController.java | 14 +-- .../controller/HealtCheckController.java | 2 +- .../ru/soune/no_copy/dto/BaseRequest.java | 16 +++ .../ru/soune/no_copy/dto/BaseResponse.java | 21 ++++ .../ru/soune/no_copy/dto/MessageCode.java | 37 ++++++ .../java/ru/soune/no_copy/dto/RegRequest.java | 25 ++++ .../exception/UserAlreadyExistsException.java | 18 ++- .../handler/GlobalExceptionHandler.java | 15 ++- .../no_copy/handler/RegRequestValidator.java | 45 +++++++ .../ru/soune/no_copy/service/AuthService.java | 45 +++++-- 11 files changed, 327 insertions(+), 27 deletions(-) create mode 100644 src/main/java/ru/soune/no_copy/controller/ApiController.java create mode 100644 src/main/java/ru/soune/no_copy/dto/BaseRequest.java create mode 100644 src/main/java/ru/soune/no_copy/dto/BaseResponse.java create mode 100644 src/main/java/ru/soune/no_copy/dto/MessageCode.java create mode 100644 src/main/java/ru/soune/no_copy/dto/RegRequest.java create mode 100644 src/main/java/ru/soune/no_copy/handler/RegRequestValidator.java diff --git a/src/main/java/ru/soune/no_copy/controller/ApiController.java b/src/main/java/ru/soune/no_copy/controller/ApiController.java new file mode 100644 index 0000000..0e7a207 --- /dev/null +++ b/src/main/java/ru/soune/no_copy/controller/ApiController.java @@ -0,0 +1,116 @@ +package ru.soune.no_copy.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.BeanPropertyBindingResult; +import org.springframework.validation.BindingResult; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.annotation.*; +import ru.soune.no_copy.dto.BaseRequest; +import ru.soune.no_copy.dto.MessageCode; +import ru.soune.no_copy.dto.RegRequest; +import ru.soune.no_copy.entity.AuthToken; +import ru.soune.no_copy.exception.UserAlreadyExistsException; +import ru.soune.no_copy.handler.RegRequestValidator; +import ru.soune.no_copy.repository.UserRepository; +import ru.soune.no_copy.service.AuthService; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +@Slf4j +@RestController +@RequestMapping("/api") +@RequiredArgsConstructor +public class ApiController { + + private final ObjectMapper objectMapper; + + private final UserRepository userRepository; + + private final RegRequestValidator regRequestValidator; + + @Autowired + private AuthService authService; + + @PostMapping("/v{version}/data") + public ResponseEntity handlePostRequest( + @RequestBody BaseRequest request, + @PathVariable("version") int version) { + Integer msgId = request.getMsgId(); + Map response = new HashMap<>(); + + switch (msgId) { + case 20002: + RegRequest regRequest = objectMapper.convertValue(request.getMessageBody(), RegRequest.class); + + if (userRepository.existsByEmail(regRequest.getEmail())) { + throw new UserAlreadyExistsException("User already exists with email: " + regRequest.getEmail(), + msgId, MessageCode.REG_EMAIL_EXISTS.getCode(), MessageCode.REG_EMAIL_EXISTS.getDescription()); + } + + BindingResult bindingResult = new BeanPropertyBindingResult(regRequest, "regRequest"); + + regRequestValidator.validate(regRequest, bindingResult); + + if (bindingResult.hasErrors()) { + return createValidationErrorResponse(bindingResult, msgId); + } else { + authService.register(regRequest); + + response = Map.of( + "msg_id", msgId, + "message_code", MessageCode.SUCCESS.getCode(), + "message_desc", MessageCode.SUCCESS.getDescription()); + } + break; + default: + return ResponseEntity.ok().body(Map.of( + "msg_id", msgId, + "message_code", MessageCode.MSG_ID_NOT_FOUND.getCode(), + "message_desc", MessageCode.MSG_ID_NOT_FOUND.getDescription())); + } + + return ResponseEntity.status(MessageCode.SUCCESS.getCode()).body(response); + } + + private ResponseEntity> createValidationErrorResponse( + BindingResult bindingResult, Integer msgId) { + + Map response = new HashMap<>(); + response.put("msg_id", msgId); + response.put("message_code", MessageCode.INVALID_FIELD.getCode()); + response.put("message_desc", MessageCode.INVALID_FIELD.getDescription()); + + List> fieldErrors = bindingResult.getFieldErrors() + .stream() + .map(this::createErrorDetail) + .collect(Collectors.toList()); + + response.put("field_errors", fieldErrors); + + return ResponseEntity.badRequest().body(response); + } + + private Map createErrorDetail(FieldError fieldError) { + Map errorDetail = new HashMap<>(); + errorDetail.put("field", fieldError.getField()); + errorDetail.put("code", fieldError.getCode() != null ? fieldError.getCode() : "VALIDATION_ERROR"); + errorDetail.put("message", fieldError.getDefaultMessage()); + + if (fieldError.getRejectedValue() != null && + !fieldError.getField().toLowerCase().contains("password")) { + errorDetail.put("rejected_value", fieldError.getRejectedValue().toString()); + } + + return errorDetail; + } +} \ No newline at end of file diff --git a/src/main/java/ru/soune/no_copy/controller/AuthController.java b/src/main/java/ru/soune/no_copy/controller/AuthController.java index 764b1a8..3edeb6f 100644 --- a/src/main/java/ru/soune/no_copy/controller/AuthController.java +++ b/src/main/java/ru/soune/no_copy/controller/AuthController.java @@ -25,13 +25,13 @@ public class AuthController { private final AuthTokenRepository authTokenRepository; - @PostMapping("/register") - public ResponseEntity register(@Valid @RequestBody RegisterRequest registerRequest) { - AuthToken authToken = authService.register(registerRequest); - - return ResponseEntity.ok(new AuthResponse(true, "success.user.register", authToken.getToken(), - authToken.getExpiresAt())); - } +// @PostMapping("/register") +// public ResponseEntity register(@Valid @RequestBody RegisterRequest registerRequest) { +// AuthToken authToken = authService.register(registerRequest); +// +// return ResponseEntity.ok(new AuthResponse(true, "success.user.register", authToken.getToken(), +// authToken.getExpiresAt())); +// } @PostMapping("/login") public ResponseEntity login(@Valid @RequestBody LoginRequest request) { diff --git a/src/main/java/ru/soune/no_copy/controller/HealtCheckController.java b/src/main/java/ru/soune/no_copy/controller/HealtCheckController.java index 33b6ab9..b455f67 100644 --- a/src/main/java/ru/soune/no_copy/controller/HealtCheckController.java +++ b/src/main/java/ru/soune/no_copy/controller/HealtCheckController.java @@ -5,7 +5,7 @@ import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; @RestController -@RequestMapping("/api") +@RequestMapping("check/api") public class HealtCheckController { @GetMapping("/healt") diff --git a/src/main/java/ru/soune/no_copy/dto/BaseRequest.java b/src/main/java/ru/soune/no_copy/dto/BaseRequest.java new file mode 100644 index 0000000..818890d --- /dev/null +++ b/src/main/java/ru/soune/no_copy/dto/BaseRequest.java @@ -0,0 +1,16 @@ +package ru.soune.no_copy.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class BaseRequest { + @JsonProperty("version") + Integer version; + + @JsonProperty("msg_id") + Integer msgId; + + @JsonProperty("message_body") + Object messageBody; +} diff --git a/src/main/java/ru/soune/no_copy/dto/BaseResponse.java b/src/main/java/ru/soune/no_copy/dto/BaseResponse.java new file mode 100644 index 0000000..cf16762 --- /dev/null +++ b/src/main/java/ru/soune/no_copy/dto/BaseResponse.java @@ -0,0 +1,21 @@ +package ru.soune.no_copy.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class BaseResponse { + @JsonProperty("msg_id") + private Integer msgId; + + @JsonProperty("message_code") + private Integer messageCode; + + @JsonProperty("message_desc") + private String messageDesc; + + @JsonProperty("message_body") + private Object messageBody; +} diff --git a/src/main/java/ru/soune/no_copy/dto/MessageCode.java b/src/main/java/ru/soune/no_copy/dto/MessageCode.java new file mode 100644 index 0000000..5b4e69b --- /dev/null +++ b/src/main/java/ru/soune/no_copy/dto/MessageCode.java @@ -0,0 +1,37 @@ +package ru.soune.no_copy.dto; + +public enum MessageCode { + SUCCESS(0, "Operation successful"), + REG_EMAIL_EXISTS(2001, "Email already registered"), + INVALID_FIELD(2002, "Invalid field"), + MSG_ID_NOT_FOUND(2004, "Message id not found"), + + + REGISTER_SUCCESS(10002, "Register success"), + BAD_REQUEST(400, "Bad request"), + UNAUTHORIZED(403, "Unauthorized"), + FORBIDDEN(402, "Forbidden"), + NOT_FOUND(404, "Not found"), + INTERNAL_ERROR(500, "Internal server error"), + + AUTH_INVALID_CREDENTIALS(101, "Invalid credentials"), + AUTH_EMAIL_NOT_CONFIRMED(103, "Email not confirmed"); + + + private final Integer code; + + private final String description; + + MessageCode(Integer code, String description) { + this.code = code; + this.description = description; + } + + public Integer getCode() { + return code; + } + + public String getDescription() { + return description; + } +} diff --git a/src/main/java/ru/soune/no_copy/dto/RegRequest.java b/src/main/java/ru/soune/no_copy/dto/RegRequest.java new file mode 100644 index 0000000..f43cb75 --- /dev/null +++ b/src/main/java/ru/soune/no_copy/dto/RegRequest.java @@ -0,0 +1,25 @@ +package ru.soune.no_copy.dto; + +import jakarta.validation.constraints.*; +import lombok.Data; + + +@Data +public class RegRequest { + @NotEmpty(message = "Full name is required") + private String fullName; + + private String companyName; + + @Size(min = 11, max = 14, message = "Phone must be 11-14 digits") + private String phone; + + @NotBlank(message = "Email is required") + @Email(message = "Invalid email format") + @Size(max = 128, message = "Email too long") + private String email; + + @NotBlank(message = "Password is required") + @Size(min = 8, message = "Password must be at least 8 characters") + private String password; +} diff --git a/src/main/java/ru/soune/no_copy/exception/UserAlreadyExistsException.java b/src/main/java/ru/soune/no_copy/exception/UserAlreadyExistsException.java index 8815885..099770c 100644 --- a/src/main/java/ru/soune/no_copy/exception/UserAlreadyExistsException.java +++ b/src/main/java/ru/soune/no_copy/exception/UserAlreadyExistsException.java @@ -1,7 +1,23 @@ package ru.soune.no_copy.exception; +import lombok.Getter; + +@Getter public class UserAlreadyExistsException extends RuntimeException { - public UserAlreadyExistsException(String message) { + + private final String message; + + private final Integer messageId; + + private final Integer messageCode; + + private final String messageDescription; + + public UserAlreadyExistsException(String message, Integer messageId, Integer messageCode, String messageDescription) { super(message); + this.message = message; + this.messageId = messageId; + this.messageCode = messageCode; + this.messageDescription = messageDescription; } } diff --git a/src/main/java/ru/soune/no_copy/handler/GlobalExceptionHandler.java b/src/main/java/ru/soune/no_copy/handler/GlobalExceptionHandler.java index c3a02b2..2edd0ff 100644 --- a/src/main/java/ru/soune/no_copy/handler/GlobalExceptionHandler.java +++ b/src/main/java/ru/soune/no_copy/handler/GlobalExceptionHandler.java @@ -8,8 +8,10 @@ import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; +import ru.soune.no_copy.dto.MessageCode; import ru.soune.no_copy.exception.*; +import java.time.LocalDateTime; import java.util.Map; @RestControllerAdvice @@ -30,14 +32,15 @@ public class GlobalExceptionHandler { } @ExceptionHandler(UserAlreadyExistsException.class) - @ResponseStatus(HttpStatus.CONFLICT) + @ResponseStatus(HttpStatus.OK) public ResponseEntity handleUserContainsException(UserAlreadyExistsException ex) { - return ResponseEntity. - badRequest() + + return ResponseEntity + .ok() .body(Map.of( - "success", false, - "message" ,ex.getMessage() - )); + "msg_id", ex.getMessageId(), + "message_code", ex.getMessageCode(), + "message_desc", ex.getMessageDescription())); } @ExceptionHandler(UserNotFoundException.class) diff --git a/src/main/java/ru/soune/no_copy/handler/RegRequestValidator.java b/src/main/java/ru/soune/no_copy/handler/RegRequestValidator.java new file mode 100644 index 0000000..98cf464 --- /dev/null +++ b/src/main/java/ru/soune/no_copy/handler/RegRequestValidator.java @@ -0,0 +1,45 @@ +package ru.soune.no_copy.handler; + +import org.springframework.stereotype.Component; +import org.springframework.validation.Errors; +import org.springframework.validation.Validator; +import ru.soune.no_copy.dto.RegRequest; + +@Component +public class RegRequestValidator implements Validator { + + @Override + public boolean supports(Class clazz) { + return RegRequest.class.isAssignableFrom(clazz); + } + + @Override + public void validate(Object target, Errors errors) { + RegRequest request = (RegRequest) target; + + validatePhone(request.getPhone(), errors); + } + + private void validatePhone(String phone, Errors errors) { + if (phone == null || phone.trim().isEmpty()) { + errors.rejectValue("phone", "phone.empty", + "Test phone numbers are not allowed"); + return; + } + + String trimmedPhone = phone.trim(); + String digitsOnly = trimmedPhone.replaceAll("[^0-9+]", ""); + + if (digitsOnly.length() < 11 || digitsOnly.length() > 14) { + errors.rejectValue("phone", "phone.invalid.length", + "Phone number must contain 11-14 digits"); + return; + } + + if (!digitsOnly.matches("^(\\+7|8|7)[0-9]{10}$")) { + errors.rejectValue("phone", "phone.invalid.format", + "Invalid phone number format"); + return; + } + } +} diff --git a/src/main/java/ru/soune/no_copy/service/AuthService.java b/src/main/java/ru/soune/no_copy/service/AuthService.java index 1cb1966..3176dd2 100644 --- a/src/main/java/ru/soune/no_copy/service/AuthService.java +++ b/src/main/java/ru/soune/no_copy/service/AuthService.java @@ -6,6 +6,7 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import ru.soune.no_copy.dto.LoginRequest; +import ru.soune.no_copy.dto.RegRequest; import ru.soune.no_copy.dto.RegisterRequest; import ru.soune.no_copy.entity.AuthToken; import ru.soune.no_copy.entity.User; @@ -35,23 +36,43 @@ public class AuthService { private final SecureRandom secureRandom = new SecureRandom(); +// @Transactional +// public AuthToken register(RegisterRequest registerRequest) { +// User user = new User(); +// user.setFullName(registerRequest.fullName()); +// user.setEmail(registerRequest.email()); +// user.setPassword(passwordEncoder.encode(registerRequest.password())); +// +// if (registerRequest.companyName() != null) { +// user.setCompany(registerRequest.companyName()); +// } +// +// if (registerRequest.phone() != null) { +// user.setPhone(registerRequest.phone()); +// } +// +// User savedUser = userRepository.save(user); +// +// AuthToken authToken = new AuthToken(); +// authToken.setToken(generateAuthToken()); +// authToken.setUser(savedUser); +// +// return authTokenRepository.save(authToken); +// } + @Transactional - public AuthToken register(RegisterRequest registerRequest) { - if (userRepository.existsByEmail(registerRequest.email())) { - throw new UserAlreadyExistsException("User already exists with email: " + registerRequest.email()); - } - + public AuthToken register(RegRequest registerRequest) { User user = new User(); - user.setFullName(registerRequest.fullName()); - user.setEmail(registerRequest.email()); - user.setPassword(passwordEncoder.encode(registerRequest.password())); + user.setFullName(registerRequest.getFullName()); + user.setEmail(registerRequest.getEmail()); + user.setPassword(passwordEncoder.encode(registerRequest.getPassword())); - if (registerRequest.companyName() != null) { - user.setCompany(registerRequest.companyName()); + if (registerRequest.getCompanyName() != null) { + user.setCompany(registerRequest.getCompanyName()); } - if (registerRequest.phone() != null) { - user.setPhone(registerRequest.phone()); + if (registerRequest.getPhone() != null) { + user.setPhone(registerRequest.getPhone()); } User savedUser = userRepository.save(user); -- 2.54.0 From b5b8bebb6949c13020907cb7738b6e8a4a6b3981 Mon Sep 17 00:00:00 2001 From: vladp Date: Wed, 10 Dec 2025 04:22:09 +0700 Subject: [PATCH 02/12] NCBACK-9 work controller for register --- .../no_copy/controller/ApiController.java | 41 ++- .../no_copy/controller/AuthController.java | 8 - .../no_copy/handler/RegRequestValidator.java | 237 ++++++++++++++++++ 3 files changed, 256 insertions(+), 30 deletions(-) diff --git a/src/main/java/ru/soune/no_copy/controller/ApiController.java b/src/main/java/ru/soune/no_copy/controller/ApiController.java index 0e7a207..8f3f734 100644 --- a/src/main/java/ru/soune/no_copy/controller/ApiController.java +++ b/src/main/java/ru/soune/no_copy/controller/ApiController.java @@ -1,7 +1,6 @@ package ru.soune.no_copy.controller; import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -13,17 +12,14 @@ import org.springframework.web.bind.annotation.*; import ru.soune.no_copy.dto.BaseRequest; import ru.soune.no_copy.dto.MessageCode; import ru.soune.no_copy.dto.RegRequest; -import ru.soune.no_copy.entity.AuthToken; import ru.soune.no_copy.exception.UserAlreadyExistsException; import ru.soune.no_copy.handler.RegRequestValidator; import ru.soune.no_copy.repository.UserRepository; import ru.soune.no_copy.service.AuthService; -import java.io.Serializable; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.stream.Collectors; @Slf4j @@ -42,11 +38,9 @@ public class ApiController { private AuthService authService; @PostMapping("/v{version}/data") - public ResponseEntity handlePostRequest( - @RequestBody BaseRequest request, - @PathVariable("version") int version) { + public ResponseEntity handlePostRequest(@RequestBody BaseRequest request, @PathVariable("version") int version) { Integer msgId = request.getMsgId(); - Map response = new HashMap<>(); + Map response; switch (msgId) { case 20002: @@ -65,30 +59,24 @@ public class ApiController { return createValidationErrorResponse(bindingResult, msgId); } else { authService.register(regRequest); - - response = Map.of( - "msg_id", msgId, - "message_code", MessageCode.SUCCESS.getCode(), - "message_desc", MessageCode.SUCCESS.getDescription()); + response = fillResponseInfo(msgId, MessageCode.SUCCESS.getCode(), + MessageCode.SUCCESS.getDescription()); } break; + case 20001: default: - return ResponseEntity.ok().body(Map.of( - "msg_id", msgId, - "message_code", MessageCode.MSG_ID_NOT_FOUND.getCode(), - "message_desc", MessageCode.MSG_ID_NOT_FOUND.getDescription())); + return ResponseEntity.ok().body(fillResponseInfo(msgId, MessageCode.MSG_ID_NOT_FOUND.getCode(), + MessageCode.MSG_ID_NOT_FOUND.getDescription())); } - return ResponseEntity.status(MessageCode.SUCCESS.getCode()).body(response); + return ResponseEntity.ok().body(response); } private ResponseEntity> createValidationErrorResponse( BindingResult bindingResult, Integer msgId) { - Map response = new HashMap<>(); - response.put("msg_id", msgId); - response.put("message_code", MessageCode.INVALID_FIELD.getCode()); - response.put("message_desc", MessageCode.INVALID_FIELD.getDescription()); + Map response = fillResponseInfo(msgId, MessageCode.INVALID_FIELD.getCode(), + MessageCode.INVALID_FIELD.getDescription()); List> fieldErrors = bindingResult.getFieldErrors() .stream() @@ -113,4 +101,13 @@ public class ApiController { return errorDetail; } + + private Map fillResponseInfo(Integer msgId, Integer messageCode, String messageDesc) { + Map response = new HashMap<>(); + response.put("msg_id", msgId); + response.put("message_code", messageCode); + response.put("message_desc", messageDesc); + + return response; + } } \ No newline at end of file diff --git a/src/main/java/ru/soune/no_copy/controller/AuthController.java b/src/main/java/ru/soune/no_copy/controller/AuthController.java index 3edeb6f..5586e80 100644 --- a/src/main/java/ru/soune/no_copy/controller/AuthController.java +++ b/src/main/java/ru/soune/no_copy/controller/AuthController.java @@ -25,14 +25,6 @@ public class AuthController { private final AuthTokenRepository authTokenRepository; -// @PostMapping("/register") -// public ResponseEntity register(@Valid @RequestBody RegisterRequest registerRequest) { -// AuthToken authToken = authService.register(registerRequest); -// -// return ResponseEntity.ok(new AuthResponse(true, "success.user.register", authToken.getToken(), -// authToken.getExpiresAt())); -// } - @PostMapping("/login") public ResponseEntity login(@Valid @RequestBody LoginRequest request) { AuthToken login = authService.login(request); diff --git a/src/main/java/ru/soune/no_copy/handler/RegRequestValidator.java b/src/main/java/ru/soune/no_copy/handler/RegRequestValidator.java index 98cf464..f7ea83e 100644 --- a/src/main/java/ru/soune/no_copy/handler/RegRequestValidator.java +++ b/src/main/java/ru/soune/no_copy/handler/RegRequestValidator.java @@ -5,8 +5,13 @@ import org.springframework.validation.Errors; import org.springframework.validation.Validator; import ru.soune.no_copy.dto.RegRequest; +import java.util.*; + @Component public class RegRequestValidator implements Validator { + private static final String COMPANY_REGEX = "^[a-zA-Zа-яА-ЯёЁ0-9\\s\\-&.,'()]{0,200}$"; + + private static final String NAME_REGEX = "^[a-zA-Zа-яА-ЯёЁ\\s\\-'.]{2,100}$"; @Override public boolean supports(Class clazz) { @@ -18,6 +23,150 @@ public class RegRequestValidator implements Validator { RegRequest request = (RegRequest) target; validatePhone(request.getPhone(), errors); + validatePassword(request.getPassword(), errors); + validateEmail(request.getEmail(), errors); + validateCompanyName(request.getCompanyName(), errors); + validateFullName(request.getFullName(), errors); + } + + private void validateFullName(String fullName, Errors errors) { + if (fullName == null || fullName.trim().isEmpty()) { + errors.rejectValue("fullName", "fullName.required", + "Full name is required"); + return; + } + + String trimmedName = fullName.trim(); + + if (trimmedName.length() < 2) { + errors.rejectValue("fullName", "fullName.too.short", + "Full name must be at least 2 characters"); + } + + if (trimmedName.length() > 100) { + errors.rejectValue("fullName", "fullName.too.long", + "Full name must be less than 100 characters"); + } + + if (!trimmedName.matches(NAME_REGEX)) { + errors.rejectValue("fullName", "fullName.invalid.chars", + "Name can only contain letters, spaces, hyphens and apostrophes"); + } + + String[] nameParts = trimmedName.split("\\s+"); + if (nameParts.length < 2) { + errors.rejectValue("fullName", "fullName.missing.parts", + "Please enter both first and last name"); + } + + for (int i = 0; i < nameParts.length; i++) { + String part = nameParts[i]; + if (part.length() < 2 && part.length() > 0) { + errors.rejectValue("fullName", "fullName.part.too.short", + "Each name part must be at least 2 characters"); + break; + } + + if (!Character.isUpperCase(part.charAt(0))) { + errors.rejectValue("fullName", "fullName.capitalization", + "Each name part should start with capital letter"); + break; + } + } + } + + private void validateCompanyName(String companyName, Errors errors) { + if (companyName == null || companyName.trim().isEmpty()) { + return; + } + + String trimmedCompany = companyName.trim(); + + if (trimmedCompany.length() > 200) { + errors.rejectValue("companyName", "companyName.too.long", + "Company name must be less than 200 characters"); + } + + if (!trimmedCompany.matches(COMPANY_REGEX)) { + errors.rejectValue("companyName", "companyName.invalid.chars", + "Company name contains invalid characters"); + } + + validateForbiddenWords(trimmedCompany, "companyName", errors, + Arrays.asList("admin", "root", "system", "test")); + } + + private void validateForbiddenWords(String text, String fieldName, + Errors errors, List forbiddenWords) { + String lowerText = text.toLowerCase(); + for (String word : forbiddenWords) { + if (lowerText.contains(word)) { + errors.rejectValue(fieldName, fieldName + ".forbidden.word", + "Contains forbidden word: " + word); + break; + } + } + } + + private void validateEmail(String email, Errors errors) { + if (email == null || email.trim().isEmpty()) { + errors.rejectValue("email", "email.is.empty", + "Email must not be empty"); + return; + } + + String trimmedEmail = email.trim().toLowerCase(); + + if (trimmedEmail.length() > 128) { + errors.rejectValue("email", "email.too.long", + "Email must be less than 128 characters"); + return; + } + + if (!trimmedEmail.matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$")) { + errors.rejectValue("email", "email.invalid.format", + "Invalid email format"); + return; + } + + String[] parts = trimmedEmail.split("@"); + if (parts.length != 2) { + return; + } + + String localPart = parts[0]; + String domain = parts[1]; + + if (localPart.length() > 64) { + errors.rejectValue("email", "email.local.too.long", + "Email username too long"); + } + + if (!localPart.matches("^[a-z0-9+_.-]+$")) { + errors.rejectValue("email", "email.local.invalid.chars", + "Email contains invalid characters"); + } + + validateEmailDomain(domain, errors); + } + + private void validateEmailDomain(String domain, Errors errors) { + if (domain.length() > 255) { + errors.rejectValue("email", "email.domain.too.long", + "Email domain too long"); + } + + String[] domainParts = domain.split("\\."); + if (domainParts.length < 2) { + errors.rejectValue("email", "email.domain.invalid", + "Invalid domain name"); + } + + String tld = domainParts[domainParts.length - 1]; + if (tld.length() < 2) { + errors.rejectValue("email", "email.tld.invalid", + "Invalid domain extension"); + } } private void validatePhone(String phone, Errors errors) { @@ -42,4 +191,92 @@ public class RegRequestValidator implements Validator { return; } } + + private void validatePassword(String password, Errors errors) { + if (password == null || password.isEmpty()) { + errors.rejectValue("password", "password.empty", + "Password are not allowed"); + return; + } + + if (password.length() < 8) { + errors.rejectValue("password", "password.too.short", + "Password must be at least 8 characters"); + } + + if (password.length() > 50) { + errors.rejectValue("password", "password.too.long", + "Password must be less than 50 characters"); + } + + if (password.contains(" ")) { + errors.rejectValue("password", "password.contains.spaces", + "Password cannot contain spaces"); + } + +// recomment if need complexity +// checkPasswordComplexity(password, errors); + +// reccoment if need check simply standart password +// checkCommonPasswords(password, errors); + +// reccoment if need check simply standart password +// checkForSequences(password, errors); + } + + private void checkPasswordComplexity(String password, Errors errors) { + boolean hasUpper = false; + boolean hasLower = false; + boolean hasDigit = false; + boolean hasSpecial = false; + + for (char c : password.toCharArray()) { + if (Character.isUpperCase(c)) hasUpper = true; + if (Character.isLowerCase(c)) hasLower = true; + if (Character.isDigit(c)) hasDigit = true; + if ("!@#$%^&*()_+-=[]{}|;:,.<>?".indexOf(c) >= 0) hasSpecial = true; + } + + List missing = new ArrayList<>(); + if (!hasUpper) missing.add("uppercase letter"); + if (!hasLower) missing.add("lowercase letter"); + if (!hasDigit) missing.add("digit"); + if (!hasSpecial) missing.add("special character"); + + if (!missing.isEmpty()) { + String message = "Password must contain: " + String.join(", ", missing); + errors.rejectValue("password", "password.complexity.missing", message); + } + } + + private void checkCommonPasswords(String password, Errors errors) { + Set commonPasswords = Set.of( + "password", "12345678", "qwerty123", "admin123", + "welcome1", "password1", "123456789", "qwertyuiop" + ); + + if (commonPasswords.contains(password.toLowerCase())) { + errors.rejectValue("password", "password.too.common", + "This password is too common, please choose another"); + } + } + + private void checkForSequences(String password, Errors errors) { + String lower = password.toLowerCase(); + + if (lower.matches(".*123456.*") || lower.matches(".*987654.*")) { + errors.rejectValue("password", "password.sequence.numbers", + "Password contains predictable number sequence"); + } + + if (lower.matches(".*abcdef.*") || lower.matches(".*qwerty.*")) { + errors.rejectValue("password", "password.sequence.letters", + "Password contains predictable letter sequence"); + } + + if (lower.matches(".*(.)\\1{3,}.*")) { + errors.rejectValue("password", "password.repeating.chars", + "Password contains too many repeating characters"); + } + } } -- 2.54.0 From 8a33bd33a2d3882a68720d0b74a24dd6879813df Mon Sep 17 00:00:00 2001 From: vladp Date: Wed, 10 Dec 2025 04:51:07 +0700 Subject: [PATCH 03/12] NCBACK-9 add login --- .../no_copy/controller/ApiController.java | 23 ++++++++++- .../ru/soune/no_copy/dto/MessageCode.java | 13 +------ ...ption.java => NotValidFieldException.java} | 4 +- .../handler/GlobalExceptionHandler.java | 6 +-- .../ru/soune/no_copy/service/AuthService.java | 38 +++---------------- .../no_copy/service/AuthServiceTest.java | 4 +- 6 files changed, 34 insertions(+), 54 deletions(-) rename src/main/java/ru/soune/no_copy/exception/{UserAlreadyExistsException.java => NotValidFieldException.java} (68%) diff --git a/src/main/java/ru/soune/no_copy/controller/ApiController.java b/src/main/java/ru/soune/no_copy/controller/ApiController.java index 8f3f734..9b3c934 100644 --- a/src/main/java/ru/soune/no_copy/controller/ApiController.java +++ b/src/main/java/ru/soune/no_copy/controller/ApiController.java @@ -5,14 +5,17 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.*; import ru.soune.no_copy.dto.BaseRequest; +import ru.soune.no_copy.dto.LoginRequest; import ru.soune.no_copy.dto.MessageCode; import ru.soune.no_copy.dto.RegRequest; -import ru.soune.no_copy.exception.UserAlreadyExistsException; +import ru.soune.no_copy.entity.AuthToken; +import ru.soune.no_copy.exception.NotValidFieldException; import ru.soune.no_copy.handler.RegRequestValidator; import ru.soune.no_copy.repository.UserRepository; import ru.soune.no_copy.service.AuthService; @@ -34,6 +37,8 @@ public class ApiController { private final RegRequestValidator regRequestValidator; + private final PasswordEncoder passwordEncoder; + @Autowired private AuthService authService; @@ -47,7 +52,7 @@ public class ApiController { RegRequest regRequest = objectMapper.convertValue(request.getMessageBody(), RegRequest.class); if (userRepository.existsByEmail(regRequest.getEmail())) { - throw new UserAlreadyExistsException("User already exists with email: " + regRequest.getEmail(), + throw new NotValidFieldException("User already exists with email: " + regRequest.getEmail(), msgId, MessageCode.REG_EMAIL_EXISTS.getCode(), MessageCode.REG_EMAIL_EXISTS.getDescription()); } @@ -64,6 +69,20 @@ public class ApiController { } break; case 20001: + LoginRequest loginRequest = objectMapper.convertValue(request.getMessageBody(), LoginRequest.class); + + if (!userRepository.existsByEmail(loginRequest.getEmail())) { + + throw new NotValidFieldException("User with email not found: " + loginRequest.getEmail(), + msgId, MessageCode.AUTH_EMAIL_NOT_FOUND.getCode(), + MessageCode.AUTH_EMAIL_NOT_FOUND.getDescription()); + } + + authService.login(loginRequest); + + response = fillResponseInfo(msgId, MessageCode.SUCCESS.getCode(), + MessageCode.SUCCESS.getDescription()); + break; default: return ResponseEntity.ok().body(fillResponseInfo(msgId, MessageCode.MSG_ID_NOT_FOUND.getCode(), MessageCode.MSG_ID_NOT_FOUND.getDescription())); diff --git a/src/main/java/ru/soune/no_copy/dto/MessageCode.java b/src/main/java/ru/soune/no_copy/dto/MessageCode.java index 5b4e69b..5359d44 100644 --- a/src/main/java/ru/soune/no_copy/dto/MessageCode.java +++ b/src/main/java/ru/soune/no_copy/dto/MessageCode.java @@ -6,17 +6,8 @@ public enum MessageCode { INVALID_FIELD(2002, "Invalid field"), MSG_ID_NOT_FOUND(2004, "Message id not found"), - - REGISTER_SUCCESS(10002, "Register success"), - BAD_REQUEST(400, "Bad request"), - UNAUTHORIZED(403, "Unauthorized"), - FORBIDDEN(402, "Forbidden"), - NOT_FOUND(404, "Not found"), - INTERNAL_ERROR(500, "Internal server error"), - - AUTH_INVALID_CREDENTIALS(101, "Invalid credentials"), - AUTH_EMAIL_NOT_CONFIRMED(103, "Email not confirmed"); - + AUTH_EMAIL_NOT_FOUND(2005, "Email not found"), + AUTH_PASSWORD_NOT_MATCHES(2006, "Password does not match"); private final Integer code; diff --git a/src/main/java/ru/soune/no_copy/exception/UserAlreadyExistsException.java b/src/main/java/ru/soune/no_copy/exception/NotValidFieldException.java similarity index 68% rename from src/main/java/ru/soune/no_copy/exception/UserAlreadyExistsException.java rename to src/main/java/ru/soune/no_copy/exception/NotValidFieldException.java index 099770c..2181038 100644 --- a/src/main/java/ru/soune/no_copy/exception/UserAlreadyExistsException.java +++ b/src/main/java/ru/soune/no_copy/exception/NotValidFieldException.java @@ -3,7 +3,7 @@ package ru.soune.no_copy.exception; import lombok.Getter; @Getter -public class UserAlreadyExistsException extends RuntimeException { +public class NotValidFieldException extends RuntimeException { private final String message; @@ -13,7 +13,7 @@ public class UserAlreadyExistsException extends RuntimeException { private final String messageDescription; - public UserAlreadyExistsException(String message, Integer messageId, Integer messageCode, String messageDescription) { + public NotValidFieldException(String message, Integer messageId, Integer messageCode, String messageDescription) { super(message); this.message = message; this.messageId = messageId; diff --git a/src/main/java/ru/soune/no_copy/handler/GlobalExceptionHandler.java b/src/main/java/ru/soune/no_copy/handler/GlobalExceptionHandler.java index 2edd0ff..7b78902 100644 --- a/src/main/java/ru/soune/no_copy/handler/GlobalExceptionHandler.java +++ b/src/main/java/ru/soune/no_copy/handler/GlobalExceptionHandler.java @@ -8,10 +8,8 @@ import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; -import ru.soune.no_copy.dto.MessageCode; import ru.soune.no_copy.exception.*; -import java.time.LocalDateTime; import java.util.Map; @RestControllerAdvice @@ -31,9 +29,9 @@ public class GlobalExceptionHandler { "message" ,message)); } - @ExceptionHandler(UserAlreadyExistsException.class) + @ExceptionHandler(NotValidFieldException.class) @ResponseStatus(HttpStatus.OK) - public ResponseEntity handleUserContainsException(UserAlreadyExistsException ex) { + public ResponseEntity handleUserContainsException(NotValidFieldException ex) { return ResponseEntity .ok() diff --git a/src/main/java/ru/soune/no_copy/service/AuthService.java b/src/main/java/ru/soune/no_copy/service/AuthService.java index 3176dd2..2a76f68 100644 --- a/src/main/java/ru/soune/no_copy/service/AuthService.java +++ b/src/main/java/ru/soune/no_copy/service/AuthService.java @@ -6,12 +6,12 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import ru.soune.no_copy.dto.LoginRequest; +import ru.soune.no_copy.dto.MessageCode; import ru.soune.no_copy.dto.RegRequest; -import ru.soune.no_copy.dto.RegisterRequest; import ru.soune.no_copy.entity.AuthToken; import ru.soune.no_copy.entity.User; +import ru.soune.no_copy.exception.NotValidFieldException; import ru.soune.no_copy.exception.NotValidationPasswordException; -import ru.soune.no_copy.exception.UserAlreadyExistsException; import ru.soune.no_copy.exception.UserNotFoundException; import ru.soune.no_copy.repository.AuthTokenRepository; import ru.soune.no_copy.repository.UserRepository; @@ -19,7 +19,6 @@ import ru.soune.no_copy.repository.UserRepository; import java.security.SecureRandom; import java.time.LocalDateTime; import java.util.Base64; -import java.util.Locale; import java.util.Optional; @Service @@ -36,30 +35,6 @@ public class AuthService { private final SecureRandom secureRandom = new SecureRandom(); -// @Transactional -// public AuthToken register(RegisterRequest registerRequest) { -// User user = new User(); -// user.setFullName(registerRequest.fullName()); -// user.setEmail(registerRequest.email()); -// user.setPassword(passwordEncoder.encode(registerRequest.password())); -// -// if (registerRequest.companyName() != null) { -// user.setCompany(registerRequest.companyName()); -// } -// -// if (registerRequest.phone() != null) { -// user.setPhone(registerRequest.phone()); -// } -// -// User savedUser = userRepository.save(user); -// -// AuthToken authToken = new AuthToken(); -// authToken.setToken(generateAuthToken()); -// authToken.setUser(savedUser); -// -// return authTokenRepository.save(authToken); -// } - @Transactional public AuthToken register(RegRequest registerRequest) { User user = new User(); @@ -87,15 +62,12 @@ public class AuthService { @Transactional public AuthToken login(LoginRequest request) { Optional userOpt = userRepository.findByEmail(request.getEmail()); - - if (userOpt.isEmpty()) { - throw new UserNotFoundException("User with email " + request.getEmail() + " not found"); - } - User user = userOpt.get(); if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) { - throw new NotValidationPasswordException("Invalid password"); + throw new NotValidFieldException("Invalid password", 20003, + MessageCode.AUTH_PASSWORD_NOT_MATCHES.getCode(), + MessageCode.AUTH_PASSWORD_NOT_MATCHES.getDescription()); } user.setLastLoginAt(LocalDateTime.now()); diff --git a/src/test/java/ru/soune/no_copy/service/AuthServiceTest.java b/src/test/java/ru/soune/no_copy/service/AuthServiceTest.java index 2b75fcb..c2a38a4 100644 --- a/src/test/java/ru/soune/no_copy/service/AuthServiceTest.java +++ b/src/test/java/ru/soune/no_copy/service/AuthServiceTest.java @@ -13,7 +13,7 @@ import ru.soune.no_copy.dto.RegisterRequest; import ru.soune.no_copy.entity.AuthToken; import ru.soune.no_copy.entity.User; import ru.soune.no_copy.exception.NotValidationPasswordException; -import ru.soune.no_copy.exception.UserAlreadyExistsException; +import ru.soune.no_copy.exception.NotValidFieldException; import ru.soune.no_copy.exception.UserNotFoundException; import ru.soune.no_copy.repository.AuthTokenRepository; import ru.soune.no_copy.repository.UserRepository; @@ -80,7 +80,7 @@ public class AuthServiceTest { when(messageSource.getMessage(anyString(), any(), any(Locale.class))) .thenReturn("User exists"); - UserAlreadyExistsException ex = assertThrows(UserAlreadyExistsException.class, + NotValidFieldException ex = assertThrows(NotValidFieldException.class, () -> authService.register(request)); assertEquals("User exists", ex.getMessage()); -- 2.54.0 From 9ef192ed32bb03e788ba3de8139fb2e5d8d799fd Mon Sep 17 00:00:00 2001 From: vladp Date: Wed, 10 Dec 2025 12:17:08 +0700 Subject: [PATCH 04/12] add strategy for controller --- .../no_copy/controller/ApiController.java | 94 +++++++------------ .../no_copy/controller/AuthController.java | 13 --- .../exception/ValidationException.java | 16 ++++ .../no_copy/handler/LoginRequestHandler.java | 47 ++++++++++ .../no_copy/handler/RegRequestHandler.java | 59 ++++++++++++ .../soune/no_copy/handler/RequestHandler.java | 9 ++ 6 files changed, 166 insertions(+), 72 deletions(-) create mode 100644 src/main/java/ru/soune/no_copy/exception/ValidationException.java create mode 100644 src/main/java/ru/soune/no_copy/handler/LoginRequestHandler.java create mode 100644 src/main/java/ru/soune/no_copy/handler/RegRequestHandler.java create mode 100644 src/main/java/ru/soune/no_copy/handler/RequestHandler.java diff --git a/src/main/java/ru/soune/no_copy/controller/ApiController.java b/src/main/java/ru/soune/no_copy/controller/ApiController.java index 9b3c934..174fcf7 100644 --- a/src/main/java/ru/soune/no_copy/controller/ApiController.java +++ b/src/main/java/ru/soune/no_copy/controller/ApiController.java @@ -1,24 +1,20 @@ package ru.soune.no_copy.controller; -import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; import org.springframework.http.ResponseEntity; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.*; import ru.soune.no_copy.dto.BaseRequest; -import ru.soune.no_copy.dto.LoginRequest; import ru.soune.no_copy.dto.MessageCode; -import ru.soune.no_copy.dto.RegRequest; -import ru.soune.no_copy.entity.AuthToken; import ru.soune.no_copy.exception.NotValidFieldException; -import ru.soune.no_copy.handler.RegRequestValidator; -import ru.soune.no_copy.repository.UserRepository; -import ru.soune.no_copy.service.AuthService; +import ru.soune.no_copy.exception.ValidationException; +import ru.soune.no_copy.handler.LoginRequestHandler; +import ru.soune.no_copy.handler.RegRequestHandler; +import ru.soune.no_copy.handler.RequestHandler; import java.util.HashMap; import java.util.List; @@ -30,65 +26,45 @@ import java.util.stream.Collectors; @RequestMapping("/api") @RequiredArgsConstructor public class ApiController { + private final ApplicationContext applicationContext; - private final ObjectMapper objectMapper; + private Map handlers = new HashMap<>(); - private final UserRepository userRepository; + @PostConstruct + public void init() { + RegRequestHandler regHandler = applicationContext.getBean(RegRequestHandler.class); + LoginRequestHandler loginHandler = applicationContext.getBean(LoginRequestHandler.class); - private final RegRequestValidator regRequestValidator; - - private final PasswordEncoder passwordEncoder; - - @Autowired - private AuthService authService; + handlers.put(20002, regHandler); + handlers.put(20001, loginHandler); + } @PostMapping("/v{version}/data") - public ResponseEntity handlePostRequest(@RequestBody BaseRequest request, @PathVariable("version") int version) { + public ResponseEntity handlePostRequest(@RequestBody BaseRequest request, + @PathVariable("version") int version) { Integer msgId = request.getMsgId(); - Map response; - switch (msgId) { - case 20002: - RegRequest regRequest = objectMapper.convertValue(request.getMessageBody(), RegRequest.class); + try { + RequestHandler handler = handlers.get(msgId); - if (userRepository.existsByEmail(regRequest.getEmail())) { - throw new NotValidFieldException("User already exists with email: " + regRequest.getEmail(), - msgId, MessageCode.REG_EMAIL_EXISTS.getCode(), MessageCode.REG_EMAIL_EXISTS.getDescription()); - } - - BindingResult bindingResult = new BeanPropertyBindingResult(regRequest, "regRequest"); - - regRequestValidator.validate(regRequest, bindingResult); - - if (bindingResult.hasErrors()) { - return createValidationErrorResponse(bindingResult, msgId); - } else { - authService.register(regRequest); - response = fillResponseInfo(msgId, MessageCode.SUCCESS.getCode(), - MessageCode.SUCCESS.getDescription()); - } - break; - case 20001: - LoginRequest loginRequest = objectMapper.convertValue(request.getMessageBody(), LoginRequest.class); - - if (!userRepository.existsByEmail(loginRequest.getEmail())) { - - throw new NotValidFieldException("User with email not found: " + loginRequest.getEmail(), - msgId, MessageCode.AUTH_EMAIL_NOT_FOUND.getCode(), - MessageCode.AUTH_EMAIL_NOT_FOUND.getDescription()); - } - - authService.login(loginRequest); - - response = fillResponseInfo(msgId, MessageCode.SUCCESS.getCode(), - MessageCode.SUCCESS.getDescription()); - break; - default: - return ResponseEntity.ok().body(fillResponseInfo(msgId, MessageCode.MSG_ID_NOT_FOUND.getCode(), + if (handler == null) { + return ResponseEntity.ok().body(fillResponseInfo(msgId, + MessageCode.MSG_ID_NOT_FOUND.getCode(), MessageCode.MSG_ID_NOT_FOUND.getDescription())); - } + } - return ResponseEntity.ok().body(response); + Map response = handler.handle(request); + + return ResponseEntity.ok().body(response); + + } catch (ValidationException e) { + return createValidationErrorResponse(e.getBindingResult(), e.getMsgId()); + } catch (NotValidFieldException e) { + throw e; + } catch (Exception e) { + log.error("Handler execution failed for msgId: {}", msgId, e); + throw new RuntimeException("Handler execution failed", e); + } } private ResponseEntity> createValidationErrorResponse( diff --git a/src/main/java/ru/soune/no_copy/controller/AuthController.java b/src/main/java/ru/soune/no_copy/controller/AuthController.java index 5586e80..8247049 100644 --- a/src/main/java/ru/soune/no_copy/controller/AuthController.java +++ b/src/main/java/ru/soune/no_copy/controller/AuthController.java @@ -1,13 +1,8 @@ package ru.soune.no_copy.controller; -import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import ru.soune.no_copy.dto.AuthResponse; -import ru.soune.no_copy.dto.LoginRequest; -import ru.soune.no_copy.dto.LoginResponse; -import ru.soune.no_copy.dto.RegisterRequest; import ru.soune.no_copy.entity.AuthToken; import ru.soune.no_copy.exception.TokenNotFoundException; import ru.soune.no_copy.repository.AuthTokenRepository; @@ -25,14 +20,6 @@ public class AuthController { private final AuthTokenRepository authTokenRepository; - @PostMapping("/login") - public ResponseEntity login(@Valid @RequestBody LoginRequest request) { - AuthToken login = authService.login(request); - - return ResponseEntity.ok(new LoginResponse(true, login.getUser().getEmail(), - login.getToken(),login.getExpiresAt().toString())); - } - @PostMapping("/logout") public ResponseEntity logout(@RequestHeader("Authorization") String tokenHeader) { String token = tokenHeader.replace("Bearer ", ""); diff --git a/src/main/java/ru/soune/no_copy/exception/ValidationException.java b/src/main/java/ru/soune/no_copy/exception/ValidationException.java new file mode 100644 index 0000000..f9c9d52 --- /dev/null +++ b/src/main/java/ru/soune/no_copy/exception/ValidationException.java @@ -0,0 +1,16 @@ +package ru.soune.no_copy.exception; + +import lombok.Getter; +import org.springframework.validation.BindingResult; + +@Getter +public class ValidationException extends RuntimeException { + private final BindingResult bindingResult; + private final Integer msgId; + + public ValidationException(BindingResult bindingResult, Integer msgId) { + super("Validation failed"); + this.bindingResult = bindingResult; + this.msgId = msgId; + } +} diff --git a/src/main/java/ru/soune/no_copy/handler/LoginRequestHandler.java b/src/main/java/ru/soune/no_copy/handler/LoginRequestHandler.java new file mode 100644 index 0000000..0b2044a --- /dev/null +++ b/src/main/java/ru/soune/no_copy/handler/LoginRequestHandler.java @@ -0,0 +1,47 @@ +package ru.soune.no_copy.handler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import ru.soune.no_copy.dto.BaseRequest; +import ru.soune.no_copy.dto.LoginRequest; +import ru.soune.no_copy.dto.MessageCode; +import ru.soune.no_copy.exception.NotValidFieldException; +import ru.soune.no_copy.repository.UserRepository; +import ru.soune.no_copy.service.AuthService; + +import java.util.HashMap; +import java.util.Map; + +@Component +@RequiredArgsConstructor +public class LoginRequestHandler implements RequestHandler { + + private final UserRepository userRepository; + private final AuthService authService; + private final ObjectMapper objectMapper; + + @Override + public Map handle(BaseRequest request) { + LoginRequest loginRequest = objectMapper.convertValue(request.getMessageBody(), LoginRequest.class); + + if (!userRepository.existsByEmail(loginRequest.getEmail())) { + throw new NotValidFieldException("User with email not found: " + loginRequest.getEmail(), + request.getMsgId(), MessageCode.AUTH_EMAIL_NOT_FOUND.getCode(), + MessageCode.AUTH_EMAIL_NOT_FOUND.getDescription()); + } + + authService.login(loginRequest); + + return fillResponseInfo(request.getMsgId(), MessageCode.SUCCESS.getCode(), + MessageCode.SUCCESS.getDescription()); + } + + private Map fillResponseInfo(Integer msgId, Integer messageCode, String messageDesc) { + Map response = new HashMap<>(); + response.put("msg_id", msgId); + response.put("message_code", messageCode); + response.put("message_desc", messageDesc); + return response; + } +} diff --git a/src/main/java/ru/soune/no_copy/handler/RegRequestHandler.java b/src/main/java/ru/soune/no_copy/handler/RegRequestHandler.java new file mode 100644 index 0000000..c6a83ed --- /dev/null +++ b/src/main/java/ru/soune/no_copy/handler/RegRequestHandler.java @@ -0,0 +1,59 @@ +package ru.soune.no_copy.handler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.validation.BeanPropertyBindingResult; +import org.springframework.validation.BindingResult; +import ru.soune.no_copy.dto.BaseRequest; +import ru.soune.no_copy.dto.MessageCode; +import ru.soune.no_copy.dto.RegRequest; +import ru.soune.no_copy.exception.NotValidFieldException; +import ru.soune.no_copy.exception.ValidationException; +import ru.soune.no_copy.repository.UserRepository; +import ru.soune.no_copy.service.AuthService; + +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@Component +@RequiredArgsConstructor +public class RegRequestHandler implements RequestHandler { + + private final UserRepository userRepository; + private final RegRequestValidator regRequestValidator; + private final AuthService authService; + private final ObjectMapper objectMapper; + + @Override + public Map handle(BaseRequest request) throws ValidationException { + RegRequest regRequest = objectMapper.convertValue(request.getMessageBody(), RegRequest.class); + + if (userRepository.existsByEmail(regRequest.getEmail())) { + throw new NotValidFieldException("User already exists with email: " + regRequest.getEmail(), + request.getMsgId(), MessageCode.REG_EMAIL_EXISTS.getCode(), + MessageCode.REG_EMAIL_EXISTS.getDescription()); + } + + BindingResult bindingResult = new BeanPropertyBindingResult(regRequest, "regRequest"); + regRequestValidator.validate(regRequest, bindingResult); + + if (bindingResult.hasErrors()) { + throw new ValidationException(bindingResult, request.getMsgId()); + } + + authService.register(regRequest); + return fillResponseInfo(request.getMsgId(), MessageCode.SUCCESS.getCode(), + MessageCode.SUCCESS.getDescription()); + } + + private Map fillResponseInfo(Integer msgId, Integer messageCode, String messageDesc) { + Map response = new HashMap<>(); + response.put("msg_id", msgId); + response.put("message_code", messageCode); + response.put("message_desc", messageDesc); + return response; + } +} \ No newline at end of file diff --git a/src/main/java/ru/soune/no_copy/handler/RequestHandler.java b/src/main/java/ru/soune/no_copy/handler/RequestHandler.java new file mode 100644 index 0000000..d78e19b --- /dev/null +++ b/src/main/java/ru/soune/no_copy/handler/RequestHandler.java @@ -0,0 +1,9 @@ +package ru.soune.no_copy.handler; + +import ru.soune.no_copy.dto.BaseRequest; + +import java.util.Map; + +public interface RequestHandler { + Map handle(BaseRequest request) throws Exception; +} -- 2.54.0 From 420734ff8799be453f78bd89a5ba509869a88496 Mon Sep 17 00:00:00 2001 From: vladp Date: Wed, 10 Dec 2025 15:27:14 +0700 Subject: [PATCH 05/12] fix work controller code 20001,20002 --- .../no_copy/controller/ApiController.java | 32 +++++---------- .../ru/soune/no_copy/dto/AuthResponse.java | 10 ----- .../ru/soune/no_copy/dto/LogOutAnswer.java | 17 ++++++++ .../ru/soune/no_copy/dto/LoginAnswer.java | 17 ++++++++ .../ru/soune/no_copy/dto/LoginResponse.java | 14 ------- .../java/ru/soune/no_copy/dto/RegAnswer.java | 17 ++++++++ .../ru/soune/no_copy/dto/RegisterRequest.java | 40 ------------------ .../exception/NotValidFieldException.java | 13 ++---- .../handler/GlobalExceptionHandler.java | 5 +-- .../no_copy/handler/JwtTokenProvider.java | 7 ---- .../no_copy/handler/LoginRequestHandler.java | 30 +++++++------- .../no_copy/handler/RegRequestHandler.java | 37 +++++++++-------- .../soune/no_copy/handler/RequestHandler.java | 5 +-- .../{ => validator}/RegRequestValidator.java | 2 +- .../ru/soune/no_copy/service/AuthService.java | 13 +++--- .../no_copy/service/AuthServiceTest.java | 41 ------------------- 16 files changed, 111 insertions(+), 189 deletions(-) delete mode 100644 src/main/java/ru/soune/no_copy/dto/AuthResponse.java create mode 100644 src/main/java/ru/soune/no_copy/dto/LogOutAnswer.java create mode 100644 src/main/java/ru/soune/no_copy/dto/LoginAnswer.java delete mode 100644 src/main/java/ru/soune/no_copy/dto/LoginResponse.java create mode 100644 src/main/java/ru/soune/no_copy/dto/RegAnswer.java delete mode 100644 src/main/java/ru/soune/no_copy/dto/RegisterRequest.java delete mode 100644 src/main/java/ru/soune/no_copy/handler/JwtTokenProvider.java rename src/main/java/ru/soune/no_copy/handler/{ => validator}/RegRequestValidator.java (99%) diff --git a/src/main/java/ru/soune/no_copy/controller/ApiController.java b/src/main/java/ru/soune/no_copy/controller/ApiController.java index 174fcf7..8d6a646 100644 --- a/src/main/java/ru/soune/no_copy/controller/ApiController.java +++ b/src/main/java/ru/soune/no_copy/controller/ApiController.java @@ -9,7 +9,9 @@ import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.*; import ru.soune.no_copy.dto.BaseRequest; +import ru.soune.no_copy.dto.BaseResponse; import ru.soune.no_copy.dto.MessageCode; +import ru.soune.no_copy.dto.RegAnswer; import ru.soune.no_copy.exception.NotValidFieldException; import ru.soune.no_copy.exception.ValidationException; import ru.soune.no_copy.handler.LoginRequestHandler; @@ -48,15 +50,15 @@ public class ApiController { RequestHandler handler = handlers.get(msgId); if (handler == null) { - return ResponseEntity.ok().body(fillResponseInfo(msgId, + new BaseResponse(msgId, MessageCode.MSG_ID_NOT_FOUND.getCode(), - MessageCode.MSG_ID_NOT_FOUND.getDescription())); + MessageCode.MSG_ID_NOT_FOUND.getDescription(), + new HashMap<>()); } - Map response = handler.handle(request); + BaseResponse response = handler.handle(request); return ResponseEntity.ok().body(response); - } catch (ValidationException e) { return createValidationErrorResponse(e.getBindingResult(), e.getMsgId()); } catch (NotValidFieldException e) { @@ -67,20 +69,17 @@ public class ApiController { } } - private ResponseEntity> createValidationErrorResponse( - BindingResult bindingResult, Integer msgId) { - - Map response = fillResponseInfo(msgId, MessageCode.INVALID_FIELD.getCode(), - MessageCode.INVALID_FIELD.getDescription()); - + private ResponseEntity createValidationErrorResponse(BindingResult bindingResult, Integer msgId) { List> fieldErrors = bindingResult.getFieldErrors() .stream() .map(this::createErrorDetail) .collect(Collectors.toList()); - response.put("field_errors", fieldErrors); + RegAnswer regAnswer = new RegAnswer(); + regAnswer.setFieldErrors(fieldErrors); - return ResponseEntity.badRequest().body(response); + return ResponseEntity.ok().body(new BaseResponse(msgId, MessageCode.INVALID_FIELD.getCode(), + MessageCode.INVALID_FIELD.getDescription(), regAnswer)); } private Map createErrorDetail(FieldError fieldError) { @@ -96,13 +95,4 @@ public class ApiController { return errorDetail; } - - private Map fillResponseInfo(Integer msgId, Integer messageCode, String messageDesc) { - Map response = new HashMap<>(); - response.put("msg_id", msgId); - response.put("message_code", messageCode); - response.put("message_desc", messageDesc); - - return response; - } } \ No newline at end of file diff --git a/src/main/java/ru/soune/no_copy/dto/AuthResponse.java b/src/main/java/ru/soune/no_copy/dto/AuthResponse.java deleted file mode 100644 index c39301a..0000000 --- a/src/main/java/ru/soune/no_copy/dto/AuthResponse.java +++ /dev/null @@ -1,10 +0,0 @@ -package ru.soune.no_copy.dto; - -import java.time.LocalDateTime; - -public record AuthResponse ( - boolean success, - String message, - String token, - LocalDateTime expiresAt -) {} diff --git a/src/main/java/ru/soune/no_copy/dto/LogOutAnswer.java b/src/main/java/ru/soune/no_copy/dto/LogOutAnswer.java new file mode 100644 index 0000000..1174a5e --- /dev/null +++ b/src/main/java/ru/soune/no_copy/dto/LogOutAnswer.java @@ -0,0 +1,17 @@ +package ru.soune.no_copy.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.Map; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class LogOutAnswer { + private String Token; + + private List> fieldErrors; +} diff --git a/src/main/java/ru/soune/no_copy/dto/LoginAnswer.java b/src/main/java/ru/soune/no_copy/dto/LoginAnswer.java new file mode 100644 index 0000000..724c662 --- /dev/null +++ b/src/main/java/ru/soune/no_copy/dto/LoginAnswer.java @@ -0,0 +1,17 @@ +package ru.soune.no_copy.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.Map; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class LoginAnswer { + private String Token; + + private List> fieldErrors; +} diff --git a/src/main/java/ru/soune/no_copy/dto/LoginResponse.java b/src/main/java/ru/soune/no_copy/dto/LoginResponse.java deleted file mode 100644 index 5fe7d73..0000000 --- a/src/main/java/ru/soune/no_copy/dto/LoginResponse.java +++ /dev/null @@ -1,14 +0,0 @@ -package ru.soune.no_copy.dto; - -import lombok.AllArgsConstructor; -import lombok.Data; -import ru.soune.no_copy.entity.User; - -@Data -@AllArgsConstructor -public class LoginResponse { - private boolean success; - private String email; - private String token; - private String expiresAt; -} diff --git a/src/main/java/ru/soune/no_copy/dto/RegAnswer.java b/src/main/java/ru/soune/no_copy/dto/RegAnswer.java new file mode 100644 index 0000000..b79c14f --- /dev/null +++ b/src/main/java/ru/soune/no_copy/dto/RegAnswer.java @@ -0,0 +1,17 @@ +package ru.soune.no_copy.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.Map; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class RegAnswer { + private String Token; + + private List> fieldErrors; +} \ No newline at end of file diff --git a/src/main/java/ru/soune/no_copy/dto/RegisterRequest.java b/src/main/java/ru/soune/no_copy/dto/RegisterRequest.java deleted file mode 100644 index e08f39b..0000000 --- a/src/main/java/ru/soune/no_copy/dto/RegisterRequest.java +++ /dev/null @@ -1,40 +0,0 @@ -package ru.soune.no_copy.dto; - -import com.fasterxml.jackson.annotation.JsonFormat; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Past; -import jakarta.validation.constraints.Size; -import org.springframework.format.annotation.DateTimeFormat; -import ru.soune.no_copy.entity.GenderType; -import ru.soune.no_copy.entity.SubscriptionType; - -import java.time.LocalDate; - -public record RegisterRequest( - @NotBlank(message = "error.name.length") - String fullName, - - String companyName, - - @Size(min = 11, max = 14) - String phone, - - @NotBlank(message = "error.not.blank") - @Email(message = "error.not.email") - @Size(max = 128) - String email, - - @DateTimeFormat(pattern = "dd-MM-yyyy") - @JsonFormat(pattern = "dd-MM-yyyy") - @Past - LocalDate birthday, - - @NotBlank(message = "error.not.blank") - @Size(min = 8) - String password, - - SubscriptionType subscriptionType, - - GenderType genderType -) {} diff --git a/src/main/java/ru/soune/no_copy/exception/NotValidFieldException.java b/src/main/java/ru/soune/no_copy/exception/NotValidFieldException.java index 2181038..cbf2746 100644 --- a/src/main/java/ru/soune/no_copy/exception/NotValidFieldException.java +++ b/src/main/java/ru/soune/no_copy/exception/NotValidFieldException.java @@ -1,23 +1,18 @@ package ru.soune.no_copy.exception; import lombok.Getter; +import ru.soune.no_copy.dto.BaseResponse; @Getter public class NotValidFieldException extends RuntimeException { private final String message; - private final Integer messageId; + private final BaseResponse baseResponse; - private final Integer messageCode; - - private final String messageDescription; - - public NotValidFieldException(String message, Integer messageId, Integer messageCode, String messageDescription) { + public NotValidFieldException(String message, BaseResponse baseResponse) { super(message); this.message = message; - this.messageId = messageId; - this.messageCode = messageCode; - this.messageDescription = messageDescription; + this.baseResponse = baseResponse; } } diff --git a/src/main/java/ru/soune/no_copy/handler/GlobalExceptionHandler.java b/src/main/java/ru/soune/no_copy/handler/GlobalExceptionHandler.java index 7b78902..9e80dbb 100644 --- a/src/main/java/ru/soune/no_copy/handler/GlobalExceptionHandler.java +++ b/src/main/java/ru/soune/no_copy/handler/GlobalExceptionHandler.java @@ -35,10 +35,7 @@ public class GlobalExceptionHandler { return ResponseEntity .ok() - .body(Map.of( - "msg_id", ex.getMessageId(), - "message_code", ex.getMessageCode(), - "message_desc", ex.getMessageDescription())); + .body(ex.getBaseResponse()); } @ExceptionHandler(UserNotFoundException.class) diff --git a/src/main/java/ru/soune/no_copy/handler/JwtTokenProvider.java b/src/main/java/ru/soune/no_copy/handler/JwtTokenProvider.java deleted file mode 100644 index 721869c..0000000 --- a/src/main/java/ru/soune/no_copy/handler/JwtTokenProvider.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.soune.no_copy.handler; - -import org.springframework.stereotype.Component; - -@Component -public class JwtTokenProvider { -} diff --git a/src/main/java/ru/soune/no_copy/handler/LoginRequestHandler.java b/src/main/java/ru/soune/no_copy/handler/LoginRequestHandler.java index 0b2044a..91890e9 100644 --- a/src/main/java/ru/soune/no_copy/handler/LoginRequestHandler.java +++ b/src/main/java/ru/soune/no_copy/handler/LoginRequestHandler.java @@ -3,13 +3,13 @@ package ru.soune.no_copy.handler; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -import ru.soune.no_copy.dto.BaseRequest; -import ru.soune.no_copy.dto.LoginRequest; -import ru.soune.no_copy.dto.MessageCode; +import ru.soune.no_copy.dto.*; +import ru.soune.no_copy.entity.AuthToken; import ru.soune.no_copy.exception.NotValidFieldException; import ru.soune.no_copy.repository.UserRepository; import ru.soune.no_copy.service.AuthService; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -22,26 +22,24 @@ public class LoginRequestHandler implements RequestHandler { private final ObjectMapper objectMapper; @Override - public Map handle(BaseRequest request) { + public BaseResponse handle(BaseRequest request) { LoginRequest loginRequest = objectMapper.convertValue(request.getMessageBody(), LoginRequest.class); if (!userRepository.existsByEmail(loginRequest.getEmail())) { + LoginAnswer loginAnswer = new LoginAnswer(); + loginAnswer.setFieldErrors(Arrays.asList(Map.of("email", loginRequest.getEmail()))); + throw new NotValidFieldException("User with email not found: " + loginRequest.getEmail(), - request.getMsgId(), MessageCode.AUTH_EMAIL_NOT_FOUND.getCode(), - MessageCode.AUTH_EMAIL_NOT_FOUND.getDescription()); + new BaseResponse(request.getMsgId(), MessageCode.AUTH_EMAIL_NOT_FOUND.getCode(), + MessageCode.AUTH_EMAIL_NOT_FOUND.getDescription(), loginAnswer)); } - authService.login(loginRequest); + AuthToken authToken = authService.login(loginRequest); - return fillResponseInfo(request.getMsgId(), MessageCode.SUCCESS.getCode(), - MessageCode.SUCCESS.getDescription()); - } + LoginAnswer loginAnswer = new LoginAnswer(); + loginAnswer.setToken(authToken.getToken()); - private Map fillResponseInfo(Integer msgId, Integer messageCode, String messageDesc) { - Map response = new HashMap<>(); - response.put("msg_id", msgId); - response.put("message_code", messageCode); - response.put("message_desc", messageDesc); - return response; + return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(), + MessageCode.SUCCESS.getDescription(), loginAnswer); } } diff --git a/src/main/java/ru/soune/no_copy/handler/RegRequestHandler.java b/src/main/java/ru/soune/no_copy/handler/RegRequestHandler.java index c6a83ed..2c54dc2 100644 --- a/src/main/java/ru/soune/no_copy/handler/RegRequestHandler.java +++ b/src/main/java/ru/soune/no_copy/handler/RegRequestHandler.java @@ -6,35 +6,40 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.BindingResult; -import ru.soune.no_copy.dto.BaseRequest; -import ru.soune.no_copy.dto.MessageCode; -import ru.soune.no_copy.dto.RegRequest; +import ru.soune.no_copy.dto.*; +import ru.soune.no_copy.entity.AuthToken; import ru.soune.no_copy.exception.NotValidFieldException; import ru.soune.no_copy.exception.ValidationException; +import ru.soune.no_copy.handler.validator.RegRequestValidator; import ru.soune.no_copy.repository.UserRepository; import ru.soune.no_copy.service.AuthService; -import java.util.HashMap; +import java.util.Arrays; import java.util.Map; @Slf4j @Component @RequiredArgsConstructor public class RegRequestHandler implements RequestHandler { - private final UserRepository userRepository; + private final RegRequestValidator regRequestValidator; + private final AuthService authService; + private final ObjectMapper objectMapper; @Override - public Map handle(BaseRequest request) throws ValidationException { + public BaseResponse handle(BaseRequest request) throws ValidationException { RegRequest regRequest = objectMapper.convertValue(request.getMessageBody(), RegRequest.class); if (userRepository.existsByEmail(regRequest.getEmail())) { + RegAnswer regAnswer = new RegAnswer(); + regAnswer.setFieldErrors(Arrays.asList(Map.of("email", regRequest.getEmail()))); + throw new NotValidFieldException("User already exists with email: " + regRequest.getEmail(), - request.getMsgId(), MessageCode.REG_EMAIL_EXISTS.getCode(), - MessageCode.REG_EMAIL_EXISTS.getDescription()); + new BaseResponse(request.getMsgId(), MessageCode.REG_EMAIL_EXISTS.getCode(), + MessageCode.REG_EMAIL_EXISTS.getDescription(), regAnswer)); } BindingResult bindingResult = new BeanPropertyBindingResult(regRequest, "regRequest"); @@ -44,16 +49,12 @@ public class RegRequestHandler implements RequestHandler { throw new ValidationException(bindingResult, request.getMsgId()); } - authService.register(regRequest); - return fillResponseInfo(request.getMsgId(), MessageCode.SUCCESS.getCode(), - MessageCode.SUCCESS.getDescription()); - } + AuthToken authToken = authService.register(regRequest); - private Map fillResponseInfo(Integer msgId, Integer messageCode, String messageDesc) { - Map response = new HashMap<>(); - response.put("msg_id", msgId); - response.put("message_code", messageCode); - response.put("message_desc", messageDesc); - return response; + RegAnswer regAnswer = new RegAnswer(); + regAnswer.setToken(authToken.getToken()); + + return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(), + MessageCode.SUCCESS.getDescription(), regAnswer); } } \ No newline at end of file diff --git a/src/main/java/ru/soune/no_copy/handler/RequestHandler.java b/src/main/java/ru/soune/no_copy/handler/RequestHandler.java index d78e19b..c38848b 100644 --- a/src/main/java/ru/soune/no_copy/handler/RequestHandler.java +++ b/src/main/java/ru/soune/no_copy/handler/RequestHandler.java @@ -1,9 +1,8 @@ package ru.soune.no_copy.handler; import ru.soune.no_copy.dto.BaseRequest; - -import java.util.Map; +import ru.soune.no_copy.dto.BaseResponse; public interface RequestHandler { - Map handle(BaseRequest request) throws Exception; + BaseResponse handle(BaseRequest request) throws Exception; } diff --git a/src/main/java/ru/soune/no_copy/handler/RegRequestValidator.java b/src/main/java/ru/soune/no_copy/handler/validator/RegRequestValidator.java similarity index 99% rename from src/main/java/ru/soune/no_copy/handler/RegRequestValidator.java rename to src/main/java/ru/soune/no_copy/handler/validator/RegRequestValidator.java index f7ea83e..b25c2e0 100644 --- a/src/main/java/ru/soune/no_copy/handler/RegRequestValidator.java +++ b/src/main/java/ru/soune/no_copy/handler/validator/RegRequestValidator.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.handler; +package ru.soune.no_copy.handler.validator; import org.springframework.stereotype.Component; import org.springframework.validation.Errors; diff --git a/src/main/java/ru/soune/no_copy/service/AuthService.java b/src/main/java/ru/soune/no_copy/service/AuthService.java index 2a76f68..01ad0ea 100644 --- a/src/main/java/ru/soune/no_copy/service/AuthService.java +++ b/src/main/java/ru/soune/no_copy/service/AuthService.java @@ -5,9 +5,7 @@ import org.springframework.context.MessageSource; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import ru.soune.no_copy.dto.LoginRequest; -import ru.soune.no_copy.dto.MessageCode; -import ru.soune.no_copy.dto.RegRequest; +import ru.soune.no_copy.dto.*; import ru.soune.no_copy.entity.AuthToken; import ru.soune.no_copy.entity.User; import ru.soune.no_copy.exception.NotValidFieldException; @@ -18,7 +16,9 @@ import ru.soune.no_copy.repository.UserRepository; import java.security.SecureRandom; import java.time.LocalDateTime; +import java.util.Arrays; import java.util.Base64; +import java.util.Map; import java.util.Optional; @Service @@ -65,9 +65,12 @@ public class AuthService { User user = userOpt.get(); if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) { - throw new NotValidFieldException("Invalid password", 20003, + LoginAnswer loginAnswer = new LoginAnswer(); + loginAnswer.setFieldErrors(Arrays.asList(Map.of("password", request.getPassword()))); + + throw new NotValidFieldException("Invalid password", new BaseResponse(20003, MessageCode.AUTH_PASSWORD_NOT_MATCHES.getCode(), - MessageCode.AUTH_PASSWORD_NOT_MATCHES.getDescription()); + MessageCode.AUTH_PASSWORD_NOT_MATCHES.getDescription(), loginAnswer)); } user.setLastLoginAt(LocalDateTime.now()); diff --git a/src/test/java/ru/soune/no_copy/service/AuthServiceTest.java b/src/test/java/ru/soune/no_copy/service/AuthServiceTest.java index c2a38a4..69b767e 100644 --- a/src/test/java/ru/soune/no_copy/service/AuthServiceTest.java +++ b/src/test/java/ru/soune/no_copy/service/AuthServiceTest.java @@ -9,21 +9,17 @@ import org.mockito.MockitoAnnotations; import org.springframework.context.MessageSource; import org.springframework.security.crypto.password.PasswordEncoder; import ru.soune.no_copy.dto.LoginRequest; -import ru.soune.no_copy.dto.RegisterRequest; import ru.soune.no_copy.entity.AuthToken; import ru.soune.no_copy.entity.User; import ru.soune.no_copy.exception.NotValidationPasswordException; -import ru.soune.no_copy.exception.NotValidFieldException; import ru.soune.no_copy.exception.UserNotFoundException; import ru.soune.no_copy.repository.AuthTokenRepository; import ru.soune.no_copy.repository.UserRepository; -import java.util.Locale; import java.util.Optional; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -49,43 +45,6 @@ public class AuthServiceTest { MockitoAnnotations.openMocks(this); } - @Test - void registerSuccess() { - RegisterRequest request = new RegisterRequest("John","A.","124124", - "john@example.com", null,"password123", null, null); - - when(userRepository.existsByEmail(request.email())).thenReturn(false); - when(passwordEncoder.encode(request.password())).thenReturn("hashed"); - when(userRepository.save(any(User.class))).thenAnswer(invocation -> invocation.getArgument(0)); - when(authTokenRepository.save(any(AuthToken.class))).thenAnswer(invocation -> invocation.getArgument(0)); - - AuthToken token = authService.register(request); - User user = token.getUser(); - String email = user.getEmail(); - - assertNotNull(token); - assertNotNull(token.getToken()); - assertNotNull(token.getUser()); - assertEquals("john@example.com", email); - assertNotNull(token.getExpiresAt()); - } - - @Test - void registerExistingEmailThrows() { - RegisterRequest request = new RegisterRequest("John","A.","124124", - "john@example.com", null,"password123", null, null); - - when(userRepository.existsByEmail(request.email())) - .thenReturn(true); - when(messageSource.getMessage(anyString(), any(), any(Locale.class))) - .thenReturn("User exists"); - - NotValidFieldException ex = assertThrows(NotValidFieldException.class, - () -> authService.register(request)); - - assertEquals("User exists", ex.getMessage()); - } - @Test void login_success() { LoginRequest request = new LoginRequest("test@mail.com", "password"); -- 2.54.0 From 76da2e94c95aaa3ff6d7178f8e4a9cffffcd1a48 Mon Sep 17 00:00:00 2001 From: vladp Date: Wed, 10 Dec 2025 17:17:48 +0700 Subject: [PATCH 06/12] change code message --- .../ru/soune/no_copy/controller/ApiController.java | 7 ++++--- src/main/java/ru/soune/no_copy/dto/MessageCode.java | 10 +++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/ru/soune/no_copy/controller/ApiController.java b/src/main/java/ru/soune/no_copy/controller/ApiController.java index 8d6a646..7986e11 100644 --- a/src/main/java/ru/soune/no_copy/controller/ApiController.java +++ b/src/main/java/ru/soune/no_copy/controller/ApiController.java @@ -45,19 +45,20 @@ public class ApiController { public ResponseEntity handlePostRequest(@RequestBody BaseRequest request, @PathVariable("version") int version) { Integer msgId = request.getMsgId(); + BaseResponse response; try { RequestHandler handler = handlers.get(msgId); if (handler == null) { - new BaseResponse(msgId, + response = new BaseResponse(msgId, MessageCode.MSG_ID_NOT_FOUND.getCode(), MessageCode.MSG_ID_NOT_FOUND.getDescription(), new HashMap<>()); + } else { + response = handler.handle(request); } - BaseResponse response = handler.handle(request); - return ResponseEntity.ok().body(response); } catch (ValidationException e) { return createValidationErrorResponse(e.getBindingResult(), e.getMsgId()); diff --git a/src/main/java/ru/soune/no_copy/dto/MessageCode.java b/src/main/java/ru/soune/no_copy/dto/MessageCode.java index 5359d44..75fb869 100644 --- a/src/main/java/ru/soune/no_copy/dto/MessageCode.java +++ b/src/main/java/ru/soune/no_copy/dto/MessageCode.java @@ -2,12 +2,12 @@ package ru.soune.no_copy.dto; public enum MessageCode { SUCCESS(0, "Operation successful"), - REG_EMAIL_EXISTS(2001, "Email already registered"), - INVALID_FIELD(2002, "Invalid field"), - MSG_ID_NOT_FOUND(2004, "Message id not found"), + REG_EMAIL_EXISTS(4001, "Email already registered"), + INVALID_FIELD(4002, "Invalid field"), + MSG_ID_NOT_FOUND(4003, "Message id not found"), - AUTH_EMAIL_NOT_FOUND(2005, "Email not found"), - AUTH_PASSWORD_NOT_MATCHES(2006, "Password does not match"); + AUTH_EMAIL_NOT_FOUND(4005, "Email not found"), + AUTH_PASSWORD_NOT_MATCHES(4006, "Password does not match"); private final Integer code; -- 2.54.0 From a30b0488e80a2f3942151447bdb0ee9962ed89de Mon Sep 17 00:00:00 2001 From: vladp Date: Wed, 10 Dec 2025 19:12:54 +0700 Subject: [PATCH 07/12] change package,change message_code --- .../soune/no_copy/handler/RequestHandler.java | 8 ------- .../NoCopyApplication.java | 2 +- .../configuration/ApplicationConfig.java | 2 +- .../configuration/JacksonConfig.java | 2 +- .../configuration/JpaConfiguration.java | 2 +- .../configuration/SubscriptionConfig.java | 2 +- .../controller/ApiController.java | 20 ++++++++-------- .../controller/AuthController.java | 10 ++++---- .../controller/HealtCheckController.java | 3 +-- .../controller/UserContentController.java | 2 +- .../controller/UserController.java | 24 +++++++++---------- .../{no_copy => nocopy}/dto/BaseRequest.java | 2 +- .../{no_copy => nocopy}/dto/BaseResponse.java | 2 +- .../dto/ChangePasswordRequest.java | 2 +- .../{no_copy => nocopy}/dto/LogOutAnswer.java | 2 +- .../{no_copy => nocopy}/dto/LoginAnswer.java | 2 +- .../{no_copy => nocopy}/dto/LoginRequest.java | 2 +- .../{no_copy => nocopy}/dto/MessageCode.java | 12 +++++----- .../{no_copy => nocopy}/dto/RegAnswer.java | 2 +- .../{no_copy => nocopy}/dto/RegRequest.java | 2 +- .../dto/UserContentDTO.java | 3 +-- .../dto/UserContentRequest.java | 2 +- .../dto/UserContentResponse.java | 6 ++--- .../dto/UserContentUpdateRequest.java | 2 +- .../{no_copy => nocopy}/dto/UserDTO.java | 6 ++--- .../{no_copy => nocopy}/dto/UserRequest.java | 5 ++-- .../{no_copy => nocopy}/entity/AuthToken.java | 2 +- .../entity/BaseEntity.java | 2 +- .../entity/ContentStatus.java | 2 +- .../{no_copy => nocopy}/entity/FileType.java | 2 +- .../entity/GenderType.java | 2 +- .../entity/ImageProtection.java | 2 +- .../entity/SubscriptionType.java | 2 +- .../{no_copy => nocopy}/entity/User.java | 2 +- .../entity/UserAction.java | 2 +- .../entity/UserContent.java | 3 +-- .../{no_copy => nocopy}/entity/Violation.java | 2 +- .../exception/ContentNotFoundException.java | 2 +- .../exception/InvalidPasswordException.java | 2 +- .../exception/InvalidUserEmail.java | 2 +- .../exception/NotFoundAuthToken.java | 2 +- .../exception/NotValidFieldException.java | 4 ++-- .../NotValidationPasswordException.java | 2 +- .../exception/TokenNotFoundException.java | 2 +- .../exception/UserNotFoundException.java | 2 +- .../exception/ValidationException.java | 2 +- .../handler/GlobalExceptionHandler.java | 4 ++-- .../handler/LoginRequestHandler.java | 13 +++++----- .../handler/RegRequestHandler.java | 16 ++++++------- .../soune/nocopy/handler/RequestHandler.java | 8 +++++++ .../validator/RegRequestValidator.java | 4 ++-- .../mapper/UserContentMapper.java | 6 ++--- .../mapper/UserMapper.java | 6 ++--- .../repository/AuthTokenRepository.java | 4 ++-- .../repository/UserContentRepository.java | 6 ++--- .../repository/UserRepository.java | 4 ++-- .../service/AuthService.java | 16 ++++++------- .../service/UserContentService.java | 22 ++++++++--------- .../service/UserService.java | 18 +++++++------- .../service/AuthServiceTest.java | 16 ++++++------- 60 files changed, 154 insertions(+), 161 deletions(-) delete mode 100644 src/main/java/ru/soune/no_copy/handler/RequestHandler.java rename src/main/java/ru/soune/{no_copy => nocopy}/NoCopyApplication.java (91%) rename src/main/java/ru/soune/{no_copy => nocopy}/configuration/ApplicationConfig.java (92%) rename src/main/java/ru/soune/{no_copy => nocopy}/configuration/JacksonConfig.java (97%) rename src/main/java/ru/soune/{no_copy => nocopy}/configuration/JpaConfiguration.java (83%) rename src/main/java/ru/soune/{no_copy => nocopy}/configuration/SubscriptionConfig.java (96%) rename src/main/java/ru/soune/{no_copy => nocopy}/controller/ApiController.java (87%) rename src/main/java/ru/soune/{no_copy => nocopy}/controller/AuthController.java (78%) rename src/main/java/ru/soune/{no_copy => nocopy}/controller/HealtCheckController.java (79%) rename src/main/java/ru/soune/{no_copy => nocopy}/controller/UserContentController.java (87%) rename src/main/java/ru/soune/{no_copy => nocopy}/controller/UserController.java (87%) rename src/main/java/ru/soune/{no_copy => nocopy}/dto/BaseRequest.java (89%) rename src/main/java/ru/soune/{no_copy => nocopy}/dto/BaseResponse.java (93%) rename src/main/java/ru/soune/{no_copy => nocopy}/dto/ChangePasswordRequest.java (89%) rename src/main/java/ru/soune/{no_copy => nocopy}/dto/LogOutAnswer.java (90%) rename src/main/java/ru/soune/{no_copy => nocopy}/dto/LoginAnswer.java (90%) rename src/main/java/ru/soune/{no_copy => nocopy}/dto/LoginRequest.java (94%) rename src/main/java/ru/soune/{no_copy => nocopy}/dto/MessageCode.java (57%) rename src/main/java/ru/soune/{no_copy => nocopy}/dto/RegAnswer.java (90%) rename src/main/java/ru/soune/{no_copy => nocopy}/dto/RegRequest.java (95%) rename src/main/java/ru/soune/{no_copy => nocopy}/dto/UserContentDTO.java (76%) rename src/main/java/ru/soune/{no_copy => nocopy}/dto/UserContentRequest.java (93%) rename src/main/java/ru/soune/{no_copy => nocopy}/dto/UserContentResponse.java (71%) rename src/main/java/ru/soune/{no_copy => nocopy}/dto/UserContentUpdateRequest.java (93%) rename src/main/java/ru/soune/{no_copy => nocopy}/dto/UserDTO.java (81%) rename src/main/java/ru/soune/{no_copy => nocopy}/dto/UserRequest.java (83%) rename src/main/java/ru/soune/{no_copy => nocopy}/entity/AuthToken.java (97%) rename src/main/java/ru/soune/{no_copy => nocopy}/entity/BaseEntity.java (95%) rename src/main/java/ru/soune/{no_copy => nocopy}/entity/ContentStatus.java (89%) rename src/main/java/ru/soune/{no_copy => nocopy}/entity/FileType.java (89%) rename src/main/java/ru/soune/{no_copy => nocopy}/entity/GenderType.java (57%) rename src/main/java/ru/soune/{no_copy => nocopy}/entity/ImageProtection.java (97%) rename src/main/java/ru/soune/{no_copy => nocopy}/entity/SubscriptionType.java (76%) rename src/main/java/ru/soune/{no_copy => nocopy}/entity/User.java (98%) rename src/main/java/ru/soune/{no_copy => nocopy}/entity/UserAction.java (97%) rename src/main/java/ru/soune/{no_copy => nocopy}/entity/UserContent.java (96%) rename src/main/java/ru/soune/{no_copy => nocopy}/entity/Violation.java (97%) rename src/main/java/ru/soune/{no_copy => nocopy}/exception/ContentNotFoundException.java (80%) rename src/main/java/ru/soune/{no_copy => nocopy}/exception/InvalidPasswordException.java (80%) rename src/main/java/ru/soune/{no_copy => nocopy}/exception/InvalidUserEmail.java (79%) rename src/main/java/ru/soune/{no_copy => nocopy}/exception/NotFoundAuthToken.java (79%) rename src/main/java/ru/soune/{no_copy => nocopy}/exception/NotValidFieldException.java (82%) rename src/main/java/ru/soune/{no_copy => nocopy}/exception/NotValidationPasswordException.java (82%) rename src/main/java/ru/soune/{no_copy => nocopy}/exception/TokenNotFoundException.java (80%) rename src/main/java/ru/soune/{no_copy => nocopy}/exception/UserNotFoundException.java (80%) rename src/main/java/ru/soune/{no_copy => nocopy}/exception/ValidationException.java (92%) rename src/main/java/ru/soune/{no_copy => nocopy}/handler/GlobalExceptionHandler.java (97%) rename src/main/java/ru/soune/{no_copy => nocopy}/handler/LoginRequestHandler.java (83%) rename src/main/java/ru/soune/{no_copy => nocopy}/handler/RegRequestHandler.java (83%) create mode 100644 src/main/java/ru/soune/nocopy/handler/RequestHandler.java rename src/main/java/ru/soune/{no_copy => nocopy}/handler/validator/RegRequestValidator.java (99%) rename src/main/java/ru/soune/{no_copy => nocopy}/mapper/UserContentMapper.java (79%) rename src/main/java/ru/soune/{no_copy => nocopy}/mapper/UserMapper.java (77%) rename src/main/java/ru/soune/{no_copy => nocopy}/repository/AuthTokenRepository.java (83%) rename src/main/java/ru/soune/{no_copy => nocopy}/repository/UserContentRepository.java (82%) rename src/main/java/ru/soune/{no_copy => nocopy}/repository/UserRepository.java (77%) rename src/main/java/ru/soune/{no_copy => nocopy}/service/AuthService.java (87%) rename src/main/java/ru/soune/{no_copy => nocopy}/service/UserContentService.java (81%) rename src/main/java/ru/soune/{no_copy => nocopy}/service/UserService.java (86%) rename src/test/java/ru/soune/{no_copy => nocopy}/service/AuthServiceTest.java (87%) diff --git a/src/main/java/ru/soune/no_copy/handler/RequestHandler.java b/src/main/java/ru/soune/no_copy/handler/RequestHandler.java deleted file mode 100644 index c38848b..0000000 --- a/src/main/java/ru/soune/no_copy/handler/RequestHandler.java +++ /dev/null @@ -1,8 +0,0 @@ -package ru.soune.no_copy.handler; - -import ru.soune.no_copy.dto.BaseRequest; -import ru.soune.no_copy.dto.BaseResponse; - -public interface RequestHandler { - BaseResponse handle(BaseRequest request) throws Exception; -} diff --git a/src/main/java/ru/soune/no_copy/NoCopyApplication.java b/src/main/java/ru/soune/nocopy/NoCopyApplication.java similarity index 91% rename from src/main/java/ru/soune/no_copy/NoCopyApplication.java rename to src/main/java/ru/soune/nocopy/NoCopyApplication.java index 74bec20..fd6b0f2 100644 --- a/src/main/java/ru/soune/no_copy/NoCopyApplication.java +++ b/src/main/java/ru/soune/nocopy/NoCopyApplication.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy; +package ru.soune.nocopy; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/src/main/java/ru/soune/no_copy/configuration/ApplicationConfig.java b/src/main/java/ru/soune/nocopy/configuration/ApplicationConfig.java similarity index 92% rename from src/main/java/ru/soune/no_copy/configuration/ApplicationConfig.java rename to src/main/java/ru/soune/nocopy/configuration/ApplicationConfig.java index 8b0409b..85ae0b8 100644 --- a/src/main/java/ru/soune/no_copy/configuration/ApplicationConfig.java +++ b/src/main/java/ru/soune/nocopy/configuration/ApplicationConfig.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.configuration; +package ru.soune.nocopy.configuration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; diff --git a/src/main/java/ru/soune/no_copy/configuration/JacksonConfig.java b/src/main/java/ru/soune/nocopy/configuration/JacksonConfig.java similarity index 97% rename from src/main/java/ru/soune/no_copy/configuration/JacksonConfig.java rename to src/main/java/ru/soune/nocopy/configuration/JacksonConfig.java index 0f726fb..99c5c00 100644 --- a/src/main/java/ru/soune/no_copy/configuration/JacksonConfig.java +++ b/src/main/java/ru/soune/nocopy/configuration/JacksonConfig.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.configuration; +package ru.soune.nocopy.configuration; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; diff --git a/src/main/java/ru/soune/no_copy/configuration/JpaConfiguration.java b/src/main/java/ru/soune/nocopy/configuration/JpaConfiguration.java similarity index 83% rename from src/main/java/ru/soune/no_copy/configuration/JpaConfiguration.java rename to src/main/java/ru/soune/nocopy/configuration/JpaConfiguration.java index 56ae18b..f62ccde 100644 --- a/src/main/java/ru/soune/no_copy/configuration/JpaConfiguration.java +++ b/src/main/java/ru/soune/nocopy/configuration/JpaConfiguration.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.configuration; +package ru.soune.nocopy.configuration; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; diff --git a/src/main/java/ru/soune/no_copy/configuration/SubscriptionConfig.java b/src/main/java/ru/soune/nocopy/configuration/SubscriptionConfig.java similarity index 96% rename from src/main/java/ru/soune/no_copy/configuration/SubscriptionConfig.java rename to src/main/java/ru/soune/nocopy/configuration/SubscriptionConfig.java index 7eb41ec..198a544 100644 --- a/src/main/java/ru/soune/no_copy/configuration/SubscriptionConfig.java +++ b/src/main/java/ru/soune/nocopy/configuration/SubscriptionConfig.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.configuration; +package ru.soune.nocopy.configuration; import lombok.Getter; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/src/main/java/ru/soune/no_copy/controller/ApiController.java b/src/main/java/ru/soune/nocopy/controller/ApiController.java similarity index 87% rename from src/main/java/ru/soune/no_copy/controller/ApiController.java rename to src/main/java/ru/soune/nocopy/controller/ApiController.java index 7986e11..beb3035 100644 --- a/src/main/java/ru/soune/no_copy/controller/ApiController.java +++ b/src/main/java/ru/soune/nocopy/controller/ApiController.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.controller; +package ru.soune.nocopy.controller; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; @@ -8,15 +8,15 @@ import org.springframework.http.ResponseEntity; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.*; -import ru.soune.no_copy.dto.BaseRequest; -import ru.soune.no_copy.dto.BaseResponse; -import ru.soune.no_copy.dto.MessageCode; -import ru.soune.no_copy.dto.RegAnswer; -import ru.soune.no_copy.exception.NotValidFieldException; -import ru.soune.no_copy.exception.ValidationException; -import ru.soune.no_copy.handler.LoginRequestHandler; -import ru.soune.no_copy.handler.RegRequestHandler; -import ru.soune.no_copy.handler.RequestHandler; +import ru.soune.nocopy.dto.BaseRequest; +import ru.soune.nocopy.dto.BaseResponse; +import ru.soune.nocopy.dto.MessageCode; +import ru.soune.nocopy.dto.RegAnswer; +import ru.soune.nocopy.exception.NotValidFieldException; +import ru.soune.nocopy.exception.ValidationException; +import ru.soune.nocopy.handler.LoginRequestHandler; +import ru.soune.nocopy.handler.RegRequestHandler; +import ru.soune.nocopy.handler.RequestHandler; import java.util.HashMap; import java.util.List; diff --git a/src/main/java/ru/soune/no_copy/controller/AuthController.java b/src/main/java/ru/soune/nocopy/controller/AuthController.java similarity index 78% rename from src/main/java/ru/soune/no_copy/controller/AuthController.java rename to src/main/java/ru/soune/nocopy/controller/AuthController.java index 8247049..d9ba3d3 100644 --- a/src/main/java/ru/soune/no_copy/controller/AuthController.java +++ b/src/main/java/ru/soune/nocopy/controller/AuthController.java @@ -1,12 +1,12 @@ -package ru.soune.no_copy.controller; +package ru.soune.nocopy.controller; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import ru.soune.no_copy.entity.AuthToken; -import ru.soune.no_copy.exception.TokenNotFoundException; -import ru.soune.no_copy.repository.AuthTokenRepository; -import ru.soune.no_copy.service.AuthService; +import ru.soune.nocopy.entity.AuthToken; +import ru.soune.nocopy.exception.TokenNotFoundException; +import ru.soune.nocopy.repository.AuthTokenRepository; +import ru.soune.nocopy.service.AuthService; import java.util.Map; import java.util.Optional; diff --git a/src/main/java/ru/soune/no_copy/controller/HealtCheckController.java b/src/main/java/ru/soune/nocopy/controller/HealtCheckController.java similarity index 79% rename from src/main/java/ru/soune/no_copy/controller/HealtCheckController.java rename to src/main/java/ru/soune/nocopy/controller/HealtCheckController.java index b455f67..57de3e8 100644 --- a/src/main/java/ru/soune/no_copy/controller/HealtCheckController.java +++ b/src/main/java/ru/soune/nocopy/controller/HealtCheckController.java @@ -1,6 +1,5 @@ -package ru.soune.no_copy.controller; +package ru.soune.nocopy.controller; -import org.apache.coyote.Response; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; diff --git a/src/main/java/ru/soune/no_copy/controller/UserContentController.java b/src/main/java/ru/soune/nocopy/controller/UserContentController.java similarity index 87% rename from src/main/java/ru/soune/no_copy/controller/UserContentController.java rename to src/main/java/ru/soune/nocopy/controller/UserContentController.java index ea25e8f..51a4d5c 100644 --- a/src/main/java/ru/soune/no_copy/controller/UserContentController.java +++ b/src/main/java/ru/soune/nocopy/controller/UserContentController.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.controller; +package ru.soune.nocopy.controller; import lombok.AllArgsConstructor; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/src/main/java/ru/soune/no_copy/controller/UserController.java b/src/main/java/ru/soune/nocopy/controller/UserController.java similarity index 87% rename from src/main/java/ru/soune/no_copy/controller/UserController.java rename to src/main/java/ru/soune/nocopy/controller/UserController.java index 9f23605..39efe8e 100644 --- a/src/main/java/ru/soune/no_copy/controller/UserController.java +++ b/src/main/java/ru/soune/nocopy/controller/UserController.java @@ -1,19 +1,19 @@ -package ru.soune.no_copy.controller; +package ru.soune.nocopy.controller; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -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.AuthToken; -import ru.soune.no_copy.entity.User; -import ru.soune.no_copy.exception.InvalidUserEmail; -import ru.soune.no_copy.exception.NotFoundAuthToken; -import ru.soune.no_copy.mapper.UserMapper; -import ru.soune.no_copy.repository.AuthTokenRepository; -import ru.soune.no_copy.repository.UserRepository; -import ru.soune.no_copy.service.UserService; +import ru.soune.nocopy.dto.ChangePasswordRequest; +import ru.soune.nocopy.dto.UserDTO; +import ru.soune.nocopy.dto.UserRequest; +import ru.soune.nocopy.entity.AuthToken; +import ru.soune.nocopy.entity.User; +import ru.soune.nocopy.exception.InvalidUserEmail; +import ru.soune.nocopy.exception.NotFoundAuthToken; +import ru.soune.nocopy.mapper.UserMapper; +import ru.soune.nocopy.repository.AuthTokenRepository; +import ru.soune.nocopy.repository.UserRepository; +import ru.soune.nocopy.service.UserService; import java.util.List; import java.util.Optional; diff --git a/src/main/java/ru/soune/no_copy/dto/BaseRequest.java b/src/main/java/ru/soune/nocopy/dto/BaseRequest.java similarity index 89% rename from src/main/java/ru/soune/no_copy/dto/BaseRequest.java rename to src/main/java/ru/soune/nocopy/dto/BaseRequest.java index 818890d..b02ad8c 100644 --- a/src/main/java/ru/soune/no_copy/dto/BaseRequest.java +++ b/src/main/java/ru/soune/nocopy/dto/BaseRequest.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.dto; +package ru.soune.nocopy.dto; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; diff --git a/src/main/java/ru/soune/no_copy/dto/BaseResponse.java b/src/main/java/ru/soune/nocopy/dto/BaseResponse.java similarity index 93% rename from src/main/java/ru/soune/no_copy/dto/BaseResponse.java rename to src/main/java/ru/soune/nocopy/dto/BaseResponse.java index cf16762..b60419a 100644 --- a/src/main/java/ru/soune/no_copy/dto/BaseResponse.java +++ b/src/main/java/ru/soune/nocopy/dto/BaseResponse.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.dto; +package ru.soune.nocopy.dto; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; diff --git a/src/main/java/ru/soune/no_copy/dto/ChangePasswordRequest.java b/src/main/java/ru/soune/nocopy/dto/ChangePasswordRequest.java similarity index 89% rename from src/main/java/ru/soune/no_copy/dto/ChangePasswordRequest.java rename to src/main/java/ru/soune/nocopy/dto/ChangePasswordRequest.java index aff7140..204db58 100644 --- a/src/main/java/ru/soune/no_copy/dto/ChangePasswordRequest.java +++ b/src/main/java/ru/soune/nocopy/dto/ChangePasswordRequest.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.dto; +package ru.soune.nocopy.dto; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/src/main/java/ru/soune/no_copy/dto/LogOutAnswer.java b/src/main/java/ru/soune/nocopy/dto/LogOutAnswer.java similarity index 90% rename from src/main/java/ru/soune/no_copy/dto/LogOutAnswer.java rename to src/main/java/ru/soune/nocopy/dto/LogOutAnswer.java index 1174a5e..fbb7e21 100644 --- a/src/main/java/ru/soune/no_copy/dto/LogOutAnswer.java +++ b/src/main/java/ru/soune/nocopy/dto/LogOutAnswer.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.dto; +package ru.soune.nocopy.dto; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/src/main/java/ru/soune/no_copy/dto/LoginAnswer.java b/src/main/java/ru/soune/nocopy/dto/LoginAnswer.java similarity index 90% rename from src/main/java/ru/soune/no_copy/dto/LoginAnswer.java rename to src/main/java/ru/soune/nocopy/dto/LoginAnswer.java index 724c662..e791d8d 100644 --- a/src/main/java/ru/soune/no_copy/dto/LoginAnswer.java +++ b/src/main/java/ru/soune/nocopy/dto/LoginAnswer.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.dto; +package ru.soune.nocopy.dto; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/src/main/java/ru/soune/no_copy/dto/LoginRequest.java b/src/main/java/ru/soune/nocopy/dto/LoginRequest.java similarity index 94% rename from src/main/java/ru/soune/no_copy/dto/LoginRequest.java rename to src/main/java/ru/soune/nocopy/dto/LoginRequest.java index c85fe97..d64fa8b 100644 --- a/src/main/java/ru/soune/no_copy/dto/LoginRequest.java +++ b/src/main/java/ru/soune/nocopy/dto/LoginRequest.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.dto; +package ru.soune.nocopy.dto; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; diff --git a/src/main/java/ru/soune/no_copy/dto/MessageCode.java b/src/main/java/ru/soune/nocopy/dto/MessageCode.java similarity index 57% rename from src/main/java/ru/soune/no_copy/dto/MessageCode.java rename to src/main/java/ru/soune/nocopy/dto/MessageCode.java index 75fb869..8bf6c19 100644 --- a/src/main/java/ru/soune/no_copy/dto/MessageCode.java +++ b/src/main/java/ru/soune/nocopy/dto/MessageCode.java @@ -1,13 +1,13 @@ -package ru.soune.no_copy.dto; +package ru.soune.nocopy.dto; public enum MessageCode { SUCCESS(0, "Operation successful"), - REG_EMAIL_EXISTS(4001, "Email already registered"), - INVALID_FIELD(4002, "Invalid field"), - MSG_ID_NOT_FOUND(4003, "Message id not found"), + REG_EMAIL_EXISTS(1, "Email already registered"), + INVALID_FIELD(2, "Invalid field"), + MSG_ID_NOT_FOUND(4, "Message id not found"), - AUTH_EMAIL_NOT_FOUND(4005, "Email not found"), - AUTH_PASSWORD_NOT_MATCHES(4006, "Password does not match"); + AUTH_EMAIL_NOT_FOUND(4, "Email not found"), + AUTH_PASSWORD_NOT_MATCHES(2, "Password does not match"); private final Integer code; diff --git a/src/main/java/ru/soune/no_copy/dto/RegAnswer.java b/src/main/java/ru/soune/nocopy/dto/RegAnswer.java similarity index 90% rename from src/main/java/ru/soune/no_copy/dto/RegAnswer.java rename to src/main/java/ru/soune/nocopy/dto/RegAnswer.java index b79c14f..b51b4cc 100644 --- a/src/main/java/ru/soune/no_copy/dto/RegAnswer.java +++ b/src/main/java/ru/soune/nocopy/dto/RegAnswer.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.dto; +package ru.soune.nocopy.dto; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/src/main/java/ru/soune/no_copy/dto/RegRequest.java b/src/main/java/ru/soune/nocopy/dto/RegRequest.java similarity index 95% rename from src/main/java/ru/soune/no_copy/dto/RegRequest.java rename to src/main/java/ru/soune/nocopy/dto/RegRequest.java index f43cb75..e08f404 100644 --- a/src/main/java/ru/soune/no_copy/dto/RegRequest.java +++ b/src/main/java/ru/soune/nocopy/dto/RegRequest.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.dto; +package ru.soune.nocopy.dto; import jakarta.validation.constraints.*; import lombok.Data; diff --git a/src/main/java/ru/soune/no_copy/dto/UserContentDTO.java b/src/main/java/ru/soune/nocopy/dto/UserContentDTO.java similarity index 76% rename from src/main/java/ru/soune/no_copy/dto/UserContentDTO.java rename to src/main/java/ru/soune/nocopy/dto/UserContentDTO.java index 90df1d9..934bfda 100644 --- a/src/main/java/ru/soune/no_copy/dto/UserContentDTO.java +++ b/src/main/java/ru/soune/nocopy/dto/UserContentDTO.java @@ -1,7 +1,6 @@ -package ru.soune.no_copy.dto; +package ru.soune.nocopy.dto; import lombok.Data; -import ru.soune.no_copy.entity.FileType; @Data public class UserContentDTO { diff --git a/src/main/java/ru/soune/no_copy/dto/UserContentRequest.java b/src/main/java/ru/soune/nocopy/dto/UserContentRequest.java similarity index 93% rename from src/main/java/ru/soune/no_copy/dto/UserContentRequest.java rename to src/main/java/ru/soune/nocopy/dto/UserContentRequest.java index 06ef01e..bd28100 100644 --- a/src/main/java/ru/soune/no_copy/dto/UserContentRequest.java +++ b/src/main/java/ru/soune/nocopy/dto/UserContentRequest.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.dto; +package ru.soune.nocopy.dto; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; diff --git a/src/main/java/ru/soune/no_copy/dto/UserContentResponse.java b/src/main/java/ru/soune/nocopy/dto/UserContentResponse.java similarity index 71% rename from src/main/java/ru/soune/no_copy/dto/UserContentResponse.java rename to src/main/java/ru/soune/nocopy/dto/UserContentResponse.java index 86d1d84..9257b05 100644 --- a/src/main/java/ru/soune/no_copy/dto/UserContentResponse.java +++ b/src/main/java/ru/soune/nocopy/dto/UserContentResponse.java @@ -1,7 +1,7 @@ -package ru.soune.no_copy.dto; +package ru.soune.nocopy.dto; -import ru.soune.no_copy.entity.ContentStatus; -import ru.soune.no_copy.entity.FileType; +import ru.soune.nocopy.entity.ContentStatus; +import ru.soune.nocopy.entity.FileType; import java.time.LocalDateTime; diff --git a/src/main/java/ru/soune/no_copy/dto/UserContentUpdateRequest.java b/src/main/java/ru/soune/nocopy/dto/UserContentUpdateRequest.java similarity index 93% rename from src/main/java/ru/soune/no_copy/dto/UserContentUpdateRequest.java rename to src/main/java/ru/soune/nocopy/dto/UserContentUpdateRequest.java index 8955969..7595b21 100644 --- a/src/main/java/ru/soune/no_copy/dto/UserContentUpdateRequest.java +++ b/src/main/java/ru/soune/nocopy/dto/UserContentUpdateRequest.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.dto; +package ru.soune.nocopy.dto; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; diff --git a/src/main/java/ru/soune/no_copy/dto/UserDTO.java b/src/main/java/ru/soune/nocopy/dto/UserDTO.java similarity index 81% rename from src/main/java/ru/soune/no_copy/dto/UserDTO.java rename to src/main/java/ru/soune/nocopy/dto/UserDTO.java index ba5b278..45c19ee 100644 --- a/src/main/java/ru/soune/no_copy/dto/UserDTO.java +++ b/src/main/java/ru/soune/nocopy/dto/UserDTO.java @@ -1,11 +1,11 @@ -package ru.soune.no_copy.dto; +package ru.soune.nocopy.dto; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import ru.soune.no_copy.entity.GenderType; -import ru.soune.no_copy.entity.SubscriptionType; +import ru.soune.nocopy.entity.GenderType; +import ru.soune.nocopy.entity.SubscriptionType; import java.time.LocalDate; import java.time.LocalDateTime; diff --git a/src/main/java/ru/soune/no_copy/dto/UserRequest.java b/src/main/java/ru/soune/nocopy/dto/UserRequest.java similarity index 83% rename from src/main/java/ru/soune/no_copy/dto/UserRequest.java rename to src/main/java/ru/soune/nocopy/dto/UserRequest.java index db8c8fe..c5f1662 100644 --- a/src/main/java/ru/soune/no_copy/dto/UserRequest.java +++ b/src/main/java/ru/soune/nocopy/dto/UserRequest.java @@ -1,14 +1,13 @@ -package ru.soune.no_copy.dto; +package ru.soune.nocopy.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 ru.soune.nocopy.entity.GenderType; import java.time.LocalDate; -import java.time.LocalDateTime; @Data public class UserRequest { diff --git a/src/main/java/ru/soune/no_copy/entity/AuthToken.java b/src/main/java/ru/soune/nocopy/entity/AuthToken.java similarity index 97% rename from src/main/java/ru/soune/no_copy/entity/AuthToken.java rename to src/main/java/ru/soune/nocopy/entity/AuthToken.java index 6418073..63cf34a 100644 --- a/src/main/java/ru/soune/no_copy/entity/AuthToken.java +++ b/src/main/java/ru/soune/nocopy/entity/AuthToken.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.entity; +package ru.soune.nocopy.entity; import jakarta.persistence.*; import lombok.*; diff --git a/src/main/java/ru/soune/no_copy/entity/BaseEntity.java b/src/main/java/ru/soune/nocopy/entity/BaseEntity.java similarity index 95% rename from src/main/java/ru/soune/no_copy/entity/BaseEntity.java rename to src/main/java/ru/soune/nocopy/entity/BaseEntity.java index b51c525..2743abf 100644 --- a/src/main/java/ru/soune/no_copy/entity/BaseEntity.java +++ b/src/main/java/ru/soune/nocopy/entity/BaseEntity.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.entity; +package ru.soune.nocopy.entity; import jakarta.persistence.*; import lombok.Getter; diff --git a/src/main/java/ru/soune/no_copy/entity/ContentStatus.java b/src/main/java/ru/soune/nocopy/entity/ContentStatus.java similarity index 89% rename from src/main/java/ru/soune/no_copy/entity/ContentStatus.java rename to src/main/java/ru/soune/nocopy/entity/ContentStatus.java index d97f66c..c2dfa41 100644 --- a/src/main/java/ru/soune/no_copy/entity/ContentStatus.java +++ b/src/main/java/ru/soune/nocopy/entity/ContentStatus.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.entity; +package ru.soune.nocopy.entity; import lombok.Getter; diff --git a/src/main/java/ru/soune/no_copy/entity/FileType.java b/src/main/java/ru/soune/nocopy/entity/FileType.java similarity index 89% rename from src/main/java/ru/soune/no_copy/entity/FileType.java rename to src/main/java/ru/soune/nocopy/entity/FileType.java index 4e0406d..7802a4f 100644 --- a/src/main/java/ru/soune/no_copy/entity/FileType.java +++ b/src/main/java/ru/soune/nocopy/entity/FileType.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.entity; +package ru.soune.nocopy.entity; import lombok.Getter; diff --git a/src/main/java/ru/soune/no_copy/entity/GenderType.java b/src/main/java/ru/soune/nocopy/entity/GenderType.java similarity index 57% rename from src/main/java/ru/soune/no_copy/entity/GenderType.java rename to src/main/java/ru/soune/nocopy/entity/GenderType.java index e85f0f2..580d825 100644 --- a/src/main/java/ru/soune/no_copy/entity/GenderType.java +++ b/src/main/java/ru/soune/nocopy/entity/GenderType.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.entity; +package ru.soune.nocopy.entity; public enum GenderType { MALE, FEMALE diff --git a/src/main/java/ru/soune/no_copy/entity/ImageProtection.java b/src/main/java/ru/soune/nocopy/entity/ImageProtection.java similarity index 97% rename from src/main/java/ru/soune/no_copy/entity/ImageProtection.java rename to src/main/java/ru/soune/nocopy/entity/ImageProtection.java index 79a8c8d..eef9e95 100644 --- a/src/main/java/ru/soune/no_copy/entity/ImageProtection.java +++ b/src/main/java/ru/soune/nocopy/entity/ImageProtection.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.entity; +package ru.soune.nocopy.entity; import jakarta.persistence.*; import lombok.*; diff --git a/src/main/java/ru/soune/no_copy/entity/SubscriptionType.java b/src/main/java/ru/soune/nocopy/entity/SubscriptionType.java similarity index 76% rename from src/main/java/ru/soune/no_copy/entity/SubscriptionType.java rename to src/main/java/ru/soune/nocopy/entity/SubscriptionType.java index 4c78049..952722e 100644 --- a/src/main/java/ru/soune/no_copy/entity/SubscriptionType.java +++ b/src/main/java/ru/soune/nocopy/entity/SubscriptionType.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.entity; +package ru.soune.nocopy.entity; import lombok.Getter; diff --git a/src/main/java/ru/soune/no_copy/entity/User.java b/src/main/java/ru/soune/nocopy/entity/User.java similarity index 98% rename from src/main/java/ru/soune/no_copy/entity/User.java rename to src/main/java/ru/soune/nocopy/entity/User.java index 63a23f2..a4fba7d 100644 --- a/src/main/java/ru/soune/no_copy/entity/User.java +++ b/src/main/java/ru/soune/nocopy/entity/User.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.entity; +package ru.soune.nocopy.entity; import com.fasterxml.jackson.annotation.JsonIgnore; import jakarta.persistence.*; diff --git a/src/main/java/ru/soune/no_copy/entity/UserAction.java b/src/main/java/ru/soune/nocopy/entity/UserAction.java similarity index 97% rename from src/main/java/ru/soune/no_copy/entity/UserAction.java rename to src/main/java/ru/soune/nocopy/entity/UserAction.java index d9d22ef..661ab3a 100644 --- a/src/main/java/ru/soune/no_copy/entity/UserAction.java +++ b/src/main/java/ru/soune/nocopy/entity/UserAction.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.entity; +package ru.soune.nocopy.entity; import jakarta.persistence.*; import lombok.*; diff --git a/src/main/java/ru/soune/no_copy/entity/UserContent.java b/src/main/java/ru/soune/nocopy/entity/UserContent.java similarity index 96% rename from src/main/java/ru/soune/no_copy/entity/UserContent.java rename to src/main/java/ru/soune/nocopy/entity/UserContent.java index 22ee0b0..4c7fe9a 100644 --- a/src/main/java/ru/soune/no_copy/entity/UserContent.java +++ b/src/main/java/ru/soune/nocopy/entity/UserContent.java @@ -1,8 +1,7 @@ -package ru.soune.no_copy.entity; +package ru.soune.nocopy.entity; import jakarta.persistence.*; import lombok.*; -import org.hibernate.annotations.CreationTimestamp; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; diff --git a/src/main/java/ru/soune/no_copy/entity/Violation.java b/src/main/java/ru/soune/nocopy/entity/Violation.java similarity index 97% rename from src/main/java/ru/soune/no_copy/entity/Violation.java rename to src/main/java/ru/soune/nocopy/entity/Violation.java index 6e1768c..dd504bd 100644 --- a/src/main/java/ru/soune/no_copy/entity/Violation.java +++ b/src/main/java/ru/soune/nocopy/entity/Violation.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.entity; +package ru.soune.nocopy.entity; import jakarta.persistence.*; import lombok.*; diff --git a/src/main/java/ru/soune/no_copy/exception/ContentNotFoundException.java b/src/main/java/ru/soune/nocopy/exception/ContentNotFoundException.java similarity index 80% rename from src/main/java/ru/soune/no_copy/exception/ContentNotFoundException.java rename to src/main/java/ru/soune/nocopy/exception/ContentNotFoundException.java index af0f040..75b8af7 100644 --- a/src/main/java/ru/soune/no_copy/exception/ContentNotFoundException.java +++ b/src/main/java/ru/soune/nocopy/exception/ContentNotFoundException.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.exception; +package ru.soune.nocopy.exception; public class ContentNotFoundException extends RuntimeException { public ContentNotFoundException(String message) { diff --git a/src/main/java/ru/soune/no_copy/exception/InvalidPasswordException.java b/src/main/java/ru/soune/nocopy/exception/InvalidPasswordException.java similarity index 80% rename from src/main/java/ru/soune/no_copy/exception/InvalidPasswordException.java rename to src/main/java/ru/soune/nocopy/exception/InvalidPasswordException.java index b9f2820..72a43e9 100644 --- a/src/main/java/ru/soune/no_copy/exception/InvalidPasswordException.java +++ b/src/main/java/ru/soune/nocopy/exception/InvalidPasswordException.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.exception; +package ru.soune.nocopy.exception; public class InvalidPasswordException extends RuntimeException { public InvalidPasswordException(String message) { diff --git a/src/main/java/ru/soune/no_copy/exception/InvalidUserEmail.java b/src/main/java/ru/soune/nocopy/exception/InvalidUserEmail.java similarity index 79% rename from src/main/java/ru/soune/no_copy/exception/InvalidUserEmail.java rename to src/main/java/ru/soune/nocopy/exception/InvalidUserEmail.java index 7ce203b..850a7f1 100644 --- a/src/main/java/ru/soune/no_copy/exception/InvalidUserEmail.java +++ b/src/main/java/ru/soune/nocopy/exception/InvalidUserEmail.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.exception; +package ru.soune.nocopy.exception; public class InvalidUserEmail extends RuntimeException { public InvalidUserEmail(String message) { diff --git a/src/main/java/ru/soune/no_copy/exception/NotFoundAuthToken.java b/src/main/java/ru/soune/nocopy/exception/NotFoundAuthToken.java similarity index 79% rename from src/main/java/ru/soune/no_copy/exception/NotFoundAuthToken.java rename to src/main/java/ru/soune/nocopy/exception/NotFoundAuthToken.java index 7a61eea..473f486 100644 --- a/src/main/java/ru/soune/no_copy/exception/NotFoundAuthToken.java +++ b/src/main/java/ru/soune/nocopy/exception/NotFoundAuthToken.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.exception; +package ru.soune.nocopy.exception; public class NotFoundAuthToken extends RuntimeException { public NotFoundAuthToken(String message) { diff --git a/src/main/java/ru/soune/no_copy/exception/NotValidFieldException.java b/src/main/java/ru/soune/nocopy/exception/NotValidFieldException.java similarity index 82% rename from src/main/java/ru/soune/no_copy/exception/NotValidFieldException.java rename to src/main/java/ru/soune/nocopy/exception/NotValidFieldException.java index cbf2746..fee0335 100644 --- a/src/main/java/ru/soune/no_copy/exception/NotValidFieldException.java +++ b/src/main/java/ru/soune/nocopy/exception/NotValidFieldException.java @@ -1,7 +1,7 @@ -package ru.soune.no_copy.exception; +package ru.soune.nocopy.exception; import lombok.Getter; -import ru.soune.no_copy.dto.BaseResponse; +import ru.soune.nocopy.dto.BaseResponse; @Getter public class NotValidFieldException extends RuntimeException { diff --git a/src/main/java/ru/soune/no_copy/exception/NotValidationPasswordException.java b/src/main/java/ru/soune/nocopy/exception/NotValidationPasswordException.java similarity index 82% rename from src/main/java/ru/soune/no_copy/exception/NotValidationPasswordException.java rename to src/main/java/ru/soune/nocopy/exception/NotValidationPasswordException.java index 6e24040..48a2fe5 100644 --- a/src/main/java/ru/soune/no_copy/exception/NotValidationPasswordException.java +++ b/src/main/java/ru/soune/nocopy/exception/NotValidationPasswordException.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.exception; +package ru.soune.nocopy.exception; public class NotValidationPasswordException extends RuntimeException { public NotValidationPasswordException(String message) { diff --git a/src/main/java/ru/soune/no_copy/exception/TokenNotFoundException.java b/src/main/java/ru/soune/nocopy/exception/TokenNotFoundException.java similarity index 80% rename from src/main/java/ru/soune/no_copy/exception/TokenNotFoundException.java rename to src/main/java/ru/soune/nocopy/exception/TokenNotFoundException.java index d2e526b..b934cf4 100644 --- a/src/main/java/ru/soune/no_copy/exception/TokenNotFoundException.java +++ b/src/main/java/ru/soune/nocopy/exception/TokenNotFoundException.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.exception; +package ru.soune.nocopy.exception; public class TokenNotFoundException extends RuntimeException { public TokenNotFoundException(String message) { diff --git a/src/main/java/ru/soune/no_copy/exception/UserNotFoundException.java b/src/main/java/ru/soune/nocopy/exception/UserNotFoundException.java similarity index 80% rename from src/main/java/ru/soune/no_copy/exception/UserNotFoundException.java rename to src/main/java/ru/soune/nocopy/exception/UserNotFoundException.java index a8d8b03..919ff70 100644 --- a/src/main/java/ru/soune/no_copy/exception/UserNotFoundException.java +++ b/src/main/java/ru/soune/nocopy/exception/UserNotFoundException.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.exception; +package ru.soune.nocopy.exception; public class UserNotFoundException extends RuntimeException { public UserNotFoundException(String message) { diff --git a/src/main/java/ru/soune/no_copy/exception/ValidationException.java b/src/main/java/ru/soune/nocopy/exception/ValidationException.java similarity index 92% rename from src/main/java/ru/soune/no_copy/exception/ValidationException.java rename to src/main/java/ru/soune/nocopy/exception/ValidationException.java index f9c9d52..71b8638 100644 --- a/src/main/java/ru/soune/no_copy/exception/ValidationException.java +++ b/src/main/java/ru/soune/nocopy/exception/ValidationException.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.exception; +package ru.soune.nocopy.exception; import lombok.Getter; import org.springframework.validation.BindingResult; diff --git a/src/main/java/ru/soune/no_copy/handler/GlobalExceptionHandler.java b/src/main/java/ru/soune/nocopy/handler/GlobalExceptionHandler.java similarity index 97% rename from src/main/java/ru/soune/no_copy/handler/GlobalExceptionHandler.java rename to src/main/java/ru/soune/nocopy/handler/GlobalExceptionHandler.java index 9e80dbb..071b9ae 100644 --- a/src/main/java/ru/soune/no_copy/handler/GlobalExceptionHandler.java +++ b/src/main/java/ru/soune/nocopy/handler/GlobalExceptionHandler.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.handler; +package ru.soune.nocopy.handler; import lombok.AllArgsConstructor; import org.springframework.context.support.DefaultMessageSourceResolvable; @@ -8,7 +8,7 @@ import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; -import ru.soune.no_copy.exception.*; +import ru.soune.nocopy.exception.*; import java.util.Map; diff --git a/src/main/java/ru/soune/no_copy/handler/LoginRequestHandler.java b/src/main/java/ru/soune/nocopy/handler/LoginRequestHandler.java similarity index 83% rename from src/main/java/ru/soune/no_copy/handler/LoginRequestHandler.java rename to src/main/java/ru/soune/nocopy/handler/LoginRequestHandler.java index 91890e9..95abf63 100644 --- a/src/main/java/ru/soune/no_copy/handler/LoginRequestHandler.java +++ b/src/main/java/ru/soune/nocopy/handler/LoginRequestHandler.java @@ -1,16 +1,15 @@ -package ru.soune.no_copy.handler; +package ru.soune.nocopy.handler; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -import ru.soune.no_copy.dto.*; -import ru.soune.no_copy.entity.AuthToken; -import ru.soune.no_copy.exception.NotValidFieldException; -import ru.soune.no_copy.repository.UserRepository; -import ru.soune.no_copy.service.AuthService; +import ru.soune.nocopy.dto.*; +import ru.soune.nocopy.entity.AuthToken; +import ru.soune.nocopy.exception.NotValidFieldException; +import ru.soune.nocopy.repository.UserRepository; +import ru.soune.nocopy.service.AuthService; import java.util.Arrays; -import java.util.HashMap; import java.util.Map; @Component diff --git a/src/main/java/ru/soune/no_copy/handler/RegRequestHandler.java b/src/main/java/ru/soune/nocopy/handler/RegRequestHandler.java similarity index 83% rename from src/main/java/ru/soune/no_copy/handler/RegRequestHandler.java rename to src/main/java/ru/soune/nocopy/handler/RegRequestHandler.java index 2c54dc2..65bc887 100644 --- a/src/main/java/ru/soune/no_copy/handler/RegRequestHandler.java +++ b/src/main/java/ru/soune/nocopy/handler/RegRequestHandler.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.handler; +package ru.soune.nocopy.handler; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; @@ -6,13 +6,13 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.BindingResult; -import ru.soune.no_copy.dto.*; -import ru.soune.no_copy.entity.AuthToken; -import ru.soune.no_copy.exception.NotValidFieldException; -import ru.soune.no_copy.exception.ValidationException; -import ru.soune.no_copy.handler.validator.RegRequestValidator; -import ru.soune.no_copy.repository.UserRepository; -import ru.soune.no_copy.service.AuthService; +import ru.soune.nocopy.dto.*; +import ru.soune.nocopy.entity.AuthToken; +import ru.soune.nocopy.exception.NotValidFieldException; +import ru.soune.nocopy.exception.ValidationException; +import ru.soune.nocopy.handler.validator.RegRequestValidator; +import ru.soune.nocopy.repository.UserRepository; +import ru.soune.nocopy.service.AuthService; import java.util.Arrays; import java.util.Map; diff --git a/src/main/java/ru/soune/nocopy/handler/RequestHandler.java b/src/main/java/ru/soune/nocopy/handler/RequestHandler.java new file mode 100644 index 0000000..230c87a --- /dev/null +++ b/src/main/java/ru/soune/nocopy/handler/RequestHandler.java @@ -0,0 +1,8 @@ +package ru.soune.nocopy.handler; + +import ru.soune.nocopy.dto.BaseRequest; +import ru.soune.nocopy.dto.BaseResponse; + +public interface RequestHandler { + BaseResponse handle(BaseRequest request) throws Exception; +} diff --git a/src/main/java/ru/soune/no_copy/handler/validator/RegRequestValidator.java b/src/main/java/ru/soune/nocopy/handler/validator/RegRequestValidator.java similarity index 99% rename from src/main/java/ru/soune/no_copy/handler/validator/RegRequestValidator.java rename to src/main/java/ru/soune/nocopy/handler/validator/RegRequestValidator.java index b25c2e0..5b8bfb4 100644 --- a/src/main/java/ru/soune/no_copy/handler/validator/RegRequestValidator.java +++ b/src/main/java/ru/soune/nocopy/handler/validator/RegRequestValidator.java @@ -1,9 +1,9 @@ -package ru.soune.no_copy.handler.validator; +package ru.soune.nocopy.handler.validator; import org.springframework.stereotype.Component; import org.springframework.validation.Errors; import org.springframework.validation.Validator; -import ru.soune.no_copy.dto.RegRequest; +import ru.soune.nocopy.dto.RegRequest; import java.util.*; diff --git a/src/main/java/ru/soune/no_copy/mapper/UserContentMapper.java b/src/main/java/ru/soune/nocopy/mapper/UserContentMapper.java similarity index 79% rename from src/main/java/ru/soune/no_copy/mapper/UserContentMapper.java rename to src/main/java/ru/soune/nocopy/mapper/UserContentMapper.java index 5617cbd..3959f8f 100644 --- a/src/main/java/ru/soune/no_copy/mapper/UserContentMapper.java +++ b/src/main/java/ru/soune/nocopy/mapper/UserContentMapper.java @@ -1,11 +1,11 @@ -package ru.soune.no_copy.mapper; +package ru.soune.nocopy.mapper; import org.mapstruct.Mapper; import org.mapstruct.MappingTarget; import org.mapstruct.NullValuePropertyMappingStrategy; import org.mapstruct.factory.Mappers; -import ru.soune.no_copy.dto.UserContentUpdateRequest; -import ru.soune.no_copy.entity.UserContent; +import ru.soune.nocopy.dto.UserContentUpdateRequest; +import ru.soune.nocopy.entity.UserContent; @Mapper(componentModel = "spring", nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) diff --git a/src/main/java/ru/soune/no_copy/mapper/UserMapper.java b/src/main/java/ru/soune/nocopy/mapper/UserMapper.java similarity index 77% rename from src/main/java/ru/soune/no_copy/mapper/UserMapper.java rename to src/main/java/ru/soune/nocopy/mapper/UserMapper.java index 442f082..c151480 100644 --- a/src/main/java/ru/soune/no_copy/mapper/UserMapper.java +++ b/src/main/java/ru/soune/nocopy/mapper/UserMapper.java @@ -1,10 +1,10 @@ -package ru.soune.no_copy.mapper; +package ru.soune.nocopy.mapper; import org.mapstruct.Mapper; import org.mapstruct.NullValuePropertyMappingStrategy; import org.mapstruct.factory.Mappers; -import ru.soune.no_copy.dto.UserDTO; -import ru.soune.no_copy.entity.User; +import ru.soune.nocopy.dto.UserDTO; +import ru.soune.nocopy.entity.User; @Mapper(componentModel = "spring", nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) diff --git a/src/main/java/ru/soune/no_copy/repository/AuthTokenRepository.java b/src/main/java/ru/soune/nocopy/repository/AuthTokenRepository.java similarity index 83% rename from src/main/java/ru/soune/no_copy/repository/AuthTokenRepository.java rename to src/main/java/ru/soune/nocopy/repository/AuthTokenRepository.java index af56845..74826fd 100644 --- a/src/main/java/ru/soune/no_copy/repository/AuthTokenRepository.java +++ b/src/main/java/ru/soune/nocopy/repository/AuthTokenRepository.java @@ -1,8 +1,8 @@ -package ru.soune.no_copy.repository; +package ru.soune.nocopy.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import ru.soune.no_copy.entity.AuthToken; +import ru.soune.nocopy.entity.AuthToken; import java.time.LocalDate; import java.util.Optional; diff --git a/src/main/java/ru/soune/no_copy/repository/UserContentRepository.java b/src/main/java/ru/soune/nocopy/repository/UserContentRepository.java similarity index 82% rename from src/main/java/ru/soune/no_copy/repository/UserContentRepository.java rename to src/main/java/ru/soune/nocopy/repository/UserContentRepository.java index 95f524b..f1103a4 100644 --- a/src/main/java/ru/soune/no_copy/repository/UserContentRepository.java +++ b/src/main/java/ru/soune/nocopy/repository/UserContentRepository.java @@ -1,9 +1,9 @@ -package ru.soune.no_copy.repository; +package ru.soune.nocopy.repository; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; -import ru.soune.no_copy.entity.FileType; -import ru.soune.no_copy.entity.UserContent; +import ru.soune.nocopy.entity.FileType; +import ru.soune.nocopy.entity.UserContent; import java.util.List; diff --git a/src/main/java/ru/soune/no_copy/repository/UserRepository.java b/src/main/java/ru/soune/nocopy/repository/UserRepository.java similarity index 77% rename from src/main/java/ru/soune/no_copy/repository/UserRepository.java rename to src/main/java/ru/soune/nocopy/repository/UserRepository.java index 472fe58..da4d7f9 100644 --- a/src/main/java/ru/soune/no_copy/repository/UserRepository.java +++ b/src/main/java/ru/soune/nocopy/repository/UserRepository.java @@ -1,7 +1,7 @@ -package ru.soune.no_copy.repository; +package ru.soune.nocopy.repository; import org.springframework.data.jpa.repository.JpaRepository; -import ru.soune.no_copy.entity.User; +import ru.soune.nocopy.entity.User; import java.util.Optional; diff --git a/src/main/java/ru/soune/no_copy/service/AuthService.java b/src/main/java/ru/soune/nocopy/service/AuthService.java similarity index 87% rename from src/main/java/ru/soune/no_copy/service/AuthService.java rename to src/main/java/ru/soune/nocopy/service/AuthService.java index 01ad0ea..2377b2b 100644 --- a/src/main/java/ru/soune/no_copy/service/AuthService.java +++ b/src/main/java/ru/soune/nocopy/service/AuthService.java @@ -1,18 +1,16 @@ -package ru.soune.no_copy.service; +package ru.soune.nocopy.service; import lombok.RequiredArgsConstructor; import org.springframework.context.MessageSource; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import ru.soune.no_copy.dto.*; -import ru.soune.no_copy.entity.AuthToken; -import ru.soune.no_copy.entity.User; -import ru.soune.no_copy.exception.NotValidFieldException; -import ru.soune.no_copy.exception.NotValidationPasswordException; -import ru.soune.no_copy.exception.UserNotFoundException; -import ru.soune.no_copy.repository.AuthTokenRepository; -import ru.soune.no_copy.repository.UserRepository; +import ru.soune.nocopy.dto.*; +import ru.soune.nocopy.entity.AuthToken; +import ru.soune.nocopy.entity.User; +import ru.soune.nocopy.exception.NotValidFieldException; +import ru.soune.nocopy.repository.AuthTokenRepository; +import ru.soune.nocopy.repository.UserRepository; import java.security.SecureRandom; import java.time.LocalDateTime; diff --git a/src/main/java/ru/soune/no_copy/service/UserContentService.java b/src/main/java/ru/soune/nocopy/service/UserContentService.java similarity index 81% rename from src/main/java/ru/soune/no_copy/service/UserContentService.java rename to src/main/java/ru/soune/nocopy/service/UserContentService.java index eb89f77..b1fe0b3 100644 --- a/src/main/java/ru/soune/no_copy/service/UserContentService.java +++ b/src/main/java/ru/soune/nocopy/service/UserContentService.java @@ -1,18 +1,18 @@ -package ru.soune.no_copy.service; +package ru.soune.nocopy.service; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import ru.soune.no_copy.dto.UserContentRequest; -import ru.soune.no_copy.dto.UserContentUpdateRequest; -import ru.soune.no_copy.entity.FileType; -import ru.soune.no_copy.entity.User; -import ru.soune.no_copy.entity.UserContent; -import ru.soune.no_copy.exception.ContentNotFoundException; -import ru.soune.no_copy.exception.UserNotFoundException; -import ru.soune.no_copy.mapper.UserContentMapper; -import ru.soune.no_copy.repository.UserContentRepository; -import ru.soune.no_copy.repository.UserRepository; +import ru.soune.nocopy.dto.UserContentRequest; +import ru.soune.nocopy.dto.UserContentUpdateRequest; +import ru.soune.nocopy.entity.FileType; +import ru.soune.nocopy.entity.User; +import ru.soune.nocopy.entity.UserContent; +import ru.soune.nocopy.exception.ContentNotFoundException; +import ru.soune.nocopy.exception.UserNotFoundException; +import ru.soune.nocopy.mapper.UserContentMapper; +import ru.soune.nocopy.repository.UserContentRepository; +import ru.soune.nocopy.repository.UserRepository; import java.util.List; import java.util.Optional; diff --git a/src/main/java/ru/soune/no_copy/service/UserService.java b/src/main/java/ru/soune/nocopy/service/UserService.java similarity index 86% rename from src/main/java/ru/soune/no_copy/service/UserService.java rename to src/main/java/ru/soune/nocopy/service/UserService.java index 4cb0a51..7c4b79f 100644 --- a/src/main/java/ru/soune/no_copy/service/UserService.java +++ b/src/main/java/ru/soune/nocopy/service/UserService.java @@ -1,17 +1,17 @@ -package ru.soune.no_copy.service; +package ru.soune.nocopy.service; import lombok.AllArgsConstructor; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -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.exception.InvalidUserEmail; -import ru.soune.no_copy.exception.NotValidationPasswordException; -import ru.soune.no_copy.exception.UserNotFoundException; -import ru.soune.no_copy.repository.UserRepository; +import ru.soune.nocopy.dto.ChangePasswordRequest; +import ru.soune.nocopy.dto.UserDTO; +import ru.soune.nocopy.dto.UserRequest; +import ru.soune.nocopy.entity.User; +import ru.soune.nocopy.exception.InvalidUserEmail; +import ru.soune.nocopy.exception.NotValidationPasswordException; +import ru.soune.nocopy.exception.UserNotFoundException; +import ru.soune.nocopy.repository.UserRepository; @Service @AllArgsConstructor diff --git a/src/test/java/ru/soune/no_copy/service/AuthServiceTest.java b/src/test/java/ru/soune/nocopy/service/AuthServiceTest.java similarity index 87% rename from src/test/java/ru/soune/no_copy/service/AuthServiceTest.java rename to src/test/java/ru/soune/nocopy/service/AuthServiceTest.java index 69b767e..499d694 100644 --- a/src/test/java/ru/soune/no_copy/service/AuthServiceTest.java +++ b/src/test/java/ru/soune/nocopy/service/AuthServiceTest.java @@ -1,4 +1,4 @@ -package ru.soune.no_copy.service; +package ru.soune.nocopy.service; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -8,13 +8,13 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.context.MessageSource; import org.springframework.security.crypto.password.PasswordEncoder; -import ru.soune.no_copy.dto.LoginRequest; -import ru.soune.no_copy.entity.AuthToken; -import ru.soune.no_copy.entity.User; -import ru.soune.no_copy.exception.NotValidationPasswordException; -import ru.soune.no_copy.exception.UserNotFoundException; -import ru.soune.no_copy.repository.AuthTokenRepository; -import ru.soune.no_copy.repository.UserRepository; +import ru.soune.nocopy.dto.LoginRequest; +import ru.soune.nocopy.entity.AuthToken; +import ru.soune.nocopy.entity.User; +import ru.soune.nocopy.exception.NotValidationPasswordException; +import ru.soune.nocopy.exception.UserNotFoundException; +import ru.soune.nocopy.repository.AuthTokenRepository; +import ru.soune.nocopy.repository.UserRepository; import java.util.Optional; -- 2.54.0 From 0635b9b4ac1b80f080bcdc4ed2fcab30bbd882ff Mon Sep 17 00:00:00 2001 From: vladp Date: Wed, 10 Dec 2025 19:25:45 +0700 Subject: [PATCH 08/12] add check jsonbody for request --- .../java/ru/soune/nocopy/controller/ApiController.java | 8 +++++++- src/main/java/ru/soune/nocopy/dto/MessageCode.java | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/ru/soune/nocopy/controller/ApiController.java b/src/main/java/ru/soune/nocopy/controller/ApiController.java index beb3035..460ad8b 100644 --- a/src/main/java/ru/soune/nocopy/controller/ApiController.java +++ b/src/main/java/ru/soune/nocopy/controller/ApiController.java @@ -66,7 +66,13 @@ public class ApiController { throw e; } catch (Exception e) { log.error("Handler execution failed for msgId: {}", msgId, e); - throw new RuntimeException("Handler execution failed", e); + + BaseResponse errorResponse = new BaseResponse(msgId, + MessageCode.INVALID_JSON_BODY.getCode(), + MessageCode.INVALID_JSON_BODY.getDescription(), + new HashMap<>()); + + return ResponseEntity.ok().body(errorResponse); } } diff --git a/src/main/java/ru/soune/nocopy/dto/MessageCode.java b/src/main/java/ru/soune/nocopy/dto/MessageCode.java index 8bf6c19..e5fd6e4 100644 --- a/src/main/java/ru/soune/nocopy/dto/MessageCode.java +++ b/src/main/java/ru/soune/nocopy/dto/MessageCode.java @@ -4,6 +4,7 @@ public enum MessageCode { SUCCESS(0, "Operation successful"), REG_EMAIL_EXISTS(1, "Email already registered"), INVALID_FIELD(2, "Invalid field"), + INVALID_JSON_BODY(2, "Invalid fields in JSON object"), MSG_ID_NOT_FOUND(4, "Message id not found"), AUTH_EMAIL_NOT_FOUND(4, "Email not found"), -- 2.54.0 From 015f2f516c326c7f6ed61ceafcc1f69929534081 Mon Sep 17 00:00:00 2001 From: vladp Date: Thu, 11 Dec 2025 20:53:28 +0700 Subject: [PATCH 09/12] delete need full name --- .../validator/RegRequestValidator.java | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/src/main/java/ru/soune/nocopy/handler/validator/RegRequestValidator.java b/src/main/java/ru/soune/nocopy/handler/validator/RegRequestValidator.java index 5b8bfb4..ef7559f 100644 --- a/src/main/java/ru/soune/nocopy/handler/validator/RegRequestValidator.java +++ b/src/main/java/ru/soune/nocopy/handler/validator/RegRequestValidator.java @@ -52,27 +52,6 @@ public class RegRequestValidator implements Validator { errors.rejectValue("fullName", "fullName.invalid.chars", "Name can only contain letters, spaces, hyphens and apostrophes"); } - - String[] nameParts = trimmedName.split("\\s+"); - if (nameParts.length < 2) { - errors.rejectValue("fullName", "fullName.missing.parts", - "Please enter both first and last name"); - } - - for (int i = 0; i < nameParts.length; i++) { - String part = nameParts[i]; - if (part.length() < 2 && part.length() > 0) { - errors.rejectValue("fullName", "fullName.part.too.short", - "Each name part must be at least 2 characters"); - break; - } - - if (!Character.isUpperCase(part.charAt(0))) { - errors.rejectValue("fullName", "fullName.capitalization", - "Each name part should start with capital letter"); - break; - } - } } private void validateCompanyName(String companyName, Errors errors) { -- 2.54.0 From f1643709893a7e65ed5e974fdc6efbc0df2d6ac5 Mon Sep 17 00:00:00 2001 From: vladp Date: Fri, 12 Dec 2025 13:07:46 +0700 Subject: [PATCH 10/12] add check adress --- build.gradle | 8 ++- .../validator/RegRequestValidator.java | 70 +++++++------------ 2 files changed, 34 insertions(+), 44 deletions(-) diff --git a/build.gradle b/build.gradle index c6cb590..d42173a 100644 --- a/build.gradle +++ b/build.gradle @@ -29,13 +29,19 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.security:spring-security-crypto:6.5.3' implementation 'org.mapstruct:mapstruct:1.5.5.Final' + implementation 'commons-validator:commons-validator:1.7' + annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final' + annotationProcessor 'org.projectlombok:lombok' + compileOnly 'org.projectlombok:lombok' + developmentOnly 'org.springframework.boot:spring-boot-devtools' + runtimeOnly 'com.microsoft.sqlserver:mssql-jdbc' runtimeOnly 'com.mysql:mysql-connector-j' runtimeOnly 'org.postgresql:postgresql' - annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.mockito:mockito-core:5.3.1' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' diff --git a/src/main/java/ru/soune/nocopy/handler/validator/RegRequestValidator.java b/src/main/java/ru/soune/nocopy/handler/validator/RegRequestValidator.java index ef7559f..884bc89 100644 --- a/src/main/java/ru/soune/nocopy/handler/validator/RegRequestValidator.java +++ b/src/main/java/ru/soune/nocopy/handler/validator/RegRequestValidator.java @@ -1,10 +1,14 @@ package ru.soune.nocopy.handler.validator; +import org.apache.commons.validator.routines.DomainValidator; +import org.apache.commons.validator.routines.EmailValidator; import org.springframework.stereotype.Component; import org.springframework.validation.Errors; import org.springframework.validation.Validator; import ru.soune.nocopy.dto.RegRequest; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.*; @Component @@ -89,65 +93,45 @@ public class RegRequestValidator implements Validator { private void validateEmail(String email, Errors errors) { if (email == null || email.trim().isEmpty()) { - errors.rejectValue("email", "email.is.empty", - "Email must not be empty"); + errors.rejectValue("email", "email.is.empty", "Email must not be empty"); return; } String trimmedEmail = email.trim().toLowerCase(); - if (trimmedEmail.length() > 128) { - errors.rejectValue("email", "email.too.long", - "Email must be less than 128 characters"); + if (trimmedEmail.length() > 254) { + errors.rejectValue("email", "email.too.long", "Email is too long"); return; } - if (!trimmedEmail.matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$")) { - errors.rejectValue("email", "email.invalid.format", - "Invalid email format"); + EmailValidator emailValidator = EmailValidator.getInstance(true, true); + if (!emailValidator.isValid(trimmedEmail)) { + errors.rejectValue("email", "email.invalid", "Invalid email address"); return; } String[] parts = trimmedEmail.split("@"); - if (parts.length != 2) { - return; - } + if (parts.length == 2) { + String domain = parts[1]; + DomainValidator domainValidator = DomainValidator.getInstance(); - String localPart = parts[0]; - String domain = parts[1]; - - if (localPart.length() > 64) { - errors.rejectValue("email", "email.local.too.long", - "Email username too long"); - } - - if (!localPart.matches("^[a-z0-9+_.-]+$")) { - errors.rejectValue("email", "email.local.invalid.chars", - "Email contains invalid characters"); - } - - validateEmailDomain(domain, errors); - } - - private void validateEmailDomain(String domain, Errors errors) { - if (domain.length() > 255) { - errors.rejectValue("email", "email.domain.too.long", - "Email domain too long"); - } - - String[] domainParts = domain.split("\\."); - if (domainParts.length < 2) { - errors.rejectValue("email", "email.domain.invalid", - "Invalid domain name"); - } - - String tld = domainParts[domainParts.length - 1]; - if (tld.length() < 2) { - errors.rejectValue("email", "email.tld.invalid", - "Invalid domain extension"); + if (!checkDomainExists(domain)) { + errors.rejectValue("email", "email.domain.not.found", + "Domain does not exist"); + } } } + private boolean checkDomainExists(String domain) { + try { + InetAddress.getByName(domain); + return true; + } catch (UnknownHostException e) { + return false; + } + } + + private void validatePhone(String phone, Errors errors) { if (phone == null || phone.trim().isEmpty()) { errors.rejectValue("phone", "phone.empty", -- 2.54.0 From fade754c7c42ba0955c67224a955a12f4d330e39 Mon Sep 17 00:00:00 2001 From: vladp Date: Tue, 16 Dec 2025 12:41:55 +0700 Subject: [PATCH 11/12] fix check email --- .../validator/RegRequestValidator.java | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/src/main/java/ru/soune/nocopy/handler/validator/RegRequestValidator.java b/src/main/java/ru/soune/nocopy/handler/validator/RegRequestValidator.java index 884bc89..f3dbda7 100644 --- a/src/main/java/ru/soune/nocopy/handler/validator/RegRequestValidator.java +++ b/src/main/java/ru/soune/nocopy/handler/validator/RegRequestValidator.java @@ -109,26 +109,6 @@ public class RegRequestValidator implements Validator { errors.rejectValue("email", "email.invalid", "Invalid email address"); return; } - - String[] parts = trimmedEmail.split("@"); - if (parts.length == 2) { - String domain = parts[1]; - DomainValidator domainValidator = DomainValidator.getInstance(); - - if (!checkDomainExists(domain)) { - errors.rejectValue("email", "email.domain.not.found", - "Domain does not exist"); - } - } - } - - private boolean checkDomainExists(String domain) { - try { - InetAddress.getByName(domain); - return true; - } catch (UnknownHostException e) { - return false; - } } -- 2.54.0 From 6797a47df56ad2ec59817e0951deac1e649d342e Mon Sep 17 00:00:00 2001 From: vladp Date: Tue, 16 Dec 2025 16:43:20 +0700 Subject: [PATCH 12/12] check unique phone --- src/main/java/ru/soune/nocopy/dto/MessageCode.java | 1 + src/main/java/ru/soune/nocopy/entity/User.java | 1 + .../ru/soune/nocopy/handler/RegRequestHandler.java | 10 ++++++---- .../ru/soune/nocopy/repository/UserRepository.java | 2 ++ 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/ru/soune/nocopy/dto/MessageCode.java b/src/main/java/ru/soune/nocopy/dto/MessageCode.java index e5fd6e4..baa48be 100644 --- a/src/main/java/ru/soune/nocopy/dto/MessageCode.java +++ b/src/main/java/ru/soune/nocopy/dto/MessageCode.java @@ -3,6 +3,7 @@ package ru.soune.nocopy.dto; public enum MessageCode { SUCCESS(0, "Operation successful"), REG_EMAIL_EXISTS(1, "Email already registered"), + REG_EMAIL_OR_PHONE_EXISTS(1, "Email or phone already registered"), INVALID_FIELD(2, "Invalid field"), INVALID_JSON_BODY(2, "Invalid fields in JSON object"), MSG_ID_NOT_FOUND(4, "Message id not found"), diff --git a/src/main/java/ru/soune/nocopy/entity/User.java b/src/main/java/ru/soune/nocopy/entity/User.java index a4fba7d..0841027 100644 --- a/src/main/java/ru/soune/nocopy/entity/User.java +++ b/src/main/java/ru/soune/nocopy/entity/User.java @@ -42,6 +42,7 @@ public class User { private String password; @Size(min = 11, max = 14) + @Column(unique = true) private String phone; @Enumerated(EnumType.STRING) diff --git a/src/main/java/ru/soune/nocopy/handler/RegRequestHandler.java b/src/main/java/ru/soune/nocopy/handler/RegRequestHandler.java index 65bc887..349f0a7 100644 --- a/src/main/java/ru/soune/nocopy/handler/RegRequestHandler.java +++ b/src/main/java/ru/soune/nocopy/handler/RegRequestHandler.java @@ -33,13 +33,15 @@ public class RegRequestHandler implements RequestHandler { public BaseResponse handle(BaseRequest request) throws ValidationException { RegRequest regRequest = objectMapper.convertValue(request.getMessageBody(), RegRequest.class); - if (userRepository.existsByEmail(regRequest.getEmail())) { + if (userRepository.existsByEmail(regRequest.getEmail()) || userRepository.existsByPhone(regRequest.getPhone())) { RegAnswer regAnswer = new RegAnswer(); regAnswer.setFieldErrors(Arrays.asList(Map.of("email", regRequest.getEmail()))); + regAnswer.setFieldErrors(Arrays.asList(Map.of("phone", regRequest.getPhone()))); - throw new NotValidFieldException("User already exists with email: " + regRequest.getEmail(), - new BaseResponse(request.getMsgId(), MessageCode.REG_EMAIL_EXISTS.getCode(), - MessageCode.REG_EMAIL_EXISTS.getDescription(), regAnswer)); + throw new NotValidFieldException("User already exists with email:" + regRequest.getEmail() + " or phone: " + + regRequest.getPhone(), new BaseResponse(request.getMsgId(), + MessageCode.REG_EMAIL_OR_PHONE_EXISTS.getCode(), + MessageCode.REG_EMAIL_OR_PHONE_EXISTS.getDescription(), regAnswer)); } BindingResult bindingResult = new BeanPropertyBindingResult(regRequest, "regRequest"); diff --git a/src/main/java/ru/soune/nocopy/repository/UserRepository.java b/src/main/java/ru/soune/nocopy/repository/UserRepository.java index da4d7f9..f674629 100644 --- a/src/main/java/ru/soune/nocopy/repository/UserRepository.java +++ b/src/main/java/ru/soune/nocopy/repository/UserRepository.java @@ -1,5 +1,6 @@ package ru.soune.nocopy.repository; +import jakarta.validation.constraints.Size; import org.springframework.data.jpa.repository.JpaRepository; import ru.soune.nocopy.entity.User; @@ -8,4 +9,5 @@ import java.util.Optional; public interface UserRepository extends JpaRepository { Optional findByEmail(String email); boolean existsByEmail(String email); + boolean existsByPhone(@Size(min = 11, max = 14) String phone); } -- 2.54.0