diff --git a/src/main/kotlin/top/fatweb/oxygen/api/controller/permission/UserController.kt b/src/main/kotlin/top/fatweb/oxygen/api/controller/permission/UserController.kt index c644e71..a332fec 100644 --- a/src/main/kotlin/top/fatweb/oxygen/api/controller/permission/UserController.kt +++ b/src/main/kotlin/top/fatweb/oxygen/api/controller/permission/UserController.kt @@ -51,6 +51,20 @@ class UserController( if (userService.updateInfo(userInfoUpdateParam)) ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS) else ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_FAILED) + /** + * Change password + * + * @author FatttSnake, fatttsnake@gmail.com + * @since 1.0.0 + */ + @Operation(summary = "更改密码") + @PostMapping("info") + fun password(@RequestBody @Valid userChangePasswordParam: UserChangePasswordParam): ResponseResult { + userService.password(userChangePasswordParam) + + return ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS) + } + /** * Get user by ID * diff --git a/src/main/kotlin/top/fatweb/oxygen/api/param/permission/RegisterParam.kt b/src/main/kotlin/top/fatweb/oxygen/api/param/permission/RegisterParam.kt index 88f017a..7b26d33 100644 --- a/src/main/kotlin/top/fatweb/oxygen/api/param/permission/RegisterParam.kt +++ b/src/main/kotlin/top/fatweb/oxygen/api/param/permission/RegisterParam.kt @@ -45,6 +45,6 @@ data class RegisterParam( */ @Schema(description = "密码", required = true) @field:NotBlank(message = "Password can not be blank") - @field:Size(min = 10, max = 30) + @field:Size(min = 10, max = 30, message = "Password must be 10-20 characters") val password: String? ) : CaptchaCodeParam() \ No newline at end of file diff --git a/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserAddParam.kt b/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserAddParam.kt index 52b941a..ae817a8 100644 --- a/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserAddParam.kt +++ b/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserAddParam.kt @@ -11,7 +11,7 @@ import java.time.LocalDateTime * @author FatttSnake, fatttsnake@gmail.com * @since 1.0.0 */ -@Schema(description = "用户添加请求参数") +@Schema(description = "添加用户请求参数") data class UserAddParam( /** * Username diff --git a/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserChangePasswordParam.kt b/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserChangePasswordParam.kt new file mode 100644 index 0000000..7e704e6 --- /dev/null +++ b/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserChangePasswordParam.kt @@ -0,0 +1,35 @@ +package top.fatweb.oxygen.api.param.permission.user + +import io.swagger.v3.oas.annotations.media.Schema +import jakarta.validation.constraints.NotBlank +import jakarta.validation.constraints.Size + +/** + * Change password of user parameters + * + * @author FatttSnake, fatttsnake@gmail.com + * @since 1.0.0 + */ +@Schema(description = "用户更改密码请求参数") +data class UserChangePasswordParam( + /** + * Original password + * + * @author FatttSnake, fatttsnake@gmail.com + * @since 1.0.0 + */ + @Schema(description = "原密码", required = true) + @field:NotBlank(message = "Original password can not be blank") + val originalPassword: String?, + + /** + * New password + * + * @author FatttSnake, fatttsnake@gmail.com + * @since 1.0.0 + */ + @Schema(description = "原密码", required = true) + @field:NotBlank(message = "New password can not be blank") + @field:Size(min = 10, max = 30, message = "New password must be 10-20 characters") + val newPassword: String? +) diff --git a/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserDeleteParam.kt b/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserDeleteParam.kt index 0a61709..714a096 100644 --- a/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserDeleteParam.kt +++ b/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserDeleteParam.kt @@ -9,7 +9,7 @@ import jakarta.validation.constraints.NotEmpty * @author FatttSnake, fatttsnake@gmail.com * @since 1.0.0 */ -@Schema(description = "用户删除请求参数") +@Schema(description = "删除用户请求参数") data class UserDeleteParam( /** * List of user IDs diff --git a/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserGetParam.kt b/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserGetParam.kt index 93c4fa0..c8a68ec 100644 --- a/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserGetParam.kt +++ b/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserGetParam.kt @@ -10,7 +10,7 @@ import top.fatweb.oxygen.api.param.PageSortParam * @since 1.0.0 * @see PageSortParam */ -@Schema(description = "用户查询请求参数") +@Schema(description = "查询用户请求参数") data class UserGetParam( /** * Type of search diff --git a/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserInfoUpdateParam.kt b/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserInfoUpdateParam.kt index 8a303dc..92529ed 100644 --- a/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserInfoUpdateParam.kt +++ b/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserInfoUpdateParam.kt @@ -1,7 +1,8 @@ package top.fatweb.oxygen.api.param.permission.user import io.swagger.v3.oas.annotations.media.Schema -import jakarta.validation.constraints.Pattern +import jakarta.validation.constraints.NotBlank +import jakarta.validation.constraints.Size /** * Update user information parameters @@ -9,7 +10,7 @@ import jakarta.validation.constraints.Pattern * @author FatttSnake, fatttsnake@gmail.com * @since 1.0.0 */ -@Schema(description = "用户信息更新请求参数") +@Schema(description = "更新用户信息请求参数") data class UserInfoUpdateParam( /** * Avatar base64 @@ -27,6 +28,7 @@ data class UserInfoUpdateParam( * @since 1.0.0 */ @Schema(description = "昵称", example = "QwQ") - @field:Pattern(regexp = "^.{3,20}$", message = "Nickname must be 3-20 characters") + @field:NotBlank(message = "Nickname can not be blank") + @field:Size(min = 3, max = 30, message = "Nickname must be 3-20 characters") val nickname: String? ) diff --git a/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserUpdateParam.kt b/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserUpdateParam.kt index fb7298b..b8830a6 100644 --- a/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserUpdateParam.kt +++ b/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserUpdateParam.kt @@ -12,7 +12,7 @@ import java.time.LocalDateTime * @author FatttSnake, fatttsnake@gmail.com * @since 1.0.0 */ -@Schema(description = "用户更新请求参数") +@Schema(description = "更新用户请求参数") data class UserUpdateParam( /** * ID diff --git a/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserUpdatePasswordParam.kt b/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserUpdatePasswordParam.kt index 76e8413..3801ecd 100644 --- a/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserUpdatePasswordParam.kt +++ b/src/main/kotlin/top/fatweb/oxygen/api/param/permission/user/UserUpdatePasswordParam.kt @@ -11,7 +11,7 @@ import java.time.LocalDateTime * @author FatttSnake, fatttsnake@gmail.com * @since 1.0.0 */ -@Schema(description = "用户更改密码请求参数") +@Schema(description = "更改用户密码请求参数") data class UserUpdatePasswordParam( /** * ID diff --git a/src/main/kotlin/top/fatweb/oxygen/api/service/permission/IUserService.kt b/src/main/kotlin/top/fatweb/oxygen/api/service/permission/IUserService.kt index 7fb4d8e..ff456b6 100644 --- a/src/main/kotlin/top/fatweb/oxygen/api/service/permission/IUserService.kt +++ b/src/main/kotlin/top/fatweb/oxygen/api/service/permission/IUserService.kt @@ -47,6 +47,14 @@ interface IUserService : IService { */ fun updateInfo(userInfoUpdateParam: UserInfoUpdateParam): Boolean + /** + * Change password + * + * @author FatttSnake, fatttsnake@gmail.com + * @since 1.0.0 + */ + fun password(userChangePasswordParam: UserChangePasswordParam) + /** * Get one user by ID * diff --git a/src/main/kotlin/top/fatweb/oxygen/api/service/permission/impl/UserServiceImpl.kt b/src/main/kotlin/top/fatweb/oxygen/api/service/permission/impl/UserServiceImpl.kt index f1e12d9..270d933 100644 --- a/src/main/kotlin/top/fatweb/oxygen/api/service/permission/impl/UserServiceImpl.kt +++ b/src/main/kotlin/top/fatweb/oxygen/api/service/permission/impl/UserServiceImpl.kt @@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.kotlin.KtUpdateWrapper import com.baomidou.mybatisplus.extension.plugins.pagination.Page import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl import org.springframework.security.access.AccessDeniedException +import org.springframework.security.authentication.BadCredentialsException import org.springframework.security.crypto.password.PasswordEncoder import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @@ -85,7 +86,7 @@ class UserServiceImpl( ?: throw UserNotFoundException() override fun updateInfo(userInfoUpdateParam: UserInfoUpdateParam): Boolean { - val userId = WebUtil.getLoginUserId() ?: throw UserNotFoundException() + val userId = WebUtil.getLoginUserId() ?: throw AccessDeniedException("Access denied") return userInfoService.update( KtUpdateWrapper(UserInfo()).eq(UserInfo::userId, userId) .set(UserInfo::avatar, userInfoUpdateParam.avatar) @@ -93,6 +94,26 @@ class UserServiceImpl( ) } + override fun password(userChangePasswordParam: UserChangePasswordParam) { + val user = this.getById(WebUtil.getLoginUserId() ?: throw AccessDeniedException("Access denied")) + user?.let { + if (!passwordEncoder.matches(userChangePasswordParam.originalPassword, user.password)) { + throw BadCredentialsException("Passwords do not match") + } + val wrapper = KtUpdateWrapper(User()) + .eq(User::id, user.id) + .set(User::password, passwordEncoder.encode(userChangePasswordParam.newPassword)) + .set(User::credentialsExpiration, null) + .set(User::updateTime, LocalDateTime.now(ZoneOffset.UTC)) + + if (!this.update(wrapper)) { + throw DatabaseUpdateException() + } + + WebUtil.offlineUser(redisUtil, user.id!!) + } ?: throw NoRecordFoundException() + } + override fun getOne(id: Long): UserWithRoleInfoVo = baseMapper.selectOneWithRoleInfoById(id)?.let(UserConverter::userToUserWithRoleInfoVo) ?: throw UserNotFoundException() @@ -256,7 +277,7 @@ class UserServiceImpl( val user = this.getById(userUpdatePasswordParam.id) user?.let { val wrapper = KtUpdateWrapper(User()) - wrapper.eq(User::id, user.id) + .eq(User::id, user.id) .set(User::password, passwordEncoder.encode(userUpdatePasswordParam.password)) .set( User::credentialsExpiration,