]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | # -*- coding: utf-8 -*- |
2 | from __future__ import absolute_import | |
3 | ||
4 | import cherrypy | |
5 | ||
9f95a23c TL |
6 | from . import ApiController, RESTController, UiApiController,\ |
7 | CreatePermission | |
11fdf7f2 TL |
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): | |
9f95a23c | 46 | # type: () -> list |
11fdf7f2 TL |
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 | ||
9f95a23c TL |
52 | @staticmethod |
53 | def _get(name): | |
11fdf7f2 TL |
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 | ||
9f95a23c TL |
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): | |
11fdf7f2 TL |
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 | ||
9f95a23c TL |
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 | ||
11fdf7f2 | 87 | def set(self, name, description=None, scopes_permissions=None): |
9f95a23c | 88 | # type: (str, str, dict) -> dict |
11fdf7f2 TL |
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): | |
9f95a23c | 105 | # type: (str) -> None |
11fdf7f2 TL |
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 | ||
9f95a23c TL |
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 | ||
11fdf7f2 TL |
128 | |
129 | @UiApiController('/scope', SecurityScope.USER) | |
130 | class Scope(RESTController): | |
131 | def list(self): | |
132 | return SecurityScope.all_scopes() |