@@ -210,6 +210,93 @@ function Model:printModel()
210210 end
211211end
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
214301function Model :sortPoliciesByPriority ()
215302 if not self .model [" p" ] then return end
0 commit comments