Skip to content

Commit 89749a3

Browse files
committed
feat: Folder authorization backend
1 parent d696d2e commit 89749a3

26 files changed

+310
-335
lines changed

apps/application/serializers/application.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -347,14 +347,15 @@ def get_query_set(self, instance: Dict, workspace_manage: bool, is_x_pack_ee: bo
347347
application_custom_sql_query_set = application_query_set
348348
application_query_set = application_query_set.order_by("-create_time")
349349

350-
return {'folder_query_set': folder_query_set,
351-
'application_query_set': application_query_set,
352-
'workspace_user_resource_permission_query_set': QuerySet(WorkspaceUserResourcePermission).filter(
350+
resource_and_folder_query_set = QuerySet(WorkspaceUserResourcePermission).filter(
353351
auth_target_type="APPLICATION",
354352
workspace_id=workspace_id,
355-
user_id=user_id)} if (
353+
user_id=user_id)
354+
355+
return {'application_query_set': application_query_set,
356+
'workspace_user_resource_permission_query_set': resource_and_folder_query_set,
357+
} if (
356358
not workspace_manage) else {
357-
'folder_query_set': folder_query_set,
358359
'application_query_set': application_query_set,
359360
'application_custom_sql': application_custom_sql_query_set
360361
}

apps/application/sql/list_application.sql

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,5 @@ from (select application."id"::text, application."name",
1515
from application
1616
left join "user" on user_id = "user".id
1717
${application_custom_sql}
18-
UNION
19-
select application_folder."id", application_folder."name", application_folder."desc", true as "is_publish", 'folder' as "type", 'folder' as "resource_type", application_folder."workspace_id", application_folder."parent_id" as "folder_id", application_folder."user_id", "user"."nick_name" as "nick_name", application_folder."create_time", application_folder."update_time", null as "publish_time", null as "icon"
20-
from application_folder left join "user"
21-
on user_id = "user".id ${folder_query_set}) temp
18+
) temp
2219
${application_query_set}

apps/application/sql/list_application_user.sql

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,5 @@ from (select application."id"::text, application."name",
1616
left join "user" on user_id = "user".id
1717
where application."id" in (select target
1818
from workspace_user_resource_permission ${workspace_user_resource_permission_query_set}
19-
and 'VIEW' = any (permission_list))
20-
UNION
21-
select application_folder."id",
22-
application_folder."name",
23-
application_folder."desc",
24-
true as "is_publish",
25-
'folder' as "type",
26-
'folder' as "resource_type",
27-
application_folder."workspace_id",
28-
application_folder."parent_id" as "folder_id",
29-
application_folder."user_id",
30-
"user"."nick_name" as "nick_name",
31-
application_folder."create_time",
32-
application_folder."update_time",
33-
null as "publish_time",
34-
null as "icon"
35-
from application_folder
36-
left join "user" on user_id = "user".id ${folder_query_set}) temp ${application_query_set}
19+
and 'VIEW' = any (permission_list))) temp
20+
${application_query_set}

apps/application/sql/list_application_user_ee.sql

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ from (select application."id"::text, application."name",
1414
application.icon
1515
from application
1616
left join "user" on user_id = "user".id
17-
where "application".id in (select target
17+
where "application".id::text in (select target
1818
from workspace_user_resource_permission ${workspace_user_resource_permission_query_set}
1919
and case
2020
when auth_type = 'ROLE' then
@@ -33,22 +33,5 @@ from (select application."id"::text, application."name",
3333

3434
else
3535
'VIEW' = any (permission_list)
36-
end)
37-
UNION
38-
select application_folder."id",
39-
application_folder."name",
40-
application_folder."desc",
41-
true as "is_publish",
42-
'folder' as "type",
43-
'folder' as "resource_type",
44-
application_folder."workspace_id",
45-
application_folder."parent_id" as "folder_id",
46-
application_folder."user_id",
47-
"user"."nick_name" as "nick_name",
48-
application_folder."create_time",
49-
application_folder."update_time",
50-
null as "publish_time",
51-
null as "icon"
52-
53-
from application_folder
54-
left join "user" on user_id = "user".id ${folder_query_set}) temp ${application_query_set}
36+
end)) temp
37+
${application_query_set}

apps/common/constants/permission_constants.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ class Group(Enum):
8888
OVERVIEW = "OVERVIEW"
8989
OPERATION_LOG = "OPERATION_LOG"
9090

91+
APPLICATION_FOLDER = "APPLICATION_FOLDER"
92+
KNOWLEDGE_FOLDER = "KNOWLEDGE_FOLDER"
93+
TOOL_FOLDER = "TOOL_FOLDER"
94+
9195

9296
class SystemGroup(Enum):
9397
"""
@@ -203,8 +207,11 @@ def __eq__(self, other):
203207

204208
class Resource(models.TextChoices):
205209
KNOWLEDGE = Group.KNOWLEDGE.value
210+
KNOWLEDGE_FOLDER = Group.KNOWLEDGE_FOLDER.value
206211
APPLICATION = Group.APPLICATION.value
212+
APPLICATION_FOLDER = Group.APPLICATION_FOLDER.value
207213
TOOL = Group.TOOL.value
214+
TOOL_FOLDER = Group.TOOL_FOLDER.value
208215
MODEL = Group.MODEL.value
209216

210217
def __eq__(self, other):
@@ -222,10 +229,16 @@ def __eq__(self, other):
222229

223230
class ResourcePermissionConst:
224231
KNOWLEDGE_MANGE = ResourcePermissionGroup(Resource.KNOWLEDGE, ResourcePermission.MANAGE)
232+
KNOWLEDGE_FOLDER_MANGE = ResourcePermissionGroup(Resource.KNOWLEDGE_FOLDER, ResourcePermission.MANAGE)
233+
KNOWLEDGE_FOLDER_VIEW = ResourcePermissionGroup(Resource.KNOWLEDGE_FOLDER, ResourcePermission.VIEW)
225234
KNOWLEDGE_VIEW = ResourcePermissionGroup(Resource.KNOWLEDGE, ResourcePermission.VIEW)
226235
APPLICATION_MANGE = ResourcePermissionGroup(Resource.APPLICATION, ResourcePermission.MANAGE)
236+
APPLICATION_FOLDER_MANGE = ResourcePermissionGroup(Resource.APPLICATION_FOLDER, ResourcePermission.MANAGE)
237+
APPLICATION_FOLDER_VIEW = ResourcePermissionGroup(Resource.APPLICATION_FOLDER, ResourcePermission.VIEW)
227238
APPLICATION_VIEW = ResourcePermissionGroup(Resource.APPLICATION, ResourcePermission.VIEW)
228239
TOOL_MANGE = ResourcePermissionGroup(Resource.TOOL, ResourcePermission.MANAGE)
240+
TOOL_FOLDER_MANGE = ResourcePermissionGroup(Resource.TOOL_FOLDER, ResourcePermission.MANAGE)
241+
TOOL_FOLDER_VIEW = ResourcePermissionGroup(Resource.TOOL_FOLDER, ResourcePermission.VIEW)
229242
TOOL_VIEW = ResourcePermissionGroup(Resource.TOOL, ResourcePermission.VIEW)
230243
MODEL_MANGE = ResourcePermissionGroup(Resource.MODEL, ResourcePermission.MANAGE)
231244
MODEL_VIEW = ResourcePermissionGroup(Resource.MODEL, ResourcePermission.VIEW)
@@ -437,6 +450,30 @@ class PermissionConstants(Enum):
437450
TOOL = Permission(
438451
group=Group.TOOL, operate=Operate.SELF, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
439452
)
453+
APPLICATION_FOLDER_READ = Permission(
454+
group=Group.APPLICATION_FOLDER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
455+
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_VIEW]
456+
)
457+
APPLICATION_FOLDER_EDIT = Permission(
458+
group=Group.APPLICATION_FOLDER, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
459+
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_MANGE]
460+
)
461+
KNOWLEDGE_FOLDER_READ = Permission(
462+
group=Group.KNOWLEDGE_FOLDER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
463+
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_VIEW]
464+
)
465+
KNOWLEDGE_FOLDER_EDIT = Permission(
466+
group=Group.KNOWLEDGE_FOLDER, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
467+
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_MANGE]
468+
)
469+
TOOL_FOLDER_READ = Permission(
470+
group=Group.TOOL_FOLDER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
471+
resource_permission_group_list=[ResourcePermissionConst.TOOL_VIEW]
472+
)
473+
TOOL_FOLDER_EDIT = Permission(
474+
group=Group.TOOL_FOLDER, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
475+
resource_permission_group_list=[ResourcePermissionConst.TOOL_MANGE]
476+
)
440477

441478
USER_READ = Permission(
442479
group=Group.USER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],

apps/folders/serializers/folder.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import uuid_utils.compat as uuid
44
from django.db import transaction
5-
from django.db.models import QuerySet, Q
5+
from django.db.models import QuerySet, Q, Func, F
66
from django.utils.translation import gettext_lazy as _
77
from rest_framework import serializers
88

@@ -269,7 +269,8 @@ def _check_tree_integrity(queryset):
269269
return True # 需要重建
270270
return False
271271

272-
def get_folder_tree(self, name=None):
272+
def get_folder_tree(self,
273+
current_user, name=None):
273274
self.is_valid(raise_exception=True)
274275
Folder = get_folder_type(self.data.get('source')) # noqa
275276

@@ -280,15 +281,21 @@ def get_folder_tree(self, name=None):
280281
if self._check_tree_integrity(workspace_folders):
281282
Folder.objects.rebuild()
282283

284+
workspace_manage = is_workspace_manage(current_user.id, self.data.get('workspace_id'))
285+
286+
base_q = Q(workspace_id=self.data.get('workspace_id'))
287+
283288
if name is not None:
284-
nodes = Folder.objects.filter(
285-
Q(workspace_id=self.data.get('workspace_id')) &
286-
Q(name__contains=name)
287-
).get_cached_trees()
288-
else:
289-
nodes = Folder.objects.filter(
290-
Q(workspace_id=self.data.get('workspace_id'))
291-
).get_cached_trees()
289+
base_q &= Q(name__contains=name)
290+
if not workspace_manage:
291+
base_q &= Q(id__in=WorkspaceUserResourcePermission.objects.filter(user_id=current_user.id,
292+
auth_target_type=self.data.get('source'),
293+
workspace_id=self.data.get('workspace_id'),
294+
permission_list__contains=['VIEW'])
295+
.values_list(
296+
'target', flat=True))
297+
298+
nodes = Folder.objects.filter(base_q).get_cached_trees()
292299

293300
TreeSerializer = get_folder_tree_serializer(self.data.get('source')) # noqa
294301
serializer = TreeSerializer(nodes, many=True)

apps/folders/views/folder.py

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
from common.auth import TokenAuth
88
from common.auth.authentication import has_permissions
9-
from common.constants.permission_constants import Permission, Group, Operate, RoleConstants
9+
from common.constants.permission_constants import Permission, Group, Operate, RoleConstants, ViewPermission, \
10+
PermissionConstants, CompareConstants
1011
from common.log.log import log
1112
from common.result import result
1213
from folders.api.folder import FolderCreateAPI, FolderEditAPI, FolderReadAPI, FolderTreeReadAPI, FolderDeleteAPI
@@ -37,9 +38,17 @@ class FolderView(APIView):
3738
tags=[_('Folder')] # type: ignore
3839
)
3940
@has_permissions(
40-
lambda r, kwargs: Permission(group=Group(kwargs.get('source')), operate=Operate.CREATE,
41-
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}"),
42-
RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role()
41+
lambda r, kwargs: Permission(group=Group(f"{kwargs.get('source')}_FOLDER"), operate=Operate.EDIT,
42+
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('source')}/{r.data.get('parent_id')}"),
43+
lambda r, kwargs: Permission(group=Group(kwargs.get('source')), operate=Operate.EDIT,
44+
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/ROLE/WORKSPACE_MANAGE"
45+
),
46+
lambda r, kwargs: ViewPermission([RoleConstants.USER.get_workspace_role()],
47+
[Permission(group=Group(f"{kwargs.get('source')}_FOLDER"),
48+
operate=Operate.SELF,
49+
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('source')}/{r.data.get('parent_id')}"
50+
)], CompareConstants.AND),
51+
RoleConstants.WORKSPACE_MANAGE.get_workspace_role()
4352
)
4453
@log(
4554
menu='folder', operate='Create folder',
@@ -63,7 +72,8 @@ def post(self, request: Request, workspace_id: str, source: str):
6372
tags=[_('Folder')] # type: ignore
6473
)
6574
@has_permissions(
66-
lambda r, kwargs: Permission(group=Group(f"{kwargs.get('source')}_WORKSPACE_USER_RESOURCE_PERMISSION"), operate= Operate.READ,
75+
lambda r, kwargs: Permission(group=Group(f"{kwargs.get('source')}_WORKSPACE_USER_RESOURCE_PERMISSION"),
76+
operate=Operate.READ,
6777
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}"),
6878
lambda r, kwargs: Permission(group=Group(kwargs.get('source')), operate=Operate.READ,
6979
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}"),
@@ -73,7 +83,7 @@ def post(self, request: Request, workspace_id: str, source: str):
7383
def get(self, request: Request, workspace_id: str, source: str):
7484
return result.success(FolderTreeSerializer(
7585
data={'workspace_id': workspace_id, 'source': source}
76-
).get_folder_tree(request.query_params.get('name')))
86+
).get_folder_tree(request.user, request.query_params.get('name')))
7787

7888
class Operate(APIView):
7989
authentication_classes = [TokenAuth]
@@ -90,8 +100,17 @@ class Operate(APIView):
90100
)
91101
@has_permissions(
92102
lambda r, kwargs: Permission(group=Group(kwargs.get('source')), operate=Operate.EDIT,
93-
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}"),
94-
RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role()
103+
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/ROLE/WORKSPACE_MANAGE"
104+
),
105+
lambda r, kwargs: Permission(group=Group(f"{kwargs.get('source')}_FOLDER"), operate=Operate.EDIT,
106+
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('source')}/{kwargs.get('folder_id')}"
107+
),
108+
lambda r, kwargs: ViewPermission([RoleConstants.USER.get_workspace_role()],
109+
[Permission(group=Group(f"{kwargs.get('source')}_FOLDER"),
110+
operate=Operate.SELF,
111+
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('source')}/{kwargs.get('folder_id')}"
112+
)], CompareConstants.AND),
113+
RoleConstants.WORKSPACE_MANAGE.get_workspace_role()
95114
)
96115
@log(
97116
menu='folder', operate='Edit folder',
@@ -132,9 +151,18 @@ def get(self, request: Request, workspace_id: str, source: str, folder_id: str):
132151
tags=[_('Folder')] # type: ignore
133152
)
134153
@has_permissions(
135-
lambda r, kwargs: Permission(group=Group(kwargs.get('source')), operate=Operate.DELETE,
136-
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}"),
137-
RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role()
154+
lambda r, kwargs: Permission(group=Group(kwargs.get('source')), operate=Operate.EDIT,
155+
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/ROLE/WORKSPACE_MANAGE"
156+
),
157+
lambda r, kwargs: Permission(group=Group(f"{kwargs.get('source')}_FOLDER"), operate=Operate.EDIT,
158+
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('source')}/{kwargs.get('folder_id')}"
159+
),
160+
lambda r, kwargs: ViewPermission([RoleConstants.USER.get_workspace_role()],
161+
[Permission(group=Group(f"{kwargs.get('source')}_FOLDER"),
162+
operate=Operate.SELF,
163+
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('source')}/{kwargs.get('folder_id')}"
164+
)], CompareConstants.AND),
165+
RoleConstants.WORKSPACE_MANAGE.get_workspace_role()
138166
)
139167
@log(
140168
menu='folder', operate='Delete folder',

apps/knowledge/serializers/knowledge.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ def get_query_set(self, workspace_manage, is_x_pack_ee):
161161
query_set_dict['knowledge_custom_sql'] = QuerySet(model=get_dynamics_model({
162162
'knowledge.workspace_id': models.CharField(),
163163
})).filter(**{'knowledge.workspace_id': workspace_id})
164-
query_set_dict['folder_query_set'] = folder_query_set
164+
# query_set_dict['folder_query_set'] = folder_query_set
165165
if not workspace_manage:
166166
query_set_dict['workspace_user_resource_permission_query_set'] = QuerySet(
167167
WorkspaceUserResourcePermission).filter(
@@ -321,7 +321,6 @@ def one(self):
321321
'knowledge_custom_sql': QuerySet(
322322
model=get_dynamics_model({'knowledge.id': models.CharField()})
323323
).filter(**{'knowledge.id': self.data.get("knowledge_id")}),
324-
'folder_query_set': QuerySet(KnowledgeFolder)
325324
}
326325
if not workspace_manage:
327326
query_set_dict['workspace_user_resource_permission_query_set'] = QuerySet(

apps/knowledge/sql/list_knowledge.sql

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,5 @@ FROM (SELECT "temp_knowledge".id::text, "temp_knowledge".name,
2828
GROUP BY knowledge_id) app_knowledge_temp
2929
ON temp_knowledge."id" = "app_knowledge_temp".knowledge_id
3030
left join "user" on "user".id = temp_knowledge.user_id
31-
UNION
32-
SELECT knowledge_folder."id",
33-
knowledge_folder."name",
34-
knowledge_folder."desc",
35-
0 as "type",
36-
'folder' as "resource_type",
37-
knowledge_folder."workspace_id",
38-
knowledge_folder."parent_id" as "folder_id",
39-
knowledge_folder."user_id",
40-
"user"."nick_name" as "nick_name",
41-
knowledge_folder."create_time",
42-
knowledge_folder."update_time",
43-
0 as file_size_limit,
44-
0 as file_count_limit,
45-
'WORKSPACE' as "scope",
46-
'' as "embedding_model_id",
47-
0 as char_length,
48-
'{}'::jsonb as meta,
49-
0 as application_mapping_count,
50-
0 as document_count
51-
from knowledge_folder left join "user"
52-
on "user".id = user_id ${folder_query_set}) temp
31+
) temp
5332
${default_sql}

apps/knowledge/sql/list_knowledge_application.sql

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ SELECT
33
FROM
44
application
55
WHERE
6-
user_id = %s UNION
6+
user_id = %s
7+
UNION
78
SELECT
89
*
910
FROM
1011
application
1112
WHERE
12-
"id" in (select target from workspace_user_resource_permission where auth_target_type = 'APPLICATION' and 'VIEW' = any (permission_list))
13+
"id"::text in (select target from workspace_user_resource_permission where auth_target_type = 'APPLICATION' and 'VIEW' = any (permission_list))

0 commit comments

Comments
 (0)