121 lines
3.1 KiB
Go
121 lines
3.1 KiB
Go
package system
|
|
|
|
import (
|
|
"errors"
|
|
"strconv"
|
|
|
|
"kra/internal/biz/system"
|
|
|
|
"github.com/casbin/casbin/v2"
|
|
gormadapter "github.com/casbin/gorm-adapter/v3"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type casbinRepo struct {
|
|
db *gorm.DB
|
|
enforcer *casbin.SyncedCachedEnforcer
|
|
}
|
|
|
|
// NewCasbinRepo 创建Casbin仓储
|
|
func NewCasbinRepo(db *gorm.DB, enforcer *casbin.SyncedCachedEnforcer) system.CasbinRepo {
|
|
return &casbinRepo{db: db, enforcer: enforcer}
|
|
}
|
|
|
|
// ClearCasbin 清除匹配的权限
|
|
func (r *casbinRepo) ClearCasbin(v int, p ...string) bool {
|
|
success, _ := r.enforcer.RemoveFilteredPolicy(v, p...)
|
|
return success
|
|
}
|
|
|
|
// UpdateCasbinApi API更新随动
|
|
func (r *casbinRepo) UpdateCasbinApi(oldPath, newPath, oldMethod, newMethod string) error {
|
|
err := r.db.Model(&gormadapter.CasbinRule{}).
|
|
Where("v1 = ? AND v2 = ?", oldPath, oldMethod).
|
|
Updates(map[string]any{"v1": newPath, "v2": newMethod}).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return r.enforcer.LoadPolicy()
|
|
}
|
|
|
|
// GetPolicyPathByAuthorityId 获取权限列表
|
|
func (r *casbinRepo) GetPolicyPathByAuthorityId(authorityId uint) []system.CasbinRule {
|
|
authorityIdStr := strconv.FormatUint(uint64(authorityId), 10)
|
|
list, _ := r.enforcer.GetFilteredPolicy(0, authorityIdStr)
|
|
pathMaps := make([]system.CasbinRule, len(list))
|
|
for i, v := range list {
|
|
pathMaps[i] = system.CasbinRule{
|
|
Path: v[1],
|
|
Method: v[2],
|
|
}
|
|
}
|
|
return pathMaps
|
|
}
|
|
|
|
// FreshCasbin 刷新Casbin缓存
|
|
func (r *casbinRepo) FreshCasbin() error {
|
|
return r.enforcer.LoadPolicy()
|
|
}
|
|
|
|
// AddPolicies 添加策略(使用数据库方法)
|
|
func (r *casbinRepo) AddPolicies(rules [][]string) error {
|
|
if len(rules) == 0 {
|
|
return nil
|
|
}
|
|
casbinRules := make([]gormadapter.CasbinRule, len(rules))
|
|
for i, rule := range rules {
|
|
casbinRules[i] = gormadapter.CasbinRule{
|
|
Ptype: "p",
|
|
V0: rule[0],
|
|
V1: rule[1],
|
|
V2: rule[2],
|
|
}
|
|
}
|
|
return r.db.Create(&casbinRules).Error
|
|
}
|
|
|
|
// UpdateCasbin 更新Casbin权限
|
|
func (r *casbinRepo) UpdateCasbin(adminAuthorityID, authorityId uint, casbinInfos []system.CasbinRule) error {
|
|
authorityIdStr := strconv.FormatUint(uint64(authorityId), 10)
|
|
|
|
// 清除旧权限
|
|
r.ClearCasbin(0, authorityIdStr)
|
|
|
|
// 去重处理
|
|
deduplicateMap := make(map[string]bool)
|
|
var rules [][]string
|
|
for _, v := range casbinInfos {
|
|
key := authorityIdStr + v.Path + v.Method
|
|
if !deduplicateMap[key] {
|
|
deduplicateMap[key] = true
|
|
rules = append(rules, []string{authorityIdStr, v.Path, v.Method})
|
|
}
|
|
}
|
|
|
|
if len(rules) == 0 {
|
|
return nil
|
|
}
|
|
|
|
// 使用enforcer添加策略
|
|
success, _ := r.enforcer.AddPolicies(rules)
|
|
if !success {
|
|
return errors.New("存在相同api,添加失败,请联系管理员")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// RemoveFilteredPolicy 删除筛选的策略
|
|
func (r *casbinRepo) RemoveFilteredPolicy(authorityId string) error {
|
|
return r.db.Delete(&gormadapter.CasbinRule{}, "v0 = ?", authorityId).Error
|
|
}
|
|
|
|
// SyncPolicy 同步策略(先删除再添加)
|
|
func (r *casbinRepo) SyncPolicy(authorityId string, rules [][]string) error {
|
|
// 先删除旧策略
|
|
if err := r.RemoveFilteredPolicy(authorityId); err != nil {
|
|
return err
|
|
}
|
|
// 再添加新策略
|
|
return r.AddPolicies(rules)
|
|
}
|