@@ -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