Merge lp:~stevenk/launchpad/proper-error-on-bug-attachment-bad-filename into lp:launchpad

Proposed by Steve Kowalik on 2012-09-04
Status: Merged
Approved by: Steve Kowalik on 2012-09-04
Approved revision: no longer in the source branch.
Merged at revision: 15905
Proposed branch: lp:~stevenk/launchpad/proper-error-on-bug-attachment-bad-filename
Merge into: lp:launchpad
Diff against target: 118 lines (+29/-10)
3 files modified
lib/lp/bugs/tests/test_bugs_webservice.py (+14/-4)
lib/lp/registry/errors.py (+6/-0)
lib/lp/services/librarian/model.py (+9/-6)
To merge this branch: bzr merge lp:~stevenk/launchpad/proper-error-on-bug-attachment-bad-filename
Reviewer Review Type Date Requested Status
Ian Booth (community) 2012-09-04 Approve on 2012-09-04
Review via email: mp+122608@code.launchpad.net

Commit Message

If adding an LFA raises an IntegrityError, catch it and re-raise it so the API gives Bad Request rather than an OOPS.

Description of the Change

If adding the LFA in IBug.addAttachment raises an IntegrityError, catch it and raise it as BadRequest.

To post a comment you must log in.
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/bugs/tests/test_bugs_webservice.py'
2--- lib/lp/bugs/tests/test_bugs_webservice.py 2012-08-30 06:18:38 +0000
3+++ lib/lp/bugs/tests/test_bugs_webservice.py 2012-09-04 04:32:21 +0000
4@@ -19,9 +19,7 @@
5 Equals,
6 LessThan,
7 )
8-from zope.component import (
9- getMultiAdapter,
10- )
11+from zope.component import getMultiAdapter
12
13 from lp.bugs.browser.bugtask import get_comments_for_bugtask
14 from lp.bugs.interfaces.bug import IBug
15@@ -344,7 +342,7 @@
16
17 class TestErrorHandling(TestCaseWithFactory):
18
19- layer = DatabaseFunctionalLayer
20+ layer = LaunchpadFunctionalLayer
21
22 def test_add_duplicate_bugtask_for_project_gives_bad_request(self):
23 bug = self.factory.makeBug()
24@@ -375,6 +373,18 @@
25 self.assertRaises(
26 BadRequest, lp_bug.addTask, target=api_url(product2))
27
28+ def test_add_attachment_with_bad_filename_raises_exception(self):
29+ # Test that addAttachment raises BadRequest when the filename given
30+ # contains slashes.
31+ owner = self.factory.makePerson()
32+ bug = self.factory.makeBug(owner=owner)
33+ login_person(owner)
34+ launchpad = launchpadlib_for('test', owner)
35+ lp_bug = launchpad.load(api_url(bug))
36+ self.assertRaises(
37+ BadRequest, lp_bug.addAttachment, comment='foo', data='foo',
38+ filename='/home/foo/bar.txt')
39+
40
41 class BugSetTestCase(TestCaseWithFactory):
42
43
44=== modified file 'lib/lp/registry/errors.py'
45--- lib/lp/registry/errors.py 2012-08-28 00:07:47 +0000
46+++ lib/lp/registry/errors.py 2012-09-04 04:32:21 +0000
47@@ -11,6 +11,7 @@
48 'CommercialSubscribersOnly',
49 'CountryMirrorAlreadySet',
50 'DeleteSubscriptionError',
51+ 'InvalidFilename',
52 'InvalidName',
53 'JoinNotAllowed',
54 'MirrorNotOfficial',
55@@ -56,6 +57,11 @@
56 """The name given for a person is not valid."""
57
58
59+@error_status(httplib.BAD_REQUEST)
60+class InvalidFilename(Exception):
61+ """An invalid filename was used as an attachment filename."""
62+
63+
64 class NoSuchDistroSeries(NameLookupFailed):
65 """Raised when we try to find a DistroSeries that doesn't exist."""
66 _message_prefix = "No such distribution series"
67
68=== modified file 'lib/lp/services/librarian/model.py'
69--- lib/lp/services/librarian/model.py 2011-12-30 06:14:56 +0000
70+++ lib/lp/services/librarian/model.py 2012-09-04 04:32:21 +0000
71@@ -1,8 +1,6 @@
72 # Copyright 2009-2011 Canonical Ltd. This software is licensed under the
73 # GNU Affero General Public License version 3 (see the file LICENSE).
74
75-# pylint: disable-msg=E0611,W0212
76-
77 __metaclass__ = type
78 __all__ = [
79 'LibraryFileAlias',
80@@ -30,6 +28,7 @@
81 SQLRelatedJoin,
82 StringCol,
83 )
84+from storm.exceptions import IntegrityError
85 from storm.locals import (
86 Date,
87 Desc,
88@@ -46,6 +45,7 @@
89 Interface,
90 )
91
92+from lp.registry.errors import InvalidFilename
93 from lp.services.config import config
94 from lp.services.database.constants import (
95 DEFAULT,
96@@ -269,15 +269,18 @@
97
98 implements(ILibraryFileAliasSet)
99
100- def create(
101- self, name, size, file, contentType, expires=None, debugID=None,
102- restricted=False):
103+ def create(self, name, size, file, contentType, expires=None,
104+ debugID=None, restricted=False):
105 """See `ILibraryFileAliasSet`"""
106 if restricted:
107 client = getUtility(IRestrictedLibrarianClient)
108 else:
109 client = getUtility(ILibrarianClient)
110- fid = client.addFile(name, size, file, contentType, expires, debugID)
111+ try:
112+ fid = client.addFile(
113+ name, size, file, contentType, expires, debugID)
114+ except IntegrityError:
115+ raise InvalidFilename("Filename cannot contain slashes.")
116 lfa = IMasterStore(LibraryFileAlias).find(
117 LibraryFileAlias, LibraryFileAlias.id == fid).one()
118 assert lfa is not None, "client.addFile didn't!"