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