implement mailing subscription for positions api

This commit is contained in:
Rio6 2021-08-18 16:23:55 -04:00
parent 459eb7010e
commit 7d4da2e694
3 changed files with 29 additions and 13 deletions

View File

@ -37,5 +37,3 @@ def update_positions():
txn = UpdateMemberPositionsTransaction(member_positions) txn = UpdateMemberPositionsTransaction(member_positions)
return create_streaming_response(txn) return create_streaming_response(txn)
# TODO un/subscribe to mailing list

View File

@ -82,8 +82,8 @@ class LDAPService:
entry = self._get_readable_entry_for_group(conn, cn) entry = self._get_readable_entry_for_group(conn, cn)
return Group.deserialize_from_ldap(entry) return Group.deserialize_from_ldap(entry)
def get_users_with_positions(self, gssapi_bind: bool = False) -> List[IUser]: def get_users_with_positions(self) -> List[IUser]:
conn = self._get_ldap_conn(gssapi_bind) conn = self._get_ldap_conn()
conn.search(self.ldap_users_base, '(position=*)', attributes=ldap3.ALL_ATTRIBUTES) conn.search(self.ldap_users_base, '(position=*)', attributes=ldap3.ALL_ATTRIBUTES)
return [User.deserialize_from_ldap(entry) for entry in conn.entries] return [User.deserialize_from_ldap(entry) for entry in conn.entries]

View File

@ -3,22 +3,30 @@ from typing import List, Dict
from zope import component from zope import component
from ..AbstractTransaction import AbstractTransaction 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): 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 # 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]]): def __init__(self, positions: Dict[str, List[str]]):
super().__init__() super().__init__()
self.positions = positions self.positions = positions
self.ldap_srv = component.getUtility(ILDAPService)
self.old_positions = {} # For rollback self.old_positions = {} # For rollback
self.ldap_srv = component.getUtility(ILDAPService)
def child_execute_iter(self): 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 # Remove positions for old users
for user in self.ldap_srv.get_users_with_positions(): for user in self.ldap_srv.get_users_with_positions():
@ -30,13 +38,23 @@ class UpdateMemberPositionsTransaction(AbstractTransaction):
user = self.ldap_srv.get_user(username) user = self.ldap_srv.get_user(username)
self.old_positions[username] = user.positions[:] self.old_positions[username] = user.positions[:]
user.set_positions(positions) user.set_positions(positions)
subscribe_status[user] = len(positions) > 0
for position in user.positions:
new_positions[position] = user.uid
yield f'update_positions_{username}' 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): def rollback(self):
for username, positions in self.old_positions.items(): for username, positions in self.old_positions.items():