Mark Sapiro pushed to branch master at GNU Mailman / Mailman Core
Commits: a43b7cc5 by Mark Sapiro at 2021-06-12T13:22:47-07:00 Missing held messages can now be accepted and/or forwarded. - - - - - f8760c92 by Mark Sapiro at 2021-06-12T22:45:40+00:00 Merge branch 'lost' into 'master' Missing held messages can now be accepted and/or forwarded. Closes #914 See merge request mailman/mailman!874 - - - - - 3 changed files: - src/mailman/app/moderator.py - src/mailman/app/tests/test_moderation.py - src/mailman/docs/NEWS.rst Changes: ===================================== src/mailman/app/moderator.py ===================================== @@ -92,6 +92,19 @@ def hold_message(mlist, msg, msgdata=None, reason=None): return request_id +def _lost_message(mlist, subject, sender, message_id): + # Create a substitute for a message not found in the message store. + text = _("""\ +The content of this message was lost. It was probably cross-posted to +multiple lists and previously handled on another list. +""") + msg = UserNotification( + mlist.posting_address, sender, subject, text, mlist.preferred_language) + del msg['message-id'] + msg['Message-ID'] = message_id + return msg + + @public def handle_message(mlist, id, action, comment=None, forward=None): message_store = getUtility(IMessageStore) @@ -121,6 +134,8 @@ def handle_message(mlist, id, action, comment=None, forward=None): elif action is Action.accept: # Start by getting the message from the message store. msg = message_store.get_message_by_id(message_id) + if msg is None: + msg = _lost_message(mlist, subject, sender, message_id) # Delete moderation-specific entries from the message metadata. for key in list(msgdata): if key.startswith('_mod_'): @@ -148,6 +163,8 @@ def handle_message(mlist, id, action, comment=None, forward=None): if forward: # Get a copy of the original message from the message store. msg = message_store.get_message_by_id(message_id) + if msg is None: + msg = _lost_message(mlist, subject, sender, message_id) # It's possible the forwarding address list is a comma separated list # of display_name/address pairs. addresses = [addr[1] for addr in getaddresses(forward)] ===================================== src/mailman/app/tests/test_moderation.py ===================================== @@ -96,6 +96,44 @@ Message-ID: <alpha> self.assertEqual(message['x-mailfrom'], 'test-boun...@example.com') self.assertEqual(message['x-rcptto'], 'b...@example.com') + def test_missing_accepted_message_gets_posted(self): + # A message that is accepted by the moderator should get posted to the + # mailing list. LP: #827697 + msgdata = dict(listname='t...@example.com', + recipients=['b...@example.com']) + request_id = hold_message(self._mlist, self._msg, msgdata) + message_store = getUtility(IMessageStore) + message_store.delete_message('<alpha>') + handle_message(self._mlist, request_id, Action.accept) + self._in.run() + self._pipeline.run() + self._out.run() + messages = list(SMTPLayer.smtpd.messages) + self.assertEqual(len(messages), 1) + message = messages[0] + # We don't need to test the entire posted message, just the bits that + # prove it got sent out. + self.assertIn('x-mailman-version', message) + self.assertIn('x-peer', message) + # The X-Mailman-Approved-At header has local timezone information in + # it, so test that separately. + self.assertEqual(message['x-mailman-approved-at'][:-5], + 'Mon, 01 Aug 2005 07:49:23 ') + del message['x-mailman-approved-at'] + # The Message-ID matches the original. + self.assertEqual(message['message-id'], '<alpha>') + # Anne sent the message and the mailing list received it. + self.assertEqual(message['from'], 'a...@example.com') + self.assertEqual(message['to'], 't...@example.com') + # The Subject header has the list's prefix. + self.assertEqual(message['subject'], '[Test] hold me') + # The list's -bounce address is the actual sender, and Bart is the + # only actual recipient. These headers are added by the testing + # framework and don't show up in production. They match the RFC 5321 + # envelope. + self.assertEqual(message['x-mailfrom'], 'test-boun...@example.com') + self.assertEqual(message['x-rcptto'], 'b...@example.com') + def test_hold_action_alias_for_defer(self): # In handle_message(), the 'hold' action is the same as 'defer' for # purposes of this API. @@ -130,6 +168,23 @@ Message-ID: <alpha> self.assertEqual(list(items[0].msgdata['recipients']), ['z...@example.com']) + def test_missing_forward(self): + # We can forward the message to an email address. + request_id = hold_message(self._mlist, self._msg) + message_store = getUtility(IMessageStore) + message_store.delete_message('<alpha>') + handle_message(self._mlist, request_id, Action.discard, + forward=['z...@example.com']) + # The forwarded message lives in the virgin queue. + items = get_queue_messages('virgin', expected_count=1) + self.assertEqual(str(items[0].msg['subject']), + 'Forward of moderated message') + self.assertEqual(list(items[0].msgdata['recipients']), + ['z...@example.com']) + payload = items[0].msg.get_payload()[0] + self.assertIsNotNone(payload) + self.assertEqual('<alpha>', payload['message-id']) + def test_survive_a_deleted_message(self): # When the message that should be deleted is not found in the store, # no error is raised. ===================================== src/mailman/docs/NEWS.rst ===================================== @@ -73,6 +73,8 @@ Bugs (Closes #892) * DMARC policy discovery ignores domains with multiple DMARC records per RFC 7849. (Closes #907) +* Held messages missing from the message store can now be accepted and/or + forwarded. (closes #914) Command line ------------ View it on GitLab: https://gitlab.com/mailman/mailman/-/compare/c7b79d173ff95eebbea251d41945381d0332ca37...f8760c92b8ed4162bda1629d68edc774eb188303 -- View it on GitLab: https://gitlab.com/mailman/mailman/-/compare/c7b79d173ff95eebbea251d41945381d0332ca37...f8760c92b8ed4162bda1629d68edc774eb188303 You're receiving this email because of your account on gitlab.com.
_______________________________________________ Mailman-checkins mailing list -- mailman-checkins@python.org To unsubscribe send an email to mailman-checkins-le...@python.org https://mail.python.org/mailman3/lists/mailman-checkins.python.org/ Member address: arch...@jab.org