-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
Copy pathapi.py
154 lines (145 loc) · 4.93 KB
/
api.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
from flask import current_app, request
from flask_appbuilder import ModelRestApi
from flask_appbuilder.api import expose, safe
from flask_appbuilder.const import API_RESULT_RES_KEY
from flask_appbuilder.models.sqla.interface import SQLAInterface
from flask_appbuilder.security.decorators import permission_name, protect
from flask_appbuilder.security.sqla.apis.role.schema import (
RolePermissionListSchema,
RolePermissionPostSchema,
)
from flask_appbuilder.security.sqla.models import PermissionView, Role
from marshmallow import ValidationError
from sqlalchemy.exc import IntegrityError
class RoleApi(ModelRestApi):
resource_name = "security/roles"
openapi_spec_tag = "Security Roles"
class_permission_name = "Role"
datamodel = SQLAInterface(Role)
allow_browser_login = True
list_columns = ["id", "name"]
show_columns = list_columns
add_columns = ["name"]
edit_columns = ["name"]
search_columns = list_columns
list_role_permission_schema = RolePermissionListSchema()
add_role_permission_schema = RolePermissionPostSchema()
openapi_spec_component_schemas = (
RolePermissionListSchema,
RolePermissionPostSchema,
)
@expose("/<int:pk>/permissions/", methods=["GET"])
@protect()
@safe
@permission_name("list_role_permissions")
def list_role_permissions(self, pk):
"""list role permissions
---
get:
parameters:
- in: path
schema:
type: integer
name: pk
responses:
200:
description: List of permissions
content:
application/json:
schema:
type: object
properties:
result:
$ref: '#/components/schemas/RolePermissionListSchema'
400:
$ref: '#/components/responses/400'
401:
$ref: '#/components/responses/401'
404:
$ref: '#/components/responses/404'
422:
$ref: '#/components/responses/422'
500:
$ref: '#/components/responses/500'
"""
role = self.datamodel.get(pk, select_columns=["permissions"])
if not role:
return self.response_404()
permissions = [
{
"id": p.id,
"permission_name": p.permission.name,
"view_menu_name": p.view_menu.name,
}
for p in role.permissions
]
return self.response(200, **{API_RESULT_RES_KEY: permissions})
@expose("/<int:role_id>/permissions", methods=["POST"])
@protect()
@safe
@permission_name("add_role_permissions")
def add_role_permissions(self, role_id):
"""add role permissions
---
post:
parameters:
- in: path
schema:
type: integer
name: role_id
requestBody:
description: Add role permissions schema
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RolePermissionPostSchema'
responses:
200:
description: Permissions added
content:
application/json:
schema:
type: object
properties:
result:
$ref: '#/components/schemas/RolePermissionPostSchema'
400:
$ref: '#/components/responses/400'
401:
$ref: '#/components/responses/401'
404:
$ref: '#/components/responses/404'
422:
$ref: '#/components/responses/422'
500:
$ref: '#/components/responses/500'
"""
try:
item = self.add_role_permission_schema.load(request.json)
role = self.datamodel.get(role_id)
if not role:
return self.response_404()
permissions = []
for id in item["permission_view_menu_ids"]:
permission = (
current_app.appbuilder.get_session.query(PermissionView)
.filter_by(id=id)
.one_or_none()
)
if permission:
permissions.append(permission)
role.permissions = permissions
self.datamodel.edit(role, raise_exception=True)
return self.response(
200,
**{
API_RESULT_RES_KEY: self.add_role_permission_schema.dump(
item, many=False
)
},
)
except ValidationError as error:
return self.response_400(message=error.messages)
except IntegrityError as e:
return self.response_422(message=str(e.orig))