Mark Sapiro pushed to branch master at GNU Mailman / Mailman Core


Commits:
eba826d4 by Mark Sapiro at 2021-04-21T13:46:42-07:00
Handle header instances in To and CC in avoid_duplicates and deliver.
Fix other minor inconsistencies.

- - - - -
48a21206 by Mark Sapiro at 2021-04-21T21:35:33+00:00
Merge branch 'fixes' into 'master'

Handle header instances in To and CC in avoid_duplicates and deliver.

Closes #883, #882, and #881

See merge request mailman/mailman!841
- - - - -


7 changed files:

- src/mailman/docs/NEWS.rst
- src/mailman/handlers/avoid_duplicates.py
- src/mailman/handlers/tests/test_avoid_duplicates.py
- src/mailman/mta/deliver.py
- src/mailman/mta/tests/test_delivery.py
- src/mailman/runners/docs/outgoing.rst
- src/mailman/runners/tests/test_outgoing.py


Changes:

=====================================
src/mailman/docs/NEWS.rst
=====================================
@@ -39,6 +39,12 @@ Bugs
 * Attempts to get a message from the message store with a missing file are
   now handled.  (Closes #877)
 * The task runner no longer prematurely deletes saved DSNs.  (Closes #878)
+* The avoid_duplicates handler properly handles headers that are returned as
+  email.header.Header instances rather than strings.  (Closeds #881)
+* The mta.deliver module properly handles headers that are returned as
+  email.header.Header instances rather than strings.  (Closeds #882)
+* Places where  ``to_list`` in the message metadata were increctly referenced
+  as ``tolist`` have been corrected.  (Closes #883)
 
 Command line
 ------------


=====================================
src/mailman/handlers/avoid_duplicates.py
=====================================
@@ -65,7 +65,8 @@ class AvoidDuplicates:
         # '"real name\r\n (dept)" <u...@example.com>' which parses incorrectly,
         # so we "unfold" headers here.
         for header in ('to', 'cc', 'resent-to', 'resent-cc'):
-            hdrs_unfolded = [re.sub('[\r\n]', '', value) for value in
+            # The value can contain a Header instance so stringify it.
+            hdrs_unfolded = [re.sub('[\r\n]', '', str(value)) for value in
                              msg.get_all(header, [])]
             addrs = getaddresses(hdrs_unfolded)
             header_addresses = dict((addr, formataddr((name, addr)))


=====================================
src/mailman/handlers/tests/test_avoid_duplicates.py
=====================================
@@ -19,6 +19,7 @@
 
 import unittest
 
+from email.header import make_header
 from mailman.app.lifecycle import create_list
 from mailman.handlers.avoid_duplicates import AvoidDuplicates
 from mailman.interfaces.member import MemberRole
@@ -139,5 +140,35 @@ To: a...@example.com
 Subject: A subject
 X-Mailman-Version: X.Y
 
+More things to say.
+""")
+
+    def test_cc_with_header_instance(self):
+        # Ensure we can process header instances.
+        msg = mfs("""\
+From: a...@example.com
+To: a...@example.com
+Subject: A subject
+X-Mailman-Version: X.Y
+
+More things to say.
+""")
+        msgdata = dict(recipients=set(['a...@example.com']))
+        msg['Cc'] = make_header(
+            [('"last, first" <ot...@example.com>', None),
+             ('"real name (dept)" <u...@example.com>', None)])
+        AvoidDuplicates().process(self._mlist, msg, msgdata)
+        # Don't test the whole message. The order in the Cc: varies with
+        # Python version.
+        ccs = msg.get('cc')
+        self.assertIn('"last, first" <ot...@example.com>', ccs)
+        self.assertIn('"real name (dept)" <u...@example.com>', ccs)
+        del msg['cc']
+        self.assertMultiLineEqual(msg.as_string(), """\
+From: a...@example.com
+To: a...@example.com
+Subject: A subject
+X-Mailman-Version: X.Y
+
 More things to say.
 """)


=====================================
src/mailman/mta/deliver.py
=====================================
@@ -121,10 +121,14 @@ def deliver(mlist, msg, msgdata):
         # Log the successful post, but if it was not destined to the mailing
         # list (e.g. to the owner or admin), print the actual recipients
         # instead of just the number.
-        if not msgdata.get('tolist', False):
+        if not msgdata.get('to_list', False):
+            # XXX This is meaningless as the config.logging.smtp.success
+            # template doesn't contain a recip substitution, but do it anyway
+            # in case the template is changed.
             recips = msg.get_all('to', [])
             recips.extend(msg.get_all('cc', []))
-            substitutions['recips'] = COMMA.join(recips)
+            # recips can contain a Header() instance.  Stringify it.
+            substitutions['recip'] = COMMA.join(map(str, recips))
         template = config.logging.smtp.success
         if template.lower() != 'no':
             log.info('%s', expand(template, mlist, substitutions))


=====================================
src/mailman/mta/tests/test_delivery.py
=====================================
@@ -22,6 +22,7 @@ import shutil
 import tempfile
 import unittest
 
+from email.header import make_header
 from mailman.app.lifecycle import create_list
 from mailman.config import config
 from mailman.interfaces.mailinglist import Personalization
@@ -381,8 +382,24 @@ Message-ID:
     def test_logging_with_folded_messageid(self):
         # Test that folded Message-ID header doesn't fold the log messages.
         mark = LogFileMark('mailman.smtp')
-        msgdata = dict(recipients=['a...@example.org'], tolist=True)
+        msgdata = dict(recipients=['a...@example.org'], to_list=True)
         self._deliverer(self._mlist, self._msg, msgdata)
         logs = mark.read()
         self.assertRegex(logs, r' \(\d+\) <AM6PR09MB347488.*smtp')
         self.assertRegex(logs, r' \(\d+\) <AM6PR09MB347488.*post')
+
+    def test_logging_with_header_instance(self):
+        msgdata = dict(recipients=['t...@example.com', 'b...@example.org'])
+        self._mlist.personalize = Personalization.none
+        msgdata['recipients'] = ['t...@example.com', 'b...@example.org']
+        self._msg['CC'] = make_header([('b...@example.org', None)])
+        config.push('logging', """
+        [logging.smtp]
+        success: post for $recip recips
+        """)
+        self.addCleanup(config.pop, 'logging')
+        mark = LogFileMark('mailman.smtp')
+        self._deliverer(self._mlist, self._msg, msgdata)
+        self.assertIn(
+            'post for t...@example.com,b...@example.org recips',
+            mark.read())


=====================================
src/mailman/runners/docs/outgoing.rst
=====================================
@@ -58,7 +58,7 @@ destination mailing list name.  Simulate that here too.
 
     >>> ignore = outgoing_queue.enqueue(
     ...     msg, msgdata,
-    ...     tolist=True,
+    ...     to_list=True,
     ...     listid=mlist.list_id)
 
 Running the outgoing runner processes the message, delivering it to the


=====================================
src/mailman/runners/tests/test_outgoing.py
=====================================
@@ -73,7 +73,7 @@ Message-Id: <first>
         deliver_after = now() + timedelta(days=10)
         self._msgdata['deliver_after'] = deliver_after
         self._outq.enqueue(self._msg, self._msgdata,
-                           tolist=True, listid='test.example.com')
+                           to_list=True, listid='test.example.com')
         self._runner.run()
         items = get_queue_messages('out', expected_count=1)
         self.assertEqual(items[0].msgdata['deliver_after'], deliver_after)



View it on GitLab: 
https://gitlab.com/mailman/mailman/-/compare/a767e0db48891aa8be48977abd6b7b2be7ac052e...48a21206ab16ac267df8e0889026e248fdf512c5

-- 
View it on GitLab: 
https://gitlab.com/mailman/mailman/-/compare/a767e0db48891aa8be48977abd6b7b2be7ac052e...48a21206ab16ac267df8e0889026e248fdf512c5
You're receiving this email because of your account on gitlab.com.


_______________________________________________
Mailman-checkins mailing list -- mailman-checkins@python.org
To unsubscribe send an email to mailman-checkins-le...@python.org
https://mail.python.org/mailman3/lists/mailman-checkins.python.org/
Member address: arch...@jab.org

Reply via email to