Merge lp:~stevenk/launchpad/catch-incomingemailerror into lp:launchpad

Proposed by Steve Kowalik
Status: Merged
Approved by: Steve Kowalik
Approved revision: no longer in the source branch.
Merged at revision: 15990
Proposed branch: lp:~stevenk/launchpad/catch-incomingemailerror
Merge into: lp:launchpad
Diff against target: 93 lines (+11/-23)
2 files modified
lib/lp/services/mail/incoming.py (+6/-12)
lib/lp/services/mail/tests/test_incoming.py (+5/-11)
To merge this branch: bzr merge lp:~stevenk/launchpad/catch-incomingemailerror
Reviewer Review Type Date Requested Status
Ian Booth (community) Approve
Review via email: mp+125416@code.launchpad.net

Commit message

Also catch IncomingEmailError as well as InvalidSignature in handle_one_mail so the sender gets a nice mail back, rather than an OOPS.

Description of the change

In the incoming mail handler, handle_one_mail, we call a function called authenticateEmail which tries to work out based on DKIM or GPG signature who the principal is. This is called inside a try block and the two exceptions InvalidSignature or InactiveAccount are handled and do not cause an OOPS. The problem is, authenticateEmail can also raise an IncomingEmailError, which isn't caught, and so will oops.

I have changed the except block to treat InvalidSignature or IncomingEmailError as the same. I can not see a way to test this, since it would require sending a mail with a plausible out of date timestamp. The pieces themselves are tested, there just isn't a way to test everything together.

Perform some cleanup, mostly whitespace.

To post a comment you must log in.
Revision history for this message
Ian Booth (wallyworld) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/services/mail/incoming.py'
2--- lib/lp/services/mail/incoming.py 2012-06-29 08:40:05 +0000
3+++ lib/lp/services/mail/incoming.py 2012-09-20 06:02:20 +0000
4@@ -3,8 +3,6 @@
5
6 """Functions dealing with mails coming into Launchpad."""
7
8-# pylint: disable-msg=W0631
9-
10 __metaclass__ = type
11
12 from cStringIO import StringIO as cStringIO
13@@ -42,6 +40,7 @@
14 from lp.services.mail.helpers import (
15 ensure_sane_signature_timestamp,
16 get_error_message,
17+ IncomingEmailError,
18 save_mail_to_librarian,
19 )
20 from lp.services.mail.interfaces import IWeaklyAuthenticatedPrincipal
21@@ -238,8 +237,7 @@
22 return (dkim_principal, dkim_trusted_address)
23
24
25-def authenticateEmail(mail,
26- signature_timestamp_checker=None):
27+def authenticateEmail(mail, signature_timestamp_checker=None):
28 """Authenticates an email by verifying the PGP signature.
29
30 The mail is expected to be an ISignedMessage.
31@@ -511,17 +509,13 @@
32 # It's probably big and it's probably mostly binary, so trim it pretty
33 # aggressively.
34 send_process_error_notification(
35- mail['From'],
36- 'Mail to Launchpad was too large',
37- complaint,
38- mail,
39- max_return_size=8192)
40+ mail['From'], 'Mail to Launchpad was too large', complaint,
41+ mail, max_return_size=8192)
42 return
43
44 try:
45- principal = authenticateEmail(
46- mail, signature_timestamp_checker)
47- except InvalidSignature as error:
48+ principal = authenticateEmail(mail, signature_timestamp_checker)
49+ except (InvalidSignature, IncomingEmailError) as error:
50 send_process_error_notification(
51 mail['From'], 'Submit Request Failure', str(error), mail)
52 return
53
54=== modified file 'lib/lp/services/mail/tests/test_incoming.py'
55--- lib/lp/services/mail/tests/test_incoming.py 2012-04-16 00:07:11 +0000
56+++ lib/lp/services/mail/tests/test_incoming.py 2012-09-20 06:02:20 +0000
57@@ -88,12 +88,8 @@
58 self.assertEqual([], self.oopses)
59 [notification] = pop_notifications()
60 body = notification.get_payload()[0].get_payload(decode=True)
61- self.assertIn(
62- "The mail you sent to Launchpad is too long.",
63- body)
64- self.assertIn(
65- "was 55 MB and the limit is 10 MB.",
66- body)
67+ self.assertIn("The mail you sent to Launchpad is too long.", body)
68+ self.assertIn("was 55 MB and the limit is 10 MB.", body)
69
70 def test_invalid_to_addresses(self):
71 """Invalid To: header should not be handled as an OOPS."""
72@@ -121,9 +117,8 @@
73 def fail_all_timestamps(timestamp, context):
74 raise helpers.IncomingEmailError("fail!")
75 self.assertRaises(
76- helpers.IncomingEmailError,
77- authenticateEmail,
78- msg, fail_all_timestamps)
79+ helpers.IncomingEmailError, authenticateEmail, msg,
80+ fail_all_timestamps)
81
82 def test_unknown_email(self):
83 # An unknown email address returns no principal.
84@@ -141,8 +136,7 @@
85 original_to = 'eric@vikings.example.com'
86 mail[ORIGINAL_TO_HEADER] = original_to
87 self.assertThat(
88- extract_addresses(mail, None, None),
89- Equals([original_to]))
90+ extract_addresses(mail, None, None), Equals([original_to]))
91
92 def test_original_to_in_body(self):
93 header_to = 'eric@vikings-r-us.example.com'