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'], '[email protected]')
self.assertEqual(message['x-rcptto'], '[email protected]')
+ 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='[email protected]',
+ recipients=['[email protected]'])
+ 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'], '[email protected]')
+ self.assertEqual(message['to'], '[email protected]')
+ # 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'], '[email protected]')
+ self.assertEqual(message['x-rcptto'], '[email protected]')
+
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']),
['[email protected]'])
+ 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=['[email protected]'])
+ # 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']),
+ ['[email protected]'])
+ 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 -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/mailman-checkins.python.org/
Member address: [email protected]