@@ -134,14 +134,20 @@ def compare_policy(policy):
134
134
name = self .get_name_with_domain (domain , policy [sub_index ])
135
135
return subject_hierarchy_map .get (name , 0 )
136
136
137
- assertion .policy = sorted (assertion .policy , key = compare_policy , reverse = True )
137
+ assertion .policy = sorted (assertion .policy , key = compare_policy )
138
138
for i , policy in enumerate (assertion .policy ):
139
139
assertion .policy_map ["," .join (policy )] = i
140
140
141
141
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 ()
145
151
for policy in policies :
146
152
if len (policy ) < 2 :
147
153
raise RuntimeError ("policy g expect 2 more params" )
@@ -150,33 +156,28 @@ def get_subject_hierarchy_map(self, policies):
150
156
domain = policy [2 ]
151
157
child = self .get_name_with_domain (domain , policy [0 ])
152
158
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 }
180
181
181
182
def get_name_with_domain (self , domain , name ):
182
183
return "{}{}{}" .format (domain , DEFAULT_SEPARATOR , name )
0 commit comments