From 7d4da2e6947ac3fb00785e78e93a836cd788b914 Mon Sep 17 00:00:00 2001 From: Rio6 Date: Wed, 18 Aug 2021 16:23:55 -0400 Subject: [PATCH] implement mailing subscription for positions api --- ceod/api/positions.py | 2 -- ceod/model/LDAPService.py | 4 +-- .../UpdateMemberPositionsTransaction.py | 36 ++++++++++++++----- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/ceod/api/positions.py b/ceod/api/positions.py index d3608dd..ce2b894 100644 --- a/ceod/api/positions.py +++ b/ceod/api/positions.py @@ -37,5 +37,3 @@ def update_positions(): txn = UpdateMemberPositionsTransaction(member_positions) return create_streaming_response(txn) - - # TODO un/subscribe to mailing list diff --git a/ceod/model/LDAPService.py b/ceod/model/LDAPService.py index d239384..1e23b80 100644 --- a/ceod/model/LDAPService.py +++ b/ceod/model/LDAPService.py @@ -82,8 +82,8 @@ class LDAPService: entry = self._get_readable_entry_for_group(conn, cn) return Group.deserialize_from_ldap(entry) - def get_users_with_positions(self, gssapi_bind: bool = False) -> List[IUser]: - conn = self._get_ldap_conn(gssapi_bind) + def get_users_with_positions(self) -> List[IUser]: + conn = self._get_ldap_conn() conn.search(self.ldap_users_base, '(position=*)', attributes=ldap3.ALL_ATTRIBUTES) return [User.deserialize_from_ldap(entry) for entry in conn.entries] diff --git a/ceod/transactions/members/UpdateMemberPositionsTransaction.py b/ceod/transactions/members/UpdateMemberPositionsTransaction.py index 84f3a61..d570328 100644 --- a/ceod/transactions/members/UpdateMemberPositionsTransaction.py +++ b/ceod/transactions/members/UpdateMemberPositionsTransaction.py @@ -3,22 +3,30 @@ from typing import List, Dict from zope import component from ..AbstractTransaction import AbstractTransaction -from ceo_common.interfaces import ILDAPService +from ceo_common.interfaces import ILDAPService, IConfig +from ceo_common.errors import UserAlreadySubscribedError, UserNotSubscribedError +from ceo_common.logger_factory import logger_factory + +logger = logger_factory(__name__) class UpdateMemberPositionsTransaction(AbstractTransaction): """ - Transaction to update member's positions, and remove positions for anyone that's not in the list + Transaction to update member's positions, and remove positions for anyone that's not in the list, + then subscribe new execs to mailing list and unsubscribe old execs from it. """ # Positions is a dict where keys are member names and values are the list of positions they have def __init__(self, positions: Dict[str, List[str]]): super().__init__() self.positions = positions - self.ldap_srv = component.getUtility(ILDAPService) self.old_positions = {} # For rollback + self.ldap_srv = component.getUtility(ILDAPService) def child_execute_iter(self): - new_positions = {} + cfg = component.getUtility(IConfig) + mailing_lists = cfg.get('auxiliary mailing lists_exec') + + subscribe_status: Dict[IUser, bool] = {} # Remove positions for old users for user in self.ldap_srv.get_users_with_positions(): @@ -30,13 +38,23 @@ class UpdateMemberPositionsTransaction(AbstractTransaction): user = self.ldap_srv.get_user(username) self.old_positions[username] = user.positions[:] user.set_positions(positions) - - for position in user.positions: - new_positions[position] = user.uid - + subscribe_status[user] = len(positions) > 0 yield f'update_positions_{username}' - self.finish(new_positions) + # Update mailing list subscription + for user, subscribe in subscribe_status.items(): + for mailing_list in mailing_lists: + try: + if subscribe: + user.subscribe_to_mailing_list(mailing_list) + else: + user.unsubscribe_from_mailing_list(mailing_list) + except (UserAlreadySubscribedError, UserNotSubscribedError): + pass + except Exception as e: + logger.warning(f'Failed to update mailing list for {user.uid}') + + self.finish(None) def rollback(self): for username, positions in self.old_positions.items():