feat: 密码不允许使用最近修改的密码功能
This commit is contained in:
@@ -237,6 +237,13 @@ func (s *SysProfileController) PasswordUpdate(c *gin.Context) {
|
|||||||
return
|
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.Password = body.NewPassword
|
||||||
userInfo.UpdateBy = userInfo.UserName
|
userInfo.UpdateBy = userInfo.UserName
|
||||||
@@ -296,6 +303,13 @@ func (s *SysProfileController) PasswordForce(c *gin.Context) {
|
|||||||
return
|
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.Password = body.Password
|
||||||
userInfo.UpdateBy = reqctx.LoginUserToUserName(c)
|
userInfo.UpdateBy = reqctx.LoginUserToUserName(c)
|
||||||
rows := s.sysUserService.Update(userInfo)
|
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/constants"
|
||||||
"be.ems/src/framework/i18n"
|
"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/model"
|
||||||
"be.ems/src/modules/system/repository"
|
"be.ems/src/modules/system/repository"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewSysUser 实例化服务层
|
// NewSysUser 实例化服务层
|
||||||
var NewSysUser = &SysUser{
|
var NewSysUser = &SysUser{
|
||||||
sysUserRepository: repository.NewSysUser,
|
sysUserRepository: repository.NewSysUser,
|
||||||
sysRoleRepository: repository.NewSysRole,
|
sysRoleRepository: repository.NewSysRole,
|
||||||
sysDeptRepository: repository.NewSysDept,
|
sysDeptRepository: repository.NewSysDept,
|
||||||
sysUserRoleRepository: repository.NewSysUserRole,
|
sysUserRoleRepository: repository.NewSysUserRole,
|
||||||
sysUserPostRepository: repository.NewSysUserPost,
|
sysUserPostRepository: repository.NewSysUserPost,
|
||||||
sysDictTypeService: NewSysDictType,
|
sysDictTypeService: NewSysDictType,
|
||||||
sysDictDataService: NewSysDictData,
|
sysDictDataService: NewSysDictData,
|
||||||
sysConfigService: NewSysConfig,
|
sysConfigService: NewSysConfig,
|
||||||
|
sysLogUserPasswordService: NewSysLogUserPassword,
|
||||||
}
|
}
|
||||||
|
|
||||||
// SysUser 用户 服务层处理
|
// SysUser 用户 服务层处理
|
||||||
type SysUser struct {
|
type SysUser struct {
|
||||||
sysUserRepository *repository.SysUser // 用户服务
|
sysUserRepository *repository.SysUser // 用户服务
|
||||||
sysRoleRepository *repository.SysRole // 角色服务
|
sysRoleRepository *repository.SysRole // 角色服务
|
||||||
sysDeptRepository *repository.SysDept // 部门服务
|
sysDeptRepository *repository.SysDept // 部门服务
|
||||||
sysUserRoleRepository *repository.SysUserRole // 用户与角色服务
|
sysUserRoleRepository *repository.SysUserRole // 用户与角色服务
|
||||||
sysUserPostRepository *repository.SysUserPost // 用户与岗位服务
|
sysUserPostRepository *repository.SysUserPost // 用户与岗位服务
|
||||||
sysDictTypeService *SysDictType // 字典类型服务
|
sysDictTypeService *SysDictType // 字典类型服务
|
||||||
sysDictDataService *SysDictData // 字典数据服务
|
sysDictDataService *SysDictData // 字典数据服务
|
||||||
sysConfigService *SysConfig // 参数配置服务
|
sysConfigService *SysConfig // 参数配置服务
|
||||||
|
sysLogUserPasswordService *SysLogUserPassword // 用户密码变更日志服务
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindByPage 分页查询列表数据
|
// FindByPage 分页查询列表数据
|
||||||
@@ -140,7 +144,17 @@ func (s SysUser) insertUserPost(userId int64, postIds []int64) int64 {
|
|||||||
|
|
||||||
// Update 修改信息
|
// Update 修改信息
|
||||||
func (s SysUser) Update(sysUser model.SysUser) int64 {
|
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 修改用户信息同时更新角色和岗位
|
// UpdateUserAndRolePost 修改用户信息同时更新角色和岗位
|
||||||
@@ -164,8 +178,9 @@ func (s SysUser) DeleteByIds(userIds []int64) (int64, error) {
|
|||||||
return 0, fmt.Errorf("没有权限访问用户数据!")
|
return 0, fmt.Errorf("没有权限访问用户数据!")
|
||||||
}
|
}
|
||||||
if len(users) == len(userIds) {
|
if len(users) == len(userIds) {
|
||||||
s.sysUserRoleRepository.DeleteByUserIds(userIds) // 删除用户与角色关联
|
s.sysUserRoleRepository.DeleteByUserIds(userIds) // 删除用户与角色关联
|
||||||
s.sysUserPostRepository.DeleteByUserIds(userIds) // 删除用户与岗位关联
|
s.sysUserPostRepository.DeleteByUserIds(userIds) // 删除用户与岗位关联
|
||||||
|
s.sysLogUserPasswordService.DeleteByUserId(userIds) // 删除用户密码变更日志
|
||||||
return s.sysUserRepository.DeleteByIds(userIds), nil
|
return s.sysUserRepository.DeleteByIds(userIds), nil
|
||||||
}
|
}
|
||||||
return 0, fmt.Errorf("删除用户信息失败!")
|
return 0, fmt.Errorf("删除用户信息失败!")
|
||||||
@@ -320,3 +335,28 @@ func (s SysUser) ValidatePasswordExpireTime(passwordUpdateTime int64) (bool, err
|
|||||||
}
|
}
|
||||||
return alertFlag, nil
|
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