summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBarry Warsaw2012-03-01 15:07:43 -0500
committerBarry Warsaw2012-03-01 15:07:43 -0500
commitde572e747fb46f1c942dbe0dc37fb9fd7f8ae01a (patch)
tree7bb8b06a32d3b713323baad4309bca50f791cd25 /src
parent3559021627038314f5bf22d3515738d99d0f8805 (diff)
downloadmailman-de572e747fb46f1c942dbe0dc37fb9fd7f8ae01a.tar.gz
mailman-de572e747fb46f1c942dbe0dc37fb9fd7f8ae01a.tar.zst
mailman-de572e747fb46f1c942dbe0dc37fb9fd7f8ae01a.zip
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).
Diffstat (limited to 'src')
-rw-r--r--src/mailman/app/registrar.py1
-rw-r--r--src/mailman/commands/eml_confirm.py10
-rw-r--r--src/mailman/runners/tests/test_confirm.py49
3 files changed, 57 insertions, 3 deletions
diff --git a/src/mailman/app/registrar.py b/src/mailman/app/registrar.py
index a22e5df8c..448b4f375 100644
--- a/src/mailman/app/registrar.py
+++ b/src/mailman/app/registrar.py
@@ -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
diff --git a/src/mailman/commands/eml_confirm.py b/src/mailman/commands/eml_confirm.py
index 97bb80f06..2461192ed 100644
--- a/src/mailman/commands/eml_confirm.py
+++ b/src/mailman/commands/eml_confirm.py
@@ -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
diff --git a/src/mailman/runners/tests/test_confirm.py b/src/mailman/runners/tests/test_confirm.py
index 94a630a42..21dc653d2 100644
--- a/src/mailman/runners/tests/test_confirm.py
+++ b/src/mailman/runners/tests/test_confirm.py
@@ -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: test-confirm@example.com
subject = 'Re: confirm {0}'.format(self._token)
to = 'test-confirm+{0}@example.com'.format(self._token)
msg = mfs("""\
-From: Anne Person <anne@example.org
+From: Anne Person <anne@example.org>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
@@ -157,11 +158,13 @@ Franziskanerstra=C3=9Fe
set(['anne@example.org']))
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 <anne@example.org
+From: Anne Person <anne@example.org>
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(['anne@example.org']))
+
+ 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 <anne@example.org>
+
+""")
+ msg['Subject'] = subject
+ msg['To'] = to
+ self._commandq.enqueue(msg, dict(listname='test@example.com',
+ 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('anne@example.org')
+ self.assertEqual(list(user.addresses)[0].email, 'anne@example.org')
+ # 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])