You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2016/09/01 16:08:19 UTC
[2/4] allura git commit: [#8117] add email notifications to 2FA;
add helper with nice From: address
[#8117] add email notifications to 2FA; add helper with nice From: address
Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/b8562071
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/b8562071
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/b8562071
Branch: refs/heads/db/8117
Commit: b85620717fb7a727a6a727c9f5f4dea0eb75e8a7
Parents: 56fa52c
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Aug 31 18:29:39 2016 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Thu Sep 1 10:54:05 2016 -0400
----------------------------------------------------------------------
Allura/allura/controllers/auth.py | 13 ++++++--
Allura/allura/lib/multifactor.py | 2 +-
Allura/allura/tasks/mail_tasks.py | 33 +++++++++++++++++++-
.../allura/templates/mail/twofactor_disabled.md | 26 +++++++++++++++
.../allura/templates/mail/twofactor_enabled.md | 26 +++++++++++++++
Allura/allura/tests/functional/test_auth.py | 11 +++++++
6 files changed, 107 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/allura/blob/b8562071/Allura/allura/controllers/auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/auth.py b/Allura/allura/controllers/auth.py
index 7dbfa1b..42840d2 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -50,6 +50,7 @@ from allura.lib.widgets import forms, form_fields as ffw
from allura.lib import mail_util
from allura.lib.multifactor import TotpService
from allura.controllers import BaseController
+from allura.tasks.mail_tasks import send_system_mail_to_user
log = logging.getLogger(__name__)
@@ -685,7 +686,6 @@ class PreferencesController(BaseController):
@reconfirm_auth
@require_post()
def totp_set(self, code, **kw):
- # TODO: email notification
key = session['totp_new_key']
totp_service = TotpService.get()
totp = totp_service.Totp(key)
@@ -702,18 +702,27 @@ class PreferencesController(BaseController):
del session['totp_new_key']
session.save()
tg.flash('Two factor authentication has now been set up.')
+ email_body = g.jinja2_env.get_template('allura:templates/mail/twofactor_enabled.md').render(dict(
+ user=c.user,
+ config=config,
+ ))
+ send_system_mail_to_user(c.user, u'Two-Factor Authentication Enabled', email_body)
redirect('.')
@expose()
@require_post()
@reconfirm_auth
def multifactor_disable(self, **kw):
- # TODO: email notification
h.auditlog_user('Disabled multifactor TOTP')
totp_service = TotpService.get()
totp_service.set_secret_key(c.user, None)
c.user.set_pref('multifactor', False)
tg.flash('Multifactor authentication has now been disabled.')
+ email_body = g.jinja2_env.get_template('allura:templates/mail/twofactor_disabled.md').render(dict(
+ user=c.user,
+ config=config,
+ ))
+ send_system_mail_to_user(c.user, u'Two-Factor Authentication Disabled', email_body)
redirect('.')
http://git-wip-us.apache.org/repos/asf/allura/blob/b8562071/Allura/allura/lib/multifactor.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/multifactor.py b/Allura/allura/lib/multifactor.py
index 9970893..56827a4 100644
--- a/Allura/allura/lib/multifactor.py
+++ b/Allura/allura/lib/multifactor.py
@@ -117,7 +117,7 @@ class TotpService(object):
def set_secret_key(self, user, key):
'''
:param user: a :class:`User <allura.model.auth.User>`
- :param bytes key: may be `None` to clear out a key
+ :param bytes|None key: may be `None` to clear out a key
'''
raise NotImplementedError('set_secret_key')
http://git-wip-us.apache.org/repos/asf/allura/blob/b8562071/Allura/allura/tasks/mail_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/mail_tasks.py b/Allura/allura/tasks/mail_tasks.py
index 963555f..ce0f98a 100644
--- a/Allura/allura/tasks/mail_tasks.py
+++ b/Allura/allura/tasks/mail_tasks.py
@@ -18,7 +18,7 @@
import logging
import HTMLParser
-from pylons import tmpl_context as c, app_globals as g
+from pylons import tmpl_context as c, app_globals as g, config
from bson import ObjectId
from allura.lib import helpers as h
@@ -30,6 +30,7 @@ log = logging.getLogger(__name__)
smtp_client = mail_util.SMTPClient()
+
def mail_meta_content(metalink):
'''
Helper function used to include a view action button in your email client
@@ -47,6 +48,7 @@ def mail_meta_content(metalink):
<meta itemprop="description" content="View"></meta>
</div>""" % metalink)
+
@task
def route_email(
peer, mailfrom, rcpttos, data):
@@ -223,3 +225,32 @@ def sendsimplemail(
smtp_client.sendmail(
[toaddr], fromaddr, reply_to, subject, message_id,
in_reply_to, multi_msg, sender=sender, references=references, cc=cc, to=toaddr)
+
+
+def send_system_mail_to_user(user_or_emailaddr, subject, text):
+ '''
+ Sends a standard email from the Allura system itself, to a user.
+ This is a helper function around sendsimplemail() that generates a new task
+
+ :param user_or_emailaddr: an email addres (str) or a User object
+ :param subject: subject of the email
+ :param text: text of the email (markdown)
+ '''
+ if isinstance(user_or_emailaddr, basestring):
+ toaddr = user_or_emailaddr
+ else:
+ toaddr = user_or_emailaddr._id
+
+ email = {
+ 'toaddr': toaddr,
+ 'fromaddr': u'"{}" <{}>'.format(
+ config['site_name'],
+ config['forgemail.return_path']
+ ),
+ 'sender': unicode(config['forgemail.return_path']),
+ 'reply_to': unicode(config['forgemail.return_path']),
+ 'message_id': h.gen_message_id(),
+ 'subject': subject,
+ 'text': text,
+ }
+ sendsimplemail.post(**email)
http://git-wip-us.apache.org/repos/asf/allura/blob/b8562071/Allura/allura/templates/mail/twofactor_disabled.md
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/mail/twofactor_disabled.md b/Allura/allura/templates/mail/twofactor_disabled.md
new file mode 100644
index 0000000..3e4e619
--- /dev/null
+++ b/Allura/allura/templates/mail/twofactor_disabled.md
@@ -0,0 +1,26 @@
+{#
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-#}
+
+Hello {{ user.username }},
+
+You have recently disabled two-factor authentication on {{ config['site_name'] }}. :(
+
+{% block footer %}
+If you did not do this, please contact us immediately.
+{% endblock %}
http://git-wip-us.apache.org/repos/asf/allura/blob/b8562071/Allura/allura/templates/mail/twofactor_enabled.md
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/mail/twofactor_enabled.md b/Allura/allura/templates/mail/twofactor_enabled.md
new file mode 100644
index 0000000..e2d0ca0
--- /dev/null
+++ b/Allura/allura/templates/mail/twofactor_enabled.md
@@ -0,0 +1,26 @@
+{#
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-#}
+
+Hello {{ user.username }},
+
+You have recently set up new two-factor authentication on {{ config['site_name'] }}. This is a confirmation email, you are all set.
+
+{% block footer %}
+If you did not do this, please contact us immediately.
+{% endblock %}
http://git-wip-us.apache.org/repos/asf/allura/blob/b8562071/Allura/allura/tests/functional/test_auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_auth.py b/Allura/allura/tests/functional/test_auth.py
index e203869..a50a13a 100644
--- a/Allura/allura/tests/functional/test_auth.py
+++ b/Allura/allura/tests/functional/test_auth.py
@@ -2072,6 +2072,11 @@ class TestTwoFactor(TestController):
assert_equal('Two factor authentication has now been set up.', json.loads(self.webflash(r))['message'],
self.webflash(r))
+ tasks = M.MonQTask.query.find(dict(task_name='allura.tasks.mail_tasks.sendsimplemail')).all()
+ assert_equal(len(tasks), 1)
+ assert_equal(tasks[0].kwargs['subject'], 'Two-Factor Authentication Enabled')
+ assert_in('new two-factor authentication', tasks[0].kwargs['text'])
+
def test_reset_totp(self):
self._init_totp()
@@ -2137,6 +2142,12 @@ class TestTwoFactor(TestController):
assert_equal(user.get_pref('multifactor'), False)
assert_equal(TotpService().get().get_secret_key(user), None)
+ # email confirmation
+ tasks = M.MonQTask.query.find(dict(task_name='allura.tasks.mail_tasks.sendsimplemail')).all()
+ assert_equal(len(tasks), 1)
+ assert_equal(tasks[0].kwargs['subject'], 'Two-Factor Authentication Disabled')
+ assert_in('disabled two-factor authentication', tasks[0].kwargs['text'])
+
def test_login_totp(self):
self._init_totp()