diff options
Diffstat (limited to 'src/pybind/mgr/dashboard/controllers/role.py')
-rw-r--r-- | src/pybind/mgr/dashboard/controllers/role.py | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/pybind/mgr/dashboard/controllers/role.py b/src/pybind/mgr/dashboard/controllers/role.py new file mode 100644 index 00000000..f87eff7b --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/role.py @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import cherrypy + +from . import ApiController, RESTController, UiApiController +from .. import mgr +from ..exceptions import RoleDoesNotExist, DashboardException,\ + RoleIsAssociatedWithUser, RoleAlreadyExists +from ..security import Scope as SecurityScope, Permission +from ..services.access_control import SYSTEM_ROLES + + +@ApiController('/role', SecurityScope.USER) +class Role(RESTController): + @staticmethod + def _role_to_dict(role): + role_dict = role.to_dict() + role_dict['system'] = role_dict['name'] in SYSTEM_ROLES + return role_dict + + @staticmethod + def _validate_permissions(scopes_permissions): + if scopes_permissions: + for scope, permissions in scopes_permissions.items(): + if scope not in SecurityScope.all_scopes(): + raise DashboardException(msg='Invalid scope', + code='invalid_scope', + component='role') + if any(permission not in Permission.all_permissions() + for permission in permissions): + raise DashboardException(msg='Invalid permission', + code='invalid_permission', + component='role') + + @staticmethod + def _set_permissions(role, scopes_permissions): + role.reset_scope_permissions() + if scopes_permissions: + for scope, permissions in scopes_permissions.items(): + if permissions: + role.set_scope_permissions(scope, permissions) + + def list(self): + roles = dict(mgr.ACCESS_CTRL_DB.roles) + roles.update(SYSTEM_ROLES) + roles = sorted(roles.values(), key=lambda role: role.name) + return [Role._role_to_dict(r) for r in roles] + + def get(self, name): + role = SYSTEM_ROLES.get(name) + if not role: + try: + role = mgr.ACCESS_CTRL_DB.get_role(name) + except RoleDoesNotExist: + raise cherrypy.HTTPError(404) + return Role._role_to_dict(role) + + def create(self, name=None, description=None, scopes_permissions=None): + if not name: + raise DashboardException(msg='Name is required', + code='name_required', + component='role') + Role._validate_permissions(scopes_permissions) + try: + role = mgr.ACCESS_CTRL_DB.create_role(name, description) + except RoleAlreadyExists: + raise DashboardException(msg='Role already exists', + code='role_already_exists', + component='role') + Role._set_permissions(role, scopes_permissions) + mgr.ACCESS_CTRL_DB.save() + return Role._role_to_dict(role) + + def set(self, name, description=None, scopes_permissions=None): + try: + role = mgr.ACCESS_CTRL_DB.get_role(name) + except RoleDoesNotExist: + if name in SYSTEM_ROLES: + raise DashboardException(msg='Cannot update system role', + code='cannot_update_system_role', + component='role') + raise cherrypy.HTTPError(404) + Role._validate_permissions(scopes_permissions) + Role._set_permissions(role, scopes_permissions) + role.description = description + mgr.ACCESS_CTRL_DB.update_users_with_roles(role) + mgr.ACCESS_CTRL_DB.save() + return Role._role_to_dict(role) + + def delete(self, name): + try: + mgr.ACCESS_CTRL_DB.delete_role(name) + except RoleDoesNotExist: + if name in SYSTEM_ROLES: + raise DashboardException(msg='Cannot delete system role', + code='cannot_delete_system_role', + component='role') + raise cherrypy.HTTPError(404) + except RoleIsAssociatedWithUser: + raise DashboardException(msg='Role is associated with user', + code='role_is_associated_with_user', + component='role') + mgr.ACCESS_CTRL_DB.save() + + +@UiApiController('/scope', SecurityScope.USER) +class Scope(RESTController): + def list(self): + return SecurityScope.all_scopes() |