This commit is contained in:
Yvan
2026-08-18 15:04:07 +08:00
parent 10ccc005be
commit 1ef8ecb7b2
42 changed files with 3027 additions and 296 deletions
+70 -39
View File
@@ -32,10 +32,33 @@ func (r *apiRepo) APIRoleIDs(ctx context.Context, path, method string) ([]uint,
return ids, nil
}
func (r *apiRepo) SetAPIRoles(ctx context.Context, path, method string, ids []uint) error {
access := &authorityAccessRepo{data: r.data}
_, allowedAuthorities, strict, err := access.strictAuthorityAccess(ctx)
if err != nil {
return err
}
if strict {
for _, id := range ids {
if !allowedAuthorities[id] {
return errors.New("您提交的角色ID不合法")
}
}
if err := r.checkPolicyPathsAuth(ctx, []*biz.API{{Path: path, Method: method}}); err != nil {
return err
}
}
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
// A path/method need not be present in sys_apis when replacing
// all matching policy rows. Do not validate or deduplicate authority IDs.
if err := deletePoliciesForPath(tx, path, method); err != nil {
if strict {
authorityIDs := make([]string, 0, len(allowedAuthorities))
for authorityID := range allowedAuthorities {
authorityIDs = append(authorityIDs, strconv.FormatUint(uint64(authorityID), 10))
}
if len(authorityIDs) > 0 {
if err := policyScope(tx).Where("v1 = ? AND v2 = ? AND v0 IN ?", path, method, authorityIDs).Delete(&casbinRulePO{}).Error; err != nil {
return err
}
}
} else if err := deletePoliciesForPath(tx, path, method); err != nil {
return err
}
if len(ids) == 0 {
@@ -100,42 +123,8 @@ func (r *apiRepo) SetPolicyPaths(ctx context.Context, aid uint, paths []*biz.API
if err := (&authorityAccessRepo{data: r.data}).checkAuthorityIDAuth(ctx, aid); err != nil {
return err
}
config := r.data.runtime.Admin()
if actor, ok := biz.ActorFromContext(ctx); ok && config != nil && config.System != nil && config.System.UseStrictAuth {
var authority authorityPO
if err := r.data.gormDB.WithContext(ctx).Where("authority_id = ?", actor.AuthorityID).First(&authority).Error; err != nil {
return err
}
var registered []apiPO
if err := r.data.gormDB.WithContext(ctx).Find(&registered).Error; err != nil {
return err
}
allowedSet := make(map[string]bool, len(registered))
if authority.ParentID == nil || *authority.ParentID == 0 {
for _, item := range registered {
allowedSet[item.Path+"\x00"+item.Method] = true
}
} else {
policies, err := policyRowsForAuthority(r.data.gormDB.WithContext(ctx), actor.AuthorityID)
if err != nil {
return err
}
policySet := make(map[string]bool, len(policies))
for _, item := range policies {
policySet[item.V1+"\x00"+item.V2] = true
}
for _, item := range registered {
key := item.Path + "\x00" + item.Method
if policySet[key] {
allowedSet[key] = true
}
}
}
for _, item := range paths {
if !allowedSet[item.Path+"\x00"+item.Method] {
return errors.New("存在api不在权限列表中")
}
}
if err := r.checkPolicyPathsAuth(ctx, paths); err != nil {
return err
}
db := r.data.gormDB.WithContext(ctx)
// The reference enforcer removes the old authority policies before it
@@ -165,3 +154,45 @@ func (r *apiRepo) SetPolicyPaths(ctx context.Context, aid uint, paths []*biz.API
}
return nil
}
func (r *apiRepo) checkPolicyPathsAuth(ctx context.Context, paths []*biz.API) error {
actor, _, strict, err := (&authorityAccessRepo{data: r.data}).strictAuthorityAccess(ctx)
if err != nil || !strict {
return err
}
var authority authorityPO
if err := r.data.gormDB.WithContext(ctx).Where("authority_id = ?", actor.AuthorityID).First(&authority).Error; err != nil {
return err
}
var registered []apiPO
if err := r.data.gormDB.WithContext(ctx).Find(&registered).Error; err != nil {
return err
}
allowedSet := make(map[string]bool, len(registered))
if authority.ParentID == nil || *authority.ParentID == 0 {
for _, item := range registered {
allowedSet[item.Path+"\x00"+item.Method] = true
}
} else {
policies, err := policyRowsForAuthority(r.data.gormDB.WithContext(ctx), actor.AuthorityID)
if err != nil {
return err
}
policySet := make(map[string]bool, len(policies))
for _, item := range policies {
policySet[item.V1+"\x00"+item.V2] = true
}
for _, item := range registered {
key := item.Path + "\x00" + item.Method
if policySet[key] {
allowedSet[key] = true
}
}
}
for _, item := range paths {
if !allowedSet[item.Path+"\x00"+item.Method] {
return errors.New("存在api不在权限列表中")
}
}
return nil
}