加固后台管理安全
This commit is contained in:
@@ -76,10 +76,12 @@ func (r *Repository) Create(ctx context.Context, req CreateAdminRequest) (*Admin
|
||||
return nil, err
|
||||
}
|
||||
admin := model.AdminUser{
|
||||
Username: req.Username,
|
||||
PasswordHash: string(hash),
|
||||
Nickname: req.Nickname,
|
||||
Status: "active",
|
||||
Username: req.Username,
|
||||
PasswordHash: string(hash),
|
||||
Nickname: req.Nickname,
|
||||
Status: "active",
|
||||
TokenVersion: 1,
|
||||
PasswordMustChange: true,
|
||||
}
|
||||
if err := r.db.WithContext(ctx).Create(&admin).Error; err != nil {
|
||||
return nil, err
|
||||
@@ -102,6 +104,12 @@ func (r *Repository) Update(ctx context.Context, id uint64, req UpdateAdminReque
|
||||
if err := db.Save(&admin).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if req.Status != "" {
|
||||
if err := r.bumpTokenVersion(db, id); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r.invalidatePermCache(ctx, id)
|
||||
}
|
||||
return r.FindByID(ctx, id)
|
||||
}
|
||||
|
||||
@@ -150,7 +158,7 @@ func (r *Repository) AssignRoles(ctx context.Context, adminID uint64, roleIDs []
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return r.bumpTokenVersion(tx, adminID)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -159,7 +167,7 @@ func (r *Repository) AssignRoles(ctx context.Context, adminID uint64, roleIDs []
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Repository) ChangePassword(ctx context.Context, id uint64, oldPwd, newPwd string) error {
|
||||
func (r *Repository) ChangeOwnPassword(ctx context.Context, id uint64, oldPwd, newPwd string) error {
|
||||
var admin model.AdminUser
|
||||
if err := r.db.WithContext(ctx).First(&admin, id).Error; err != nil {
|
||||
return err
|
||||
@@ -171,7 +179,35 @@ func (r *Repository) ChangePassword(ctx context.Context, id uint64, oldPwd, newP
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return r.db.WithContext(ctx).Model(&admin).Update("password_hash", string(hash)).Error
|
||||
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Model(&admin).Updates(map[string]any{
|
||||
"password_hash": string(hash),
|
||||
"password_must_change": false,
|
||||
}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return r.bumpTokenVersion(tx, id)
|
||||
})
|
||||
}
|
||||
|
||||
func (r *Repository) ResetPassword(ctx context.Context, id uint64, newPwd string) error {
|
||||
var admin model.AdminUser
|
||||
if err := r.db.WithContext(ctx).First(&admin, id).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(newPwd), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Model(&admin).Updates(map[string]any{
|
||||
"password_hash": string(hash),
|
||||
"password_must_change": true,
|
||||
}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return r.bumpTokenVersion(tx, id)
|
||||
})
|
||||
}
|
||||
|
||||
func (r *Repository) GetPermissionCodes(ctx context.Context, adminID uint64) ([]string, error) {
|
||||
@@ -223,6 +259,12 @@ func (r *Repository) invalidatePermCache(ctx context.Context, adminID uint64) {
|
||||
r.redis.Del(ctx, permCacheKey(adminID))
|
||||
}
|
||||
|
||||
func (r *Repository) bumpTokenVersion(db *gorm.DB, adminID uint64) error {
|
||||
return db.Model(&model.AdminUser{}).
|
||||
Where("id = ?", adminID).
|
||||
UpdateColumn("token_version", gorm.Expr("token_version + 1")).Error
|
||||
}
|
||||
|
||||
func permCacheKey(adminID uint64) string {
|
||||
return fmt.Sprintf("admin:perms:%d", adminID)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user