import traceback from zope import component from ..AbstractTransaction import AbstractTransaction from ceo_common.errors import UserNotInGroupError, UserNotSubscribedError from ceo_common.interfaces import ILDAPService, IConfig from ceo_common.logger_factory import logger_factory logger = logger_factory(__name__) class RemoveMemberFromGroupTransaction(AbstractTransaction): """A transaction to remove a member from a group.""" operations = [ 'remove_user_from_group', 'remove_user_from_auxiliary_groups', 'unsubscribe_user_from_auxiliary_mailing_lists', ] def __init__(self, username: str, group_name: str, unsubscribe_from_lists: bool = True): super().__init__() self.username = username self.group_name = group_name self.unsubscribe_from_lists = unsubscribe_from_lists # a list of auxiliary Groups from which the user will be removed self.aux_groups = [] # a list of mailing list names from which the user will be unsubscribed self.aux_lists = [] self.user = None self.group = None def child_execute_iter(self): cfg = component.getUtility(IConfig) ldap_srv = component.getUtility(ILDAPService) user = ldap_srv.get_user(self.username) self.user = user group = ldap_srv.get_group(self.group_name) self.group = group group.remove_member(self.username) yield 'remove_user_from_group' try: aux_groups = cfg.get('auxiliary groups_' + self.group_name) for aux_group_name in aux_groups: try: aux_group = ldap_srv.get_group(aux_group_name) aux_group.remove_member(self.username) self.aux_groups.append(aux_group) except UserNotInGroupError: pass if self.aux_groups: yield 'remove_user_from_auxiliary_groups' except KeyError: pass if self.unsubscribe_from_lists: try: aux_lists = cfg.get('auxiliary mailing lists_' + self.group_name) for aux_list in aux_lists: try: user.unsubscribe_from_mailing_list(aux_list) self.aux_lists.append(aux_list) except UserNotSubscribedError: pass if self.aux_lists: yield 'unsubscribe_user_from_auxiliary_mailing_lists' except KeyError: pass except Exception: logger.error(traceback.format_exc()) yield 'failed_to_unsubscribe_user_from_auxiliary_mailing_lists' result = { 'removed_from_groups': [self.group_name] + [ group.cn for group in self.aux_groups ], } if self.aux_lists: result['unsubscribed_from_lists'] = self.aux_lists self.finish(result) def rollback(self): for aux_group in self.aux_groups: aux_group.add_member(self.username) if 'remove_user_from_group' in self.finished_operations: self.group.add_member(self.username)