Commit 83f5bfbc authored by Barry Warsaw's avatar Barry Warsaw

Merge branch 'fix/empty-sender' into 'master'

Protect against messages without a sender

Closes #414

See merge request !324
parents b2de80c4 c53b2c91
Pipeline #12729094 failed with stage
in 30 minutes and 53 seconds
......@@ -117,6 +117,13 @@ class NonmemberModeration:
for sender in msg.senders:
if ban_manager.is_banned(sender):
return False
if len(msg.senders) == 0:
with _.defer_translation():
# This will be translated at the point of use.
reason = _('No sender was found in the message.')
msgdata, mlist.default_nonmember_action, 'No sender', reason)
return True
# Every sender email must be a member or nonmember directly. If it is
# neither, make the email a nonmembers.
for sender in msg.senders:
......@@ -141,8 +148,9 @@ class NonmemberModeration:
# Check the '*_these_nonmembers' properties first. XXX These are
# legacy attributes from MM2.1; their database type is 'pickle' and
# they should eventually get replaced.
for action in ('accept', 'hold', 'reject', 'discard'):
legacy_attribute_name = '{}_these_nonmembers'.format(action)
for action_name in ('accept', 'hold', 'reject', 'discard'):
legacy_attribute_name = '{}_these_nonmembers'.format(
checklist = getattr(mlist, legacy_attribute_name)
for addr in checklist:
if ((addr.startswith('^') and re.match(addr, sender))
......@@ -151,8 +159,8 @@ class NonmemberModeration:
# This will be translated at the point of use.
reason = (
_('The sender is in the nonmember {} list'),
_record_action(msgdata, action, sender, reason)
_record_action(msgdata, action_name, sender, reason)
return True
action = (mlist.default_nonmember_action
if nonmember.moderation_action is None
......@@ -306,3 +306,25 @@ A message body.
result = rule.check(self._mlist, msg, {})
def test_no_senders(self):
rule = moderation.NonmemberModeration()
# Message without a From
msg = mfs("""\
Subject: A test message
Message-ID: <ant>
MIME-Version: 1.0
A message body.
self.assertEqual(msg.senders, [])
msgdata = {}
# The NonmemberModeration rule should hit.
result = rule.check(self._mlist, msg, msgdata)
self.assertTrue(result, 'NonmemberModeration rule should hit')
self.assertEqual(msgdata, {
'member_moderation_action': Action.hold,
'moderation_reasons': ['No sender was found in the message.'],
'moderation_sender': 'No sender',
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment