summaryrefslogtreecommitdiff
path: root/src/mailman
diff options
context:
space:
mode:
Diffstat (limited to 'src/mailman')
-rw-r--r--src/mailman/rules/moderation.py19
-rw-r--r--src/mailman/rules/tests/test_moderation.py37
2 files changed, 54 insertions, 2 deletions
diff --git a/src/mailman/rules/moderation.py b/src/mailman/rules/moderation.py
index 0cc0b81c3..d2ca6ef6d 100644
--- a/src/mailman/rules/moderation.py
+++ b/src/mailman/rules/moderation.py
@@ -23,6 +23,8 @@ __all__ = [
]
+import re
+
from mailman.core.i18n import _
from mailman.interfaces.action import Action
from mailman.interfaces.member import MemberRole
@@ -93,8 +95,21 @@ class NonmemberModeration:
# Do nonmember moderation check.
for sender in msg.senders:
nonmember = mlist.nonmembers.get_member(sender)
- action = (None if nonmember is None
- else nonmember.moderation_action)
+ assert nonmember is not None, (
+ 'Sender not added to the nonmembers: {0}'.format(sender))
+ # Check the '*_these_nonmembers' properties first
+ for action in ('accept', 'hold', 'reject', 'discard'):
+ checklist = getattr(mlist, '{}_these_nonmembers'.format(action))
+ for addr in checklist:
+ if (addr.startswith('^') and re.match(addr, sender)) \
+ or addr == sender:
+ msgdata['moderation_action'] = action
+ msgdata['moderation_sender'] = sender
+ msgdata.setdefault('moderation_reasons', []).append(
+ 'The sender is in the nonmember {} list'.format(
+ action))
+ return True
+ action = nonmember.moderation_action
if action is Action.defer:
# The regular moderation rules apply.
return False
diff --git a/src/mailman/rules/tests/test_moderation.py b/src/mailman/rules/tests/test_moderation.py
index a2e988874..737b1f81d 100644
--- a/src/mailman/rules/tests/test_moderation.py
+++ b/src/mailman/rules/tests/test_moderation.py
@@ -110,3 +110,40 @@ A message body.
reasons = msgdata['moderation_reasons']
self.assertEqual(
reasons, ['The message comes from a moderated member'])
+
+ def test_these_nonmembers(self):
+ user_manager = getUtility(IUserManager)
+ actions = {
+ 'anne@example.com': "accept",
+ 'bill@example.com': "hold",
+ 'chris@example.com': "reject",
+ 'dana@example.com': "discard",
+ '^anne-.*@example.com': "accept",
+ '^bill-.*@example.com': "hold",
+ '^chris-.*@example.com': "reject",
+ '^dana-.*@example.com': "discard",
+ }
+ rule = moderation.NonmemberModeration()
+ user_manager = getUtility(IUserManager)
+ for address, action_name in actions.items():
+ setattr(self._mlist, '{}_these_nonmembers'.format(action_name),
+ [address])
+ if address.startswith('^'):
+ # It's a pattern, craft a proper address
+ address = address[1:].replace('.*', 'something')
+ user_manager.create_address(address)
+ msg = mfs("""\
+From: {}
+To: test@example.com
+Subject: A test message
+Message-ID: <ant>
+MIME-Version: 1.0
+
+A message body.
+""".format(address))
+ msgdata = {}
+ result = rule.check(self._mlist, msg, msgdata)
+ self.assertTrue(result, 'NonmemberModeration rule should hit')
+ self.assertIn('moderation_action', msgdata)
+ self.assertEqual(msgdata['moderation_action'], action_name,
+ "Wrong action for {}: {}".format(address, action_name))