Skip to content

Commit 7158a79

Browse files
authored
feat: Add function sortPoliciesBySubjectHierarchy (#110)
Signed-off-by: Edmond <edomondja@gmail.com>
1 parent 3c4d150 commit 7158a79

File tree

7 files changed

+154
-1
lines changed

7 files changed

+154
-1
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[request_definition]
2+
r = sub, obj, act
3+
4+
[policy_definition]
5+
p = sub, obj, act, eft
6+
7+
[role_definition]
8+
g = _, _
9+
10+
[policy_effect]
11+
e = subjectPriority(p.eft) || deny
12+
13+
[matchers]
14+
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[request_definition]
2+
r = sub, obj, dom, act
3+
4+
[policy_definition]
5+
p = sub, obj, dom, act, eft
6+
7+
[role_definition]
8+
g = _, _, _
9+
10+
[policy_effect]
11+
e = subjectPriority(p.eft) || deny
12+
13+
[matchers]
14+
m = g(r.sub, p.sub, r.dom) && r.dom == p.dom && r.obj == p.obj && r.act == p.act
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
p, root, data1, read, deny
2+
p, admin, data1, read, deny
3+
4+
p, editor, data1, read, deny
5+
p, subscriber, data1, read, deny
6+
7+
p, jane, data1, read, allow
8+
p, alice, data1, read, allow
9+
10+
g, admin, root
11+
12+
g, editor, admin
13+
g, subscriber, admin
14+
15+
g, jane, editor
16+
g, alice, subscriber
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
p, admin, data1, domain1, write, deny
2+
p, alice, data1, domain1, write, allow
3+
p, admin, data2, domain2, write, deny
4+
p, bob, data2, domain2, write, allow
5+
6+
7+
g, alice, admin, domain1
8+
g, bob, admin, domain2

src/effect/DefaultEffector.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ function DefaultEffector:mergeEffects(expr, effects)
6464
break
6565
end
6666
end
67-
elseif expr == "priority(p_eft) || deny" then
67+
elseif expr == "priority(p_eft) || deny" or expr == "subjectPriority(p_eft) || deny" then
6868
result = false
6969
for i, eft in pairs(effects) do
7070
if eft ~= self.Effect.INDETERMINATE then

src/model/Model.lua

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,93 @@ function Model:printModel()
210210
end
211211
end
212212

213+
local function getSubjectHierarchyMap(policies)
214+
local subjectHierarchyMap = { }
215+
--Tree structure of role
216+
local policyMap = { }
217+
for _, policy in pairs(policies) do
218+
if #policy < 2 then
219+
return nil, error("policy g expect 2 more params")
220+
end
221+
local domain=""
222+
if #policy~=2 then
223+
domain = policy[3]
224+
end
225+
local child = domain.."::"..policy[1]
226+
local parent = domain.."::"..policy[2]
227+
if policyMap[parent]==nil then
228+
policyMap[parent]={}
229+
end
230+
table.insert(policyMap[parent], child)
231+
if subjectHierarchyMap[child]==nil then
232+
subjectHierarchyMap[child] = 0
233+
end
234+
if subjectHierarchyMap[parent]==nil then
235+
subjectHierarchyMap[parent] = 0
236+
end
237+
subjectHierarchyMap[child] = 1
238+
end
239+
local queue = { }
240+
for k, v in pairs(subjectHierarchyMap) do
241+
if v == 0 then
242+
local root = k
243+
local lv = 0
244+
table.insert(queue,root)
245+
while #queue~=0 do
246+
local sz=#queue
247+
for i=1,sz do
248+
local node=queue[1]
249+
table.remove(queue,1)
250+
subjectHierarchyMap[node] = lv
251+
if policyMap[node]~=nil then
252+
for _,child in pairs(policyMap[node]) do
253+
table.insert(queue,child)
254+
end
255+
end
256+
end
257+
lv=lv+1
258+
end
259+
end
260+
end
261+
262+
return subjectHierarchyMap, nil
263+
end
264+
265+
function Model:sortPoliciesBySubjectHierarchy()
266+
if self.model["e"]["e"].value ~= "subjectPriority(p_eft) || deny" then
267+
return nil
268+
end
269+
local subIndex = 1
270+
local domainIndex = -1
271+
for ptype, assertion in pairs(self.model["p"]) do
272+
for index, token in pairs(assertion.tokens) do
273+
if token == ptype.."_dom" then
274+
domainIndex = index
275+
break
276+
end
277+
end
278+
local subjectHierarchyMap, err = getSubjectHierarchyMap(self.model["g"]["g"].policy)
279+
if err ~= nil then
280+
return err
281+
end
282+
table.sort(assertion.policy, function(i, j)
283+
local domain1, domain2 = "", ""
284+
if domainIndex ~= -1 then
285+
domain1 = i[domainIndex]
286+
domain2 = j[domainIndex]
287+
end
288+
local name1, name2 =domain1.."::"..i[subIndex], domain2.."::".. j[subIndex]
289+
local p1 = subjectHierarchyMap[name1]
290+
local p2 = subjectHierarchyMap[name2]
291+
return p1 > p2
292+
end)
293+
for i, policy in pairs(assertion.policy) do
294+
assertion.policyMap[table.concat(policy, ",")] = i
295+
end
296+
end
297+
return nil
298+
end
299+
213300
-- sortPoliciesByPriority sorts policies by their priorities if 'priority' token exists
214301
function Model:sortPoliciesByPriority()
215302
if not self.model["p"] then return end

tests/main/enforcer_spec.lua

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,20 @@ describe("Enforcer tests", function ()
390390
assert.is.True(e:enforce("data2_allow_group", "data2", "write"))
391391
end)
392392

393+
it("explicit subject priority test", function ()
394+
local model = path .. "/examples/subject_priority_model_with_domain.conf"
395+
local policy = path .. "/examples/subject_priority_policy_with_domain.csv"
396+
local e = Enforcer:new(model, policy)
397+
assert.is.False(e:enforce("alice", "data1","domain1", "write"))
398+
assert.is.False(e:enforce("bob", "data2","domain2", "write"))
399+
e.model:printPolicy()
400+
e.model:sortPoliciesBySubjectHierarchy()
401+
e.model:printPolicy()
402+
assert.is.True(e:enforce("alice", "data1","domain1", "write"))
403+
assert.is.True(e:enforce("bob", "data2","domain2", "write"))
404+
end)
405+
406+
393407
it("Batch Enforce test", function ()
394408
local model = path .. "/examples/basic_model.conf"
395409
local policy = path .. "/examples/basic_policy.csv"

0 commit comments

Comments
 (0)