@@ -216,52 +216,82 @@ def update_sign_users(self, directory_users, sign_connector: SignConnector, org_
216216 desired_groups = set ([self .get_primary_group (sign_user , self .sign_user_groups [org_name ]).name .lower ()])
217217 if not is_umg :
218218 desired_groups = set ([directory_user ['sign_roups' ][0 ].group_name .lower ()])
219- target_groups = set ([g .group_name .lower () for g in self .target_groups_by_org [org_name ]])
220-
221- groups_to_assign = []
222- for dg in desired_groups :
223- group_info = self .sign_groups [org_name ].get (dg )
224- if group_info is None :
225- raise AssertionException (f"'{ dg } ' isn't a valid Sign group" )
226-
227- assigned_group = assigned_groups .get (group_info .groupName .lower ())
228-
229- wants_group_admin = False
230- if is_umg :
231- wants_group_admin = directory_user ['is_group_admin' ]
232- else :
233- wants_group_admin = dg in directory_user ['admin_groups' ]
234219
235- change_group_admin = (assigned_group is None and
236- wants_group_admin ) or \
237- (assigned_group is not None and
238- assigned_group .isGroupAdmin is not wants_group_admin )
220+ groups_to_update = {}
221+ admin_groups = set ([g .group_name for g in directory_user ['admin_groups' ] if g .umapi_name == org_name ])
239222
240- if assigned_group is not None and not change_group_admin :
241- continue
223+ # identify groups to add for user
224+ groups_to_assign = desired_groups .difference (set (assigned_groups .keys ()))
225+ for group_name in groups_to_assign :
226+ group_info = self .sign_groups [org_name ].get (group_name )
227+ if group_info is None :
228+ raise AssertionException (f"'{ group_name } ' isn't a valid Sign group" )
242229
243- if assigned_group is None :
244- self .logger .info (f"Assigning group '{ group_info .groupId } ' to user { sign_user .email } " )
245- self .sign_users_group_updates .add (sign_user .email )
230+ is_group_admin = ((not is_umg and directory_user ['is_admin_group' ])
231+ or (group_name in admin_groups ))
232+ groups_to_update [group_name ] = UserGroupInfo (
233+ id = group_info .groupId ,
234+ name = group_info .groupName ,
235+ isGroupAdmin = is_group_admin ,
236+ isPrimaryGroup = False ,
237+ status = 'ACTIVE' ,
238+ )
239+ self .logger .info (f"Assigning group '{ group_info .groupName } ' to user { sign_user .email } " )
240+ if group_name in admin_groups :
241+ self .logger .info (f"Assigning group admin privileges to user { sign_user .email } for group '{ group_info .groupName } '" )
246242
247- admin_status = False if not wants_group_admin and assigned_group .isGroupAdmin is not wants_group_admin else True
243+ # identify groups to remove for user
244+ target_groups = set ([g .group_name .lower () for g in self .target_groups_by_org [org_name ]])
245+ assigned_group_names = set (assigned_groups .keys ())
246+ # first, get groups that are assigned but not in the desired list
247+ # then see what that has in common with overall target groups - this is the list
248+ # of groups to remove. non-targeted groups remain untouched
249+ remove_groups = target_groups .intersection (assigned_group_names .difference (desired_groups ))
250+ for group_name in remove_groups :
251+ # this should never happen but we need to check
252+ if group_name in groups_to_assign :
253+ raise AssertionException (f"Cannot remove group '{ group_name } ' because it is in the assignment list" )
254+ group_info = self .sign_groups [org_name ].get (group_name )
255+ if group_info is None :
256+ raise AssertionException (f"'{ group_name } ' isn't a valid Sign group" )
248257
249- if change_group_admin :
250- self .logger .info (f"Changing group Admin role for user '{ sign_user .email } ', status? { admin_status } " )
251- self .sign_users_role_updates .add (sign_user .email )
258+ assigned_group = assigned_groups .get (group_info .groupName .lower ())
252259
253- groups_to_assign . append ( UserGroupInfo (
260+ groups_to_update [ group_name ] = UserGroupInfo (
254261 id = group_info .groupId ,
255262 name = group_info .groupName ,
256- isGroupAdmin = admin_status ,
257- isPrimaryGroup = False ,
258- status = 'ACTIVE' ,
259- ))
263+ isGroupAdmin = assigned_group .isGroupAdmin ,
264+ isPrimaryGroup = assigned_group .isPrimaryGroup ,
265+ status = 'DELETED' ,
266+ )
267+ self .logger .info (f"Removing group '{ group_info .groupName } ' for user { sign_user .email } " )
268+
269+ # get a full list of groups the user is an admin for
270+ current_admin_groups = set ([g .name .lower () for g in assigned_groups .values () if g .isGroupAdmin ]).\
271+ union (set ([g .name .lower () for g in groups_to_update .values () if g .status == 'ACTIVE' and g .isGroupAdmin ]))
272+
273+ # if a user is group admin to any group they're not mapped to be admin for, then they
274+ # need to have their status removed
275+ non_admin_groups = current_admin_groups .difference (set ([g .group_name for g in directory_user ['admin_groups' ]]))
260276
261- if groups_to_assign :
262- group_update_data = UserGroupsInfo (groupInfoList = groups_to_assign )
277+ for group_name in non_admin_groups :
278+ if group_name in groups_to_update :
279+ groups_to_update [group_name ].isGroupAdmin = False
280+ else :
281+ group_info = assigned_groups .get (group_name )
282+ groups_to_update [group_name ] = UserGroupInfo (
283+ id = group_info .id ,
284+ name = group_info .name ,
285+ isGroupAdmin = False ,
286+ isPrimaryGroup = group_info .isPrimaryGroup ,
287+ status = 'DELETED' ,
288+ )
289+
290+
291+ if groups_to_update :
292+ group_update_data = UserGroupsInfo (groupInfoList = groups_to_update )
263293 user_groups_update_list .append ((sign_user .id , group_update_data ))
264-
294+
265295 sign_connector .update_users (users_update_list )
266296 sign_connector .update_user_groups (user_groups_update_list )
267297 self .sign_only_users_by_org [org_name ] = {}
0 commit comments