summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mailman/app/tests/test_notifications.py5
-rw-r--r--src/mailman/chains/headers.py3
-rw-r--r--src/mailman/chains/tests/test_headers.py30
-rw-r--r--src/mailman/database/alembic/versions/fa0d96e28631_template_manager.py4
-rw-r--r--src/mailman/database/tests/test_migrations.py12
-rw-r--r--src/mailman/docs/NEWS.rst16
-rw-r--r--src/mailman/rest/listconf.py4
-rw-r--r--src/mailman/rest/tests/test_listconf.py10
8 files changed, 57 insertions, 27 deletions
diff --git a/src/mailman/app/tests/test_notifications.py b/src/mailman/app/tests/test_notifications.py
index 05ce4cf2f..4a6f56a72 100644
--- a/src/mailman/app/tests/test_notifications.py
+++ b/src/mailman/app/tests/test_notifications.py
@@ -48,7 +48,8 @@ class TestNotifications(unittest.TestCase):
self._mlist = create_list('test@example.com')
self._mlist.display_name = 'Test List'
getUtility(ITemplateManager).set(
- 'user:ack:welcome', self._mlist.list_id, 'mailman:///welcome.txt')
+ 'list:user:notice:welcome', self._mlist.list_id,
+ 'mailman:///welcome.txt')
config.push('template config', """\
[paths.testing]
template_dir: {}/templates
@@ -94,7 +95,7 @@ Welcome to the Test List mailing list.
# The welcome message url can contain placeholders for the fqdn list
# name and language.
getUtility(ITemplateManager).set(
- 'user:ack:welcome', self._mlist.list_id,
+ 'list:user:notice:welcome', self._mlist.list_id,
'mailman:///$listname/$language/welcome.txt')
# Add the xx language and subscribe Anne using it.
manager = getUtility(ILanguageManager)
diff --git a/src/mailman/chains/headers.py b/src/mailman/chains/headers.py
index d41e64386..6fc061fe4 100644
--- a/src/mailman/chains/headers.py
+++ b/src/mailman/chains/headers.py
@@ -20,6 +20,7 @@
import re
import logging
+from email.header import Header
from itertools import count
from mailman.chains.base import Chain, Link
from mailman.config import config
@@ -101,6 +102,8 @@ class HeaderMatchRule:
for p in msg.walk():
headers.extend(p.get_all(self.header, []))
for value in headers:
+ if isinstance(value, Header):
+ value = value.encode()
if re.search(self.pattern, value, re.IGNORECASE):
return True
return False
diff --git a/src/mailman/chains/tests/test_headers.py b/src/mailman/chains/tests/test_headers.py
index b74b8ebc9..3da7a2435 100644
--- a/src/mailman/chains/tests/test_headers.py
+++ b/src/mailman/chains/tests/test_headers.py
@@ -19,6 +19,7 @@
import unittest
+from email.header import Header
from mailman.app.lifecycle import create_list
from mailman.chains.headers import HeaderMatchRule, make_link
from mailman.config import config
@@ -209,6 +210,35 @@ This is junk
self.assertIsInstance(event, HoldEvent)
self.assertEqual(event.chain, config.chains['hold'])
+ def test_get_all_returns_non_string(self):
+ # Test case where msg.get_all() returns header instance.
+ msg = mfs("""\
+From: anne@example.com
+To: test@example.com
+Subject: =?unknown-8bit?q?Become_smarter_now_=96_Increase__your_brain...?=
+Message-ID: <ant>
+
+body
+
+""")
+ # XXX In the wild we have seen a message instance in which the subject
+ # header value is an email.header.Header instance rather than a
+ # string. We don't know how to recreate that here so we cheat.
+ msg['Subject'] = Header(
+ 'Become_smarter_now \x96 Increase your brain...', 'utf-8')
+ msgdata = {}
+ header_matches = IHeaderMatchList(self._mlist)
+ header_matches.append('Subject', '=\?utf', 'hold')
+ # This event subscriber records the event that occurs when the message
+ # is processed by the owner chain.
+ events = []
+ with event_subscribers(events.append):
+ process(self._mlist, msg, msgdata, start_chain='header-match')
+ self.assertEqual(len(events), 1)
+ event = events[0]
+ self.assertIsInstance(event, HoldEvent)
+ self.assertEqual(event.chain, config.chains['hold'])
+
@configuration('antispam', header_checks="""
Foo: foo
""", jump_chain='hold')
diff --git a/src/mailman/database/alembic/versions/fa0d96e28631_template_manager.py b/src/mailman/database/alembic/versions/fa0d96e28631_template_manager.py
index 8fb8c1056..4e8fc39c6 100644
--- a/src/mailman/database/alembic/versions/fa0d96e28631_template_manager.py
+++ b/src/mailman/database/alembic/versions/fa0d96e28631_template_manager.py
@@ -24,9 +24,9 @@ CONVERSION_MAPPING = dict(
digest_footer_uri='list:digest:footer',
digest_header_uri='list:digest:header',
footer_uri='list:regular:footer',
- goodbye_message_uri='user:ack:goodbye',
+ goodbye_message_uri='list:user:notice:goodbye',
header_uri='list:regular:header',
- welcome_message_uri='user:ack:welcome',
+ welcome_message_uri='list:user:notice:welcome',
)
REVERSE_MAPPING = {value: key for key, value in CONVERSION_MAPPING.items()}
diff --git a/src/mailman/database/tests/test_migrations.py b/src/mailman/database/tests/test_migrations.py
index cba5dbbd5..b5d17d6db 100644
--- a/src/mailman/database/tests/test_migrations.py
+++ b/src/mailman/database/tests/test_migrations.py
@@ -374,16 +374,16 @@ class TestMigrations(unittest.TestCase):
'list:digest:header': 'digest_header',
'list:regular:footer': 'footer',
'list:regular:header': 'header',
- 'user:ack:goodbye': 'goodbye',
- 'user:ack:welcome': 'welcome',
+ 'list:user:notice:goodbye': 'goodbye',
+ 'list:user:notice:welcome': 'welcome',
}.get(name, name)))
self.assertEqual(sorted(seen_names), [
'list:digest:footer',
'list:digest:header',
'list:regular:footer',
'list:regular:header',
- 'user:ack:goodbye',
- 'user:ack:welcome',
+ 'list:user:notice:goodbye',
+ 'list:user:notice:welcome',
])
def test_fa0d96e28631_upgrade_no_uris(self):
@@ -435,10 +435,10 @@ class TestMigrations(unittest.TestCase):
manager.set('list:regular:header',
'ant.example.com',
'mailman:///header.txt')
- manager.set('user:ack:welcome',
+ manager.set('list:user:notice:welcome',
'ant.example.com',
'mailman:///welcome.txt')
- manager.set('user:ack:goodbye',
+ manager.set('list:user:notice:goodbye',
'ant.example.com',
'mailman:///goodbye.txt')
mlist_table = sa.sql.table(
diff --git a/src/mailman/docs/NEWS.rst b/src/mailman/docs/NEWS.rst
index 3a2398b74..c7bbc6de6 100644
--- a/src/mailman/docs/NEWS.rst
+++ b/src/mailman/docs/NEWS.rst
@@ -164,15 +164,6 @@ Interfaces
* ``ISubscriptionService`` now supports mass unsubscribes. Given by Harshit
Bansal.
-Internal
---------
- * Add official support for Python 3.6. (Closes #295)
- * A handful of unused legacy exceptions have been removed. The redundant
- ``MailmanException`` has been removed; use ``MailmanError`` everywhere.
- * Drop the use of the ``lazr.smtptest`` library, which is based on the
- asynchat/asyncore-based smtpd.py stdlib module. Instead, use the
- asyncio-based aiosmtpd package.
-
Message handling
----------------
* New DMARC mitigations have been added. Given by Mark Sapiro. (Closes #247)
@@ -273,7 +264,12 @@ REST
Other
-----
- * The test suite is now Python 3.5 compatible.
+ * Add official support for Python 3.5 and 3.6. (Closes #295)
+ * A handful of unused legacy exceptions have been removed. The redundant
+ ``MailmanException`` has been removed; use ``MailmanError`` everywhere.
+ * Drop the use of the ``lazr.smtptest`` library, which is based on the
+ asynchat/asyncore-based smtpd.py stdlib module. Instead, use the
+ asyncio-based `aiosmtpd <http://aiosmtpd.readthedocs.io/>`_ package.
* Improvements in importing Mailman 2.1 lists, given by Aurélien Bompard.
* The ``prototype`` archiver is not web accessible so it does not have a
``list_url`` or permalink. Given by Aurélien Bompard.
diff --git a/src/mailman/rest/listconf.py b/src/mailman/rest/listconf.py
index 87535ce48..da7111d0f 100644
--- a/src/mailman/rest/listconf.py
+++ b/src/mailman/rest/listconf.py
@@ -65,9 +65,9 @@ TEMPLATE_ATTRIBUTES = dict(
digest_footer_uri='list:digest:footer',
digest_header_uri='list:digest:header',
footer_uri='list:regular:footer',
- goodbye_message_uri='user:ack:goodbye',
+ goodbye_message_uri='list:user:notice:goodbye',
header_uri='list:regular:header',
- welcome_message_uri='user:ack:welcome',
+ welcome_message_uri='list:user:notice:welcome',
)
diff --git a/src/mailman/rest/tests/test_listconf.py b/src/mailman/rest/tests/test_listconf.py
index 06c138fee..782effd29 100644
--- a/src/mailman/rest/tests/test_listconf.py
+++ b/src/mailman/rest/tests/test_listconf.py
@@ -379,7 +379,7 @@ class TestConfiguration(unittest.TestCase):
def test_get_goodbye_message_uri(self):
with transaction():
getUtility(ITemplateManager).set(
- 'user:ack:goodbye', self._mlist.list_id,
+ 'list:user:notice:goodbye', self._mlist.list_id,
'mailman:///goodbye.txt')
resource, response = call_api(
'http://localhost:9001/3.0/lists/ant.example.com/config'
@@ -395,7 +395,7 @@ class TestConfiguration(unittest.TestCase):
self.assertEqual(response.status_code, 204)
self.assertEqual(
getUtility(ITemplateManager).raw(
- 'user:ack:goodbye', self._mlist.list_id).uri,
+ 'list:user:notice:goodbye', self._mlist.list_id).uri,
'mailman:///salutation.txt')
def test_patch_goodbye_message_uri(self):
@@ -407,14 +407,14 @@ class TestConfiguration(unittest.TestCase):
self.assertEqual(response.status_code, 204)
self.assertEqual(
getUtility(ITemplateManager).raw(
- 'user:ack:goodbye', self._mlist.list_id).uri,
+ 'list:user:notice:goodbye', self._mlist.list_id).uri,
'mailman:///salutation.txt')
def test_put_goodbye_message_uri(self):
manager = getUtility(ITemplateManager)
with transaction():
manager.set(
- 'user:ack:goodbye',
+ 'list:user:notice:goodbye',
self._mlist.list_id,
'mailman:///somefile.txt')
resource, response = call_api(
@@ -424,7 +424,7 @@ class TestConfiguration(unittest.TestCase):
'PUT')
self.assertEqual(response.status_code, 204)
self.assertEqual(
- manager.raw('user:ack:goodbye', self._mlist.list_id).uri,
+ manager.raw('list:user:notice:goodbye', self._mlist.list_id).uri,
'mailman:///salutation.txt')
def test_advertised(self):