pyceo/ceod/transactions/members/AddMemberTransaction.py

112 lines
3.5 KiB
Python

import traceback
from typing import Union, List
from zope import component
from ..AbstractTransaction import AbstractTransaction
from .utils import gen_password
from ceo_common.interfaces import IConfig, IMailService
from ceo_common.logger_factory import logger_factory
from ceod.model import User, Group
logger = logger_factory(__name__)
class AddMemberTransaction(AbstractTransaction):
"""Transaction to add a new club member."""
operations = [
'add_user_to_ldap',
'add_group_to_ldap',
'add_user_to_kerberos',
'create_home_dir',
'set_forwarding_addresses',
'subscribe_to_mailing_list',
'send_welcome_message',
]
def __init__(
self,
uid: str,
cn: str,
program: Union[str, None],
terms: Union[List[str], None] = None,
non_member_terms: Union[List[str], None] = None,
forwarding_addresses: Union[List[str], None] = None,
):
super().__init__()
cfg = component.getUtility(IConfig)
self.uid = uid
self.cn = cn
self.program = program
self.terms = terms
self.non_member_terms = non_member_terms
self.forwarding_addresses = forwarding_addresses
self.member = None
self.group = None
self.new_member_list = cfg.get('mailman3_new_member_list')
self.mail_srv = component.getUtility(IMailService)
def child_execute_iter(self):
member = User(
uid=self.uid,
cn=self.cn,
program=self.program,
terms=self.terms,
non_member_terms=self.non_member_terms,
)
self.member = member
member.add_to_ldap()
yield 'add_user_to_ldap'
group = Group(
cn=member.uid,
gid_number=member.gid_number,
)
self.group = group
group.add_to_ldap()
yield 'add_group_to_ldap'
password = gen_password()
member.add_to_kerberos(password)
yield 'add_user_to_kerberos'
member.create_home_dir()
yield 'create_home_dir'
if self.forwarding_addresses:
member.set_forwarding_addresses(self.forwarding_addresses)
yield 'set_forwarding_addresses'
# The following operations can't/shouldn't be rolled back because the
# user has already seen the email
try:
self.mail_srv.send_welcome_message_to(member)
yield 'send_welcome_message'
except Exception as err:
logger.warning('send_welcome_message failed:\n' + traceback.format_exc())
yield 'failed_to_send_welcome_message\n' + str(err)
try:
member.subscribe_to_mailing_list(self.new_member_list)
yield 'subscribe_to_mailing_list'
except Exception as err:
logger.warning('subscribe_to_mailing_list failed:\n' + traceback.format_exc())
yield 'failed_to_subscribe_to_mailing_list\n' + str(err)
user_json = member.to_dict(True)
# insert the password into the JSON so that the client can see it
user_json['password'] = password
self.finish(user_json)
def rollback(self):
if 'create_home_dir' in self.finished_operations:
self.member.delete_home_dir()
if 'add_user_to_kerberos' in self.finished_operations:
self.member.remove_from_kerberos()
if 'add_group_to_ldap' in self.finished_operations:
self.group.remove_from_ldap()
if 'add_user_to_ldap' in self.finished_operations:
self.member.remove_from_ldap()