From: Inhye Park Date: Tue, 15 Apr 2014 09:48:44 +0000 (+0900) Subject: Limit formatting routes when adding resources X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=e71d982aa1a21ad7b952fcb8516a9610a5902afb;p=openstack-build%2Fcinder-build.git Limit formatting routes when adding resources By default, routes.mapper.Mapper.resource adds a bunch of formatted routes that accept anything after a '.'. Our spec says only .xml and .json are accepted so limit the formatting to those valuse. This allows identifiers with a '.' in urls. A few tests were added to the extensions test to prove that .xml and .json are stripped but other values are not. Closes-bug: #1307956 Change-Id: I8f0b4ae3b10ea93890f6506662905bd5823412f5 --- diff --git a/cinder/api/openstack/__init__.py b/cinder/api/openstack/__init__.py index 008ff031f..8e58e77d0 100644 --- a/cinder/api/openstack/__init__.py +++ b/cinder/api/openstack/__init__.py @@ -35,6 +35,15 @@ class APIMapper(routes.Mapper): return result[0], result[1] return routes.Mapper.routematch(self, url, environ) + def connect(self, *args, **kwargs): + # NOTE(inhye): Default the format part of a route to only accept json + # and xml so it doesn't eat all characters after a '.' + # in the url. + kwargs.setdefault('requirements', {}) + if not kwargs['requirements'].get('format'): + kwargs['requirements']['format'] = 'json|xml' + return routes.Mapper.connect(self, *args, **kwargs) + class ProjectMapper(APIMapper): def resource(self, member_name, collection_name, **kwargs): diff --git a/cinder/tests/api/test_extensions.py b/cinder/tests/api/test_extensions.py index 64acba42b..22a9e2215 100644 --- a/cinder/tests/api/test_extensions.py +++ b/cinder/tests/api/test_extensions.py @@ -19,6 +19,7 @@ from lxml import etree from oslo.config import cfg import webob +from cinder.api import extensions from cinder.api.v1 import router from cinder.api import xmlutil from cinder.openstack.common import jsonutils @@ -153,3 +154,58 @@ class ExtensionControllerTest(ExtensionTestCase): 'The Fox In Socks Extension.') xmlutil.validate_schema(root, 'extension') + + +class StubExtensionManager(object): + """Provides access to Tweedle Beetles.""" + + name = "Tweedle Beetle Extension" + alias = "TWDLBETL" + + def __init__(self, resource_ext=None, action_ext=None, request_ext=None, + controller_ext=None): + self.resource_ext = resource_ext + self.controller_ext = controller_ext + self.extra_resource_ext = None + + def get_resources(self): + resource_exts = [] + if self.resource_ext: + resource_exts.append(self.resource_ext) + if self.extra_resource_ext: + resource_exts.append(self.extra_resource_ext) + return resource_exts + + def get_controller_extensions(self): + controller_extensions = [] + if self.controller_ext: + controller_extensions.append(self.controller_ext) + return controller_extensions + + +class ExtensionControllerIdFormatTest(test.TestCase): + + def _bounce_id(self, test_id): + + class BounceController(object): + def show(self, req, id): + return id + res_ext = extensions.ResourceExtension('bounce', + BounceController()) + manager = StubExtensionManager(res_ext) + app = router.APIRouter(manager) + request = webob.Request.blank("/fake/bounce/%s" % test_id) + response = request.get_response(app) + return response.body + + def test_id_with_xml_format(self): + result = self._bounce_id('foo.xml') + self.assertEqual(result, 'foo') + + def test_id_with_json_format(self): + result = self._bounce_id('foo.json') + self.assertEqual(result, 'foo') + + def test_id_with_bad_format(self): + result = self._bounce_id('foo.bad') + self.assertEqual(result, 'foo.bad')