announce new user to ceo mailing list

pull/13/head
Max Erenberg 1 year ago
parent 7142659a8c
commit 0783588323
  1. 27
      README.md
  2. 9
      ceo_common/interfaces/IMailService.py
  3. 31
      ceod/model/MailService.py
  4. 10
      ceod/model/templates/announce_new_user.j2
  5. 4
      ceod/transactions/AbstractTransaction.py
  6. 12
      ceod/transactions/members/AddMemberTransaction.py
  7. 1
      tests/ceod/api/test_members.py

@ -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.

@ -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.
"""

@ -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,
)

@ -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 }}

@ -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):

@ -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

@ -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",

Loading…
Cancel
Save