pyceo/ceod/model/MailService.py

127 lines
4.5 KiB
Python
Raw Normal View History

2021-07-23 20:08:22 -04:00
import datetime
from email.message import EmailMessage
import re
import smtplib
2021-08-22 01:44:41 -04:00
from typing import Dict, List
2021-07-23 20:08:22 -04:00
2021-08-22 01:44:41 -04:00
from flask import g
2021-07-23 20:08:22 -04:00
import jinja2
from zope import component
from zope.interface import implementer
from ceo_common.interfaces import IMailService, IConfig, IUser
smtp_url_re = re.compile(r'^(?P<scheme>smtps?)://(?P<host>[\w.-]+)(:(?P<port>\d+))?$')
@implementer(IMailService)
class MailService:
def __init__(self):
cfg = component.getUtility(IConfig)
2021-08-03 19:19:33 -04:00
smtp_url = cfg.get('mail_smtp_url')
2021-07-23 20:08:22 -04:00
match = smtp_url_re.match(smtp_url)
if match is None:
raise Exception('Invalid SMTP URL: %s' % smtp_url)
self.smtps = match.group('scheme') == 'smtps'
self.host = match.group('host')
2021-11-02 02:23:37 -04:00
if match.group('port') is not None:
self.port = int(match.group('port'))
elif self.smtps:
self.port = 465
else:
self.port = 25
2021-08-03 19:19:33 -04:00
self.starttls = cfg.get('mail_smtp_starttls')
2021-07-23 20:08:22 -04:00
assert not (self.smtps and self.starttls)
self.base_domain = cfg.get('base_domain')
self.jinja_env = jinja2.Environment(
loader=jinja2.PackageLoader('ceod.model'),
keep_trailing_newline=True,
2021-07-23 20:08:22 -04:00
)
def send(self, _from: str, to: str, headers: Dict[str, str], content: str):
msg = EmailMessage()
msg.set_content(content)
msg['From'] = _from
msg['To'] = to
msg['Date'] = datetime.datetime.now().astimezone().strftime('%a, %d %b %Y %H:%M:%S %z')
for key, val in headers.items():
msg[key] = val
if self.smtps:
client = smtplib.SMTP_SSL(self.host, self.port)
else:
client = smtplib.SMTP(self.host, self.port)
if self.starttls:
client.starttls()
2021-07-31 08:34:06 -04:00
client.ehlo()
2021-07-23 20:08:22 -04:00
client.send_message(msg)
client.quit()
2021-08-23 19:36:49 -04:00
def send_welcome_message_to(self, user: IUser, password: str):
2021-07-23 20:08:22 -04:00
template = self.jinja_env.get_template('welcome_message.j2')
first_name = user.given_name
if not first_name:
first_name = user.cn.split(' ', 1)[0]
2021-08-23 19:36:49 -04:00
body = template.render(name=first_name, user=user.uid, password=password)
2021-07-23 20:08:22 -04:00
self.send(
f'Computer Science Club <exec@{self.base_domain}>',
f'{user.cn} <{user.uid}@{self.base_domain}>',
{'Subject': 'Welcome to the Computer Science Club'},
body,
)
2021-08-22 01:44:41 -04:00
def announce_new_user(self, user: IUser, operations: List[str]):
# The person who added the new user
2021-08-25 22:19:18 -04:00
auth_user = g.auth_user
2021-08-22 01:44:41 -04:00
if '@' in auth_user:
auth_user = auth_user[:auth_user.index('@')]
2021-11-02 03:04:51 -04:00
if user.non_member_terms:
2021-08-22 01:44:41 -04:00
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,
)
def send_cloud_account_will_be_deleted_message(self, user: IUser):
template = self.jinja_env.get_template('cloud_account_will_be_deleted.j2')
body = template.render(user=user)
self.send(
f'cloudaccounts <ceo+cloudaccounts@{self.base_domain}>',
f'{user.cn} <{user.uid}@{self.base_domain}>',
{
'Subject': 'Your CSC Cloud account will be deleted',
2022-03-12 16:09:19 -05:00
'Cc': f'root@{self.base_domain}',
'Reply-To': f'syscom@{self.base_domain}',
},
body,
)
def send_cloud_account_has_been_deleted_message(self, user: IUser):
template = self.jinja_env.get_template('cloud_account_has_been_deleted.j2')
body = template.render(user=user)
self.send(
f'cloudaccounts <ceo+cloudaccounts@{self.base_domain}>',
f'{user.cn} <{user.uid}@{self.base_domain}>',
{
'Subject': 'Your CSC Cloud account has been deleted',
2022-03-12 16:09:19 -05:00
'Cc': f'root@{self.base_domain}',
'Reply-To': f'syscom@{self.base_domain}',
},
body,
)