Merge lp:~jcsackett/launchpad/email-authentication-type-error into lp:launchpad

Proposed by j.c.sackett on 2012-10-24
Status: Merged
Approved by: Curtis Hovey on 2012-10-24
Approved revision: no longer in the source branch.
Merged at revision: 16190
Proposed branch: lp:~jcsackett/launchpad/email-authentication-type-error
Merge into: lp:launchpad
Diff against target: 32 lines (+11/-1)
2 files modified
lib/lp/services/mail/incoming.py (+5/-1)
lib/lp/services/mail/tests/test_incoming.py (+6/-0)
To merge this branch: bzr merge lp:~jcsackett/launchpad/email-authentication-type-error
Reviewer Review Type Date Requested Status
Curtis Hovey (community) code 2012-10-24 Approve on 2012-10-24
Review via email: mp+131282@code.launchpad.net

Commit Message

Updates authenticateEmail to gracefully handle TypeErrors from badly formed email addresses.

Description of the Change

Summary
=======
authenticateEmail crashes on bad email address (e.g. ones that are not pure
unicode but also not US-ASCII). While we can't process them, we shouldn't
crash either.

The better approach is to simply proceed without having been able to
authenticate, and set an anauthenticated principal as we do with unknown
emails.

Implementation
==============
The call in `authenticateEmail` to `getPrincipalByLogin` is now in a
try/except block, which handles `TypeError` by setting principal to None. A
principal of None is a case which the rest of the code already handles
gracefully.

Tests
=====
bin/test -vvct test_badly_formed_email

QA
==
Using testemail.py (Curtis Hovey's script), contrive an email that has the right properties, and ensure it doesn't cause an OOPS.

LoC
===
I have approx 400 LoC credit.

Lint
====

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/services/mail/incoming.py
  lib/lp/services/mail/tests/test_incoming.py

To post a comment you must log in.
Curtis Hovey (sinzui) wrote :

Thank you.

I have a script (testemail.py) I use to send "volleys" of emails at Lp. We might be able to use to to contrive the example address in the bug.

review: Approve (code)

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-09-20 05:59:58 +0000
3+++ lib/lp/services/mail/incoming.py 2012-10-24 20:44:20 +0000
4@@ -258,7 +258,11 @@
5 principal, dkim_trusted_address = _getPrincipalByDkim(mail)
6 if dkim_trusted_address is None:
7 from_addr = parseaddr(mail['From'])[1]
8- principal = authutil.getPrincipalByLogin(from_addr)
9+ try:
10+ principal = authutil.getPrincipalByLogin(from_addr)
11+ except TypeError:
12+ # The email isn't valid, so don't authenticate
13+ principal = None
14
15 if principal is None:
16 setupInteraction(authutil.unauthenticatedPrincipal())
17
18=== modified file 'lib/lp/services/mail/tests/test_incoming.py'
19--- lib/lp/services/mail/tests/test_incoming.py 2012-09-20 05:44:34 +0000
20+++ lib/lp/services/mail/tests/test_incoming.py 2012-10-24 20:44:20 +0000
21@@ -126,6 +126,12 @@
22 mail = self.factory.makeSignedMessage(email_address=unknown)
23 self.assertThat(authenticateEmail(mail), Is(None))
24
25+ def test_badly_formed_email(self):
26+ # A badly formed email address returns no principal.
27+ bad = '\xed@example.com'
28+ mail = self.factory.makeSignedMessage(email_address=bad)
29+ self.assertThat(authenticateEmail(mail), Is(None))
30+
31
32 class TestExtractAddresses(TestCaseWithFactory):
33