diff --git a/internal/data/system/casbin.go b/internal/data/system/casbin.go new file mode 100644 index 0000000..8cf9c8e --- /dev/null +++ b/internal/data/system/casbin.go @@ -0,0 +1,110 @@ +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 +}