launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #02994
[Merge] lp:~wgrant/launchpad/bug-246523 into lp:launchpad
William Grant has proposed merging lp:~wgrant/launchpad/bug-246523 into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #736647 in Launchpad itself: "Branch:+new-recipe fails to render for +junk branches"
https://bugs.launchpad.net/launchpad/+bug/736647
For more details, see:
https://code.launchpad.net/~wgrant/launchpad/bug-246523/+merge/53763
Email to an inaccessible private bug currently OOPSes when it attempts to retrieve attributes from the bug. This branch fixes the incoming mail handler to refuse to acknowledge a bug's existence to someone who cannot see it.
--
https://code.launchpad.net/~wgrant/launchpad/bug-246523/+merge/53763
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wgrant/launchpad/bug-246523 into lp:launchpad.
=== modified file 'lib/canonical/launchpad/mail/commands.py'
--- lib/canonical/launchpad/mail/commands.py 2011-03-03 03:03:29 +0000
+++ lib/canonical/launchpad/mail/commands.py 2011-03-17 09:36:33 +0000
@@ -201,6 +201,8 @@
try:
bug = getUtility(IBugSet).get(bugid)
except NotFoundError:
+ bug = None
+ if bug is None or not check_permission('launchpad.View', bug):
raise EmailProcessingError(
get_error_message('no-such-bug.txt', bug_id=bugid))
return bug, None
=== modified file 'lib/lp/bugs/mail/tests/test_handler.py'
--- lib/lp/bugs/mail/tests/test_handler.py 2011-03-03 03:17:16 +0000
+++ lib/lp/bugs/mail/tests/test_handler.py 2011-03-17 09:36:33 +0000
@@ -9,18 +9,27 @@
import time
import transaction
+from zope.component import getUtility
+from zope.security.management import (
+ getSecurityPolicy,
+ setSecurityPolicy,
+ )
+from zope.security.proxy import removeSecurityProxy
from canonical.config import config
from canonical.database.sqlbase import commit
from canonical.launchpad.ftests import import_secret_test_key
from canonical.launchpad.mail.commands import BugEmailCommand
+from canonical.launchpad.webapp.authorization import LaunchpadSecurityPolicy
from canonical.testing.layers import (
LaunchpadFunctionalLayer,
LaunchpadZopelessLayer,
)
+from lp.bugs.interfaces.bug import IBugSet
from lp.bugs.mail.handler import MaloneHandler
from lp.services.mail import stub
from lp.testing import (
+ celebrity_logged_in,
login,
person_logged_in,
TestCaseWithFactory,
@@ -32,8 +41,20 @@
class TestMaloneHandler(TestCaseWithFactory):
"""Test that the Malone/bugs handler works."""
+ # LaunchpadFunctionalLayer has the LaunchpadSecurityPolicy that we
+ # need, but we need to be able to switch DB users. So we have to use
+ # LaunchpadZopelessLayer and set security up manually.
layer = LaunchpadZopelessLayer
+ def setUp(self):
+ super(TestMaloneHandler, self).setUp()
+ self._old_policy = getSecurityPolicy()
+ setSecurityPolicy(LaunchpadSecurityPolicy)
+
+ def tearDown(self):
+ super(TestMaloneHandler, self).tearDown()
+ setSecurityPolicy(self._old_policy)
+
def test_getCommandsEmpty(self):
"""getCommands returns an empty list for messages with no command."""
message = self.factory.makeSignedMessage()
@@ -115,11 +136,9 @@
transaction.commit()
LaunchpadZopelessLayer.switchDbUser(user)
- def test_new_bug_big_body(self):
- # If a bug email is sent with an excessively large body, we email the
- # user back and ask that they use attachments instead.
- big_body_text = 'This is really big.' * 10000
- mail = self.factory.makeSignedMessage(body=big_body_text)
+ def getFailureForMessage(self, to_address, from_address=None, body=None):
+ mail = self.factory.makeSignedMessage(
+ body=body, email_address=from_address)
self.switchDbUser(config.processmail.dbuser)
# Rejection email goes to the preferred email of the current user.
# The current user is extracted from the current interaction, which is
@@ -127,16 +146,53 @@
# real GPG signed emails, which we are faking here.
login(mail['from'])
handler = MaloneHandler()
- self.assertTrue(handler.process(mail,
- 'new@xxxxxxxxxxxxxxxxxx', None))
- notification = pop_notifications()[0]
+ self.assertTrue(handler.process(mail, to_address, None))
+ notifications = pop_notifications()
+ if not notifications:
+ return None
+ notification = notifications[0]
self.assertEqual('Submit Request Failure', notification['subject'])
# The returned message is a multipart message, the first part is
# the message, and the second is the original message.
message, original = notification.get_payload()
- self.assertIn(
- "The description is too long.",
- message.get_payload(decode=True))
+ return message.get_payload(decode=True)
+
+ def test_new_bug_big_body(self):
+ # If a bug email is sent with an excessively large body, we email the
+ # user back and ask that they use attachments instead.
+ big_body_text = 'This is really big.' * 10000
+ message = self.getFailureForMessage(
+ 'new@xxxxxxxxxxxxxxxxxx', body=big_body_text)
+ self.assertIn("The description is too long.", message)
+
+ def test_bug_not_found(self):
+ # Non-existent bug numbers result in an informative error.
+ message = self.getFailureForMessage('1234@xxxxxxxxxxxxxxxxxx')
+ self.assertIn(
+ "There is no such bug in Launchpad: 1234", message)
+
+ def test_accessible_private_bug(self):
+ # Private bugs are accessible by their subscribers.
+ person = self.factory.makePerson()
+ with celebrity_logged_in('admin'):
+ bug = getUtility(IBugSet).get(1)
+ bug.setPrivate(True, person)
+ bug.subscribe(person, person)
+ # Drop the notifications from celebrity_logged_in.
+ pop_notifications()
+ message = self.getFailureForMessage(
+ '1@xxxxxxxxxxxxxxxxxx',
+ from_address=removeSecurityProxy(person.preferredemail).email)
+ self.assertIs(None, message)
+
+ def test_inaccessible_private_bug_not_found(self):
+ # Private bugs don't acknowledge their existence to non-subscribers.
+ with celebrity_logged_in('admin'):
+ getUtility(IBugSet).get(1).setPrivate(
+ True, self.factory.makePerson())
+ message = self.getFailureForMessage('1@xxxxxxxxxxxxxxxxxx')
+ self.assertIn(
+ "There is no such bug in Launchpad: 1", message)
class FakeSignature: