diff --git a/eos/base/election.py b/eos/base/election.py index ad730d5..88232a3 100644 --- a/eos/base/election.py +++ b/eos/base/election.py @@ -95,18 +95,6 @@ class EmailUser(User): if not isinstance(other, EmailUser): return False return self.email.lower() == other.email.lower() and self.password == other.password - - def send_email(self, host, port, username, password, from_email, content): - #__pragma__('skip') - import smtplib - #__pragma__('noskip') - with smtplib.SMTP(host, port) as smtp: - if username is not None: - smtp.login(username, password) - smtp.sendmail(from_email, [self.email], content) - - def email_password(self, host, port, username, password, from_email): - self.send_email(host, port, username, password, from_email, 'Subject: Registered to vote in {1}\nFrom: {4}\nTo: {2}\n\nDear {0},\n\nYou are registered to vote in the election {1}. Your log in details are as follows:\n\nEmail: {2}\nPassword: {3}'.format(self.name, self.recurse_parents(Election).name, self.email, self.password, from_email)) class UserVoter(Voter): user = EmbeddedObjectField() diff --git a/eosweb/core/emails.py b/eosweb/core/emails.py new file mode 100644 index 0000000..c75248b --- /dev/null +++ b/eosweb/core/emails.py @@ -0,0 +1,67 @@ +# Eos - Verifiable elections +# Copyright © 2017-18 RunasSudo (Yingtong Li) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import logging +import premailer +import sass + +import flask +import flask_mail + +from eos.base.election import * + +def send_email(title, html_text, body_text, recipients): + # Prepare email + css = sass.compile(string=flask.render_template('email/base.scss')) + html = flask.render_template( + 'email/base.html', + title=title, + css=css, + text=html_text + ) + html = premailer.Premailer(html, strip_important=False).transform() + + body = flask.render_template( + 'email/base.txt', + title=title, + text=body_text + ) + + # Send email + mail = flask_mail.Mail(flask.current_app) + msg = flask_mail.Message( + title, + recipients=recipients, + body=body, + html=html + ) + mail.send(msg) + +def voter_email_password(election, voter): + send_email( + 'Registered to vote: {}'.format(election.name), + '

Dear {},

You are registered to vote in {}.

Your login details are as follows:

Email: {}

Password: {}

'.format(voter.name, election.name, voter.user.email, voter.user.password), + 'Dear {},\n\nYou are registered to vote in "{}".\n\nYour login details are as follows:\n\nEmail: {}\nPassword: {}'.format(voter.name, election.name, voter.user.email, voter.user.password), + [voter.user.email] + ) + +def task_email_failure(task): + send_email( + 'Task failed: {}'.format(task.label), + '

The task {} failed execution. The output was:

{}
'.format(task.label, '\n'.join(task.messages)), + 'The task "{}" failed execution. The output was:\n\n{}'.format(task.label, '\n'.join(task.messages)), + [admin.email for admin in flask.current_app.config['ADMINS'] if isinstance(admin, EmailUser)] + ) diff --git a/eosweb/core/main.py b/eosweb/core/main.py index dea2ce4..c60775d 100644 --- a/eosweb/core/main.py +++ b/eosweb/core/main.py @@ -30,6 +30,8 @@ from eos.psr.workflow import * from eosweb.core.tasks import * +from . import emails + import eos.core.hashing import eosweb @@ -123,7 +125,7 @@ def setup_test_election(): for voter in election.voters: if isinstance(voter, UserVoter): if isinstance(voter.user, EmailUser): - voter.user.email_password(app.config['SMTP_HOST'], app.config['SMTP_PORT'], app.config['SMTP_USER'], app.config['SMTP_PASS'], app.config['SMTP_FROM']) + emails.voter_email_password(election, voter) election.mixing_trustees.append(InternalMixingTrustee(name='Eos Voting')) election.mixing_trustees.append(InternalMixingTrustee(name='Eos Voting')) diff --git a/eosweb/core/tasks.py b/eosweb/core/tasks.py index bec82d2..b486514 100644 --- a/eosweb/core/tasks.py +++ b/eosweb/core/tasks.py @@ -14,47 +14,14 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import logging -import premailer -import sass - -import flask -import flask_mail +from . import emails from eos.core.tasks import * from eos.base.election import * class WebTask(Task): def error(self): - import eosweb - - # Prepare email - title = 'Task failed: {}'.format(self.label) - - css = sass.compile(string=flask.render_template('email/base.scss')) - html = flask.render_template( - 'email/base.html', - title=title, - css=css, - text='

The task {} failed execution. The output was:

{}
'.format(self.label, '\n'.join(self.messages)) - ) - html = premailer.Premailer(html, strip_important=False).transform() - - body = flask.render_template( - 'email/base.txt', - title=title, - text='The task "{}" failed execution. The output was:\n\n{}'.format(self.label, '\n'.join(self.messages)) - ) - - # Send email - mail = flask_mail.Mail(eosweb.app) - msg = flask_mail.Message( - title, - recipients=[admin.email for admin in eosweb.app.config['ADMINS'] if isinstance(admin, EmailUser)], - body=body, - html=html - ) - mail.send(msg) + emails.task_email_failure(self) class WorkflowTaskEntryWebTask(WorkflowTaskEntryTask, WebTask): pass