announce new user to ceo mailing list
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Max Erenberg 2021-08-22 05:44:41 +00:00
parent 7142659a8c
commit 0783588323
7 changed files with 77 additions and 17 deletions

View File

@ -35,6 +35,22 @@ called `ceod/admin` (remember to addprinc **and** ktadd).
#### Database
TODO - Andrew
#### Mailman
You should create the following mailing lists from the mail container:
```sh
/opt/mailman3/bin/mailman create syscom@csclub.internal
/opt/mailman3/bin/mailman create syscom-alerts@csclub.internal
/opt/mailman3/bin/mailman create exec@csclub.internal
/opt/mailman3/bin/mailman create ceo@csclub.internal
```
See https://git.uwaterloo.ca/csc/syscom-dev-environment/-/tree/master/mail
for instructions on how to access the Mailman UI from your browser.
If you want to actually see the archived messages, you'll
need to tweak the settings for each list from the UI so that non-member
messages get accepted (by default they get held).
#### Dependencies
Next, install and activate a virtualenv:
```sh
@ -108,14 +124,3 @@ curl --negotiate -u : --service-name ceod \
-d '{"uid":"test_1","cn":"Test One","program":"Math","terms":["s2021"]}' \
-X POST http://phosphoric-acid:9987/api/members
```
## Miscellaneous
### Mailman
You may wish to add more mailing lists to Mailman; by default, only the
csc-general list exists (from the dev environment playbooks). Just
attach to the mail container and run the following:
```sh
/opt/mailman3/bin/mailman create new_list_name@csclub.internal
```
See https://git.uwaterloo.ca/csc/syscom-dev-environment/-/tree/master/mail
for instructions on how to access the Mailman UI from your browser.

View File

@ -1,4 +1,4 @@
from typing import Dict
from typing import Dict, List
from zope.interface import Interface
@ -13,3 +13,10 @@ class IMailService(Interface):
def send_welcome_message_to(user: IUser):
"""Send a welcome message to the new member."""
def announce_new_user(user: IUser, operations: List[str]):
"""
Announce to the ceo mailing list that the new user was created.
`operations` is a list of the operations which were performed
during the transaction.
"""

View File

@ -2,8 +2,9 @@ import datetime
from email.message import EmailMessage
import re
import smtplib
from typing import Dict
from typing import Dict, List
from flask import g
import jinja2
from zope import component
from zope.interface import implementer
@ -61,3 +62,31 @@ class MailService:
{'Subject': 'Welcome to the Computer Science Club'},
body,
)
def announce_new_user(self, user: IUser, operations: List[str]):
# The person who added the new user
# TODO: store the auth_user from SPNEGO into flask.g
auth_user = g.sasl_user
if '@' in auth_user:
auth_user = auth_user[:auth_user.index('@')]
if user.is_club():
prog = 'addclubrep'
desc = 'Club Rep'
else:
prog = 'addmember'
desc = 'Member'
operations_str = '\n'.join(operations)
template = self.jinja_env.get_template('announce_new_user.j2')
body = template.render(
user=user, auth_user=auth_user, prog=prog,
operations_str=operations_str)
self.send(
f'{prog} <ceo+{prog}@{self.base_domain}>',
f'Membership and Accounts <ceo@{self.base_domain}>',
{
'Subject': f'New {desc}: {user.uid}',
'Cc': f'{auth_user}@{self.base_domain}',
},
body,
)

View File

@ -0,0 +1,10 @@
Name: {{ user.cn }}
Account: {{ user.uid }}
Program: {{ user.program }}
Added by: {{ auth_user }}
The following operations were performed:
{{ operations_str }}
Your Friend,
{{ prog }}

View File

@ -8,7 +8,7 @@ class AbstractTransaction(ABC):
operations = []
def __init__(self):
self.finished_operations = set()
self.finished_operations = []
# child classes should set this to a JSON-serializable object
# once they are finished
self.result = None
@ -33,7 +33,7 @@ class AbstractTransaction(ABC):
one is completed.
"""
for operation in self.child_execute_iter():
self.finished_operations.add(operation)
self.finished_operations.append(operation)
yield operation
def execute(self):

View File

@ -23,6 +23,7 @@ class AddMemberTransaction(AbstractTransaction):
'set_forwarding_addresses',
'subscribe_to_mailing_list',
'send_welcome_message',
'announce_new_user',
]
def __init__(
@ -86,14 +87,21 @@ class AddMemberTransaction(AbstractTransaction):
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)
yield 'failed_to_send_welcome_message: ' + str(err)
try:
user.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)
yield 'failed_to_subscribe_to_mailing_list: ' + str(err)
try:
self.mail_srv.announce_new_user(user, self.finished_operations)
yield 'announce_new_user'
except Exception as err:
logger.warning('announce_new_user failed:\n' + traceback.format_exc())
yield 'failed_to_announce_new_user: ' + str(err)
user_json = user.to_dict(True)
# insert the password into the JSON so that the client can see it

View File

@ -45,6 +45,7 @@ def test_api_create_user(cfg, create_user_resp):
{"status": "in progress", "operation": "set_forwarding_addresses"},
{"status": "in progress", "operation": "send_welcome_message"},
{"status": "in progress", "operation": "subscribe_to_mailing_list"},
{"status": "in progress", "operation": "announce_new_user"},
{"status": "completed", "result": {
"cn": "Test One",
"uid": "test_1",