Add user chang password api

This commit is contained in:
2024-02-22 18:21:36 +08:00
parent 874235ed05
commit 5ea9203a08
11 changed files with 91 additions and 11 deletions

View File

@@ -51,6 +51,20 @@ class UserController(
if (userService.updateInfo(userInfoUpdateParam)) ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS) if (userService.updateInfo(userInfoUpdateParam)) ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS)
else ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_FAILED) 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<Nothing> {
userService.password(userChangePasswordParam)
return ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS)
}
/** /**
* Get user by ID * Get user by ID
* *

View File

@@ -45,6 +45,6 @@ data class RegisterParam(
*/ */
@Schema(description = "密码", required = true) @Schema(description = "密码", required = true)
@field:NotBlank(message = "Password can not be blank") @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? val password: String?
) : CaptchaCodeParam() ) : CaptchaCodeParam()

View File

@@ -11,7 +11,7 @@ import java.time.LocalDateTime
* @author FatttSnake, fatttsnake@gmail.com * @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0 * @since 1.0.0
*/ */
@Schema(description = "用户添加请求参数") @Schema(description = "添加用户请求参数")
data class UserAddParam( data class UserAddParam(
/** /**
* Username * Username

View File

@@ -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?
)

View File

@@ -9,7 +9,7 @@ import jakarta.validation.constraints.NotEmpty
* @author FatttSnake, fatttsnake@gmail.com * @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0 * @since 1.0.0
*/ */
@Schema(description = "用户删除请求参数") @Schema(description = "删除用户请求参数")
data class UserDeleteParam( data class UserDeleteParam(
/** /**
* List of user IDs * List of user IDs

View File

@@ -10,7 +10,7 @@ import top.fatweb.oxygen.api.param.PageSortParam
* @since 1.0.0 * @since 1.0.0
* @see PageSortParam * @see PageSortParam
*/ */
@Schema(description = "用户查询请求参数") @Schema(description = "查询用户请求参数")
data class UserGetParam( data class UserGetParam(
/** /**
* Type of search * Type of search

View File

@@ -1,7 +1,8 @@
package top.fatweb.oxygen.api.param.permission.user package top.fatweb.oxygen.api.param.permission.user
import io.swagger.v3.oas.annotations.media.Schema 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 * Update user information parameters
@@ -9,7 +10,7 @@ import jakarta.validation.constraints.Pattern
* @author FatttSnake, fatttsnake@gmail.com * @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0 * @since 1.0.0
*/ */
@Schema(description = "用户信息更新请求参数") @Schema(description = "更新用户信息请求参数")
data class UserInfoUpdateParam( data class UserInfoUpdateParam(
/** /**
* Avatar base64 * Avatar base64
@@ -27,6 +28,7 @@ data class UserInfoUpdateParam(
* @since 1.0.0 * @since 1.0.0
*/ */
@Schema(description = "昵称", example = "QwQ") @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? val nickname: String?
) )

View File

@@ -12,7 +12,7 @@ import java.time.LocalDateTime
* @author FatttSnake, fatttsnake@gmail.com * @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0 * @since 1.0.0
*/ */
@Schema(description = "用户更新请求参数") @Schema(description = "更新用户请求参数")
data class UserUpdateParam( data class UserUpdateParam(
/** /**
* ID * ID

View File

@@ -11,7 +11,7 @@ import java.time.LocalDateTime
* @author FatttSnake, fatttsnake@gmail.com * @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0 * @since 1.0.0
*/ */
@Schema(description = "用户更改密码请求参数") @Schema(description = "更改用户密码请求参数")
data class UserUpdatePasswordParam( data class UserUpdatePasswordParam(
/** /**
* ID * ID

View File

@@ -47,6 +47,14 @@ interface IUserService : IService<User> {
*/ */
fun updateInfo(userInfoUpdateParam: UserInfoUpdateParam): Boolean 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 * Get one user by ID
* *

View File

@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.kotlin.KtUpdateWrapper
import com.baomidou.mybatisplus.extension.plugins.pagination.Page import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
import org.springframework.security.access.AccessDeniedException import org.springframework.security.access.AccessDeniedException
import org.springframework.security.authentication.BadCredentialsException
import org.springframework.security.crypto.password.PasswordEncoder import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional import org.springframework.transaction.annotation.Transactional
@@ -85,7 +86,7 @@ class UserServiceImpl(
?: throw UserNotFoundException() ?: throw UserNotFoundException()
override fun updateInfo(userInfoUpdateParam: UserInfoUpdateParam): Boolean { override fun updateInfo(userInfoUpdateParam: UserInfoUpdateParam): Boolean {
val userId = WebUtil.getLoginUserId() ?: throw UserNotFoundException() val userId = WebUtil.getLoginUserId() ?: throw AccessDeniedException("Access denied")
return userInfoService.update( return userInfoService.update(
KtUpdateWrapper(UserInfo()).eq(UserInfo::userId, userId) KtUpdateWrapper(UserInfo()).eq(UserInfo::userId, userId)
.set(UserInfo::avatar, userInfoUpdateParam.avatar) .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 = override fun getOne(id: Long): UserWithRoleInfoVo =
baseMapper.selectOneWithRoleInfoById(id)?.let(UserConverter::userToUserWithRoleInfoVo) baseMapper.selectOneWithRoleInfoById(id)?.let(UserConverter::userToUserWithRoleInfoVo)
?: throw UserNotFoundException() ?: throw UserNotFoundException()
@@ -256,7 +277,7 @@ class UserServiceImpl(
val user = this.getById(userUpdatePasswordParam.id) val user = this.getById(userUpdatePasswordParam.id)
user?.let { user?.let {
val wrapper = KtUpdateWrapper(User()) val wrapper = KtUpdateWrapper(User())
wrapper.eq(User::id, user.id) .eq(User::id, user.id)
.set(User::password, passwordEncoder.encode(userUpdatePasswordParam.password)) .set(User::password, passwordEncoder.encode(userUpdatePasswordParam.password))
.set( .set(
User::credentialsExpiration, User::credentialsExpiration,