]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Limit formatting routes when adding resources
authorInhye Park <inhye.park@samsung.com>
Tue, 15 Apr 2014 09:48:44 +0000 (18:48 +0900)
committerInhye Park <inhye.park@samsung.com>
Wed, 7 May 2014 01:36:54 +0000 (10:36 +0900)
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

cinder/api/openstack/__init__.py
cinder/tests/api/test_extensions.py

index 008ff031f15c7fb37f719670722cb8c36e76b241..8e58e77d088bc0e2fc645e45de5840f775325946 100644 (file)
@@ -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):
index 64acba42b1442b69de6f211893cad3a1b2930fe3..22a9e22150202962903f6ca0aade23b231310a22 100644 (file)
@@ -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')