Skip to content

Commit ee4d086

Browse files
authored
fix: Permission verification error (#6726)
1 parent 8b4f00c commit ee4d086

2 files changed

Lines changed: 147 additions & 106 deletions

File tree

Lines changed: 139 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# coding=utf-8
22
"""
3-
@project: MaxKB
4-
@Author:虎虎
5-
@file: authenticate.py
6-
@date:2024/3/14 03:02
7-
@desc: 用户认证
3+
@project: MaxKB
4+
@Author:虎虎
5+
@file: authenticate.py
6+
@date:2024/3/14 03:02
7+
@desc: 用户认证
88
"""
9+
910
from functools import reduce
1011

1112
from django.core.cache import cache
@@ -30,133 +31,161 @@
3031
from users.models import User
3132

3233

33-
def get_permissions(user,
34-
workspace_user_role_mapping_model,
35-
workspace_model,
36-
role_model,
37-
role_permission_mapping_model):
34+
def get_permissions(
35+
user, workspace_user_role_mapping_model, workspace_model, role_model, role_permission_mapping_model
36+
):
3837
user_id = user.id
3938
version = Cache_Version.PERMISSION_LIST.get_version()
4039
key = Cache_Version.PERMISSION_LIST.get_key(user_id=user_id)
4140
# 获取权限列表
42-
is_query_model = workspace_user_role_mapping_model is not None and workspace_model is not None and role_model is not None and role_permission_mapping_model is not None
41+
is_query_model = (
42+
workspace_user_role_mapping_model is not None
43+
and workspace_model is not None
44+
and role_model is not None
45+
and role_permission_mapping_model is not None
46+
)
4347
permission_map = cache.get(key, version=version)
4448
if permission_map is None:
4549
permission_map = {}
4650
if is_query_model:
4751
# 获取工作空间 用户 角色映射数据
4852
workspace_user_role_mapping_list = QuerySet(workspace_user_role_mapping_model).filter(user_id=user_id)
4953

50-
role_id_list = list(set([workspace_user_role_mapping.role_id for workspace_user_role_mapping in
51-
workspace_user_role_mapping_list]))
54+
role_id_list = list(
55+
set(
56+
[
57+
workspace_user_role_mapping.role_id
58+
for workspace_user_role_mapping in workspace_user_role_mapping_list
59+
]
60+
)
61+
)
5262
# 获取角色权限映射数据
53-
role_permission_mapping_list = QuerySet(role_permission_mapping_model).filter(
54-
role_id__in=role_id_list)
63+
role_permission_mapping_list = QuerySet(role_permission_mapping_model).filter(role_id__in=role_id_list)
5564
role_model_list = QuerySet(role_model).filter(id__in=role_id_list)
5665

5766
role_model_dict = {role_model.id: role_model for role_model in role_model_list}
5867

59-
role_permission_mapping_dict = group_by(
60-
role_permission_mapping_list, lambda item: str(item.role_id))
68+
role_permission_mapping_dict = group_by(role_permission_mapping_list, lambda item: str(item.role_id))
6169

6270
workspace_user_permission_list = QuerySet(WorkspaceUserResourcePermission).filter(
63-
workspace_id__in=[workspace_user_role.workspace_id for workspace_user_role in
64-
workspace_user_role_mapping_list if
65-
(role_model_dict.get(workspace_user_role.role_id).type == 'USER' if
66-
role_model_dict.get(workspace_user_role.role_id) else False)],
67-
user_id=user_id)
68-
69-
workspace_user_group_resource_permission_list = QuerySet(
70-
WorkspaceUserGroupResourcePermission).filter(
71-
user_group__user_relations__user_id=user_id
72-
).select_related('user_group').distinct()
71+
workspace_id__in=[
72+
workspace_user_role.workspace_id
73+
for workspace_user_role in workspace_user_role_mapping_list
74+
if (
75+
role_model_dict.get(workspace_user_role.role_id).type == "USER"
76+
if role_model_dict.get(workspace_user_role.role_id)
77+
else False
78+
)
79+
],
80+
user_id=user_id,
81+
)
82+
83+
workspace_user_group_resource_permission_list = (
84+
QuerySet(WorkspaceUserGroupResourcePermission)
85+
.filter(user_group__user_relations__user_id=user_id)
86+
.select_related("user_group")
87+
.distinct()
88+
)
7389
"----------------------处理资源权限--------------------------------------------------"
7490
for _ in list(workspace_user_permission_list) + list(workspace_user_group_resource_permission_list):
7591
if _.auth_type == ResourceAuthType.RESOURCE_PERMISSION_GROUP:
7692
all_permissions = flat_map(
77-
[RESOURCE_PERMISSION_MAP.get(f'{_.auth_target_type}_{_resource_permission}') for
78-
_resource_permission
79-
in
80-
_.permission_list if _resource_permission in ['VIEW', 'MANAGE']])
81-
for group, permissions in group_by(all_permissions,
82-
lambda _permission: _permission.value.group).items():
93+
[
94+
RESOURCE_PERMISSION_MAP.get(f"{_.auth_target_type}_{_resource_permission}")
95+
for _resource_permission in _.permission_list
96+
if _resource_permission in ["VIEW", "MANAGE"]
97+
]
98+
)
99+
for group, permissions in group_by(
100+
all_permissions, lambda _permission: _permission.value.group
101+
).items():
83102
k = f"{group}:{_.workspace_id}:{_.target}"
84-
bits = reduce(lambda x, y: x | y,
85-
[_permission.value.bit() for
86-
_permission in
87-
permissions], 0)
103+
bits = reduce(lambda x, y: x | y, [_permission.value.bit() for _permission in permissions], 0)
88104
permission_map[k] = permission_map.get(k, 0) | bits
89105
elif _.auth_type == ResourceAuthType.ROLE:
90-
role_ids = [m.role_id for m in workspace_user_role_mapping_list
91-
if m.workspace_id == _.workspace_id]
106+
role_ids = [m.role_id for m in workspace_user_role_mapping_list if m.workspace_id == _.workspace_id]
92107

93108
permissions = []
94109
for role_id in role_ids:
95-
for m in (role_permission_mapping_dict.get(str(role_id)) or []):
110+
for m in role_permission_mapping_dict.get(str(role_id)) or []:
96111
p = PERMISSION_STR_MAP.get(m.permission_id)
97112
if PermissionScopeConstants.WORKSPACE in p.meta.scope:
98113
permissions.append(p)
99114

100115
for group, ps in group_by(permissions, lambda p: p.meta.group).items():
101-
k = f"{group}:{_.workspace_id}:{_.target}"
116+
k = f"{group}:w:{_.workspace_id}:r:{_.target}"
102117
bits = reduce(lambda x, y: x | y, [p.value.bit() for p in ps], 0)
103118
permission_map[k] = permission_map.get(k, 0) | bits
104119

105120
"----------------------处理工作空间权限--------------------------------------------------"
106121
for _ in workspace_user_role_mapping_list:
107122
_role_permission_mapping_list = role_permission_mapping_dict.get(str(_.role_id)) or []
108-
permissions = [PERMISSION_STR_MAP.get(_role_permission_mapping.permission_id) for
109-
_role_permission_mapping in
110-
_role_permission_mapping_list]
123+
permissions = [
124+
PERMISSION_STR_MAP.get(_role_permission_mapping.permission_id)
125+
for _role_permission_mapping in _role_permission_mapping_list
126+
]
111127
# 过滤工作空间权限
112-
permissions = [_permission for _permission in permissions if
113-
PermissionScopeConstants.WORKSPACE in _permission.meta.scope]
128+
permissions = [
129+
_permission
130+
for _permission in permissions
131+
if PermissionScopeConstants.WORKSPACE in _permission.meta.scope
132+
]
114133
for group, ps in group_by(permissions, lambda p: p.meta.group).items():
115-
k = f"{group}:{_.workspace_id}"
134+
k = f"{group}:w:{_.workspace_id}"
116135
bits = reduce(lambda x, y: x | y, [p.value.bit() for p in ps], 0)
117136
permission_map[k] = permission_map.get(k, 0) | bits
118137
"----------------------处理系统权限--------------------------------------------------"
119-
system_permissions = [PERMISSION_STR_MAP.get(_role_permission_mapping.permission_id) for
120-
_role_permission_mapping in
121-
role_permission_mapping_list]
122-
system_permissions = [_permission for _permission in system_permissions if
123-
PermissionScopeConstants.SYSTEM in _permission.meta.scope]
124-
for group, permissions in group_by(system_permissions,
125-
lambda _permission: _permission.meta.group).items():
126-
permission_map[f"{group}"] = reduce(lambda x, y: x | y,
127-
[_permission.value.bit() for
128-
_permission in
129-
permissions], 0)
138+
system_permissions = [
139+
PERMISSION_STR_MAP.get(_role_permission_mapping.permission_id)
140+
for _role_permission_mapping in role_permission_mapping_list
141+
]
142+
system_permissions = [
143+
_permission
144+
for _permission in system_permissions
145+
if PermissionScopeConstants.SYSTEM in _permission.meta.scope
146+
]
147+
for group, permissions in group_by(system_permissions, lambda _permission: _permission.meta.group).items():
148+
permission_map[f"{group}"] = reduce(
149+
lambda x, y: x | y, [_permission.value.bit() for _permission in permissions], 0
150+
)
130151
cache.set(key, permission_map, version=version)
131152
else:
132-
workspace_id_list = ['default']
153+
workspace_id_list = ["default"]
133154
workspace_user_permission_list = QuerySet(WorkspaceUserResourcePermission).filter(
134-
workspace_id__in=workspace_id_list, user_id=user_id)
135-
workspace_user_group_resource_permission_list = QuerySet(
136-
WorkspaceUserGroupResourcePermission).filter(
137-
user_group__user_relations__user_id=user_id
138-
).select_related('user_group').distinct()
155+
workspace_id__in=workspace_id_list, user_id=user_id
156+
)
157+
workspace_user_group_resource_permission_list = (
158+
QuerySet(WorkspaceUserGroupResourcePermission)
159+
.filter(user_group__user_relations__user_id=user_id)
160+
.select_related("user_group")
161+
.distinct()
162+
)
139163

140164
for _ in list(workspace_user_permission_list) + list(workspace_user_group_resource_permission_list):
141165
if _.auth_type == ResourceAuthType.RESOURCE_PERMISSION_GROUP:
142166
all_permissions = flat_map(
143-
[RESOURCE_PERMISSION_MAP.get(f'{_.auth_target_type}_{_resource_permission}') for
144-
_resource_permission
145-
in
146-
_.permission_list if _resource_permission in ['VIEW', 'MANAGE']])
147-
for group, permissions in group_by(all_permissions,
148-
lambda _permission: _permission.value.group).items():
149-
permission_map[f"{group}:{_.workspace_id}:{_.target}"] = reduce(lambda x, y: x | y,
150-
[_permission.value.bit() for
151-
_permission in
152-
permissions], 0)
167+
[
168+
RESOURCE_PERMISSION_MAP.get(f"{_.auth_target_type}_{_resource_permission}")
169+
for _resource_permission in _.permission_list
170+
if _resource_permission in ["VIEW", "MANAGE"]
171+
]
172+
)
173+
for group, permissions in group_by(
174+
all_permissions, lambda _permission: _permission.value.group
175+
).items():
176+
permission_map[f"{group}:w:{_.workspace_id}:r:{_.target}"] = reduce(
177+
lambda x, y: x | y, [_permission.value.bit() for _permission in permissions], 0
178+
)
153179
cache.set(key, permission_map, version=version)
154180

155181
return permission_map
156182

157183

158-
system_role_list = [RoleConstants.ADMIN.value.name, RoleConstants.WORKSPACE_MANAGE.value.name,
159-
RoleConstants.USER.value.name]
184+
system_role_list = [
185+
RoleConstants.ADMIN.value.name,
186+
RoleConstants.WORKSPACE_MANAGE.value.name,
187+
RoleConstants.USER.value.name,
188+
]
160189

161190
system_role = RoleConstants.ADMIN.value.name
162191

@@ -166,49 +195,57 @@ def reset_workspace_role(role_id, workspace_id, role_dict):
166195
if system_role == role_id:
167196
return [role_id]
168197
else:
169-
return [f"{role_id}:/WORKSPACE/{workspace_id}", role_id]
198+
return [f"{role_id}:/w/{workspace_id}", role_id]
170199
else:
171200
r = role_dict.get(role_id)
172201
if r is None:
173202
return []
174203
role_type = role_dict.get(role_id).type
175204
if system_role == role_type:
176205
return [RoleConstants.EXTENDS_ADMIN.value.name]
177-
return [f"EXTENDS_{role_type}:/WORKSPACE/{workspace_id}"]
206+
return [f"EXTENDS_{role_type}:/w/{workspace_id}"]
178207

179208

180-
def get_role_list(user,
181-
workspace_user_role_mapping_model,
182-
workspace_model,
183-
role_model,
184-
role_permission_mapping_model):
209+
def get_role_list(user, workspace_user_role_mapping_model, workspace_model, role_model, role_permission_mapping_model):
185210
"""
186211
获取当前用户的角色列表
187212
"""
188213
version = Cache_Version.ROLE_LIST.get_version()
189214
key = Cache_Version.ROLE_LIST.get_key(user_id=user.id)
190215
role_list = cache.get(key, version=version)
191216
# 获取权限列表
192-
is_query_model = workspace_user_role_mapping_model is not None and workspace_model is not None and role_model is not None and role_permission_mapping_model is not None
217+
is_query_model = (
218+
workspace_user_role_mapping_model is not None
219+
and workspace_model is not None
220+
and role_model is not None
221+
and role_permission_mapping_model is not None
222+
)
193223
if role_list is None:
194224
if is_query_model:
195225
# 获取工作空间 用户 角色映射数据
196226
workspace_user_role_mapping_list = QuerySet(workspace_user_role_mapping_model).filter(user_id=user.id)
197227
role_list = QuerySet(role_model).filter(id__in=[wurm.role_id for wurm in workspace_user_role_mapping_list])
198228
role_dict = {r.id: r for r in role_list}
199229
role_list = list(
200-
set(reduce(lambda x, y: [*x, *y], [reset_workspace_role(workspace_user_role_mapping.role_id,
201-
workspace_user_role_mapping.workspace_id,
202-
role_dict)
203-
for
204-
workspace_user_role_mapping in
205-
workspace_user_role_mapping_list], [])))
230+
set(
231+
reduce(
232+
lambda x, y: [*x, *y],
233+
[
234+
reset_workspace_role(
235+
workspace_user_role_mapping.role_id, workspace_user_role_mapping.workspace_id, role_dict
236+
)
237+
for workspace_user_role_mapping in workspace_user_role_mapping_list
238+
],
239+
[],
240+
)
241+
)
242+
)
206243
cache.set(key, role_list, version=version)
207244
else:
208245
if user.role == RoleConstants.ADMIN.value.__str__():
209-
role_list = [user.role, f'{RoleConstants.WORKSPACE_MANAGE}:default']
246+
role_list = [user.role, f"{RoleConstants.WORKSPACE_MANAGE}:default"]
210247
else:
211-
role_list = [user.role, f'{RoleConstants.USER}:default']
248+
role_list = [user.role, f"{RoleConstants.USER}:default"]
212249
cache.set(key, role_list, version=version)
213250
return role_list
214251

@@ -219,10 +256,12 @@ def get_auth(user):
219256
role_model = DatabaseModelManage.get_model("role_model")
220257
role_permission_mapping_model = DatabaseModelManage.get_model("role_permission_mapping_model")
221258

222-
permissions = get_permissions(user, workspace_user_role_mapping_model, workspace_model,
223-
role_model, role_permission_mapping_model)
224-
role_list = get_role_list(user, workspace_user_role_mapping_model, workspace_model,
225-
role_model, role_permission_mapping_model)
259+
permissions = get_permissions(
260+
user, workspace_user_role_mapping_model, workspace_model, role_model, role_permission_mapping_model
261+
)
262+
role_list = get_role_list(
263+
user, workspace_user_role_mapping_model, workspace_model, role_model, role_permission_mapping_model
264+
)
226265
return Auth(set(role_list), permissions)
227266

228267

@@ -231,18 +270,18 @@ def support(self, request, token: str, get_token_details):
231270
auth_details = get_token_details()
232271
if auth_details is None:
233272
return False
234-
return 'id' in auth_details and auth_details.get('type') == AuthenticationType.SYSTEM_USER.value
273+
return "id" in auth_details and auth_details.get("type") == AuthenticationType.SYSTEM_USER.value
235274

236275
def handle(self, request, token: str, get_token_details):
237276
version, get_key = Cache_Version.TOKEN.value
238277
cache_token = cache.get(get_key(token), version=version)
239278
if cache_token is None:
240-
raise AppAuthenticationFailed(1002, _('Login expired'))
279+
raise AppAuthenticationFailed(1002, _("Login expired"))
241280
auth_details = get_token_details()
242281
timeout = CONFIG.get_session_timeout()
243282
cache.touch(token, timeout=timeout, version=version)
244-
user = QuerySet(User).get(id=auth_details['id'])
283+
user = QuerySet(User).get(id=auth_details["id"])
245284
if not user.is_active or user.password != cache_token.password:
246-
raise AppAuthenticationFailed(1002, _('Authentication information is incorrect'))
285+
raise AppAuthenticationFailed(1002, _("Authentication information is incorrect"))
247286
auth = get_auth(user)
248287
return Principal(user.id, UserType.SYSTEM_USER, user), auth

0 commit comments

Comments
 (0)