From: Sebastian Wagner Date: Tue, 27 Mar 2018 13:08:31 +0000 (+0200) Subject: mgr/dashboard: Fix objects named `default` are inaccessible X-Git-Tag: v13.1.0~468^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=452992b178138608301765757fbbf652cf618f48;p=ceph.git mgr/dashboard: Fix objects named `default` are inaccessible These two calls to `default()` are identical: `vpath` and params` are both empty: $ curl 'http://localhost/api/cp_path/' and $ curl 'http://localhost/api/cp_path/default' But we need to dinstinguish them. To fix this, we need to add the missing `default` We now require that all exposed controllers have a @ApiController decorator. Signed-off-by: Sebastian Wagner --- diff --git a/src/pybind/mgr/dashboard/tests/test_tools.py b/src/pybind/mgr/dashboard/tests/test_tools.py index ce7eadaefd788..ff79ccbeb0215 100644 --- a/src/pybind/mgr/dashboard/tests/test_tools.py +++ b/src/pybind/mgr/dashboard/tests/test_tools.py @@ -22,9 +22,7 @@ class FooResource(RESTController): return data def get(self, key, *args, **kwargs): - if args: - return {'detail': (key, args)} - return FooResource.elems[int(key)] + return {'detail': (key, args)} def delete(self, key): del FooResource.elems[int(key)] @@ -37,6 +35,7 @@ class FooResource(RESTController): return dict(key=key, **data) +@ApiController('fooargs') class FooArgs(RESTController): @RESTController.args_from_json def set(self, code, name, opt1=None, opt2=None): @@ -103,6 +102,12 @@ class RESTControllerTest(ControllerTestCase): self.assertJsonBody({'code': 'hello', 'name': 'world', 'opt1': None, 'opt2': 'opt2'}) def test_detail_route(self): + self._get('/foo/default') + self.assertJsonBody({'detail': ['default', []]}) + + self._get('/foo/default/default') + self.assertJsonBody({'detail': ['default', ['default']]}) + self._get('/foo/1/detail') self.assertJsonBody({'detail': ['1', ['detail']]}) diff --git a/src/pybind/mgr/dashboard/tools.py b/src/pybind/mgr/dashboard/tools.py index 153d21f5de5c6..ff65cd03da23a 100644 --- a/src/pybind/mgr/dashboard/tools.py +++ b/src/pybind/mgr/dashboard/tools.py @@ -18,7 +18,7 @@ import cherrypy from six import add_metaclass from .settings import Settings -from . import logger +from . import logger, mgr def ApiController(path): @@ -462,6 +462,18 @@ class RESTController(BaseController): @cherrypy.expose def default(self, *vpath, **params): + if cherrypy.request.path_info.startswith( + '{}/api/{}/default'.format(mgr.url_prefix, self._cp_path_)) or \ + cherrypy.request.path_info.startswith('/{}/default'.format(self._cp_path_)): + # These two calls to default() are identical: `vpath` and + # params` are both empty: + # $ curl 'http://localhost/api/cp_path/' + # and + # $ curl 'http://localhost/api/cp_path/default' + # But we need to distinguish them. To fix this, we need + # to add the missing `default` + vpath = ['default'] + list(vpath) + method, status_code = self._get_method(vpath) if cherrypy.request.method not in ['GET', 'DELETE']: