108 lines
3.3 KiB
Python
108 lines
3.3 KiB
Python
|
import base64
|
||
|
import os
|
||
|
from typing import Union, List
|
||
|
|
||
|
from zope import component
|
||
|
|
||
|
from ..AbstractTransaction import AbstractTransaction
|
||
|
from ceo_common.interfaces import IConfig, IMailService, IMailmanService
|
||
|
from ceod.model import User, Group
|
||
|
|
||
|
|
||
|
def gen_password() -> str:
|
||
|
"""Generate a temporary password."""
|
||
|
return base64.b64encode(os.urandom(18)).decode()
|
||
|
|
||
|
|
||
|
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('new_member_list')
|
||
|
self.mail_srv = component.getUtility(IMailService)
|
||
|
self.mailman_srv = component.getUtility(IMailmanService)
|
||
|
|
||
|
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
|
||
|
|
||
|
self.mail_srv.send_welcome_message_to(member)
|
||
|
yield 'send_welcome_message'
|
||
|
|
||
|
# This will be done on mail (remote)
|
||
|
self.mailman_srv.subscribe(member.uid, self.new_member_list)
|
||
|
yield 'subscribe_to_mailing_list'
|
||
|
|
||
|
user_json = member.to_dict()
|
||
|
# 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()
|