From 180d4968c277b533507db04bb9d363c6a65a2af5 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Wed, 4 Apr 2012 23:43:40 -0600 Subject: * A mailing list's *moderator password* is no longer stored in the clear; it is hashed with the currently selected scheme. Also: - Simplify and rewrite the approved.rst doctest. Now just document the good path, and only describe its functionality using the Approved: header, which is the recommended header. - Greatly expand the unittests for the approved rule. --- src/mailman/rules/tests/test_approved.py | 358 ++++++++++++++++++++++++++++++- 1 file changed, 356 insertions(+), 2 deletions(-) (limited to 'src/mailman/rules/tests/test_approved.py') diff --git a/src/mailman/rules/tests/test_approved.py b/src/mailman/rules/tests/test_approved.py index 8ffe68aa9..d078556ba 100644 --- a/src/mailman/rules/tests/test_approved.py +++ b/src/mailman/rules/tests/test_approved.py @@ -15,19 +15,25 @@ # You should have received a copy of the GNU General Public License along with # GNU Mailman. If not, see . -"""Test the mime_delete handler.""" +"""Test the `approved` handler.""" from __future__ import absolute_import, print_function, unicode_literals __metaclass__ = type __all__ = [ 'TestApproved', + 'TestApprovedNonASCII', + 'TestApprovedPseudoHeader', + 'TestApprovedPseudoHeaderMIME', ] import unittest +from flufl.password import lookup, make_secret + from mailman.app.lifecycle import create_list +from mailman.config import config from mailman.rules import approved from mailman.testing.helpers import ( specialized_message_from_string as mfs) @@ -40,6 +46,355 @@ class TestApproved(unittest.TestCase): layer = ConfigLayer + def setUp(self): + self._mlist = create_list('test@example.com') + scheme = lookup(config.passwords.password_scheme.upper()) + self._mlist.moderator_password = make_secret('super secret', scheme) + self._rule = approved.Approved() + self._msg = mfs("""\ +From: anne@example.com +To: test@example.com +Subject: A Message with non-ascii body +Message-ID: +MIME-Version: 1.0 + +A message body. +""") + + def test_approved_header(self): + self._msg['Approved'] = 'super secret' + result = self._rule.check(self._mlist, self._msg, {}) + self.assertTrue(result) + + def test_approve_header(self): + self._msg['Approve'] = 'super secret' + result = self._rule.check(self._mlist, self._msg, {}) + self.assertTrue(result) + + def test_x_approved_header(self): + self._msg['X-Approved'] = 'super secret' + result = self._rule.check(self._mlist, self._msg, {}) + self.assertTrue(result) + + def test_x_approve_header(self): + self._msg['X-Approve'] = 'super secret' + result = self._rule.check(self._mlist, self._msg, {}) + self.assertTrue(result) + + def test_approved_header_wrong_password(self): + self._msg['Approved'] = 'not the password' + result = self._rule.check(self._mlist, self._msg, {}) + self.assertFalse(result) + + def test_approve_header_wrong_password(self): + self._msg['Approve'] = 'not the password' + result = self._rule.check(self._mlist, self._msg, {}) + self.assertFalse(result) + + def test_x_approved_header_wrong_password(self): + self._msg['X-Approved'] = 'not the password' + result = self._rule.check(self._mlist, self._msg, {}) + self.assertFalse(result) + + def test_x_approve_header_wrong_password(self): + self._msg['X-Approve'] = 'not the password' + result = self._rule.check(self._mlist, self._msg, {}) + self.assertFalse(result) + + def test_removes_approved_header(self): + self._msg['Approved'] = 'super secret' + self._rule.check(self._mlist, self._msg, {}) + self.assertEqual(self._msg['approved'], None) + + def test_removes_approve_header(self): + self._msg['Approve'] = 'super secret' + self._rule.check(self._mlist, self._msg, {}) + self.assertEqual(self._msg['approve'], None) + + def test_removes_x_approved_header(self): + self._msg['X-Approved'] = 'super secret' + self._rule.check(self._mlist, self._msg, {}) + self.assertEqual(self._msg['x-approved'], None) + + def test_removes_x_approve_header(self): + self._msg['X-Approve'] = 'super secret' + self._rule.check(self._mlist, self._msg, {}) + self.assertEqual(self._msg['x-approve'], None) + + def test_removes_approved_header_wrong_password(self): + self._msg['Approved'] = 'not the password' + self._rule.check(self._mlist, self._msg, {}) + self.assertEqual(self._msg['approved'], None) + + def test_removes_approve_header_wrong_password(self): + self._msg['Approve'] = 'not the password' + self._rule.check(self._mlist, self._msg, {}) + self.assertEqual(self._msg['approve'], None) + + def test_removes_x_approved_header_wrong_password(self): + self._msg['X-Approved'] = 'not the password' + self._rule.check(self._mlist, self._msg, {}) + self.assertEqual(self._msg['x-approved'], None) + + def test_removes_x_approve_header_wrong_password(self): + self._msg['X-Approve'] = 'not the password' + self._rule.check(self._mlist, self._msg, {}) + self.assertEqual(self._msg['x-approve'], None) + + + +class TestApprovedPseudoHeader(unittest.TestCase): + """Test the approved handler.""" + + layer = ConfigLayer + + def setUp(self): + self._mlist = create_list('test@example.com') + scheme = lookup(config.passwords.password_scheme.upper()) + self._mlist.moderator_password = make_secret('super secret', scheme) + self._rule = approved.Approved() + self._msg = mfs("""\ +From: anne@example.com +To: test@example.com +Subject: A Message with non-ascii body +Message-ID: +MIME-Version: 1.0 + +""") + + def test_approved_pseudo_header(self): + self._msg.set_payload("""\ +Approved: super secret + """) + result = self._rule.check(self._mlist, self._msg, {}) + self.assertTrue(result) + + def test_approve_pseudo_header(self): + self._msg.set_payload("""\ +Approve: super secret + """) + result = self._rule.check(self._mlist, self._msg, {}) + self.assertTrue(result) + + def test_x_approved_pseudo_header(self): + self._msg.set_payload("""\ +X-Approved: super secret + """) + result = self._rule.check(self._mlist, self._msg, {}) + self.assertTrue(result) + + def test_x_approve_pseudo_header(self): + self._msg.set_payload("""\ +X-Approve: super secret + """) + result = self._rule.check(self._mlist, self._msg, {}) + self.assertTrue(result) + + def test_approved_pseudo_header_wrong_password(self): + self._msg.set_payload("""\ +Approved: not the password + """) + result = self._rule.check(self._mlist, self._msg, {}) + self.assertFalse(result) + + def test_approve_pseudo_header_wrong_password(self): + self._msg.set_payload("""\ +Approve: not the password + """) + result = self._rule.check(self._mlist, self._msg, {}) + self.assertFalse(result) + + def test_x_approved_pseudo_header_wrong_password(self): + self._msg.set_payload("""\ +X-Approved: not the password + """) + result = self._rule.check(self._mlist, self._msg, {}) + self.assertFalse(result) + + def test_x_approve_pseudo_header_wrong_password(self): + self._msg.set_payload("""\ +X-Approve: not the password + """) + result = self._rule.check(self._mlist, self._msg, {}) + self.assertFalse(result) + + def test_removes_approved_pseudo_header(self): + self._msg.set_payload("""\ +Approved: super secret + """) + self._rule.check(self._mlist, self._msg, {}) + self.assertFalse('Approved' in self._msg.get_payload()) + + def test_removes_approve_pseudo_header(self): + self._msg.set_payload("""\ +Approve: super secret + """) + self._rule.check(self._mlist, self._msg, {}) + self.assertFalse('Approve' in self._msg.get_payload()) + + def test_removes_x_approved_pseudo_header(self): + self._msg.set_payload("""\ +X-Approved: super secret + """) + self._rule.check(self._mlist, self._msg, {}) + self.assertFalse('X-Approved' in self._msg.get_payload()) + + def test_removes_x_approve_pseudo_header(self): + self._msg.set_payload("""\ +X-Approve: super secret + """) + self._rule.check(self._mlist, self._msg, {}) + self.assertFalse('X-Approve' in self._msg.get_payload()) + + def test_removes_approved_pseudo_header_wrong_password(self): + self._msg.set_payload("""\ +Approved: not the password + """) + self._rule.check(self._mlist, self._msg, {}) + self.assertFalse('Approved' in self._msg.get_payload()) + + def test_removes_approve_pseudo_header_wrong_password(self): + self._msg.set_payload("""\ +Approve: not the password + """) + self._rule.check(self._mlist, self._msg, {}) + self.assertFalse('Approve' in self._msg.get_payload()) + + def test_removes_x_approved_pseudo_header_wrong_password(self): + self._msg.set_payload("""\ +X-Approved: not the password + """) + self._rule.check(self._mlist, self._msg, {}) + self.assertFalse('X-Approved' in self._msg.get_payload()) + + def test_removes_x_approve_pseudo_header_wrong_password(self): + self._msg.set_payload("""\ +X-Approve: not the password + """) + self._rule.check(self._mlist, self._msg, {}) + self.assertFalse('X-Approve' in self._msg.get_payload()) + + + +class TestApprovedPseudoHeaderMIME(unittest.TestCase): + """Test the approved handler.""" + + layer = ConfigLayer + + def setUp(self): + self._mlist = create_list('test@example.com') + scheme = lookup(config.passwords.password_scheme.upper()) + self._mlist.moderator_password = make_secret('super secret', scheme) + self._rule = approved.Approved() + self._msg_text_template = """\ +From: anne@example.com +To: test@example.com +Subject: A Message with non-ascii body +Message-ID: +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="AAA" + +--AAA +Content-Type: application/x-ignore + +{0}: not the password +The above line will be ignored. + +--AAA +Content-Type: text/plain + +{0}: {1} +An important message. + +""" + + def test_approved_pseudo_header_mime(self): + msg = mfs(self._msg_text_template.format('Approved', 'super secret')) + result = self._rule.check(self._mlist, msg, {}) + self.assertTrue(result) + + def test_approve_pseudo_header_mime(self): + msg = mfs(self._msg_text_template.format('Approve', 'super secret')) + result = self._rule.check(self._mlist, msg, {}) + self.assertTrue(result) + + def test_x_approved_pseudo_header_mime(self): + msg = mfs(self._msg_text_template.format('X-Approved', 'super secret')) + result = self._rule.check(self._mlist, msg, {}) + self.assertTrue(result) + + def test_x_approve_pseudo_header_mime(self): + msg = mfs(self._msg_text_template.format('X-Approve', 'super secret')) + result = self._rule.check(self._mlist, msg, {}) + self.assertTrue(result) + + def test_approved_pseudo_header_wrong_password_mime(self): + msg = mfs(self._msg_text_template.format('Approved', 'not password')) + result = self._rule.check(self._mlist, msg, {}) + self.assertFalse(result) + + def test_approve_pseudo_header_wrong_password_mime(self): + msg = mfs(self._msg_text_template.format('Approve', 'not password')) + result = self._rule.check(self._mlist, msg, {}) + self.assertFalse(result) + + def test_x_approved_pseudo_header_wrong_password_mime(self): + msg = mfs(self._msg_text_template.format('X-Approved', 'not password')) + result = self._rule.check(self._mlist, msg, {}) + self.assertFalse(result) + + def test_x_approve_pseudo_header_wrong_password_mime(self): + msg = mfs(self._msg_text_template.format('X-Approve', 'not password')) + result = self._rule.check(self._mlist, msg, {}) + self.assertFalse(result) + + def test_removes_approved_pseudo_header_mime(self): + msg = mfs(self._msg_text_template.format('Approved', 'super secret')) + self._rule.check(self._mlist, msg, {}) + self.assertFalse('Approved' in msg.get_payload(1).get_payload()) + + def test_removes_approve_pseudo_header_mime(self): + msg = mfs(self._msg_text_template.format('Approve', 'super secret')) + self._rule.check(self._mlist, msg, {}) + self.assertFalse('Approve' in msg.get_payload(1).get_payload()) + + def test_removes_x_approved_pseudo_header_mime(self): + msg = mfs(self._msg_text_template.format('X-Approved', 'super secret')) + self._rule.check(self._mlist, msg, {}) + self.assertFalse('X-Approved' in msg.get_payload(1).get_payload()) + + def test_removes_x_approve_pseudo_header_mime(self): + msg = mfs(self._msg_text_template.format('X-Approve', 'super secret')) + self._rule.check(self._mlist, msg, {}) + self.assertFalse('X-Approve' in msg.get_payload(1).get_payload()) + + def test_removes_approved_pseudo_header_wrong_password_mime(self): + msg = mfs(self._msg_text_template.format('Approved', 'not password')) + self._rule.check(self._mlist, msg, {}) + self.assertFalse('Approved' in msg.get_payload(1).get_payload()) + + def test_removes_approve_pseudo_header_wrong_password_mime(self): + msg = mfs(self._msg_text_template.format('Approve', 'not password')) + self._rule.check(self._mlist, msg, {}) + self.assertFalse('Approve' in msg.get_payload(1).get_payload()) + + def test_removes_x_approved_pseudo_header_wrong_password_mime(self): + msg = mfs(self._msg_text_template.format('X-Approved', 'not password')) + self._rule.check(self._mlist, msg, {}) + self.assertFalse('X-Approved' in msg.get_payload(1).get_payload()) + + def test_removes_x_approve_pseudo_header_wrong_password_mime(self): + msg = mfs(self._msg_text_template.format('X-Approve', 'not password')) + self._rule.check(self._mlist, msg, {}) + self.assertFalse('X-Approve' in msg.get_payload(1).get_payload()) + + + +class TestApprovedNonASCII(unittest.TestCase): + """Test the approved handler with non-ascii messages.""" + + layer = ConfigLayer + def setUp(self): self._mlist = create_list('test@example.com') self._rule = approved.Approved() @@ -53,7 +408,6 @@ Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable This is a message body with a non-ascii character =E4 - """) def test_nonascii_body_missing_header(self): -- cgit v1.2.3-70-g09d2