launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #13914
[Merge] lp:~jcsackett/launchpad/invalid-product-names into lp:launchpad
j.c.sackett has proposed merging lp:~jcsackett/launchpad/invalid-product-names into lp:launchpad.
Commit message:
Updates handling of InvalidProductName on bzr push to return an error message to the user rather than OOPSing.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #798954 in Launchpad itself: "InvalidProductName: Invalid name for product: bookmark:galapagos. "
https://bugs.launchpad.net/launchpad/+bug/798954
For more details, see:
https://code.launchpad.net/~jcsackett/launchpad/invalid-product-names/+merge/132405
Summary
=======
When someone pushes to an invalid product name (i.e. one that doesn't satisfy
our name validation), an unexpected error is triggered.
We should just handle it as we do non-existant products and products you don't
have permission to post to, rather than OOPSing.
Preimp
======
Spoke with Curtis Hovey.
Implementation
==============
The InvalidProductName exception is now caught in a block that handles all the
other expected errors when getting branch information from the path. In its
place, an xmlrpc fault.InvalidProductName is returned.
This is trapped and and returned as a PermissionDenied fault, as that is the
only fault that we return in order to avoid the bzr client being "clever" by
suggesting --create-prrefix or other solutions be tried.
Also: updated InvalidProductIdentifier to be InvalidProductName--there's no
reason to have two separate names for the same error.
Tests were written, which required adding a clause to check if the product
name is valid an if not raise the expected error in the InMemory backend. I
confess I can't figure out the purpose of the inmemory backend, as it seems to
be a mock of some sort but we test everything directly against the db.
Tests
=====
bin/test -vvct test_createBranch_invalid_product
QA
==
Attempt to push a branch to fiz:bar/trunk on qastaging. You should get back a
permission denied error about the branch being an invalid name, rather than an
unexpected error dump.
LoC
===
I have ~300 LoC of credit.
Lint
====
Checking for conflicts and issues in changed files.
Linting changed files:
lib/lp/xmlrpc/faults.py
lib/lp/code/xmlrpc/codehosting.py
lib/lp/code/xmlrpc/tests/test_codehosting.py
lib/lp/xmlrpc/configure.zcml
lib/lp/codehosting/vfs/branchfs.py
lib/lp/codehosting/inmemory.py
lib/lp/code/model/tests/test_branchlookup.py
lib/lp/code/xmlrpc/branch.py
--
https://code.launchpad.net/~jcsackett/launchpad/invalid-product-names/+merge/132405
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jcsackett/launchpad/invalid-product-names into lp:launchpad.
=== modified file 'lib/lp/code/model/tests/test_branchlookup.py'
--- lib/lp/code/model/tests/test_branchlookup.py 2012-09-18 18:36:09 +0000
+++ lib/lp/code/model/tests/test_branchlookup.py 2012-10-31 19:20:28 +0000
@@ -446,7 +446,7 @@
self.assertRaises(NoSuchProduct, self.traverser.traverse, 'bb')
def test_invalid_product(self):
- # `traverse` raises `InvalidProductIdentifier` when resolving an lp
+ # `traverse` raises `InvalidProductName` when resolving an lp
# path for a completely invalid product development focus branch.
self.assertRaises(
InvalidProductName, self.traverser.traverse, 'b')
=== modified file 'lib/lp/code/xmlrpc/branch.py'
--- lib/lp/code/xmlrpc/branch.py 2012-07-04 18:06:32 +0000
+++ lib/lp/code/xmlrpc/branch.py 2012-10-31 19:20:28 +0000
@@ -304,7 +304,7 @@
# the model code(blech) or some automated way of reraising as faults
# or using a narrower range of faults (e.g. only one "NoSuch" fault).
except InvalidProductName as e:
- raise faults.InvalidProductIdentifier(urlutils.escape(e.name))
+ raise faults.InvalidProductName(urlutils.escape(e.name))
except NoSuchProductSeries as e:
raise faults.NoSuchProductSeries(
urlutils.escape(e.name), e.product)
=== modified file 'lib/lp/code/xmlrpc/codehosting.py'
--- lib/lp/code/xmlrpc/codehosting.py 2012-07-24 06:39:54 +0000
+++ lib/lp/code/xmlrpc/codehosting.py 2012-10-31 19:20:28 +0000
@@ -65,7 +65,10 @@
IPersonSet,
NoSuchPerson,
)
-from lp.registry.interfaces.product import NoSuchProduct
+from lp.registry.interfaces.product import (
+ NoSuchProduct,
+ InvalidProductName,
+ )
from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
from lp.services.scripts.interfaces.scriptactivity import IScriptActivitySet
from lp.services.webapp import LaunchpadXMLRPCView
@@ -219,6 +222,8 @@
except NoSuchProduct as e:
return faults.NotFound(
"Project '%s' does not exist." % e.name)
+ except InvalidProductName as e:
+ return faults.InvalidProductName(escape(e.name))
except NoSuchSourcePackageName as e:
try:
getUtility(ISourcePackageNameSet).new(e.name)
=== modified file 'lib/lp/code/xmlrpc/tests/test_codehosting.py'
--- lib/lp/code/xmlrpc/tests/test_codehosting.py 2012-09-18 19:41:02 +0000
+++ lib/lp/code/xmlrpc/tests/test_codehosting.py 2012-10-31 19:20:28 +0000
@@ -297,6 +297,16 @@
owner.id, escape('/~%s/no-such-product/%s' % (owner.name, name)))
self.assertEqual(faults.NotFound(message), fault)
+ def test_createBranch_invalid_product(self):
+ # Creating a branch with an invalid product name fails.
+ owner = self.factory.makePerson()
+ name = self.factory.getUniqueString()
+ from lp.code.interfaces.codehosting import BRANCH_ALIAS_PREFIX
+ branch_name = "/%s/fiz:buzz/%s" % (BRANCH_ALIAS_PREFIX, name)
+ fault = self.codehosting_api.createBranch(
+ owner.id, branch_name)
+ self.assertEqual(faults.InvalidProductName(escape('fiz:buzz')), fault)
+
def test_createBranch_other_user(self):
# Creating a branch under another user's directory fails.
creator = self.factory.makePerson()
=== modified file 'lib/lp/codehosting/inmemory.py'
--- lib/lp/codehosting/inmemory.py 2012-09-19 01:19:35 +0000
+++ lib/lp/codehosting/inmemory.py 2012-10-31 19:20:28 +0000
@@ -651,6 +651,8 @@
if data['product'] == '+junk':
product = None
elif data['product'] is not None:
+ if not valid_name(data['product']):
+ raise faults.InvalidProductName(escape(data['product']))
product = self._product_set.getByName(data['product'])
if product is None:
raise faults.NotFound(
=== modified file 'lib/lp/codehosting/vfs/branchfs.py'
--- lib/lp/codehosting/vfs/branchfs.py 2012-07-05 14:53:47 +0000
+++ lib/lp/codehosting/vfs/branchfs.py 2012-10-31 19:20:28 +0000
@@ -607,7 +607,7 @@
# parent directories", which is just misleading.
fault = trap_fault(
fail, faults.NotFound, faults.PermissionDenied,
- faults.InvalidSourcePackageName)
+ faults.InvalidSourcePackageName, faults.InvalidProductName)
faultString = fault.faultString
if isinstance(faultString, unicode):
faultString = faultString.encode('utf-8')
=== modified file 'lib/lp/xmlrpc/configure.zcml'
--- lib/lp/xmlrpc/configure.zcml 2012-01-20 06:58:13 +0000
+++ lib/lp/xmlrpc/configure.zcml 2012-10-31 19:20:28 +0000
@@ -150,7 +150,7 @@
<require like_class="xmlrpclib.Fault" />
</class>
- <class class="lp.xmlrpc.faults.InvalidProductIdentifier">
+ <class class="lp.xmlrpc.faults.InvalidProductName">
<require like_class="xmlrpclib.Fault" />
</class>
=== modified file 'lib/lp/xmlrpc/faults.py'
--- lib/lp/xmlrpc/faults.py 2012-01-20 06:58:13 +0000
+++ lib/lp/xmlrpc/faults.py 2012-10-31 19:20:28 +0000
@@ -20,7 +20,7 @@
'InvalidBranchIdentifier',
'InvalidBranchName',
'InvalidBranchUniqueName',
- 'InvalidProductIdentifier',
+ 'InvalidProductName',
'InvalidBranchUrl',
'InvalidSourcePackageName',
'OopsOccurred',
@@ -294,7 +294,7 @@
component_type=component_type)
-class InvalidProductIdentifier(LaunchpadFault):
+class InvalidProductName(LaunchpadFault):
"""Raised when we are passed an invalid name for a product.
This is for when users try to specify a product using a silly name
Follow ups