summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAurélien Bompard2015-09-11 16:09:08 +0200
committerBarry Warsaw2015-10-20 21:10:35 -0400
commitd468d096b35e42f8450a5ae449501ea155992a95 (patch)
treef75f38a4650e606a872819ad157fa9e4e20c793e /src
parented772e4fe2296460f0261a114b4f4eea3b318d6a (diff)
downloadmailman-d468d096b35e42f8450a5ae449501ea155992a95.tar.gz
mailman-d468d096b35e42f8450a5ae449501ea155992a95.tar.zst
mailman-d468d096b35e42f8450a5ae449501ea155992a95.zip
Diffstat (limited to 'src')
-rw-r--r--src/mailman/chains/headers.py13
-rw-r--r--src/mailman/chains/tests/test_headers.py40
2 files changed, 45 insertions, 8 deletions
diff --git a/src/mailman/chains/headers.py b/src/mailman/chains/headers.py
index c98726e21..b696bcfe7 100644
--- a/src/mailman/chains/headers.py
+++ b/src/mailman/chains/headers.py
@@ -140,14 +140,15 @@ class HeaderMatchChain(Chain):
'contains bogus line: {0}'.format(line))
continue
yield make_link(parts[0], parts[1].lstrip())
- # Then return all the list-specific header matches.
- # Python 3.3: Use 'yield from'
- for entry in mlist.header_matches:
- yield make_link(entry.header, entry.pattern, entry.chain)
# Then return all the explicitly added links.
for link in self._extended_links:
yield link
- # Finally, if any of the above rules matched, jump to the chain
- # defined in the configuration file.
+ # If any of the above rules matched, jump to the chain
+ # defined in the configuration file. This takes precedence over
+ # list-specific matches for security considerations.
yield Link(config.rules['any'], LinkAction.jump,
config.chains[config.antispam.jump_chain])
+ # Then return all the list-specific header matches.
+ # Python 3.3: Use 'yield from'
+ for entry in mlist.header_matches:
+ yield make_link(entry.header, entry.pattern, entry.chain)
diff --git a/src/mailman/chains/tests/test_headers.py b/src/mailman/chains/tests/test_headers.py
index c55d39876..104913034 100644
--- a/src/mailman/chains/tests/test_headers.py
+++ b/src/mailman/chains/tests/test_headers.py
@@ -29,9 +29,12 @@ from mailman.chains.headers import HeaderMatchRule
from mailman.config import config
from mailman.email.message import Message
from mailman.model.mailinglist import HeaderMatch
-from mailman.interfaces.chain import LinkAction
+from mailman.interfaces.chain import LinkAction, HoldEvent
+from mailman.core.chains import process
from mailman.testing.layers import ConfigLayer
-from mailman.testing.helpers import LogFileMark, configuration
+from mailman.testing.helpers import (LogFileMark, configuration,
+ event_subscribers, get_queue_messages,
+ specialized_message_from_string as mfs)
@@ -152,3 +155,36 @@ class TestHeaderChain(unittest.TestCase):
('Bar', 'b+', LinkAction.jump, 'discard'),
('Baz', 'z+', LinkAction.jump, 'accept'),
])
+
+ @configuration('antispam', header_checks="""
+ Foo: foo
+ """, jump_chain="hold")
+ def test_priority_site_over_list(self):
+ # Test that the site-wide checks take precedence over the list-specific
+ # checks.
+ msg = mfs("""\
+From: anne@example.com
+To: test@example.com
+Subject: A message
+Message-ID: <ant>
+Foo: foo
+MIME-Version: 1.0
+
+A message body.
+""")
+ msgdata = {}
+ self._mlist.header_matches = [
+ HeaderMatch(header='Foo', pattern='foo', chain='accept')
+ ]
+ # This event subscriber records the event that occurs when the message
+ # is processed by the owner chain.
+ events = []
+ def catch_event(event):
+ events.append(event)
+ with event_subscribers(catch_event):
+ process(self._mlist, msg, msgdata, start_chain='header-match')
+ self.assertEqual(len(events), 1)
+ event = events[0]
+ # Site-wide wants to hold the message, the list wants to accept it.
+ self.assertTrue(isinstance(event, HoldEvent))
+ self.assertEqual(event.chain, config.chains['hold'])