diff --git a/config.py.example b/config.py.example index 7e778ebdb22260d658a86dd7f334347d06986bda..8149fb28acce8ea54f62ea9e5ed58555299d4b96 100644 --- a/config.py.example +++ b/config.py.example @@ -6,3 +6,5 @@ SECRET_KEY = "FIXME" SESSION_COOKIE_PATH = '/' SESSION_COOKIE_NAME = 'mo_session' + +MAIL_FROM = "mo-submit@matfyz.cz" # FIXME \ No newline at end of file diff --git a/mo/util.py b/mo/util.py index 1205e109b0a31c8590f61dbfb80f0c6fa3828264..c0772882bb05aa89fe0c45b5cf4011420cae5872 100644 --- a/mo/util.py +++ b/mo/util.py @@ -1,7 +1,14 @@ # Různé -import mo.db as db from typing import Any, Optional +import email.message +import email.headerregistry +import datetime +import subprocess +import textwrap + +import mo.db as db +import config current_log_user: Optional[db.User] = None @@ -14,3 +21,44 @@ def log(type: db.LogType, what: int, details: Any): details=details, ) db.get_session().add(entry) + + +def send_password_reset_email(user: db.User, link: str): + if not hasattr(config, 'MAIL_FROM'): + raise RuntimeError('V configu chybí pole MAIL_FROM.') + + msg = email.message.EmailMessage() + msg['From'] = email.headerregistry.Address( + display_name='MO Submit', addr_spec=config.MAIL_FROM + ) + msg['To'] = [ + email.headerregistry.Address( + display_name='{} {}'.format(user.first_name, user.last_name), + addr_spec=user.email, + ) + ] + msg['Subject'] = f'MO Submit – obnova hesla' + msg['Date'] = datetime.datetime.now() + + body = textwrap.dedent(''' + Pro obnovení hesla pro váš účet na MO Submit klikněte sem: {} + + Váš MO Submit + '''.format(link)) + + msg.set_content(body, cte='quoted-printable') + + sm = subprocess.Popen( + [ + '/usr/sbin/sendmail', + '-oi', + '-f', + config.MAIL_FROM, + user.email, + ], + stdin=subprocess.PIPE, + ) + sm.communicate(msg.as_bytes()) + + if sm.returncode != 0: + raise RuntimeError('Sendmail failed with return code {}'.format(sm.returncode)) diff --git a/mo/web/main.py b/mo/web/main.py index 105507a8b5f5facba964ef8063e2eed98190a592..65bfd97a13482c2394079520b0b9ece0bb045d39 100644 --- a/mo/web/main.py +++ b/mo/web/main.py @@ -4,6 +4,7 @@ import wtforms import wtforms.validators as validators from sqlalchemy.orm import joinedload +import mo.util import mo.db as db import mo.rights import mo.users @@ -37,7 +38,12 @@ def login(): token = mo.users.ask_reset_password(user) link = url_for('reset', token=token) db.get_session().commit() - # FIXME: Poslat e-mail + + try: + mo.util.send_password_reset_email(user, link) + except RuntimeError as e: + app.logger.error('Login: problém při posílání emailu: {}'.format(e)) + app.logger.info('Link: %s', link) return render_template('reset.html') elif not form.passwd.data or not mo.users.check_password(user, form.passwd.data):