launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #03867
[Merge] lp:~mbp/launchpad/790902-mail-librarian into lp:launchpad
Martin Pool has proposed merging lp:~mbp/launchpad/790902-mail-librarian into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~mbp/launchpad/790902-mail-librarian/+merge/63816
Launchpad stores mails into the librarian for the sake of debugging, and so that mailman and code review can later get back the exact original mail.
At the moment there are two functions that do this; this unifies them.
Also, one of them tries to obfuscate the message id, but in a not particularly useful way since it is deterministic. This makes it just random instead. (Bug 790902.)
--
https://code.launchpad.net/~mbp/launchpad/790902-mail-librarian/+merge/63816
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~mbp/launchpad/790902-mail-librarian into lp:launchpad.
=== modified file 'lib/canonical/launchpad/helpers.py'
--- lib/canonical/launchpad/helpers.py 2011-04-07 04:58:20 +0000
+++ lib/canonical/launchpad/helpers.py 2011-06-08 05:48:32 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Various functions and classes that are useful across different parts of
@@ -11,7 +11,6 @@
__metaclass__ = type
from difflib import unified_diff
-import hashlib
import os
import random
import re
@@ -28,7 +27,6 @@
IRequestLocalLanguages,
IRequestPreferredLanguages,
)
-from lp.services.utils import compress_hash
def text_replaced(text, replacements, _cache={}):
@@ -413,14 +411,6 @@
return "application/octet-stream"
-def get_filename_from_message_id(message_id):
- """Returns a librarian filename based on the email message_id.
-
- It generates a file name that's not easily guessable.
- """
- return '%s.msg' % compress_hash(hashlib.sha1(message_id))
-
-
def intOrZero(value):
"""Return int(value) or 0 if the conversion fails.
=== modified file 'lib/canonical/launchpad/mail/helpers.py'
--- lib/canonical/launchpad/mail/helpers.py 2011-02-01 04:57:42 +0000
+++ lib/canonical/launchpad/mail/helpers.py 2011-06-08 05:48:32 +0000
@@ -1,11 +1,13 @@
-# Copyright 2009 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
__metaclass__ = type
+from cStringIO import StringIO as cStringIO
import os.path
import re
import time
+from uuid import uuid1
from zope.component import getUtility
@@ -18,10 +20,10 @@
EmailProcessingError,
IWeaklyAuthenticatedPrincipal,
)
+from canonical.launchpad.interfaces.librarian import ILibraryFileAliasSet
from canonical.launchpad.webapp import canonical_url
from canonical.launchpad.webapp.interaction import get_current_principal
from canonical.launchpad.webapp.interfaces import ILaunchBag
-from lp.bugs.enum import BugNotificationLevel
from lp.registry.vocabularies import ValidPersonOrTeamVocabulary
@@ -257,3 +259,20 @@
or timestamp > ten_minutes_in_the_future):
error_message = get_error_message(error_template, context=context)
raise IncomingEmailError(error_message)
+
+
+def save_mail_to_librarian(raw_mail):
+ """Save the message to the librarian.
+
+ It can be referenced from errors, and also accessed by code that needs to
+ get back the exact original form.
+ """
+ # File the raw_mail in the Librarian. We generate a filename to avoid
+ # people guessing the URL. We don't want URLs to private bug messages to
+ # be guessable for example.
+ file_name = str(uuid1()) + '.txt'
+ file_alias = getUtility(ILibraryFileAliasSet).create(
+ file_name,
+ len(raw_mail),
+ cStringIO(raw_mail), 'message/rfc822')
+ return file_alias
=== modified file 'lib/lp/services/mail/incoming.py'
--- lib/lp/services/mail/incoming.py 2011-06-07 19:12:20 +0000
+++ lib/lp/services/mail/incoming.py 2011-06-08 05:48:32 +0000
@@ -16,7 +16,6 @@
import logging
import re
import sys
-from uuid import uuid1
import dkim
import dns.exception
@@ -32,11 +31,13 @@
GPGVerificationError,
IGPGHandler,
)
-from canonical.launchpad.interfaces.librarian import ILibraryFileAliasSet
from canonical.launchpad.interfaces.mail import IWeaklyAuthenticatedPrincipal
from canonical.launchpad.interfaces.mailbox import IMailBox
from canonical.launchpad.mail.commands import get_error_message
-from canonical.launchpad.mail.helpers import ensure_sane_signature_timestamp
+from canonical.launchpad.mail.helpers import (
+ ensure_sane_signature_timestamp,
+ save_mail_to_librarian,
+ )
from canonical.launchpad.mailnotification import (
send_process_error_notification,
)
@@ -329,12 +330,18 @@
try:
for mail_id, raw_mail in mailbox.items():
log.info("Processing mail %s" % mail_id)
+ trans.begin()
try:
- file_alias = save_mail_to_librarian(trans, log, raw_mail)
+ file_alias = save_mail_to_librarian(raw_mail)
# Let's save the url of the file alias, otherwise we might not
# be able to access it later if we get a DB exception.
file_alias_url = file_alias.http_url
log.debug('Uploaded mail to librarian %s' % (file_alias_url,))
+ # If something goes wrong when handling the mail, the
+ # transaction will be aborted. Therefore we need to commit the
+ # transaction now, to ensure that the mail gets stored in the
+ # Librarian.
+ trans.commit()
except UploadFailed:
# Something went wrong in the Librarian. It could be that it's
# not running, but not necessarily. Log the error and skip the
@@ -400,22 +407,6 @@
trans.commit()
-def save_mail_to_librarian(trans, log, raw_mail):
- """Save the message to the librarian, for reference from errors."""
- trans.begin()
- # File the raw_mail in the Librarian
- file_name = str(uuid1()) + '.txt'
- file_alias = getUtility(ILibraryFileAliasSet).create(
- file_name, len(raw_mail),
- cStringIO(raw_mail), 'message/rfc822')
- # If something goes wrong when handling the mail, the
- # transaction will be aborted. Therefore we need to commit the
- # transaction now, to ensure that the mail gets stored in the
- # Librarian.
- trans.commit()
- return file_alias
-
-
def handle_one_mail(log, mail, file_alias, file_alias_url,
signature_timestamp_checker):
"""Process one message.
=== modified file 'lib/lp/services/messages/model/message.py'
--- lib/lp/services/messages/model/message.py 2011-05-31 20:59:10 +0000
+++ lib/lp/services/messages/model/message.py 2011-06-08 05:48:32 +0000
@@ -62,7 +62,6 @@
from canonical.database.datetimecol import UtcDateTimeCol
from canonical.database.enumcol import EnumCol
from canonical.database.sqlbase import SQLBase
-from canonical.launchpad.helpers import get_filename_from_message_id
from canonical.launchpad.interfaces.librarian import (
ILibraryFileAliasSet,
)
@@ -76,7 +75,9 @@
IUserToUserEmail,
UnknownSender,
)
-from canonical.launchpad.mail import signed_message_from_string
+from canonical.launchpad.mail import (
+ signed_message_from_string,
+ )
from lp.app.errors import NotFoundError
from lp.registry.interfaces.person import (
IPersonSet,
@@ -306,14 +307,11 @@
# already in there.
file_alias_set = getUtility(ILibraryFileAliasSet) # Reused later
if filealias is None:
- # We generate a filename to avoid people guessing the URL.
- # We don't want URLs to private bug messages to be guessable
- # for example.
- raw_filename = get_filename_from_message_id(
- parsed_message['message-id'])
- raw_email_message = file_alias_set.create(
- raw_filename, len(email_message),
- cStringIO(email_message), 'message/rfc822')
+ # Avoid circular import.
+ from canonical.launchpad.mail.helpers import (
+ save_mail_to_librarian,
+ )
+ raw_email_message = save_mail_to_librarian(email_message)
else:
raw_email_message = filealias
@@ -473,8 +471,7 @@
name=filename,
size=len(content),
file=cStringIO(content),
- contentType=content_type
- )
+ contentType=content_type)
MessageChunk(message=message, sequence=sequence,
blob=blob)
sequence += 1
@@ -551,8 +548,7 @@
blob = ForeignKey(
foreignKey='LibraryFileAlias', dbName='blob', notNull=False,
- default=None
- )
+ default=None)
def __unicode__(self):
"""Return a text representation of this chunk.
@@ -567,8 +563,7 @@
return (
"Attachment: %s\n"
"Type: %s\n"
- "URL: %s" % (blob.filename, blob.mimetype, blob.url)
- )
+ "URL: %s" % (blob.filename, blob.mimetype, blob.url))
class UserToUserEmail(Storm):