@@ -134,14 +134,20 @@ def compare_policy(policy):
134134                name  =  self .get_name_with_domain (domain , policy [sub_index ])
135135                return  subject_hierarchy_map .get (name , 0 )
136136
137-             assertion .policy  =  sorted (assertion .policy , key = compare_policy ,  reverse = True )
137+             assertion .policy  =  sorted (assertion .policy , key = compare_policy )
138138            for  i , policy  in  enumerate (assertion .policy ):
139139                assertion .policy_map ["," .join (policy )] =  i 
140140
141141    def  get_subject_hierarchy_map (self , policies ):
142-         subject_hierarchy_map  =  {}
143-         # Tree structure of role 
144-         policy_map  =  {}
142+         """ 
143+         Get the subject hierarchy from the policy. 
144+         Select the lowest level subject in multiple rounds until all subjects are selected. 
145+         Return the subject hierarchy dictionary, the subject is the key, and the level is the value. 
146+         The level starts from 0 and increases in turn. The smaller the level, the higher the priority. 
147+         """ 
148+         # Init unsorted policy, and subject 
149+         unsorted_policy  =  []
150+         unsorted_sub  =  set ()
145151        for  policy  in  policies :
146152            if  len (policy ) <  2 :
147153                raise  RuntimeError ("policy g expect 2 more params" )
@@ -150,33 +156,28 @@ def get_subject_hierarchy_map(self, policies):
150156                domain  =  policy [2 ]
151157            child  =  self .get_name_with_domain (domain , policy [0 ])
152158            parent  =  self .get_name_with_domain (domain , policy [1 ])
153-             if  parent  not  in   policy_map .keys ():
154-                 policy_map [parent ] =  [child ]
155-             else :
156-                 policy_map [parent ].append (child )
157-             if  child  not  in   subject_hierarchy_map .keys ():
158-                 subject_hierarchy_map [child ] =  0 
159-             if  parent  not  in   subject_hierarchy_map .keys ():
160-                 subject_hierarchy_map [parent ] =  0 
161-             subject_hierarchy_map [child ] =  1 
162-         # Use queues for levelOrder 
163-         queue  =  []
164-         for  k , v  in  subject_hierarchy_map .items ():
165-             root  =  k 
166-             if  v  !=  0 :
167-                 continue 
168-             lv  =  0 
169-             queue .append (root )
170-             while  len (queue ) !=  0 :
171-                 sz  =  len (queue )
172-                 for  _  in  range (sz ):
173-                     node  =  queue .pop (0 )
174-                     subject_hierarchy_map [node ] =  lv 
175-                     if  node  in  policy_map .keys ():
176-                         for  child  in  policy_map [node ]:
177-                             queue .append (child )
178-                 lv  +=  1 
179-         return  subject_hierarchy_map 
159+             unsorted_policy .append ([child , parent ])
160+             unsorted_sub .add (child )
161+             unsorted_sub .add (parent )
162+         # sort policy,and update sorted_sub_list 
163+         sorted_sub_list  =  []
164+         while  len (unsorted_policy ) >  0 :
165+             # get all parent subject 
166+             parent_sub  =  {p [1 ] for  p  in  unsorted_policy  if  p [1 ] !=  "" }
167+             # remove parent subject from unsorted_sub 
168+             sorted_sub  =  unsorted_sub  -  parent_sub 
169+             if  not  sorted_sub :
170+                 raise  RuntimeError ("cycle dependency in subject hierarchy.subjects: {}" .format (unsorted_sub ))
171+             # update sorted_sub_list 
172+             sorted_sub_list .append (sorted_sub )
173+             # remove sorted subject, and update unsorted_policy 
174+             unsorted_policy  =  [p  for  p  in  unsorted_policy  if  p [0 ] not  in   sorted_sub ]
175+             # update unsorted_sub 
176+             unsorted_sub  =  unsorted_sub  -  sorted_sub 
177+         if  len (unsorted_sub ) >  0 :
178+             sorted_sub_list .append (unsorted_sub )
179+         # Tree structure of subject 
180+         return  {sub : i  for  i , subs  in  enumerate (sorted_sub_list ) for  sub  in  subs }
180181
181182    def  get_name_with_domain (self , domain , name ):
182183        return  "{}{}{}" .format (domain , DEFAULT_SEPARATOR , name )
0 commit comments