Priority Model
Casbin support load policies with priority.
Load Policy with Priority Implicitlyโ
It's quite simple, the order determines the priority, policy appeared earlier has higher priority.
model.conf:
[policy_effect]
e = priority(p.eft) || deny
Load Policy with Priority Explicitlyโ
Also see: casbin#550
The smaller priority value will have a higher priority. If there's a non-numerical character in priority, it will be in the last, rather than throw an error.
The priority token name in policy definition is "priority" conventionally. A customized one requires invoking e.SetFieldIndex()
and reload policies (full example on TestCustomizedFieldIndex ).
model.conf:
[policy_definition]
p = customized_priority, sub, obj, act, eft
Golang code example:
e, _ := NewEnforcer("./example/priority_model_explicit_customized.conf",
"./example/priority_policy_explicit_customized.csv")
// Due to the customized priority token, the enforcer failed to handle the priority.
ok, err := e.Enforce("bob", "data2", "read") // the result will be `true, nil`
// set PriorityIndex and reload
e.SetFieldIndex("p", constant.PriorityIndex, 0)
err := e.LoadPolicy()
if err != nil {
log.Fatalf("LoadPolicy: %v", err)
}
ok, err := e.Enforce("bob", "data2", "read") // the result will be `false, nil`
Now, explicit priority only support AddPolicy
& AddPolicies
, if UpdatePolicy
been called, you shouldn't change the priority attribute.
model.conf:
[request_definition]
r = sub, obj, act
[policy_definition]
p = priority, sub, obj, act, eft
[role_definition]
g = _, _
[policy_effect]
e = priority(p.eft) || deny
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
policy.csv
p, 10, data1_deny_group, data1, read, deny
p, 10, data1_deny_group, data1, write, deny
p, 10, data2_allow_group, data2, read, allow
p, 10, data2_allow_group, data2, write, allow
p, 1, alice, data1, write, allow
p, 1, alice, data1, read, allow
p, 1, bob, data2, read, deny
g, bob, data2_allow_group
g, alice, data1_deny_group
request:
alice, data1, write --> true // for `p, 1, alice, data1, write, allow` has highest priority
bob, data2, read --> false
bob, data2, write --> true // for bob has role of `data2_allow_group` which has right to write data2, and there's no deny policy with higher priority
Load Policy with Priority Based on Role and User Hierarchyโ
The inherited structure of roles and users can only be multiple trees, not graphs. If one user has multiple roles,you have to make sure the user has the same level in different trees. If two roles have the same level,the policy(the role corresponding) appeared earlier has higher priority. more details also see casbin#833ใcasbin#831
model.conf:
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act, eft
[role_definition]
g = _, _
[policy_effect]
e = subjectPriority(p.eft) || deny
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
policy.csv
p, root, data1, read, deny
p, admin, data1, read, deny
p, editor, data1, read, deny
p, subscriber, data1, read, deny
p, jane, data1, read, allow
p, alice, data1, read, allow
g, admin, root
g, editor, admin
g, subscriber, admin
g, jane, editor
g, alice, subscriber
Request:
jane, data1, read --> true // jane is at the bottom,so priority is higher than editor, admin and root
alice, data1, read --> true
The role hierarchy like this:
role: root
โโ role: admin
โโ role editor
โ โโ user: jane
โ
โโ role: subscriber
โโ user: alice
The priority automatically like this:
role: root # auto priority: 30
โโ role: admin # auto priority: 20
โโ role: editor # auto priority: 10
โโ role: subscriber # auto priority: 10