Barry Warsaw pushed to branch master at mailman / Mailman

Commits:
5a02cc71 by Abhilash Raj at 2016-11-25T11:45:06-05:00
Return 'defective message' for a bad held message

If a message can't be parsed by Python due to bad structure, don't 
raise an
error but return a generic 'this message is defective' string instead.

- - - - -
1f4919ab by Abhilash Raj at 2016-11-25T11:45:06-05:00
Rename test email and use resource filename instead of __file__.

- - - - -
17ec3681 by Barry Warsaw at 2016-11-25T11:54:10-05:00
Add NEWS and a little bit of cleanup.

- - - - -


5 changed files:

- src/mailman/docs/NEWS.rst
- src/mailman/rest/post_moderation.py
- + src/mailman/rest/tests/data/__init__.py
- + src/mailman/rest/tests/data/bad_email.eml
- src/mailman/rest/tests/test_moderation.py


Changes:

=====================================
src/mailman/docs/NEWS.rst
=====================================
--- a/src/mailman/docs/NEWS.rst
+++ b/src/mailman/docs/NEWS.rst
@@ -101,6 +101,8 @@ Bugs
    addresses.  Given by Tom Briles.  (Closes: #68)
  * Transmit the moderation reason and expose it in the REST API as the
    ``reason`` attribute.  Given by Aurélien Bompard.
+ * Don't return a 500 error from the REST API when trying to handle a held
+   message with defective content.  Given by Abhilash Raj.  (Closes: #256)
 
 Configuration
 -------------


=====================================
src/mailman/rest/post_moderation.py
=====================================
--- a/src/mailman/rest/post_moderation.py
+++ b/src/mailman/rest/post_moderation.py
@@ -71,7 +71,14 @@ class _HeldMessageBase(_ModerationBase):
         # resource.  XXX See LP: #967954
         key = resource.pop('key')
         msg = getUtility(IMessageStore).get_message_by_id(key)
-        resource['msg'] = msg.as_string()
+        try:
+            resource['msg'] = msg.as_string()
+        except KeyError:
+            # If the message can't be parsed, return a generic message instead
+            # of raising an error.
+            #
+            # See http://bugs.python.org/issue27321 and GL#256
+            resource['msg'] = 'This message is defective'
         # Some of the _mod_* keys we want to rename and place into the JSON
         # resource.  Others we can drop.  Since we're mutating the dictionary,
         # we need to make a copy of the keys.  When you port this to Python 3,


=====================================
src/mailman/rest/tests/data/__init__.py
=====================================
--- /dev/null
+++ b/src/mailman/rest/tests/data/__init__.py


=====================================
src/mailman/rest/tests/data/bad_email.eml
=====================================
--- /dev/null
+++ b/src/mailman/rest/tests/data/bad_email.eml
@@ -0,0 +1,8 @@
+To: <t...@example.com>
+Subject: =?koi8-r?B?UF9AX/NfQ1/5X+xfS1/p?=
+From: =?koi8-r?B?8sXL0sXB1MnXzs/FIMHHxc7U09TXzw==?=
+Content-Type: text/plain; charset=koi8-r
+Message-Id: <20160614102505.9OFQ19L1C>
+
+   ?
+       ?


=====================================
src/mailman/rest/tests/test_moderation.py
=====================================
--- a/src/mailman/rest/tests/test_moderation.py
+++ b/src/mailman/rest/tests/test_moderation.py
@@ -17,8 +17,10 @@
 
 """REST moderation tests."""
 
+import os
 import unittest
 
+from email import message_from_binary_file
 from mailman.app.lifecycle import create_list
 from mailman.app.moderator import hold_message
 from mailman.database.transaction import transaction
@@ -31,6 +33,7 @@ from mailman.testing.helpers import (
     call_api, get_queue_messages, set_preferred,
     specialized_message_from_string as mfs)
 from mailman.testing.layers import RESTLayer
+from pkg_resources import resource_filename
 from urllib.error import HTTPError
 from zope.component import getUtility
 
@@ -206,6 +209,24 @@ class TestSubscriptionModeration(unittest.TestCase):
         emails = set(json['email'] for json in content['entries'])
         self.assertEqual(emails, {'a...@example.com', 'b...@example.com'})
 
+    def test_view_malformed_held_message(self):
+        # Opening a bad (i.e. bad structure) email and holding it.
+        email_path = resource_filename(
+            'mailman.rest.tests.data', 'bad_email.eml')
+        with open(email_path, 'rb') as fp:
+            msg = message_from_binary_file(fp)
+        msg.sender = 'aper...@example.com'
+        with transaction():
+            hold_message(self._mlist, msg)
+        # Now trying to access held messages from REST API should not give
+        # 500 server error if one of the messages can't be parsed properly.
+        content, response = call_api(
+            'http://localhost:9001/3.0/lists/a...@example.com/held')
+        self.assertEqual(response.status, 200)
+        self.assertEqual(len(content['entries']), 1)
+        self.assertEqual(content['entries'][0]['msg'],
+                         'This message is defective')
+
     def test_individual_request(self):
         # We can view an individual request.
         with transaction():



View it on GitLab: 
https://gitlab.com/mailman/mailman/compare/055082f2694c84d5dd46ba194224b1b9f51f835f...17ec368191f4e2c80fbead954511bb5a251dfe45
_______________________________________________
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
https://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to