Commit de572e74 authored by Barry Warsaw's avatar Barry Warsaw

Prevent the `confirm` command from running more than once on the same token.

Also add some debugging to the verification message, IOW, which template is it
using (this may be more generally useful, but for now, it's an experiment).
parent 35590216
......@@ -87,6 +87,7 @@ class Registrar:
# Send a verification email to the address.
text = _(resource_string('mailman.templates.en', 'verify.txt'))
msg = UserNotification(email, confirm_address, subject, text)
msg['X-Mailman-Template'] = 'verify.txt'
msg.send(mlist)
return token
......
......@@ -49,7 +49,15 @@ class Confirm:
if len(arguments) == 0:
print >> results, _('No confirmation token found')
return ContinueProcessing.no
succeeded = getUtility(IRegistrar).confirm(arguments[0])
# Make sure we don't try to confirm the same token more than once.
token = arguments[0]
tokens = getattr(results, 'confirms', set())
if token in tokens:
# Do not try to confirm this one again.
return ContinueProcessing.yes
tokens.add(token)
results.confirms = tokens
succeeded = getUtility(IRegistrar).confirm(token)
if succeeded:
print >> results, _('Confirmed')
return ContinueProcessing.yes
......
......@@ -27,6 +27,7 @@ __all__ = [
import unittest
from datetime import datetime
from email.iterators import body_line_iterator
from zope.component import getUtility
from mailman.app.lifecycle import create_list
......@@ -103,7 +104,7 @@ To: [email protected]
subject = 'Re: confirm {0}'.format(self._token)
to = 'test-confirm+{0}@example.com'.format(self._token)
msg = mfs("""\
From: Anne Person <[email protected]
From: Anne Person <[email protected]>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
......@@ -157,11 +158,13 @@ Franziskanerstra=C3=9Fe
set(['[email protected]']))
def test_confirm_with_no_command_in_utf8_body(self):
# Clear out the virgin queue so that the test below only sees the
# reply to the confirmation message.
get_queue_messages('virgin')
subject = 'Re: confirm {0}'.format(self._token)
to = 'test-confirm+{0}@example.com'.format(self._token)
msg = mfs("""\
From: Anne Person <[email protected]
From: Anne Person <[email protected]>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
......@@ -186,3 +189,45 @@ Franziskanerstra=C3=9Fe
self.assertEqual(len(messages), 1)
self.assertEqual(messages[0].msgdata['recipients'],
set(['[email protected]']))
def test_double_confirmation(self):
# 'confirm' in the Subject and in the To header should not try to
# confirm the token twice.
#
# Clear out the virgin queue so that the test below only sees the
# reply to the confirmation message.
get_queue_messages('virgin')
subject = 'Re: confirm {0}'.format(self._token)
to = 'test-confirm+{0}@example.com'.format(self._token)
msg = mfs("""\
From: Anne Person <[email protected]>
""")
msg['Subject'] = subject
msg['To'] = to
self._commandq.enqueue(msg, dict(listname='[email protected]',
subaddress='confirm'))
self._runner.run()
# Anne is now a confirmed member so her user record and email address
# should exist in the database.
manager = getUtility(IUserManager)
user = manager.get_user('[email protected]')
self.assertEqual(list(user.addresses)[0].email, '[email protected]')
# Make sure that the confirmation was not attempted twice.
messages = get_queue_messages('virgin')
self.assertEqual(len(messages), 1)
# Search the contents of the results message. There should be just
# one 'Confirmation email' line.
confirmation_lines = []
in_results = False
for line in body_line_iterator(messages[0].msg, decode=True):
line = line.strip()
if in_results:
if line.startswith('- Done'):
break
if len(line) > 0:
confirmation_lines.append(line)
if line.strip() == '- Results:':
in_results = True
self.assertEqual(len(confirmation_lines), 1)
self.assertFalse('did not match' in confirmation_lines[0])
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment