加固后台管理安全
This commit is contained in:
@@ -3,19 +3,22 @@ package adminrole
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"hfb_sys/backend/internal/model"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
type Repository struct {
|
||||
db *gorm.DB
|
||||
db *gorm.DB
|
||||
redis *redis.Client
|
||||
}
|
||||
|
||||
func NewRepository(db *gorm.DB) *Repository {
|
||||
return &Repository{db: db}
|
||||
func NewRepository(db *gorm.DB, redis *redis.Client) *Repository {
|
||||
return &Repository{db: db, redis: redis}
|
||||
}
|
||||
|
||||
func (r *Repository) List(ctx context.Context) ([]RoleDTO, error) {
|
||||
@@ -108,15 +111,27 @@ func (r *Repository) Delete(ctx context.Context, id uint64) error {
|
||||
if role.Code == "super_admin" {
|
||||
return ErrProtectedRole
|
||||
}
|
||||
return db.Transaction(func(tx *gorm.DB) error {
|
||||
adminIDs, err := r.adminIDsByRole(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = db.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Where("role_id = ?", id).Delete(&model.RolePermission{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("role_id = ?", id).Delete(&model.AdminUserRole{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Delete(&model.Role{}, id).Error
|
||||
if err := tx.Delete(&model.Role{}, id).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return r.bumpAdminTokenVersions(tx, adminIDs)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.invalidateAdminPermCaches(ctx, adminIDs)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Repository) AssignPermissions(ctx context.Context, roleID uint64, permIDs []uint64) error {
|
||||
@@ -125,7 +140,11 @@ func (r *Repository) AssignPermissions(ctx context.Context, roleID uint64, permI
|
||||
if err := db.First(&role, roleID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return db.Transaction(func(tx *gorm.DB) error {
|
||||
adminIDs, err := r.adminIDsByRole(ctx, roleID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = db.Transaction(func(tx *gorm.DB) error {
|
||||
if role.Code == "super_admin" {
|
||||
var allPermIDs []uint64
|
||||
if err := tx.Model(&model.Permission{}).Pluck("id", &allPermIDs).Error; err != nil {
|
||||
@@ -142,8 +161,13 @@ func (r *Repository) AssignPermissions(ctx context.Context, roleID uint64, permI
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return r.bumpAdminTokenVersions(tx, adminIDs)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.invalidateAdminPermCaches(ctx, adminIDs)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Repository) ListPermissions(ctx context.Context) ([]PermissionDTO, error) {
|
||||
@@ -186,6 +210,34 @@ func (r *Repository) getRolePermissions(ctx context.Context, roleID uint64) ([]P
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (r *Repository) adminIDsByRole(ctx context.Context, roleID uint64) ([]uint64, error) {
|
||||
var ids []uint64
|
||||
err := r.db.WithContext(ctx).Model(&model.AdminUserRole{}).
|
||||
Where("role_id = ?", roleID).
|
||||
Pluck("admin_user_id", &ids).Error
|
||||
return ids, err
|
||||
}
|
||||
|
||||
func (r *Repository) bumpAdminTokenVersions(tx *gorm.DB, adminIDs []uint64) error {
|
||||
if len(adminIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
return tx.Model(&model.AdminUser{}).
|
||||
Where("id IN ?", adminIDs).
|
||||
UpdateColumn("token_version", gorm.Expr("token_version + 1")).Error
|
||||
}
|
||||
|
||||
func (r *Repository) invalidateAdminPermCaches(ctx context.Context, adminIDs []uint64) {
|
||||
if r.redis == nil || len(adminIDs) == 0 {
|
||||
return
|
||||
}
|
||||
keys := make([]string, 0, len(adminIDs))
|
||||
for _, id := range adminIDs {
|
||||
keys = append(keys, fmt.Sprintf("admin:perms:%d", id))
|
||||
}
|
||||
_ = r.redis.Del(ctx, keys...).Err()
|
||||
}
|
||||
|
||||
var ErrProtectedRole = errors.New("protected role")
|
||||
|
||||
func IsNotFound(err error) bool {
|
||||
|
||||
Reference in New Issue
Block a user