Thanks for all your patience and help. The updated branch now passes at least the two doctests that were identified as failing. The specific change is that I've gone back to the approach of passing in the timestamp-checking callback, but moved it to a more appropriate spot that (I think) covers all cases. This is imo cleaner than monkey patching, as I was doing. I'm thinking of also retargeting this to devel. It has no database dependencies. === modified file 'lib/canonical/launchpad/doc/emailauthentication.txt' --- lib/canonical/launchpad/doc/emailauthentication.txt 2010-10-18 22:24:59 +0000 +++ lib/canonical/launchpad/doc/emailauthentication.txt 2010-11-24 06:49:53 +0000 @@ -20,12 +20,18 @@ >>> commit() >>> LaunchpadZopelessLayer.switchDbUser(config.processmail.dbuser) +For most of these tests, we don't care whether the timestamps are out of +date: + + >>> def accept_any_timestamp(timestamp, context_message): + ... pass + Now Sample Person and Foo Bar have one OpenPGP key each. Next, let's get a test email that's signed and try to authenticate the user who sent it: >>> from canonical.launchpad.mail.ftests import read_test_message >>> msg = read_test_message('signed_detached.txt') - >>> principal = authenticateEmail(msg) + >>> principal = authenticateEmail(msg, accept_any_timestamp) If the user isn't registered in Launchpad, None is return, if it succeeds the authenticated principal: @@ -52,7 +58,7 @@ message. Inline signatures are supported as well. >>> msg = read_test_message('signed_inline.txt') - >>> principal = authenticateEmail(msg) + >>> principal = authenticateEmail(msg, accept_any_timestamp) >>> principal is not None True >>> name, addr = email.Utils.parseaddr(msg['From']) @@ -65,7 +71,7 @@ As well as signed multipart messages: >>> msg = read_test_message('signed_multipart.txt') - >>> principal = authenticateEmail(msg) + >>> principal = authenticateEmail(msg, accept_any_timestamp) >>> principal is not None True >>> name, addr = email.Utils.parseaddr(msg['From']) @@ -80,7 +86,7 @@ to deal with it if we receive a dash escaped message. >>> msg = read_test_message('signed_dash_escaped.txt') - >>> principal = authenticateEmail(msg) + >>> principal = authenticateEmail(msg, accept_any_timestamp) >>> principal is not None True >>> name, addr = email.Utils.parseaddr(msg['From']) @@ -96,7 +102,7 @@ >>> msg = read_test_message('signed_detached_invalid_signature.txt') >>> name, addr = email.Utils.parseaddr(msg['From']) >>> from_user = getUtility(IPersonSet).getByEmail(addr) - >>> principal = authenticateEmail(msg) + >>> principal = authenticateEmail(msg, accept_any_timestamp) Traceback (most recent call last): ... InvalidSignature:... @@ -131,7 +137,7 @@ ... msg = email.message_from_string( ... line_ending.join(msg_lines), _class=SignedMessage) ... msg.parsed_string = msg.as_string() - ... principal = authenticateEmail(msg) + ... principal = authenticateEmail(msg, accept_any_timestamp) ... authenticated_person = IPerson(principal) ... print authenticated_person.preferredemail.email