snapshot of https://github.com/casbin/casbin.git (master, 2026-09-15; blobs > 131072B omitted)
This commit is contained in:
202
model/assertion.go
Normal file
202
model/assertion.go
Normal file
@@ -0,0 +1,202 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/casbin/casbin/v3/rbac"
|
||||
)
|
||||
|
||||
// Assertion represents an expression in a section of the model.
|
||||
// For example: r = sub, obj, act.
|
||||
type Assertion struct {
|
||||
Key string
|
||||
Value string
|
||||
Tokens []string
|
||||
ParamsTokens []string
|
||||
Policy [][]string
|
||||
PolicyMap map[string]int
|
||||
RM rbac.RoleManager
|
||||
CondRM rbac.ConditionalRoleManager
|
||||
FieldIndexMap map[string]int
|
||||
FieldIndexMutex sync.RWMutex
|
||||
}
|
||||
|
||||
func (ast *Assertion) buildIncrementalRoleLinks(rm rbac.RoleManager, op PolicyOp, rules [][]string) error {
|
||||
ast.RM = rm
|
||||
count := strings.Count(ast.Value, "_")
|
||||
if count < 2 {
|
||||
return errors.New("the number of \"_\" in role definition should be at least 2")
|
||||
}
|
||||
|
||||
for _, rule := range rules {
|
||||
if len(rule) < count {
|
||||
return errors.New("grouping policy elements do not meet role definition")
|
||||
}
|
||||
if len(rule) > count {
|
||||
rule = rule[:count]
|
||||
}
|
||||
switch op {
|
||||
case PolicyAdd:
|
||||
err := rm.AddLink(rule[0], rule[1], rule[2:]...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case PolicyRemove:
|
||||
err := rm.DeleteLink(rule[0], rule[1], rule[2:]...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ast *Assertion) buildRoleLinks(rm rbac.RoleManager) error {
|
||||
ast.RM = rm
|
||||
count := strings.Count(ast.Value, "_")
|
||||
if count < 2 {
|
||||
return errors.New("the number of \"_\" in role definition should be at least 2")
|
||||
}
|
||||
for _, rule := range ast.Policy {
|
||||
if len(rule) < count {
|
||||
return errors.New("grouping policy elements do not meet role definition")
|
||||
}
|
||||
if len(rule) > count {
|
||||
rule = rule[:count]
|
||||
}
|
||||
err := ast.RM.AddLink(rule[0], rule[1], rule[2:]...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ast *Assertion) buildIncrementalConditionalRoleLinks(condRM rbac.ConditionalRoleManager, op PolicyOp, rules [][]string) error {
|
||||
ast.CondRM = condRM
|
||||
count := strings.Count(ast.Value, "_")
|
||||
if count < 2 {
|
||||
return errors.New("the number of \"_\" in role definition should be at least 2")
|
||||
}
|
||||
|
||||
for _, rule := range rules {
|
||||
if len(rule) < count {
|
||||
return errors.New("grouping policy elements do not meet role definition")
|
||||
}
|
||||
if len(rule) > count {
|
||||
rule = rule[:count]
|
||||
}
|
||||
|
||||
var err error
|
||||
domainRule := rule[2:len(ast.Tokens)]
|
||||
|
||||
switch op {
|
||||
case PolicyAdd:
|
||||
err = ast.addConditionalRoleLink(rule, domainRule)
|
||||
case PolicyRemove:
|
||||
err = ast.CondRM.DeleteLink(rule[0], rule[1], rule[2:]...)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ast *Assertion) buildConditionalRoleLinks(condRM rbac.ConditionalRoleManager) error {
|
||||
ast.CondRM = condRM
|
||||
count := strings.Count(ast.Value, "_")
|
||||
if count < 2 {
|
||||
return errors.New("the number of \"_\" in role definition should be at least 2")
|
||||
}
|
||||
for _, rule := range ast.Policy {
|
||||
if len(rule) < count {
|
||||
return errors.New("grouping policy elements do not meet role definition")
|
||||
}
|
||||
if len(rule) > count {
|
||||
rule = rule[:count]
|
||||
}
|
||||
|
||||
domainRule := rule[2:len(ast.Tokens)]
|
||||
|
||||
err := ast.addConditionalRoleLink(rule, domainRule)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// addConditionalRoleLink adds Link to rbac.ConditionalRoleManager and sets the parameters for LinkConditionFunc.
|
||||
func (ast *Assertion) addConditionalRoleLink(rule []string, domainRule []string) error {
|
||||
var err error
|
||||
if len(domainRule) == 0 {
|
||||
err = ast.CondRM.AddLink(rule[0], rule[1])
|
||||
if err == nil {
|
||||
ast.CondRM.SetLinkConditionFuncParams(rule[0], rule[1], rule[len(ast.Tokens):]...)
|
||||
}
|
||||
} else {
|
||||
domain := domainRule[0]
|
||||
err = ast.CondRM.AddLink(rule[0], rule[1], domain)
|
||||
if err == nil {
|
||||
ast.CondRM.SetDomainLinkConditionFuncParams(rule[0], rule[1], domain, rule[len(ast.Tokens):]...)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (ast *Assertion) copy() *Assertion {
|
||||
tokens := append([]string(nil), ast.Tokens...)
|
||||
policy := make([][]string, len(ast.Policy))
|
||||
|
||||
for i, p := range ast.Policy {
|
||||
policy[i] = append(policy[i], p...)
|
||||
}
|
||||
policyMap := make(map[string]int)
|
||||
for k, v := range ast.PolicyMap {
|
||||
policyMap[k] = v
|
||||
}
|
||||
|
||||
ast.FieldIndexMutex.RLock()
|
||||
fieldIndexMap := make(map[string]int)
|
||||
for k, v := range ast.FieldIndexMap {
|
||||
fieldIndexMap[k] = v
|
||||
}
|
||||
ast.FieldIndexMutex.RUnlock()
|
||||
|
||||
newAst := &Assertion{
|
||||
Key: ast.Key,
|
||||
Value: ast.Value,
|
||||
PolicyMap: policyMap,
|
||||
Tokens: tokens,
|
||||
Policy: policy,
|
||||
FieldIndexMap: fieldIndexMap,
|
||||
ParamsTokens: append([]string(nil), ast.ParamsTokens...),
|
||||
RM: ast.RM,
|
||||
CondRM: ast.CondRM,
|
||||
}
|
||||
|
||||
return newAst
|
||||
}
|
||||
Reference in New Issue
Block a user