diff --git a/src/main/java/edu/cmipt/gcs/controller/RepositoryController.java b/src/main/java/edu/cmipt/gcs/controller/RepositoryController.java index c61f7a9..4a53126 100644 --- a/src/main/java/edu/cmipt/gcs/controller/RepositoryController.java +++ b/src/main/java/edu/cmipt/gcs/controller/RepositoryController.java @@ -177,9 +177,7 @@ public ResponseEntity updateRepository( && !repository .repositoryName() .equals(repositoryService.getById(id).getRepositoryName())) { - throw new GenericException( - ErrorCodeEnum.OPERATION_NOT_IMPLEMENTED, - "update repository name is not implemented"); + throw new GenericException(ErrorCodeEnum.OPERATION_NOT_IMPLEMENTED); } if (!repositoryService.updateById(new RepositoryPO(repository))) { throw new GenericException(ErrorCodeEnum.REPOSITORY_UPDATE_FAILED, repository); @@ -216,17 +214,14 @@ public void checkRepositoryNameValidity( min = ValidationConstant.MIN_REPOSITORY_NAME_LENGTH, max = ValidationConstant.MAX_REPOSITORY_NAME_LENGTH, message = - "REPOSITORYDTO_REPOSITORYNAME_SIZE" - + " {RepositoryDTO.repositoryName.Size}") + "{Size.repositoryController#checkRepositoryNameValidity.repositoryName}") @NotBlank( message = - "REPOSITORYDTO_REPOSITORYNAME_NOTBLANK" - + " {RepositoryDTO.repositoryName.NotBlank}") + "{NotBlank.repositoryController#checkRepositoryNameValidity.repositoryName}") @Pattern( regexp = ValidationConstant.REPOSITORY_NAME_PATTERN, message = - "REPOSITORYNAME_PATTERN_MISMATCH" - + " {REPOSITORYNAME_PATTERN_MISMATCH}") + "{Pattern.repositoryController#checkRepositoryNameValidity.repositoryName}") String repositoryName, @RequestParam("userId") Long userId) { QueryWrapper queryWrapper = new QueryWrapper<>(); diff --git a/src/main/java/edu/cmipt/gcs/controller/UserController.java b/src/main/java/edu/cmipt/gcs/controller/UserController.java index d663925..4c9e14d 100644 --- a/src/main/java/edu/cmipt/gcs/controller/UserController.java +++ b/src/main/java/edu/cmipt/gcs/controller/UserController.java @@ -261,8 +261,8 @@ public List pageUserRepository( }) public void checkEmailValidity( @RequestParam("email") - @Email(message = "USERDTO_EMAIL_EMAIL {UserDTO.email.Email}") - @NotBlank(message = "USERDTO_EMAIL_NOTBLANK {UserDTO.email.NotBlank}") + @Email(message = "{Email.userController#checkEmailValidity.email}") + @NotBlank(message = "{NotBlank.userController#checkEmailValidity.email}") String email) { QueryWrapper wrapper = new QueryWrapper(); wrapper.eq("email", email); @@ -295,11 +295,11 @@ public void checkUsernameValidity( @Size( min = ValidationConstant.MIN_USERNAME_LENGTH, max = ValidationConstant.MAX_USERNAME_LENGTH, - message = "USERDTO_USERNAME_SIZE {UserDTO.username.Size}") - @NotBlank(message = "USERDTO_USERNAME_NOTBLANK {UserDTO.username.NotBlank}") + message = "{Size.userController#checkUsernameValidity.username}") + @NotBlank(message = "{NotBlank.userController#checkUsernameValidity.username}") @Pattern( regexp = ValidationConstant.USERNAME_PATTERN, - message = "USERNAME_PATTERN_MISMATCH {USERNAME_PATTERN_MISMATCH}") + message = "{Pattern.userController#checkUsernameValidity.username}") String username) { QueryWrapper wrapper = new QueryWrapper(); wrapper.eq("username", username); @@ -332,10 +332,10 @@ public void checkPasswordValidity( @Size( min = ValidationConstant.MIN_PASSWORD_LENGTH, max = ValidationConstant.MAX_PASSWORD_LENGTH, - message = "USERDTO_PASSWORD_SIZE {UserDTO.password.Size}") - @NotBlank(message = "USERDTO_PASSWORD_NOTBLANK {UserDTO.password.NotBlank}") + message = "{Size.userController#checkPasswordValidity.password}") + @NotBlank(message = "{NotBlank.userController#checkPasswordValidity.password}") @Pattern( regexp = ValidationConstant.PASSWORD_PATTERN, - message = "PASSWORD_PATTERN_MISMATCH {PASSWORD_PATTERN_MISMATCH}") + message = "{Pattern.userController#checkPasswordValidity.password}") String password) {} } diff --git a/src/main/java/edu/cmipt/gcs/enumeration/ErrorCodeEnum.java b/src/main/java/edu/cmipt/gcs/enumeration/ErrorCodeEnum.java index 07cc41f..31d0962 100644 --- a/src/main/java/edu/cmipt/gcs/enumeration/ErrorCodeEnum.java +++ b/src/main/java/edu/cmipt/gcs/enumeration/ErrorCodeEnum.java @@ -4,20 +4,7 @@ public enum ErrorCodeEnum { // This should be ignored, this is to make the ordinal of the enum start from 1 ZERO_PLACEHOLDER, - USERDTO_ID_NULL("UserDTO.id.Null"), - USERDTO_ID_NOTNULL("UserDTO.id.NotNull"), - USERDTO_USERNAME_SIZE("UserDTO.username.Size"), - USERDTO_USERNAME_NOTBLANK("UserDTO.username.NotBlank"), - USERDTO_EMAIL_NOTBLANK("UserDTO.email.NotBlank"), - USERDTO_EMAIL_EMAIL("UserDTO.email.Email"), - USERDTO_USERPASSWORD_SIZE("UserDTO.userPassword.Size"), - USERDTO_USERPASSWORD_NOTBLANK("UserDTO.userPassword.NotBlank"), - - USERSIGNINDTO_USERNAME_NOTBLANK("UserSignInDTO.username.NotBlank"), - USERSIGNINDTO_USERPASSWORD_NOTBLANK("UserSignInDTO.userPassword.NotBlank"), - - USERNAME_PATTERN_MISMATCH("USERNAME_PATTERN_MISMATCH"), - PASSWORD_PATTERN_MISMATCH("PASSWORD_PATTERN_MISMATCH"), + VALIDATION_ERROR("VALIDATION_ERROR"), USERNAME_ALREADY_EXISTS("USERNAME_ALREADY_EXISTS"), EMAIL_ALREADY_EXISTS("EMAIL_ALREADY_EXISTS"), @@ -35,19 +22,6 @@ public enum ErrorCodeEnum { USER_UPDATE_FAILED("USER_UPDATE_FAILED"), USER_DELETE_FAILED("USER_DELETE_FAILED"), - REPOSITORYDTO_ID_NULL("RepositoryDTO.id.Null"), - REPOSITORYDTO_ID_NOTNULL("RepositoryDTO.id.NotNull"), - REPOSITORYDTO_REPOSITORYNAME_SIZE("RepositoryDTO.repositoryName.Size"), - REPOSITORYDTO_REPOSITORYNAME_NOTBLANK("RepositoryDTO.repositoryName.NotBlank"), - REPOSITORYDTO_REPOSITORYDESCRIPTION_SIZE("RepositoryDTO.repositoryDescription.Size"), - REPOSITORYDTO_STAR_NULL("RepositoryDTO.star.Null"), - REPOSITORYDTO_STAR_MIN("RepositoryDTO.star.Min"), - REPOSITORYDTO_FORK_NULL("RepositoryDTO.fork.Null"), - REPOSITORYDTO_FORK_MIN("RepositoryDTO.fork.Min"), - REPOSITORYDTO_WATCHER_NULL("RepositoryDTO.watcher.Null"), - REPOSITORYDTO_WATCHER_MIN("RepositoryDTO.watcher.Min"), - - REPOSITORYNAME_PATTERN_MISMATCH("REPOSITORYNAME_PATTERN_MISMATCH"), REPOSITORY_NOT_FOUND("REPOSITORY_NOT_FOUND"), REPOSITORY_ALREADY_EXISTS("REPOSITORY_ALREADY_EXISTS"), REPOSITORY_CREATE_FAILED("REPOSITORY_CREATE_FAILED"), @@ -59,13 +33,6 @@ public enum ErrorCodeEnum { COLLABORATION_ALREADY_EXISTS("COLLABORATION_ALREADY_EXISTS"), COLLABORATION_NOT_FOUND("COLLABORATION_NOT_FOUND"), - SSHKEYDTO_ID_NULL("SshKeyDTO.id.Null"), - SSHKEYDTO_ID_NOTNULL("SshKeyDTO.id.NotNull"), - SSHKEYDTO_NAME_NOTBLANK("SshKeyDTO.name.NotBlank"), - SSHKEYDTO_NAME_SIZE("SshKeyDTO.name.Size"), - SSHKEYDTO_PUBLICKEY_NOTBLANK("SshKeyDTO.publicKey.NotBlank"), - SSHKEYDTO_PUBLICKEY_SIZE("SshKeyDTO.publicKey.Size"), - SSH_KEY_UPLOAD_FAILED("SSH_KEY_UPLOAD_FAILED"), SSH_KEY_UPDATE_FAILED("SSH_KEY_UPDATE_FAILED"), SSH_KEY_DELETE_FAILED("SSH_KEY_DELETE_FAILED"), diff --git a/src/main/java/edu/cmipt/gcs/exception/GlobalExceptionHandler.java b/src/main/java/edu/cmipt/gcs/exception/GlobalExceptionHandler.java index 0e8cc5e..8db5a9f 100644 --- a/src/main/java/edu/cmipt/gcs/exception/GlobalExceptionHandler.java +++ b/src/main/java/edu/cmipt/gcs/exception/GlobalExceptionHandler.java @@ -2,6 +2,7 @@ import edu.cmipt.gcs.enumeration.ErrorCodeEnum; import edu.cmipt.gcs.pojo.error.ErrorVO; +import edu.cmipt.gcs.util.MessageSourceUtil; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.ConstraintViolationException; @@ -37,7 +38,10 @@ public class GlobalExceptionHandler { @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity handleMethodArgumentNotValidException( MethodArgumentNotValidException e, HttpServletRequest request) { - return handleValidationException(e.getFieldError().getDefaultMessage(), request); + var fieldError = e.getBindingResult().getFieldError(); + return handleValidationException( + MessageSourceUtil.getMessage(fieldError.getCodes()[0], fieldError.getArguments()), + request); } /** @@ -108,13 +112,8 @@ public ResponseEntity handleException(Exception e, HttpServletRequest r } private ResponseEntity handleValidationException( - String codeAndMessage, HttpServletRequest request) { - int firstSpaceIndex = codeAndMessage.indexOf(" "); - // There must be a space and not at the end of the message - assert firstSpaceIndex != -1; - assert firstSpaceIndex != codeAndMessage.length() - 1; - var exception = new GenericException(codeAndMessage.substring(firstSpaceIndex + 1)); - exception.setCode(ErrorCodeEnum.valueOf(codeAndMessage.substring(0, firstSpaceIndex))); - return handleGenericException(exception, request); + String message, HttpServletRequest request) { + return handleGenericException( + new GenericException(ErrorCodeEnum.VALIDATION_ERROR, message), request); } } diff --git a/src/main/java/edu/cmipt/gcs/pojo/repository/RepositoryDTO.java b/src/main/java/edu/cmipt/gcs/pojo/repository/RepositoryDTO.java index 1f96085..cbcf94f 100644 --- a/src/main/java/edu/cmipt/gcs/pojo/repository/RepositoryDTO.java +++ b/src/main/java/edu/cmipt/gcs/pojo/repository/RepositoryDTO.java @@ -15,12 +15,8 @@ @Schema(description = "Repository Data Transfer Object") public record RepositoryDTO( @Schema(description = "Repository ID") - @Null( - groups = CreateGroup.class, - message = "REPOSITORYDTO_ID_NULL {RepositoryDTO.id.Null}") - @NotNull( - groups = UpdateGroup.class, - message = "REPOSITORYDTO_ID_NOTNULL {RepositoryDTO.id.NotNull}") + @Null(groups = CreateGroup.class) + @NotNull(groups = UpdateGroup.class) String id, @Schema( description = "Repository Name", @@ -29,29 +25,17 @@ public record RepositoryDTO( @Size( groups = {CreateGroup.class, UpdateGroup.class}, min = ValidationConstant.MIN_REPOSITORY_NAME_LENGTH, - max = ValidationConstant.MAX_REPOSITORY_NAME_LENGTH, - message = - "REPOSITORYDTO_REPOSITORYNAME_SIZE" - + " {RepositoryDTO.repositoryName.Size}") - @NotBlank( - groups = CreateGroup.class, - message = - "REPOSITORYDTO_REPOSITORYNAME_NOTBLANK" - + " {RepositoryDTO.repositoryName.NotBlank}") + max = ValidationConstant.MAX_REPOSITORY_NAME_LENGTH) + @NotBlank(groups = CreateGroup.class) @Pattern( regexp = ValidationConstant.REPOSITORY_NAME_PATTERN, - groups = {CreateGroup.class, UpdateGroup.class}, - message = - "REPOSITORYNAME_PATTERN_MISMATCH {REPOSITORYNAME_PATTERN_MISMATCH}") + groups = {CreateGroup.class, UpdateGroup.class}) String repositoryName, @Schema(description = "Repository Description") @Size( groups = {CreateGroup.class, UpdateGroup.class}, min = ValidationConstant.MIN_REPOSITORY_DESCRIPTION_LENGTH, - max = ValidationConstant.MAX_REPOSITORY_DESCRIPTION_LENGTH, - message = - "REPOSITORYDTO_REPOSITORYDESCRIPTION_SIZE" - + " {RepositoryDTO.repositoryDescription.Size}") + max = ValidationConstant.MAX_REPOSITORY_DESCRIPTION_LENGTH) String repositoryDescription, @Schema(description = "Whether or Not Private Repo", example = "false") Boolean isPrivate) {} diff --git a/src/main/java/edu/cmipt/gcs/pojo/ssh/SshKeyDTO.java b/src/main/java/edu/cmipt/gcs/pojo/ssh/SshKeyDTO.java index 6bae458..0209ead 100644 --- a/src/main/java/edu/cmipt/gcs/pojo/ssh/SshKeyDTO.java +++ b/src/main/java/edu/cmipt/gcs/pojo/ssh/SshKeyDTO.java @@ -14,28 +14,20 @@ @Schema(description = "SSH Key Data Transfer Object") public record SshKeyDTO( @Schema(description = "SSH Key ID") - @Null(groups = CreateGroup.class, message = "SSHKEYDTO_ID_NULL {SshKeyDTO.id.Null}") - @NotNull( - groups = UpdateGroup.class, - message = "SSHKEYDTO_ID_NOTNULL {SshKeyDTO.id.NotNull}") + @Null(groups = CreateGroup.class) + @NotNull(groups = UpdateGroup.class) String id, @Schema(description = "Name", example = "My SSH Key") - @NotBlank( - groups = {CreateGroup.class, UpdateGroup.class}, - message = "SSHKEYDTO_NAME_NOTBLANK {SshKeyDTO.name.NotBlank}") + @NotBlank(groups = {CreateGroup.class, UpdateGroup.class}) @Size( groups = {CreateGroup.class, UpdateGroup.class}, min = ValidationConstant.MIN_SSH_KEY_NAME_LENGTH, - max = ValidationConstant.MAX_SSH_KEY_NAME_LENGTH, - message = "SSHKEYDTO_NAME_SIZE {SshKeyDTO.name.Size}") + max = ValidationConstant.MAX_SSH_KEY_NAME_LENGTH) String name, @Schema(description = "Public Key") - @NotBlank( - groups = CreateGroup.class, - message = "SSHKEYDTO_PUBLICKEY_NOTBLANK {SshKeyDTO.publicKey.NotBlank}") + @NotBlank(groups = CreateGroup.class) @Size( groups = {CreateGroup.class, UpdateGroup.class}, min = ValidationConstant.MIN_SSH_KEY_PUBLICKEY_LENGTH, - max = ValidationConstant.MAX_SSH_KEY_PUBLICKEY_LENGTH, - message = "SSHKEYDTO_PUBLICKEY_SIZE {SshKeyDTO.publicKey.Size}") + max = ValidationConstant.MAX_SSH_KEY_PUBLICKEY_LENGTH) String publicKey) {} diff --git a/src/main/java/edu/cmipt/gcs/pojo/user/UserDTO.java b/src/main/java/edu/cmipt/gcs/pojo/user/UserDTO.java index 3e2dad7..4f83fa3 100644 --- a/src/main/java/edu/cmipt/gcs/pojo/user/UserDTO.java +++ b/src/main/java/edu/cmipt/gcs/pojo/user/UserDTO.java @@ -21,10 +21,8 @@ @Schema(description = "User Data Transfer Object") public record UserDTO( @Schema(description = "User ID") - @Null(groups = CreateGroup.class, message = "USERDTO_ID_NULL {UserDTO.id.Null}") - @NotNull( - groups = UpdateGroup.class, - message = "USERDTO_ID_NOTNULL {UserDTO.id.NotNull}") + @Null(groups = CreateGroup.class) + @NotNull(groups = UpdateGroup.class) // The Long can not be expressed correctly in json, so use String instead String id, @Schema( @@ -34,26 +32,18 @@ public record UserDTO( @Size( groups = {CreateGroup.class, UpdateGroup.class}, min = ValidationConstant.MIN_USERNAME_LENGTH, - max = ValidationConstant.MAX_USERNAME_LENGTH, - message = "USERDTO_USERNAME_SIZE {UserDTO.username.Size}") - @NotBlank( - groups = {CreateGroup.class}, - message = "USERDTO_USERNAME_NOTBLANK {UserDTO.username.NotBlank}") + max = ValidationConstant.MAX_USERNAME_LENGTH) + @NotBlank(groups = {CreateGroup.class}) @Pattern( regexp = ValidationConstant.USERNAME_PATTERN, - groups = {CreateGroup.class, UpdateGroup.class}, - message = "USERNAME_PATTERN_MISMATCH {USERNAME_PATTERN_MISMATCH}") + groups = {CreateGroup.class, UpdateGroup.class}) String username, @Schema( description = "Email", requiredMode = Schema.RequiredMode.REQUIRED, example = "admin@cmipt.edu") - @Email( - groups = {CreateGroup.class, UpdateGroup.class}, - message = "USERDTO_EMAIL_EMAIL {UserDTO.email.Email}") - @NotBlank( - groups = {CreateGroup.class}, - message = "USERDTO_EMAIL_NOTBLANK {UserDTO.email.NotBlank}") + @Email(groups = {CreateGroup.class, UpdateGroup.class}) + @NotBlank(groups = {CreateGroup.class}) String email, @Schema( description = "User Password (Unencrypted)", @@ -62,13 +52,9 @@ public record UserDTO( @Size( groups = {CreateGroup.class, UpdateGroup.class}, min = ValidationConstant.MIN_PASSWORD_LENGTH, - max = ValidationConstant.MAX_PASSWORD_LENGTH, - message = "USERDTO_USERPASSWORD_SIZE {UserDTO.userPassword.Size}") - @NotBlank( - groups = {CreateGroup.class}, - message = "USERDTO_USERPASSWORD_NOTBLANK {UserDTO.userPassword.NotBlank}") + max = ValidationConstant.MAX_PASSWORD_LENGTH) + @NotBlank(groups = {CreateGroup.class}) @Pattern( regexp = ValidationConstant.PASSWORD_PATTERN, - groups = {CreateGroup.class, UpdateGroup.class}, - message = "PASSWORD_PATTERN_MISMATCH {PASSWORD_PATTERN_MISMATCH}") + groups = {CreateGroup.class, UpdateGroup.class}) String userPassword) {} diff --git a/src/main/java/edu/cmipt/gcs/pojo/user/UserSignInDTO.java b/src/main/java/edu/cmipt/gcs/pojo/user/UserSignInDTO.java index e907c4f..a8e89e6 100644 --- a/src/main/java/edu/cmipt/gcs/pojo/user/UserSignInDTO.java +++ b/src/main/java/edu/cmipt/gcs/pojo/user/UserSignInDTO.java @@ -10,16 +10,11 @@ public record UserSignInDTO( description = "Username", requiredMode = Schema.RequiredMode.REQUIRED, example = "admin") - @NotBlank( - message = - "USERSIGNINDTO_USERNAME_NOTBLANK {UserSignInDTO.username.NotBlank}") + @NotBlank String username, @Schema( description = "User Password (Unencrypted)", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456") - @NotBlank( - message = - "USERSIGNINDTO_USERPASSWORD_NOTBLANK" - + " {UserSignInDTO.userPassword.NotBlank}") + @NotBlank String userPassword) {} diff --git a/src/main/java/edu/cmipt/gcs/service/RepositoryServiceImpl.java b/src/main/java/edu/cmipt/gcs/service/RepositoryServiceImpl.java index faa3160..e96e607 100644 --- a/src/main/java/edu/cmipt/gcs/service/RepositoryServiceImpl.java +++ b/src/main/java/edu/cmipt/gcs/service/RepositoryServiceImpl.java @@ -39,9 +39,7 @@ public boolean save(RepositoryPO repositoryPO) { repositoryPO.getUserId(), repositoryPO.getIsPrivate())) { logger.error("Failed to create repository in gitolite"); - throw new GenericException( - ErrorCodeEnum.REPOSITORY_CREATE_FAILED, - "Failed to create repository in gitolite"); + throw new GenericException(ErrorCodeEnum.REPOSITORY_CREATE_FAILED, repositoryPO); } return true; } @@ -60,9 +58,7 @@ public boolean removeById(Serializable id) { repositoryPO.getUserId(), repositoryPO.getIsPrivate())) { logger.error("Failed to remove repository from gitolite"); - throw new GenericException( - ErrorCodeEnum.REPOSITORY_DELETE_FAILED, - "Failed to remove repository from gitolite"); + throw new GenericException(ErrorCodeEnum.REPOSITORY_DELETE_FAILED, repositoryPO); } return true; } diff --git a/src/main/java/edu/cmipt/gcs/service/SshKeyServiceImpl.java b/src/main/java/edu/cmipt/gcs/service/SshKeyServiceImpl.java index be83ce3..7779edf 100644 --- a/src/main/java/edu/cmipt/gcs/service/SshKeyServiceImpl.java +++ b/src/main/java/edu/cmipt/gcs/service/SshKeyServiceImpl.java @@ -30,8 +30,7 @@ public boolean save(SshKeyPO sshKeyPO) { if (!GitoliteUtil.addSshKey( sshKeyPO.getId(), sshKeyPO.getPublicKey(), sshKeyPO.getUserId())) { logger.error("Failed to add SSH key to gitolite"); - throw new GenericException( - ErrorCodeEnum.SSH_KEY_UPLOAD_FAILED, "Failed to add SSH key to gitolite"); + throw new GenericException(ErrorCodeEnum.SSH_KEY_UPLOAD_FAILED, sshKeyPO); } return true; } @@ -47,8 +46,7 @@ public boolean removeById(Serializable id) { } if (!GitoliteUtil.removeSshKey(sshKeyPO.getId(), sshKeyPO.getUserId())) { logger.error("Failed to remove SSH key from gitolite"); - throw new GenericException( - ErrorCodeEnum.SSH_KEY_DELETE_FAILED, "Failed to remove SSH key from gitolite"); + throw new GenericException(ErrorCodeEnum.SSH_KEY_DELETE_FAILED, sshKeyPO); } return true; } diff --git a/src/main/java/edu/cmipt/gcs/service/UserServiceImpl.java b/src/main/java/edu/cmipt/gcs/service/UserServiceImpl.java index a3c28d0..fa41fd1 100644 --- a/src/main/java/edu/cmipt/gcs/service/UserServiceImpl.java +++ b/src/main/java/edu/cmipt/gcs/service/UserServiceImpl.java @@ -36,10 +36,7 @@ public boolean removeById(Serializable id) { var sshKeyList = sshKeyService.list(wrapper); for (var sshKey : sshKeyList) { if (!sshKeyService.removeById(sshKey.getId())) { - throw new GenericException( - ErrorCodeEnum.USER_DELETE_FAILED, - "Failed to remove user ssh key: {}", - sshKey); + throw new GenericException(ErrorCodeEnum.USER_DELETE_FAILED, sshKey); } } return true; @@ -54,8 +51,7 @@ public boolean save(UserPO user) { } if (!GitoliteUtil.initUserConfig(user.getId())) { logger.error("Failed to add user to gitolite"); - throw new GenericException( - ErrorCodeEnum.USER_CREATE_FAILED, "Failed to add user to gitolite"); + throw new GenericException(ErrorCodeEnum.USER_CREATE_FAILED, user); } return true; } diff --git a/src/main/java/edu/cmipt/gcs/util/MessageSourceUtil.java b/src/main/java/edu/cmipt/gcs/util/MessageSourceUtil.java index 7114370..d350050 100644 --- a/src/main/java/edu/cmipt/gcs/util/MessageSourceUtil.java +++ b/src/main/java/edu/cmipt/gcs/util/MessageSourceUtil.java @@ -6,9 +6,6 @@ import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.stereotype.Component; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - @Component public class MessageSourceUtil { private static MessageSource messageSource; @@ -18,20 +15,19 @@ public class MessageSourceUtil { } public static String getMessage(ErrorCodeEnum code, Object... args) { + return getMessage(code.getCode(), args); + } + + public static String getMessage(String code, Object... args) { try { - return messageSource.getMessage(code.getCode(), args, LocaleContextHolder.getLocale()); + return messageSource.getMessage(code, args, LocaleContextHolder.getLocale()); } catch (Exception e) { // ignore } - String message = - messageSource.getMessage(code.getCode(), null, LocaleContextHolder.getLocale()); - Pattern pattern = Pattern.compile("\\{.*?\\}"); - Matcher matcher = pattern.matcher(message); - int i = 0; - while (matcher.find()) { - message = message.replace(matcher.group(), args[i].toString()); - i++; + try { + return messageSource.getMessage(code, null, LocaleContextHolder.getLocale()); + } catch (Exception e) { + return ""; } - return message; } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 89aa41b..d0dac74 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -40,7 +40,7 @@ spring: reset-enable: false allow: # empty means allow all messages: - basename: message/message + basename: message/exception,message/validation encoding: UTF-8 mybatis-plus: diff --git a/src/main/resources/message/exception.properties b/src/main/resources/message/exception.properties new file mode 100644 index 0000000..38fce00 --- /dev/null +++ b/src/main/resources/message/exception.properties @@ -0,0 +1,36 @@ +USERNAME_ALREADY_EXISTS=Username already exists: {0} +EMAIL_ALREADY_EXISTS=Email already exists: {0} +WRONG_SIGN_IN_INFORMATION=Wrong sign in information + +INVALID_TOKEN=Invalid token: {0} +TOKEN_NOT_FOUND=Token not found in header +ACCESS_DENIED=Operation without privileges + +MESSAGE_CONVERSION_ERROR=Error occurs while converting message + +USER_NOT_FOUND=User not found: {0} +USER_CREATE_FAILED=User create failed: {0} +USER_UPDATE_FAILED=User update failed: {0} +USER_DELETE_FAILED=User delete failed: {0} + +REPOSITORY_NOT_FOUND=Repository not found: {0} +REPOSITORY_ALREADY_EXISTS=Repository already exists: {0} +REPOSITORY_CREATE_FAILED=Repository create failed: {0} +REPOSITORY_UPDATE_FAILED=Repository update failed: {0} +REPOSITORY_DELETE_FAILED=Repository delete failed: {0} + +COLLABORATION_ADD_FAILED=Collaboration add failed: collaborator{0}, repository{1} +COLLABORATION_REMOVE_FAILED=Collaboration remove failed: collaborator{0}, repository{1} +COLLABORATION_ALREADY_EXISTS=Collaboration already exists: collaborator{0}, repository{1} +COLLABORATION_NOT_FOUND=Collaboration not found: collaborator{0}, repository{1} + +SSH_KEY_UPLOAD_FAILED=SSH key upload failed: {0} +SSH_KEY_UPDATE_FAILED=SSH key update failed: {0} +SSH_KEY_DELETE_FAILED=SSH key delete failed: {0} +SSH_KEY_NOT_FOUND=SSH key not found: {0} + +OPERATION_NOT_IMPLEMENTED=Operation not implemented + +SERVER_ERROR=Internal server error, try again later + +ILLOGICAL_OPERATION=Illogical operation, please check diff --git a/src/main/resources/message/exception_zh_CN.properties b/src/main/resources/message/exception_zh_CN.properties new file mode 100644 index 0000000..be8318c --- /dev/null +++ b/src/main/resources/message/exception_zh_CN.properties @@ -0,0 +1,36 @@ +USERNAME_ALREADY_EXISTS=用户名已存在:{0} +EMAIL_ALREADY_EXISTS=邮箱已存在:{0} +WRONG_SIGN_IN_INFORMATION=登录信息错误 + +INVALID_TOKEN=无效的令牌:{0} +TOKEN_NOT_FOUND=请求头中未找到令牌 +ACCESS_DENIED=无权限操作 + +MESSAGE_CONVERSION_ERROR=消息转换错误 + +USER_NOT_FOUND=未找到用户:{0} +USER_CREATE_FAILED=创建用户失败:{0} +USER_UPDATE_FAILED=更新用户失败:{0} +USER_DELETE_FAILED=删除用户失败:{0} + +REPOSITORY_NOT_FOUND=未找到仓库:{0} +REPOSITORY_ALREADY_EXISTS=仓库已存在:{0} +REPOSITORY_CREATE_FAILED=创建仓库失败:{0} +REPOSITORY_UPDATE_FAILED=更新仓库失败:{0} +REPOSITORY_DELETE_FAILED=删除仓库失败:{0} + +COLLABORATION_ADD_FAILED=添加协作关系失败:协作者{0}, 仓库{1} +COLLABORATION_REMOVE_FAILED=移除协作关系失败:协作者{0}, 仓库{1} +COLLABORATION_ALREADY_EXISTS=协作关系已存在:协作者{0}, 仓库{1} +COLLABORATION_NOT_FOUND=未找到协作关系:协作者{0}, 仓库{1} + +SSH_KEY_UPLOAD_FAILED=上传SSH密钥失败:{0} +SSH_KEY_UPDATE_FAILED=更新SSH密钥失败:{0} +SSH_KEY_DELETE_FAILED=删除SSH密钥失败:{0} +SSH_KEY_NOT_FOUND=未找到SSH密钥:{0} + +OPERATION_NOT_IMPLEMENTED=操作未实现 + +SERVER_ERROR=服务器错误,请稍后再试 + +ILLOGICAL_OPERATION=不合理的操作,请检查 diff --git a/src/main/resources/message/message.properties b/src/main/resources/message/message.properties deleted file mode 100644 index c13aa1f..0000000 --- a/src/main/resources/message/message.properties +++ /dev/null @@ -1,68 +0,0 @@ -# UserDTO validation messages -UserDTO.id.Null=User id must be null when creating a new user -UserDTO.id.NotNull=User id cannot be null -UserDTO.username.Size=Username must be between {min} and {max} characters -UserDTO.username.NotBlank=Username cannot be blank -UserDTO.email.NotBlank=Email cannot be blank -UserDTO.email.Email=Email must be a valid email address -UserDTO.userPassword.Size=Password must be between {min} and {max} characters -UserDTO.userPassword.NotBlank=Password cannot be blank - -# UserSignInDTO validation messages -UserSignInDTO.username.NotBlank=Username cannot be blank -UserSignInDTO.userPassword.NotBlank=Password cannot be blank - -USERNAME_PATTERN_MISMATCH=Username can only be alphanumeric, hyphen or underline -PASSWORD_PATTERN_MISMATCH=Password can only be alphanumeric, underline, hyphen, dot or at sign - -USERNAME_ALREADY_EXISTS=Username already exists: {} -EMAIL_ALREADY_EXISTS=Email already exists: {} -WRONG_SIGN_IN_INFORMATION=Wrong sign in information - -INVALID_TOKEN=Invalid token: {} -TOKEN_NOT_FOUND=Token not found in header -ACCESS_DENIED=Operation without privileges - -MESSAGE_CONVERSION_ERROR=Error occurs while converting message - -USER_NOT_FOUND=User not found: {} - -USER_CREATE_FAILED=User create failed: {} -USER_UPDATE_FAILED=User update failed: {} -USER_DELETE_FAILED=User delete failed: {} - -RepositoryDTO.id.Null=Repository id must be null when creating a new repository -RepositoryDTO.id.NotNull=Repository id cannot be null -RepositoryDTO.name.Size=Repository name must be between {min} and {max} characters -RepositoryDTO.name.NotBlank=Repository name cannot be blank -RepositoryDTO.description.Size=Repository description must be between {min} and {max} characters - -REPOSITORYNAME_PATTERN_MISMATCH=Repository name can only be alphanumeric, hyphen or underline -REPOSITORY_NOT_FOUND=Repository not found: {} -REPOSITORY_ALREADY_EXISTS=Repository already exists: {} -REPOSITORY_CREATE_FAILED=Repository create failed: {} -REPOSITORY_UPDATE_FAILED=Repository update failed: {} -REPOSITORY_DELETE_FAILED=Repository delete failed: {} - -COLLABORATION_ADD_FAILED=Collaborator add failed: collaborator{}, repository{} -COLLABORATION_REMOVE_FAILED=Collaborator remove failed: collaborator{}, repository{} -COLLABORATION_ALREADY_EXISTS=Collaborator already exists: collaborator{}, repository{} -COLLABORATION_NOT_FOUND=Collaborator not found: collaborator{}, repository{} - -SshKeyDTO.id.Null=SSH key id must be null when creating a new SSH key -SshKeyDTO.id.NotNull=SSH key id cannot be null -SshKeyDTO.name.NotBlank=SSH key name cannot be blank -SshKeyDTO.name.Size=SSH key name must be between {min} and {max} characters -SshKeyDTO.publicKey.NotBlank=SSH key public key cannot be blank -SshKeyDTO.publicKey.Size=SSH key public key must be between {min} and {max} characters - -SSH_KEY_UPLOAD_FAILED=SSH key upload failed: {} -SSH_KEY_UPDATE_FAILED=SSH key update failed: {} -SSH_KEY_DELETE_FAILED=SSH key delete failed: {} -SSH_KEY_NOT_FOUND=SSH key not found: {} - -OPERATION_NOT_IMPLEMENTED=Operation not implemented: {} - -SERVER_ERROR=Internal server error, try again later - -ILLOGICAL_OPERATION=Illogical operation, please check diff --git a/src/main/resources/message/validation.properties b/src/main/resources/message/validation.properties new file mode 100644 index 0000000..297f6a0 --- /dev/null +++ b/src/main/resources/message/validation.properties @@ -0,0 +1,52 @@ +VALIDATION_ERROR=Validation error: {0} + +# userDTO validation messages +Null.userDTO.id=User ID must be null when creating a new user +NotNull.userDTO.id=User ID cannot be null +Size.userDTO.username=Username must be between {2} and {1} characters +NotBlank.userDTO.username=Username cannot be blank +NotBlank.userDTO.email=Email cannot be blank +Email.userDTO.email=Email must be a valid email address +Size.userDTO.userPassword=Password must be between {2} and {1} characters +NotBlank.userDTO.userPassword=Password cannot be blank +Pattern.userDTO.username=Username can only be alphanumeric, hyphen or underline +Pattern.userDTO.userPassword=Password can only be alphanumeric, underline, hyphen, dot or at sign + +# checkEmailValidity validation messages +Email.userController#checkEmailValidity.email=${Email.userDTO.email} +NotBlank.userController#checkEmailValidity.email=${NotBlank.userDTO.email} + +# checkUsernameValidity validation messages +NotBlank.userController#checkUsernameValidity.username=${NotBlank.userDTO.username} +Size.userController#checkUsernameValidity.username=Username must be between {min} and {max} characters +Pattern.userController#checkUsernameValidity.username=${Pattern.userDTO.username} + +# checkPasswordValidity validation messages +NotBlank.userController#checkPasswordValidity.password=${NotBlank.userDTO.userPassword} +Size.userController#checkPasswordValidity.password=Password must be between {min} and {max} characters +Pattern.userController#checkPasswordValidity.password=${Pattern.userDTO.userPassword} + +# UserSignInDTO validation messages +NotBlank.UserSignInDTO.username=Username cannot be blank +NotBlank.UserSignInDTO.userPassword=Password cannot be blank + +# RepositoryDTO validation messages +Null.RepositoryDTO.id=Repository ID must be null when creating a new repository +NotNull.RepositoryDTO.id=Repository ID cannot be null +Size.RepositoryDTO.name=Repository name must be between {2} and {1} characters +NotBlank.RepositoryDTO.name=Repository name cannot be blank +Size.RepositoryDTO.description=Repository description must be between {2} and {1} characters +Pattern.RepositoryDTO.name=Repository name can only be alphanumeric, hyphen or underline + +# checkRepositoryNameValidity validation messages +NotBlank.repositoryController#checkRepositoryNameValidity.repositoryName=${NotBlank.RepositoryDTO.name} +Size.repositoryController#checkRepositoryNameValidity.repositoryName=Repository name must be between {min} and {max} characters +Pattern.repositoryController#checkRepositoryNameValidity.repositoryName=${Pattern.RepositoryDTO.name} + +# SshKeyDTO validation messages +Null.SshKeyDTO.id=SSH key ID must be null when creating a new SSH key +NotNull.SshKeyDTO.id=SSH key ID cannot be null +NotBlank.SshKeyDTO.name=SSH key name cannot be blank +Size.SshKeyDTO.name=SSH key name must be between {2} and {1} characters +NotBlank.SshKeyDTO.publicKey=SSH key public key cannot be blank +Size.SshKeyDTO.publicKey=SSH key public key must be between {2} and {1} characters diff --git a/src/main/resources/message/validation_zh_CN.properties b/src/main/resources/message/validation_zh_CN.properties new file mode 100644 index 0000000..c6b522b --- /dev/null +++ b/src/main/resources/message/validation_zh_CN.properties @@ -0,0 +1,52 @@ +VALIDATION_ERROR=校验错误:{0} + +# userDTO validation messages +Null.userDTO.id=在创建新用户时,用户ID必须为空 +NotNulluserDTO.id=用户ID不能为空 +Size.userDTO.username=用户名必须在{2}至{1}个字符之间 +NotBlank.userDTO.username=用户名不能为空 +NotBlank.userDTO.email=电子邮件不能为空 +Email.userDTO.email=电子邮件必须是有效的电子邮件地址 +Size.userDTO.userPassword=密码必须在{2}至{1}个字符之间 +NotBlank.userDTO.userPassword=密码不能为空 +Pattern.userDTO.username=用户名只能是字母、数字、连字符或下划线 +Pattern.userDTO.userPassword=密码只能是字母、数字、下划线、连字符、点或@符号 + +# checkEmailValidity validation messages +Email.userController#checkEmailValidity.email=${Email.userDTO.email} +NotBlank.userController#checkEmailValidity.email=${NotBlank.userDTO.email} + +# checkUsernameValidity validation messages +NotBlank.userController#checkUsernameValidity.username=${NotBlank.userDTO.username} +Size.userController#checkUsernameValidity.username=用户名必须在{min}至{max}个字符之间 +Pattern.userController#checkUsernameValidity.username=${Pattern.userDTO.username} + +# checkPasswordValidity validation messages +NotBlank.userController#checkPasswordValidity.password=${NotBlank.userDTO.userPassword} +Size.userController#checkPasswordValidity.password=密码必须在{min}至{max}个字符之间 +Pattern.userController#checkPasswordValidity.password=${Pattern.userDTO.userPassword} + +# UserSignInDTO validation messages +NotBlank.UserSignInDTO.username=用户名不能为空 +NotBlank.UserSignInDTO.userPassword=密码不能为空 + +# RepositoryDTO validation messages +Null.RepositoryDTO.id=在创建新仓库时,仓库ID必须为空 +NotNull.RepositoryDTO.id=仓库ID不能为空 +Size.RepositoryDTO.name=仓库名称必须在{2}至{1}个字符之间 +NotBlank.RepositoryDTO.name=仓库名称不能为空 +Size.RepositoryDTO.description=仓库描述必须在{2}至{1}个字符之间 +Pattern.RepositoryDTO.name=仓库名称只能是字母、数字、连字符或下划线 + +# checkRepositoryNameValidity validation messages +NotBlank.repositoryController#checkRepositoryNameValidity.repositoryName=${NotBlank.RepositoryDTO.name} +Size.repositoryController#checkRepositoryNameValidity.repositoryName=仓库名称必须在{min}至{max}个字符之间 +Pattern.repositoryController#checkRepositoryNameValidity.repositoryName=${Pattern.RepositoryDTO.name} + +# SshKeyDTO validation messages +Null.SshKeyDTO.id=在创建新SSH密钥时,SSH密钥ID必须为空 +NotNull.SshKeyDTO.id=SSH密钥ID不能为空 +NotBlank.SshKeyDTO.name=SSH密钥名称不能为空 +Size.SshKeyDTO.name=SSH密钥名称必须在{2}至{1}个字符之间 +NotBlank.SshKeyDTO.publicKey=SSH密钥公钥不能为空 +Size.SshKeyDTO.publicKey=SSH密钥公钥必须在{2}至{1}个字符之间 diff --git a/src/test/java/edu/cmipt/gcs/controller/AuthenticationControllerTest.java b/src/test/java/edu/cmipt/gcs/controller/AuthenticationControllerTest.java index 71f6afc..7faa37b 100644 --- a/src/test/java/edu/cmipt/gcs/controller/AuthenticationControllerTest.java +++ b/src/test/java/edu/cmipt/gcs/controller/AuthenticationControllerTest.java @@ -219,19 +219,7 @@ public void testSignUpInvalid() throws Exception { .content(invalidUserDTO)) .andExpectAll( status().isBadRequest(), - content() - .json( - """ - { - "code": %d, - "message": "%s" - } - """ - .formatted( - ErrorCodeEnum.USERDTO_EMAIL_EMAIL.ordinal(), - MessageSourceUtil.getMessage( - ErrorCodeEnum - .USERDTO_EMAIL_EMAIL)))); + jsonPath("$.code", is(ErrorCodeEnum.VALIDATION_ERROR.ordinal()))); } @Test