]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/controllers/role.py
import 15.2.0 Octopus source
[ceph.git] / ceph / src / pybind / mgr / dashboard / controllers / role.py
1 # -*- coding: utf-8 -*-
2 from __future__ import absolute_import
3
4 import cherrypy
5
6 from . import ApiController, RESTController, UiApiController,\
7 CreatePermission
8 from .. import mgr
9 from ..exceptions import RoleDoesNotExist, DashboardException,\
10 RoleIsAssociatedWithUser, RoleAlreadyExists
11 from ..security import Scope as SecurityScope, Permission
12 from ..services.access_control import SYSTEM_ROLES
13
14
15 @ApiController('/role', SecurityScope.USER)
16 class Role(RESTController):
17 @staticmethod
18 def _role_to_dict(role):
19 role_dict = role.to_dict()
20 role_dict['system'] = role_dict['name'] in SYSTEM_ROLES
21 return role_dict
22
23 @staticmethod
24 def _validate_permissions(scopes_permissions):
25 if scopes_permissions:
26 for scope, permissions in scopes_permissions.items():
27 if scope not in SecurityScope.all_scopes():
28 raise DashboardException(msg='Invalid scope',
29 code='invalid_scope',
30 component='role')
31 if any(permission not in Permission.all_permissions()
32 for permission in permissions):
33 raise DashboardException(msg='Invalid permission',
34 code='invalid_permission',
35 component='role')
36
37 @staticmethod
38 def _set_permissions(role, scopes_permissions):
39 role.reset_scope_permissions()
40 if scopes_permissions:
41 for scope, permissions in scopes_permissions.items():
42 if permissions:
43 role.set_scope_permissions(scope, permissions)
44
45 def list(self):
46 # type: () -> list
47 roles = dict(mgr.ACCESS_CTRL_DB.roles)
48 roles.update(SYSTEM_ROLES)
49 roles = sorted(roles.values(), key=lambda role: role.name)
50 return [Role._role_to_dict(r) for r in roles]
51
52 @staticmethod
53 def _get(name):
54 role = SYSTEM_ROLES.get(name)
55 if not role:
56 try:
57 role = mgr.ACCESS_CTRL_DB.get_role(name)
58 except RoleDoesNotExist:
59 raise cherrypy.HTTPError(404)
60 return Role._role_to_dict(role)
61
62 def get(self, name):
63 # type: (str) -> dict
64 return Role._get(name)
65
66 @staticmethod
67 def _create(name=None, description=None, scopes_permissions=None):
68 if not name:
69 raise DashboardException(msg='Name is required',
70 code='name_required',
71 component='role')
72 Role._validate_permissions(scopes_permissions)
73 try:
74 role = mgr.ACCESS_CTRL_DB.create_role(name, description)
75 except RoleAlreadyExists:
76 raise DashboardException(msg='Role already exists',
77 code='role_already_exists',
78 component='role')
79 Role._set_permissions(role, scopes_permissions)
80 mgr.ACCESS_CTRL_DB.save()
81 return Role._role_to_dict(role)
82
83 def create(self, name=None, description=None, scopes_permissions=None):
84 # type: (str, str, dict) -> dict
85 return Role._create(name, description, scopes_permissions)
86
87 def set(self, name, description=None, scopes_permissions=None):
88 # type: (str, str, dict) -> dict
89 try:
90 role = mgr.ACCESS_CTRL_DB.get_role(name)
91 except RoleDoesNotExist:
92 if name in SYSTEM_ROLES:
93 raise DashboardException(msg='Cannot update system role',
94 code='cannot_update_system_role',
95 component='role')
96 raise cherrypy.HTTPError(404)
97 Role._validate_permissions(scopes_permissions)
98 Role._set_permissions(role, scopes_permissions)
99 role.description = description
100 mgr.ACCESS_CTRL_DB.update_users_with_roles(role)
101 mgr.ACCESS_CTRL_DB.save()
102 return Role._role_to_dict(role)
103
104 def delete(self, name):
105 # type: (str) -> None
106 try:
107 mgr.ACCESS_CTRL_DB.delete_role(name)
108 except RoleDoesNotExist:
109 if name in SYSTEM_ROLES:
110 raise DashboardException(msg='Cannot delete system role',
111 code='cannot_delete_system_role',
112 component='role')
113 raise cherrypy.HTTPError(404)
114 except RoleIsAssociatedWithUser:
115 raise DashboardException(msg='Role is associated with user',
116 code='role_is_associated_with_user',
117 component='role')
118 mgr.ACCESS_CTRL_DB.save()
119
120 @RESTController.Resource('POST', status=201)
121 @CreatePermission
122 def clone(self, name, new_name):
123 # type: (str, str) -> dict
124 role = Role._get(name)
125 return Role._create(new_name, role.get('description'),
126 role.get('scopes_permissions'))
127
128
129 @UiApiController('/scope', SecurityScope.USER)
130 class Scope(RESTController):
131 def list(self):
132 return SecurityScope.all_scopes()