diff options
| author | Barry Warsaw | 2016-11-14 03:30:54 +0000 |
|---|---|---|
| committer | Barry Warsaw | 2016-11-14 03:30:54 +0000 |
| commit | 54d32b872ee4e67a64a176077dbc49a4f87b9324 (patch) | |
| tree | ba9170245c9f9c87f5604e02a8dc1aaf37443319 | |
| parent | 366dc6517716b7c77c4b7a76559b1b6b5996fc8e (diff) | |
| parent | a9e62e4350d1a108af972ab9dc2043f76b98a04c (diff) | |
| download | mailman-54d32b872ee4e67a64a176077dbc49a4f87b9324.tar.gz mailman-54d32b872ee4e67a64a176077dbc49a4f87b9324.tar.zst mailman-54d32b872ee4e67a64a176077dbc49a4f87b9324.zip | |
| -rw-r--r-- | port_me/checkdbs.py | 2 | ||||
| -rw-r--r-- | src/mailman/app/moderator.py | 2 | ||||
| -rw-r--r-- | src/mailman/app/subscriptions.py | 4 | ||||
| -rw-r--r-- | src/mailman/app/tests/test_moderation.py | 21 | ||||
| -rw-r--r-- | src/mailman/app/tests/test_subscriptions.py | 12 | ||||
| -rw-r--r-- | src/mailman/chains/hold.py | 2 | ||||
| -rw-r--r-- | src/mailman/chains/tests/test_hold.py | 11 | ||||
| -rw-r--r-- | src/mailman/docs/NEWS.rst | 2 | ||||
| -rw-r--r-- | src/mailman/email/message.py | 12 |
9 files changed, 55 insertions, 13 deletions
diff --git a/port_me/checkdbs.py b/port_me/checkdbs.py index 9e5213b4c..7f46e97d4 100644 --- a/port_me/checkdbs.py +++ b/port_me/checkdbs.py @@ -199,7 +199,7 @@ def main(): mlist.GetBouncesEmail(), subject, text, mlist.preferred_language) - msg.send(mlist, **{'tomoderators': True}) + msg.send(mlist, to_moderators=True) finally: mlist.Unlock() diff --git a/src/mailman/app/moderator.py b/src/mailman/app/moderator.py index c3347c1ff..9d3856f33 100644 --- a/src/mailman/app/moderator.py +++ b/src/mailman/app/moderator.py @@ -204,7 +204,7 @@ def hold_unsubscription(mlist, email): msg = UserNotification( mlist.owner_address, mlist.owner_address, subject, text, mlist.preferred_language) - msg.send(mlist, tomoderators=True) + msg.send(mlist, to_moderators=True) return request_id diff --git a/src/mailman/app/subscriptions.py b/src/mailman/app/subscriptions.py index 9e915a25d..9e8d8dd9d 100644 --- a/src/mailman/app/subscriptions.py +++ b/src/mailman/app/subscriptions.py @@ -286,7 +286,7 @@ class SubscriptionWorkflow(_SubscriptionWorkflowCommon): msg = UserNotification( self.mlist.owner_address, self.mlist.owner_address, subject, text, self.mlist.preferred_language) - msg.send(self.mlist, tomoderators=True) + msg.send(self.mlist, to_moderators=True) # The workflow must stop running here. raise StopIteration @@ -434,7 +434,7 @@ class UnSubscriptionWorkflow(_SubscriptionWorkflowCommon): msg = UserNotification( self.mlist.owner_address, self.mlist.owner_address, subject, text, self.mlist.preferred_language) - msg.send(self.mlist, tomoderators=True) + msg.send(self.mlist, to_moderators=True) # The workflow must stop running here raise StopIteration diff --git a/src/mailman/app/tests/test_moderation.py b/src/mailman/app/tests/test_moderation.py index 20584da49..bb3958cd7 100644 --- a/src/mailman/app/tests/test_moderation.py +++ b/src/mailman/app/tests/test_moderation.py @@ -23,6 +23,7 @@ from mailman.app.lifecycle import create_list from mailman.app.moderator import ( handle_message, handle_unsubscription, hold_message, hold_unsubscription) from mailman.interfaces.action import Action +from mailman.interfaces.member import MemberRole from mailman.interfaces.messages import IMessageStore from mailman.interfaces.requests import IListRequests from mailman.interfaces.subscriptions import ISubscriptionManager @@ -31,7 +32,7 @@ from mailman.runners.incoming import IncomingRunner from mailman.runners.outgoing import OutgoingRunner from mailman.runners.pipeline import PipelineRunner from mailman.testing.helpers import ( - get_queue_messages, make_testable_runner, + get_queue_messages, make_testable_runner, set_preferred, specialized_message_from_string as mfs) from mailman.testing.layers import SMTPLayer from mailman.utilities.datetime import now @@ -158,15 +159,29 @@ class TestUnsubscription(unittest.TestCase): def test_unsubscribe_defer(self): # When unsubscriptions must be approved by the moderator, but the # moderator defers this decision. - anne = getUtility(IUserManager).create_address( - 'anne@example.org', 'Anne Person') + user_manager = getUtility(IUserManager) + anne = user_manager.create_address('anne@example.org', 'Anne Person') token, token_owner, member = self._manager.register( anne, pre_verified=True, pre_confirmed=True, pre_approved=True) self.assertIsNone(token) self.assertEqual(member.address.email, 'anne@example.org') + bart = user_manager.create_user('bart@example.com', 'Bart User') + address = set_preferred(bart) + self._mlist.subscribe(address, MemberRole.moderator) # Now hold and handle an unsubscription request. token = hold_unsubscription(self._mlist, 'anne@example.org') handle_unsubscription(self._mlist, token, Action.defer) + items = get_queue_messages('virgin', expected_count=2) + # Find the moderator message. + for item in items: + if item.msg['to'] == 'test-owner@example.com': + break + else: + raise AssertionError('No moderator email found') + self.assertEqual(item.msgdata['recipients'], {'bart@example.com'}) + self.assertEqual( + item.msg['subject'], + 'New unsubscription request from Test by anne@example.org') def test_bogus_token(self): # Try to handle an unsubscription with a bogus token. diff --git a/src/mailman/app/tests/test_subscriptions.py b/src/mailman/app/tests/test_subscriptions.py index 19198307d..f7b9b584e 100644 --- a/src/mailman/app/tests/test_subscriptions.py +++ b/src/mailman/app/tests/test_subscriptions.py @@ -24,7 +24,7 @@ from mailman.app.lifecycle import create_list from mailman.app.subscriptions import SubscriptionWorkflow from mailman.interfaces.bans import IBanManager from mailman.interfaces.mailinglist import SubscriptionPolicy -from mailman.interfaces.member import MembershipIsBannedError +from mailman.interfaces.member import MemberRole, MembershipIsBannedError from mailman.interfaces.pending import IPendings from mailman.interfaces.subscriptions import TokenOwner from mailman.interfaces.usermanager import IUserManager @@ -436,12 +436,22 @@ class TestSubscriptionWorkflow(unittest.TestCase): self._mlist.admin_immed_notify = True self._mlist.subscription_policy = SubscriptionPolicy.moderate anne = self._user_manager.create_address(self._anne) + bart = self._user_manager.create_user('bart@example.com', 'Bart User') + address = set_preferred(bart) + self._mlist.subscribe(address, MemberRole.moderator) workflow = SubscriptionWorkflow(self._mlist, anne, pre_verified=True, pre_confirmed=True) # Consume the entire state machine. list(workflow) + # Find the moderator message. items = get_queue_messages('virgin', expected_count=1) + for item in items: + if item.msg['to'] == 'test-owner@example.com': + break + else: + raise AssertionError('No moderator email found') + self.assertEqual(item.msgdata['recipients'], {'bart@example.com'}) message = items[0].msg self.assertEqual(message['From'], 'test-owner@example.com') self.assertEqual(message['To'], 'test-owner@example.com') diff --git a/src/mailman/chains/hold.py b/src/mailman/chains/hold.py index f1bd42961..f111aee3c 100644 --- a/src/mailman/chains/hold.py +++ b/src/mailman/chains/hold.py @@ -246,7 +246,7 @@ also appear in the first line of the body of the reply.""")), nmsg.attach(text) nmsg.attach(MIMEMessage(msg)) nmsg.attach(MIMEMessage(dmsg)) - nmsg.send(mlist, **dict(tomoderators=True)) + nmsg.send(mlist, to_moderators=True) # Log the held message. Log messages are not translated, so recast # the reasons in the English. with _.using('en'): diff --git a/src/mailman/chains/tests/test_hold.py b/src/mailman/chains/tests/test_hold.py index 0957fe880..13dd1b40e 100644 --- a/src/mailman/chains/tests/test_hold.py +++ b/src/mailman/chains/tests/test_hold.py @@ -24,10 +24,11 @@ from mailman.app.lifecycle import create_list from mailman.chains.hold import autorespond_to_sender from mailman.core.chains import process as process_chain from mailman.interfaces.autorespond import IAutoResponseSet, Response +from mailman.interfaces.member import MemberRole from mailman.interfaces.messages import IMessageStore from mailman.interfaces.usermanager import IUserManager from mailman.testing.helpers import ( - LogFileMark, configuration, get_queue_messages, + LogFileMark, configuration, get_queue_messages, set_preferred, specialized_message_from_string as mfs) from mailman.testing.layers import ConfigLayer from pkg_resources import resource_filename @@ -94,6 +95,7 @@ class TestHoldChain(unittest.TestCase): def setUp(self): self._mlist = create_list('test@example.com') + self._user_manager = getUtility(IUserManager) def test_hold_chain(self): msg = mfs("""\ @@ -133,6 +135,9 @@ A message body. # Issue #144 - UnicodeEncodeError in the hold chain. self._mlist.admin_immed_notify = True self._mlist.respond_to_post_requests = False + bart = self._user_manager.create_user('bart@example.com', 'Bart User') + address = set_preferred(bart) + self._mlist.subscribe(address, MemberRole.moderator) path = resource_filename('mailman.chains.tests', 'issue144.eml') with open(path, 'rb') as fp: msg = mfb(fp.read()) @@ -142,8 +147,8 @@ A message body. # delivery to the moderators. items = get_queue_messages('virgin', expected_count=1) msgdata = items[0].msgdata - self.assertTrue(msgdata['tomoderators']) - self.assertEqual(msgdata['recipients'], {'test-owner@example.com'}) + # Should get sent to moderators. + self.assertEqual(msgdata['recipients'], {'bart@example.com'}) # Ensure that the subject looks correct in the postauth.txt. msg = items[0].msg value = None diff --git a/src/mailman/docs/NEWS.rst b/src/mailman/docs/NEWS.rst index f72498a1d..fdde0589f 100644 --- a/src/mailman/docs/NEWS.rst +++ b/src/mailman/docs/NEWS.rst @@ -97,6 +97,8 @@ Bugs (Closes: #283) * Remove the digest mbox files after the digests are sent. Given by Aurélien Bompard. (Closes: #259) + * Messages sent to the list's moderators now include the actual recipient + addresses. Given by Tom Briles. (Closes: #68) Configuration ------------- diff --git a/src/mailman/email/message.py b/src/mailman/email/message.py index 994d44cce..ebfef9d9b 100644 --- a/src/mailman/email/message.py +++ b/src/mailman/email/message.py @@ -31,6 +31,7 @@ from email.header import Header from email.mime.multipart import MIMEMultipart from mailman import public from mailman.config import config +from mailman.interfaces.member import DeliveryStatus COMMASPACE = ', ' @@ -131,7 +132,7 @@ class UserNotification(Message): self['To'] = recipients self.recipients = set([recipients]) - def send(self, mlist, add_precedence=True, **_kws): + def send(self, mlist, *, add_precedence=True, to_moderators=False, **_kws): """Sends the message by enqueuing it to the 'virgin' queue. This is used for all internally crafted messages. @@ -141,6 +142,9 @@ class UserNotification(Message): :param add_precedence: Flag indicating whether a `Precedence: bulk` header should be added to the message or not. :type add_precedence: bool + :param to_moderators: Flag indicating whether the message should be + sent to the list's moderators instead of the list's membership. + :type to_moderators: bool This function also accepts arbitrary keyword arguments. The key/value pairs for **kws is added to the metadata dictionary associated with @@ -158,6 +162,12 @@ class UserNotification(Message): # don't override an existing Precedence: header. if 'precedence' not in self and add_precedence: self['Precedence'] = 'bulk' + if to_moderators: + self.recipients = set( + member.address.email + for member in mlist.moderators.members + if member.delivery_status is DeliveryStatus.enabled) + self['To'] = COMMASPACE.join(self.recipients) self._enqueue(mlist, **_kws) def _enqueue(self, mlist, **_kws): |
