feat: 密码不允许使用最近修改的密码功能
This commit is contained in:
@@ -237,6 +237,13 @@ func (s *SysProfileController) PasswordUpdate(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 检查密码是否与历史密码一致
|
||||
err = s.sysUserService.ValidatePasswordNotAllowedHistory(userInfo.UserId, body.NewPassword)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
|
||||
// 修改新密码
|
||||
userInfo.Password = body.NewPassword
|
||||
userInfo.UpdateBy = userInfo.UserName
|
||||
@@ -296,6 +303,13 @@ func (s *SysProfileController) PasswordForce(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 检查密码是否与历史密码一致
|
||||
err = s.sysUserService.ValidatePasswordNotAllowedHistory(userInfo.UserId, body.Password)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
|
||||
userInfo.Password = body.Password
|
||||
userInfo.UpdateBy = reqctx.LoginUserToUserName(c)
|
||||
rows := s.sysUserService.Update(userInfo)
|
||||
|
||||
16
src/modules/system/model/sys_log_user_password.go
Normal file
16
src/modules/system/model/sys_log_user_password.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package model
|
||||
|
||||
// SysLogUserPassword 系统_用户密码变更日志表
|
||||
type SysLogUserPassword struct {
|
||||
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // ID
|
||||
UserId int64 `json:"userId" gorm:"column:user_id"` // 用户ID
|
||||
UserName string `json:"userName" gorm:"column:user_name"` // 用户账号
|
||||
Password string `json:"password" gorm:"column:password"` // 密码
|
||||
CreateBy string `json:"createBy" gorm:"column:create_by"` // 创建者
|
||||
CreateTime int64 `json:"createTime" gorm:"column:create_time"` // 创建时间
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*SysLogUserPassword) TableName() string {
|
||||
return "sys_log_user_password"
|
||||
}
|
||||
79
src/modules/system/repository/sys_log_user_password.go
Normal file
79
src/modules/system/repository/sys_log_user_password.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/system/model"
|
||||
)
|
||||
|
||||
// NewSysLogUserPassword 实例化数据层
|
||||
var NewSysLogUserPassword = &SysLogUserPassword{}
|
||||
|
||||
// SysLogUserPasswordRepository 系统_用户密码变更日志表 数据层处理
|
||||
type SysLogUserPassword struct{}
|
||||
|
||||
// SelectByUserId 通过用户ID日志 pageNum为0返回日志列表
|
||||
func (r SysLogUserPassword) SelectByUserId(userId int64, pageNum int) []model.SysLogUserPassword {
|
||||
rows := []model.SysLogUserPassword{}
|
||||
if userId <= 0 {
|
||||
return rows
|
||||
}
|
||||
tx := db.DB("").Model(&model.SysLogUserPassword{})
|
||||
// 构建查询条件
|
||||
tx = tx.Where("user_id = ?", userId)
|
||||
// 查询数据分页
|
||||
if pageNum > 0 {
|
||||
tx = tx.Limit(pageNum)
|
||||
}
|
||||
err := tx.Order("create_time desc").Find(&rows).Error
|
||||
if err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// SelectCountByUserId 通过用户ID日志数量
|
||||
func (r SysLogUserPassword) SelectCountByUserId(userId int64) int64 {
|
||||
var total int64 = 0
|
||||
if userId <= 0 {
|
||||
return total
|
||||
}
|
||||
tx := db.DB("").Model(&model.SysLogUserPassword{})
|
||||
// 构建查询条件
|
||||
tx = tx.Where("user_id = ?", userId)
|
||||
// 查询数量为0直接返回
|
||||
if err := tx.Count(&total).Error; err != nil || total <= 0 {
|
||||
return total
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
// Insert 新增信息 返回新增的数据ID
|
||||
func (r SysLogUserPassword) Insert(param model.SysLogUserPassword) int64 {
|
||||
if param.CreateBy != "" {
|
||||
param.CreateTime = time.Now().UnixMilli()
|
||||
}
|
||||
// 执行插入
|
||||
if err := db.DB("").Create(¶m).Error; err != nil {
|
||||
logger.Errorf("insert err => %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return param.ID
|
||||
}
|
||||
|
||||
// DeleteByUserId 删除用户日志信息 返回受影响行数
|
||||
func (r SysLogUserPassword) DeleteByUserId(userIds []int64) int64 {
|
||||
if len(userIds) <= 0 {
|
||||
return 0
|
||||
}
|
||||
tx := db.DB("").Where("user_id in ?", userIds)
|
||||
// 执行删除
|
||||
if err := tx.Delete(&model.SysLogUserPassword{}).Error; err != nil {
|
||||
logger.Errorf("delete err => %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
26
src/modules/system/service/sys_log_user_password.go
Normal file
26
src/modules/system/service/sys_log_user_password.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"be.ems/src/modules/system/model"
|
||||
"be.ems/src/modules/system/repository"
|
||||
)
|
||||
|
||||
// NewSysLogUserPassword 实例化服务层
|
||||
var NewSysLogUserPassword = &SysLogUserPassword{
|
||||
sysLogUserPasswordRepository: repository.NewSysLogUserPassword,
|
||||
}
|
||||
|
||||
// SysLogUserPassword 用户密码变更日志 服务层处理
|
||||
type SysLogUserPassword struct {
|
||||
sysLogUserPasswordRepository *repository.SysLogUserPassword // 用户密码变更日志表日志信息
|
||||
}
|
||||
|
||||
// Insert 新增信息
|
||||
func (s SysLogUserPassword) Insert(param model.SysLogUserPassword) int64 {
|
||||
return s.sysLogUserPasswordRepository.Insert(param)
|
||||
}
|
||||
|
||||
// Delete 删除信息
|
||||
func (s SysLogUserPassword) DeleteByUserId(userIds []int64) int64 {
|
||||
return s.sysLogUserPasswordRepository.DeleteByUserId(userIds)
|
||||
}
|
||||
@@ -8,32 +8,36 @@ import (
|
||||
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/utils/crypto"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/system/model"
|
||||
"be.ems/src/modules/system/repository"
|
||||
)
|
||||
|
||||
// NewSysUser 实例化服务层
|
||||
var NewSysUser = &SysUser{
|
||||
sysUserRepository: repository.NewSysUser,
|
||||
sysRoleRepository: repository.NewSysRole,
|
||||
sysDeptRepository: repository.NewSysDept,
|
||||
sysUserRoleRepository: repository.NewSysUserRole,
|
||||
sysUserPostRepository: repository.NewSysUserPost,
|
||||
sysDictTypeService: NewSysDictType,
|
||||
sysDictDataService: NewSysDictData,
|
||||
sysConfigService: NewSysConfig,
|
||||
sysUserRepository: repository.NewSysUser,
|
||||
sysRoleRepository: repository.NewSysRole,
|
||||
sysDeptRepository: repository.NewSysDept,
|
||||
sysUserRoleRepository: repository.NewSysUserRole,
|
||||
sysUserPostRepository: repository.NewSysUserPost,
|
||||
sysDictTypeService: NewSysDictType,
|
||||
sysDictDataService: NewSysDictData,
|
||||
sysConfigService: NewSysConfig,
|
||||
sysLogUserPasswordService: NewSysLogUserPassword,
|
||||
}
|
||||
|
||||
// SysUser 用户 服务层处理
|
||||
type SysUser struct {
|
||||
sysUserRepository *repository.SysUser // 用户服务
|
||||
sysRoleRepository *repository.SysRole // 角色服务
|
||||
sysDeptRepository *repository.SysDept // 部门服务
|
||||
sysUserRoleRepository *repository.SysUserRole // 用户与角色服务
|
||||
sysUserPostRepository *repository.SysUserPost // 用户与岗位服务
|
||||
sysDictTypeService *SysDictType // 字典类型服务
|
||||
sysDictDataService *SysDictData // 字典数据服务
|
||||
sysConfigService *SysConfig // 参数配置服务
|
||||
sysUserRepository *repository.SysUser // 用户服务
|
||||
sysRoleRepository *repository.SysRole // 角色服务
|
||||
sysDeptRepository *repository.SysDept // 部门服务
|
||||
sysUserRoleRepository *repository.SysUserRole // 用户与角色服务
|
||||
sysUserPostRepository *repository.SysUserPost // 用户与岗位服务
|
||||
sysDictTypeService *SysDictType // 字典类型服务
|
||||
sysDictDataService *SysDictData // 字典数据服务
|
||||
sysConfigService *SysConfig // 参数配置服务
|
||||
sysLogUserPasswordService *SysLogUserPassword // 用户密码变更日志服务
|
||||
}
|
||||
|
||||
// FindByPage 分页查询列表数据
|
||||
@@ -140,7 +144,17 @@ func (s SysUser) insertUserPost(userId int64, postIds []int64) int64 {
|
||||
|
||||
// Update 修改信息
|
||||
func (s SysUser) Update(sysUser model.SysUser) int64 {
|
||||
return s.sysUserRepository.Update(sysUser)
|
||||
rows := s.sysUserRepository.Update(sysUser)
|
||||
// 记录密码变更日志
|
||||
if rows > 0 && sysUser.Password != "" {
|
||||
s.sysLogUserPasswordService.Insert(model.SysLogUserPassword{
|
||||
UserId: sysUser.UserId,
|
||||
UserName: sysUser.UserName,
|
||||
Password: crypto.BcryptHash(sysUser.Password),
|
||||
CreateBy: sysUser.UpdateBy,
|
||||
})
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// UpdateUserAndRolePost 修改用户信息同时更新角色和岗位
|
||||
@@ -164,8 +178,9 @@ func (s SysUser) DeleteByIds(userIds []int64) (int64, error) {
|
||||
return 0, fmt.Errorf("没有权限访问用户数据!")
|
||||
}
|
||||
if len(users) == len(userIds) {
|
||||
s.sysUserRoleRepository.DeleteByUserIds(userIds) // 删除用户与角色关联
|
||||
s.sysUserPostRepository.DeleteByUserIds(userIds) // 删除用户与岗位关联
|
||||
s.sysUserRoleRepository.DeleteByUserIds(userIds) // 删除用户与角色关联
|
||||
s.sysUserPostRepository.DeleteByUserIds(userIds) // 删除用户与岗位关联
|
||||
s.sysLogUserPasswordService.DeleteByUserId(userIds) // 删除用户密码变更日志
|
||||
return s.sysUserRepository.DeleteByIds(userIds), nil
|
||||
}
|
||||
return 0, fmt.Errorf("删除用户信息失败!")
|
||||
@@ -320,3 +335,28 @@ func (s SysUser) ValidatePasswordExpireTime(passwordUpdateTime int64) (bool, err
|
||||
}
|
||||
return alertFlag, nil
|
||||
}
|
||||
|
||||
// ValidatePasswordNotAllowedHistory 密码不允许使用最近修改的
|
||||
func (s SysUser) ValidatePasswordNotAllowedHistory(userId int64, password string) error {
|
||||
passwdNotAllowedHistoryStr := s.sysConfigService.FindValueByKey("sys.user.passwdNotAllowedHistory")
|
||||
if passwdNotAllowedHistoryStr == "" {
|
||||
return nil
|
||||
}
|
||||
passwdNotAllowedHistory := parse.Number(passwdNotAllowedHistoryStr)
|
||||
if passwdNotAllowedHistory <= 0 {
|
||||
return nil
|
||||
}
|
||||
// 查询密码历史记录
|
||||
rows := s.sysLogUserPasswordService.sysLogUserPasswordRepository.SelectByUserId(userId, int(passwdNotAllowedHistory))
|
||||
if len(rows) <= 0 {
|
||||
return nil
|
||||
}
|
||||
// 检查密码是否在历史记录中
|
||||
for _, v := range rows {
|
||||
compare := crypto.BcryptCompare(password, v.Password)
|
||||
if compare {
|
||||
return fmt.Errorf("login.errPasswdHistory")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user