Now all controllers require authentication by default.
No disable authentication, a boolean parameter can be passed
in the `@ApiController` decorator.
Fixes: http://tracker.ceph.com/issues/23796
Signed-off-by: Ricardo Dias <rdias@suse.com>
class Controller(object):
- def __init__(self, path, base_url=None):
+ def __init__(self, path, base_url=None, secure=True):
self.path = path
self.base_url = base_url
+ self.secure = secure
if self.path and self.path[0] != "/":
self.path = "/" + self.path
'tools.sessions.on': True,
'tools.sessions.name': Session.NAME,
'tools.session_expire_at_browser_close.on': True,
- 'tools.dashboard_exception_handler.on': True
+ 'tools.dashboard_exception_handler.on': True,
+ 'tools.authenticate.on': self.secure,
}
if not hasattr(cls, '_cp_config'):
cls._cp_config = {}
- if 'tools.authenticate.on' not in cls._cp_config:
- config['tools.authenticate.on'] = False
cls._cp_config.update(config)
return cls
class ApiController(Controller):
- def __init__(self, path):
- super(ApiController, self).__init__(path, base_url="/api")
+ def __init__(self, path, secure=True):
+ super(ApiController, self).__init__(path, base_url="/api",
+ secure=secure)
def __call__(self, cls):
cls = super(ApiController, self).__call__(cls)
class UiApiController(Controller):
- def __init__(self, path):
- super(UiApiController, self).__init__(path, base_url="/ui-api")
-
-
-def AuthRequired(enabled=True):
- if not isinstance(enabled, bool):
- raise TypeError('AuthRequired used incorrectly. '
- 'You are likely missing parentheses!')
-
- def decorate(cls):
- if not hasattr(cls, '_cp_config'):
- cls._cp_config = {
- 'tools.authenticate.on': enabled
- }
- else:
- cls._cp_config['tools.authenticate.on'] = enabled
- return cls
- return decorate
+ def __init__(self, path, security_scope=None, secure=True):
+ super(UiApiController, self).__init__(path, base_url="/ui-api",
+ security_scope=security_scope,
+ secure=secure)
def Endpoint(method=None, path=None, path_params=None, query_params=None,
path_params = [p['name'] for p in self.path_params]
query_params = [p['name'] for p in self.query_params]
return [p for p in func_params
- if p['name'] not in path_params and
- p['name'] not in query_params]
+ if p['name'] not in path_params
+ and p['name'] not in query_params]
@property
def group(self):
from ..tools import Session
-@ApiController('/auth')
+@ApiController('/auth', secure=False)
class Auth(RESTController):
"""
Provide login and logout actions.
import cherrypy
-from ..exceptions import DashboardException
-from . import ApiController, AuthRequired, RESTController
+from . import ApiController, RESTController
from .. import mgr
+from ..exceptions import DashboardException
from ..services.ceph_service import CephService
from ..tools import ViewCache
@ApiController('/cephfs')
-@AuthRequired()
class CephFS(RESTController):
def __init__(self):
super(CephFS, self).__init__()
import cherrypy
+from . import ApiController, RESTController
from .. import mgr
from ..services.ceph_service import CephService
-from . import ApiController, RESTController, AuthRequired
@ApiController('/cluster_conf')
-@AuthRequired()
class ClusterConfiguration(RESTController):
def _append_config_option_values(self, options):
import collections
import json
-from . import ApiController, AuthRequired, Endpoint, BaseController
+from . import ApiController, Endpoint, BaseController
from .. import mgr
from ..services.ceph_service import CephService
from ..tools import NotificationQueue
@ApiController('/dashboard')
-@AuthRequired()
class Dashboard(BaseController):
def __init__(self):
super(Dashboard, self).__init__()
import cherrypy
-from . import Controller, BaseController, AuthRequired, Endpoint, ENDPOINT_MAP
+from . import Controller, BaseController, Endpoint, ENDPOINT_MAP
from .. import logger
@Controller('/docs')
-@AuthRequired()
class Docs(BaseController):
@classmethod
from cherrypy import NotFound
-from . import ApiController, AuthRequired, RESTController
+from . import ApiController, RESTController
from ..services.ceph_service import CephService
from .. import mgr
@ApiController('/erasure_code_profile')
-@AuthRequired()
class ErasureCodeProfile(RESTController):
"""
create() supports additional key-value arguments that are passed to the
import requests
from six.moves.urllib.parse import urlparse # pylint: disable=import-error
-from . import ApiController, BaseController, AuthRequired, Proxy, Endpoint
+from . import ApiController, BaseController, Proxy, Endpoint
from .. import logger
from ..settings import Settings
@ApiController('/grafana')
-@AuthRequired()
class Grafana(BaseController):
@Endpoint()
@ApiController('/grafana/proxy')
-@AuthRequired()
class GrafanaProxy(BaseController):
@Proxy()
def __call__(self, path, **params):
# -*- coding: utf-8 -*-
from __future__ import absolute_import
-from . import ApiController, AuthRequired, RESTController
+from . import ApiController, RESTController
from .. import mgr
@ApiController('/host')
-@AuthRequired()
class Host(RESTController):
def list(self):
return mgr.list_servers()
from .. import logger
-@UiApiController('/logging')
+@UiApiController('/logging', secure=False)
class Logging(BaseController):
@Endpoint('POST', path='js-error')
import json
-from . import ApiController, AuthRequired, Endpoint, BaseController
+from . import ApiController, Endpoint, BaseController
from .. import mgr
@ApiController('/monitor')
-@AuthRequired()
class Monitor(BaseController):
@Endpoint()
def __call__(self):
# -*- coding: utf-8 -*-
from __future__ import absolute_import
-from . import ApiController, AuthRequired, RESTController
+from . import ApiController, RESTController
from .. import mgr, logger
from ..services.ceph_service import CephService
from ..services.exception import handle_send_command_error
@ApiController('/osd')
-@AuthRequired()
class Osd(RESTController):
def list(self):
osds = self.get_osd_map()
# -*- coding: utf-8 -*-
from __future__ import absolute_import
-from . import ApiController, AuthRequired, RESTController
+from . import ApiController, RESTController
from .. import mgr
from ..services.ceph_service import CephService
@ApiController('perf_counters/mds')
-@AuthRequired()
class MdsPerfCounter(PerfCounter):
service_type = 'mds'
@ApiController('perf_counters/mon')
-@AuthRequired()
class MonPerfCounter(PerfCounter):
service_type = 'mon'
@ApiController('perf_counters/osd')
-@AuthRequired()
class OsdPerfCounter(PerfCounter):
service_type = 'osd'
@ApiController('perf_counters/rgw')
-@AuthRequired()
class RgwPerfCounter(PerfCounter):
service_type = 'rgw'
@ApiController('perf_counters/rbd-mirror')
-@AuthRequired()
class RbdMirrorPerfCounter(PerfCounter):
service_type = 'rbd-mirror'
@ApiController('perf_counters/mgr')
-@AuthRequired()
class MgrPerfCounter(PerfCounter):
service_type = 'mgr'
@ApiController('perf_counters')
-@AuthRequired()
class PerfCounters(RESTController):
def list(self):
return mgr.get_all_perf_counters()
import cherrypy
-from . import ApiController, RESTController, Endpoint, AuthRequired
+from . import ApiController, RESTController, Endpoint
from .. import mgr
from ..services.ceph_service import CephService
from ..services.exception import handle_send_command_error
@ApiController('/pool')
-@AuthRequired()
class Pool(RESTController):
@classmethod
import rbd
-from . import ApiController, AuthRequired, RESTController, Task
+from . import ApiController, RESTController, Task
from .. import mgr
from ..services.ceph_service import CephService
from ..tools import ViewCache
@ApiController('/block/image')
-@AuthRequired()
class Rbd(RESTController):
RESOURCE_ID = "pool_name/image_name"
@ApiController('/block/image/:pool_name/:image_name/snap')
-@AuthRequired()
class RbdSnapshot(RESTController):
RESOURCE_ID = "snapshot_name"
import rbd
-from . import ApiController, AuthRequired, Endpoint, BaseController
+from . import ApiController, Endpoint, BaseController
from .. import logger, mgr
from ..services.ceph_service import CephService
from ..tools import ViewCache
@ApiController('/rbdmirror')
-@AuthRequired()
class RbdMirror(BaseController):
def __init__(self):
import json
import cherrypy
-from . import ApiController, BaseController, RESTController, AuthRequired, Endpoint
+from . import ApiController, BaseController, RESTController, Endpoint
from .. import logger
from ..services.ceph_service import CephService
from ..services.rgw_client import RgwClient
@ApiController('/rgw')
-@AuthRequired()
class Rgw(BaseController):
@Endpoint()
@ApiController('/rgw/daemon')
-@AuthRequired()
class RgwDaemon(RESTController):
def list(self):
@ApiController('/rgw/bucket')
-@AuthRequired()
class RgwBucket(RgwRESTController):
def list(self):
@ApiController('/rgw/user')
-@AuthRequired()
class RgwUser(RgwRESTController):
def list(self):
import json
+
+from . import ApiController, Endpoint, BaseController
from .. import mgr
-from . import AuthRequired, ApiController, Endpoint, BaseController
from ..controllers.rbd_mirroring import get_daemons_and_pools
from ..tools import ViewCacheNoDataException
from ..tools import TaskManager
@ApiController('/summary')
-@AuthRequired()
class Summary(BaseController):
def _health_status(self):
health_data = mgr.get("health")
# -*- coding: utf-8 -*-
from __future__ import absolute_import
-from . import ApiController, AuthRequired, RESTController
+from . import ApiController, RESTController
from ..tools import TaskManager
@ApiController('/task')
-@AuthRequired()
class Task(RESTController):
def list(self, name=None):
executing_t, finished_t = TaskManager.list_serializable(name)
# -*- coding: utf-8 -*-
from __future__ import absolute_import
-from . import ApiController, AuthRequired, RESTController
+from . import ApiController, RESTController
from .. import mgr
from ..services.ceph_service import CephService
@ApiController('/tcmuiscsi')
-@AuthRequired()
class TcmuIscsi(RESTController):
# pylint: disable=too-many-nested-blocks
def list(self): # pylint: disable=unused-argument
ApiController, Endpoint
-@Controller("/btest/{key}", base_url="/ui")
+@Controller("/btest/{key}", base_url="/ui", secure=False)
class BTest(BaseController):
@Endpoint()
def test1(self, key, opt=1):
return {'key': key, 'opt': opt}
-@ApiController("/rtest/{key}")
+@ApiController("/rtest/{key}", secure=False)
class RTest(RESTController):
RESOURCE_ID = 'skey/ekey'
return {'key': key, 'skey': skey, 'ekey': ekey, 'opt': opt}
-@Controller("/")
+@Controller("/", secure=False)
class Root(BaseController):
@Endpoint(json_response=False)
def __call__(self):
# pylint: disable=W0613
-@Controller('foo')
+@Controller('foo', secure=False)
class FooResource(RESTController):
@Endpoint()
url='//localhost:3000', username='admin', password='admin')
-@Controller('grafana/mocked')
+@Controller('/grafana/mocked', secure=False)
class GrafanaMockInstance(BaseController):
@Proxy()
def __call__(self, path, **params):
from ..tools import NotificationQueue, TaskManager
-@Controller('test/task')
+@Controller('/test/task', secure=False)
class TaskTest(RESTController):
sleep_time = 0.0
# pylint: disable=W0613
-@Controller('/foo')
+@Controller('/foo', secure=False)
class FooResource(RESTController):
elems = []
return dict(key=key, newdata=newdata)
-@Controller('/foo/:key/:method')
+@Controller('/foo/:key/:method', secure=False)
class FooResourceDetail(RESTController):
def list(self, key, method):
return {'detail': (key, [method])}
-@ApiController('/rgw/proxy')
+@ApiController('/rgw/proxy', secure=False)
class GenerateControllerRoutesController(BaseController):
@Proxy()
def __call__(self, path, **params):
pass
-@ApiController('/fooargs')
+@ApiController('/fooargs', secure=False)
class FooArgs(RESTController):
def set(self, code, name=None, opt1=None, opt2=None):
return {'code': code, 'name': name, 'opt1': opt1, 'opt2': opt2}