From: Ricardo Dias Date: Tue, 24 Apr 2018 12:40:19 +0000 (+0100) Subject: mgr/dashboard: auth: remove single user authentication X-Git-Tag: v14.0.1~1019^2~10 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=5edfec5f3167267799334e7835dd5c742157f8ce;p=ceph.git mgr/dashboard: auth: remove single user authentication Signed-off-by: Ricardo Dias --- diff --git a/src/pybind/mgr/dashboard/controllers/auth.py b/src/pybind/mgr/dashboard/controllers/auth.py index be6c3298fe648..17e5eb9fa4ef4 100644 --- a/src/pybind/mgr/dashboard/controllers/auth.py +++ b/src/pybind/mgr/dashboard/controllers/auth.py @@ -3,12 +3,12 @@ from __future__ import absolute_import import time -import bcrypt import cherrypy from . import ApiController, RESTController -from .. import logger, mgr +from .. import logger from ..exceptions import DashboardException +from ..services.auth import AuthManager from ..tools import Session @@ -21,19 +21,13 @@ class Auth(RESTController): | KEY | DEFAULT | DESCR | ------------------------------------------------------------------------| - | username | None | Username | - | password | None | Password encrypted using bcrypt | | session-expire | 1200 | Session will expire after | | | seconds without activity | """ def create(self, username, password, stay_signed_in=False): now = time.time() - config_username = mgr.get_config('username', None) - config_password = mgr.get_config('password', None) - hash_password = Auth.password_hash(password, - config_password) - if username == config_username and hash_password == config_password: + if AuthManager.authenticate(username, password): cherrypy.session.regenerate() cherrypy.session[Session.USERNAME] = username cherrypy.session[Session.TS] = now @@ -41,11 +35,7 @@ class Auth(RESTController): logger.debug('Login successful') return {'username': username} - if config_username is None: - logger.warning('No Credentials configured. Need to call `ceph dashboard ' - 'set-login-credentials ` first.') - else: - logger.debug('Login failed') + logger.debug('Login failed') raise DashboardException(msg='Invalid credentials', code='invalid_credentials', component='auth') @@ -54,39 +44,3 @@ class Auth(RESTController): logger.debug('Logout successful') cherrypy.session[Session.USERNAME] = None cherrypy.session[Session.TS] = None - - @staticmethod - def password_hash(password, salt_password=None): - if not salt_password: - salt_password = bcrypt.gensalt() - else: - salt_password = salt_password.encode('utf8') - return bcrypt.hashpw(password.encode('utf8'), salt_password).decode('utf8') - - @staticmethod - def check_auth(): - username = cherrypy.session.get(Session.USERNAME) - if not username: - logger.debug('Unauthorized access to %s', - cherrypy.url(relative='server')) - raise cherrypy.HTTPError(401, 'You are not authorized to access ' - 'that resource') - now = time.time() - expires = float(mgr.get_config( - 'session-expire', Session.DEFAULT_EXPIRE)) - if expires > 0: - username_ts = cherrypy.session.get(Session.TS, None) - if username_ts and float(username_ts) < (now - expires): - cherrypy.session[Session.USERNAME] = None - cherrypy.session[Session.TS] = None - logger.debug('Session expired') - raise cherrypy.HTTPError(401, - 'Session expired. You are not ' - 'authorized to access that resource') - cherrypy.session[Session.TS] = now - - @staticmethod - def set_login_credentials(username, password): - mgr.set_config('username', username) - hashed_passwd = Auth.password_hash(password) - mgr.set_config('password', hashed_passwd) diff --git a/src/pybind/mgr/dashboard/module.py b/src/pybind/mgr/dashboard/module.py index cb2baa3a7eb5c..f6eddf71c0923 100644 --- a/src/pybind/mgr/dashboard/module.py +++ b/src/pybind/mgr/dashboard/module.py @@ -58,10 +58,9 @@ if 'COVERAGE_ENABLED' in os.environ: # pylint: disable=wrong-import-position from . import logger, mgr from .controllers import generate_routes, json_error_page -from .controllers.auth import Auth from .tools import SessionExpireAtBrowserCloseTool, NotificationQueue, \ RequestLoggingTool, TaskManager -from .services.auth import AuthManager +from .services.auth import AuthManager, AuthManagerTool from .services.access_control import ACCESS_CONTROL_COMMANDS, \ handle_access_control_command from .services.exception import dashboard_exception_handler @@ -127,7 +126,7 @@ class SSLCherryPyConfig(object): server_port) # Initialize custom handlers. - cherrypy.tools.authenticate = cherrypy.Tool('before_handler', Auth.check_auth) + cherrypy.tools.authenticate = AuthManagerTool() cherrypy.tools.session_expire_at_browser_close = SessionExpireAtBrowserCloseTool() cherrypy.tools.request_logging = RequestLoggingTool() cherrypy.tools.dashboard_exception_handler = HandlerWrapperTool(dashboard_exception_handler, @@ -210,13 +209,6 @@ class Module(MgrModule, SSLCherryPyConfig): """ COMMANDS = [ - { - 'cmd': 'dashboard set-login-credentials ' - 'name=username,type=CephString ' - 'name=password,type=CephString', - 'desc': 'Set the login credentials', - 'perm': 'w' - }, { 'cmd': 'dashboard set-session-expire ' 'name=seconds,type=CephInt', @@ -325,9 +317,6 @@ class Module(MgrModule, SSLCherryPyConfig): res = handle_access_control_command(cmd) if res[0] != -errno.ENOSYS: return res - if cmd['prefix'] == 'dashboard set-login-credentials': - Auth.set_login_credentials(cmd['username'], cmd['password']) - return 0, 'Username and password updated', '' elif cmd['prefix'] == 'dashboard set-session-expire': self.set_config('session-expire', str(cmd['seconds'])) return 0, 'Session expiration timeout updated', '' diff --git a/src/pybind/mgr/dashboard/tests/helper.py b/src/pybind/mgr/dashboard/tests/helper.py index 6b578a08713ed..45f67bd12a040 100644 --- a/src/pybind/mgr/dashboard/tests/helper.py +++ b/src/pybind/mgr/dashboard/tests/helper.py @@ -12,7 +12,7 @@ from cherrypy.test import helper from .. import logger from ..controllers import json_error_page, generate_controller_routes -from ..controllers.auth import Auth +from ..services.auth import AuthManagerTool from ..services.exception import dashboard_exception_handler from ..tools import SessionExpireAtBrowserCloseTool @@ -31,7 +31,7 @@ class ControllerTestCase(helper.CPWebCase): base_url: {'request.dispatch': mapper}}) def __init__(self, *args, **kwargs): - cherrypy.tools.authenticate = cherrypy.Tool('before_handler', Auth.check_auth) + cherrypy.tools.authenticate = AuthManagerTool() cherrypy.tools.session_expire_at_browser_close = SessionExpireAtBrowserCloseTool() cherrypy.tools.dashboard_exception_handler = HandlerWrapperTool(dashboard_exception_handler, priority=31) diff --git a/src/pybind/mgr/dashboard/tools.py b/src/pybind/mgr/dashboard/tools.py index 2913eac9402ab..a2a5f3ef4765d 100644 --- a/src/pybind/mgr/dashboard/tools.py +++ b/src/pybind/mgr/dashboard/tools.py @@ -21,7 +21,7 @@ from .exceptions import ViewCacheNoDataException class RequestLoggingTool(cherrypy.Tool): def __init__(self): cherrypy.Tool.__init__(self, 'before_handler', self.request_begin, - priority=95) + priority=10) def _setup(self): cherrypy.Tool._setup(self) diff --git a/src/vstart.sh b/src/vstart.sh index 7dd94a9569221..2bb60774fd65f 100755 --- a/src/vstart.sh +++ b/src/vstart.sh @@ -712,7 +712,7 @@ EOF # setting login credentials for dashboard if $with_mgr_dashboard; then - ceph_adm tell mgr dashboard set-login-credentials admin admin + ceph_adm tell mgr dashboard ac-user-create admin admin administrator if ! ceph_adm tell mgr dashboard create-self-signed-cert; then echo dashboard module not working correctly! fi