feat: Folder authorization backend

v3.2
zhangzhanwei 2025-10-14 16:31:30 +08:00 committed by zhanweizhang7
parent d696d2e1d6
commit 89749a3006
26 changed files with 310 additions and 335 deletions

View File

@ -347,14 +347,15 @@ class Query(serializers.Serializer):
application_custom_sql_query_set = application_query_set application_custom_sql_query_set = application_query_set
application_query_set = application_query_set.order_by("-create_time") application_query_set = application_query_set.order_by("-create_time")
return {'folder_query_set': folder_query_set, resource_and_folder_query_set = QuerySet(WorkspaceUserResourcePermission).filter(
'application_query_set': application_query_set,
'workspace_user_resource_permission_query_set': QuerySet(WorkspaceUserResourcePermission).filter(
auth_target_type="APPLICATION", auth_target_type="APPLICATION",
workspace_id=workspace_id, workspace_id=workspace_id,
user_id=user_id)} if ( user_id=user_id)
return {'application_query_set': application_query_set,
'workspace_user_resource_permission_query_set': resource_and_folder_query_set,
} if (
not workspace_manage) else { not workspace_manage) else {
'folder_query_set': folder_query_set,
'application_query_set': application_query_set, 'application_query_set': application_query_set,
'application_custom_sql': application_custom_sql_query_set 'application_custom_sql': application_custom_sql_query_set
} }

View File

@ -15,8 +15,5 @@ from (select application."id"::text, application."name",
from application from application
left join "user" on user_id = "user".id left join "user" on user_id = "user".id
${application_custom_sql} ${application_custom_sql}
UNION ) temp
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"
from application_folder left join "user"
on user_id = "user".id ${folder_query_set}) temp
${application_query_set} ${application_query_set}

View File

@ -16,21 +16,5 @@ from (select application."id"::text, application."name",
left join "user" on user_id = "user".id left join "user" on user_id = "user".id
where application."id" in (select target where application."id" in (select target
from workspace_user_resource_permission ${workspace_user_resource_permission_query_set} from workspace_user_resource_permission ${workspace_user_resource_permission_query_set}
and 'VIEW' = any (permission_list)) and 'VIEW' = any (permission_list))) temp
UNION ${application_query_set}
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"
from application_folder
left join "user" on user_id = "user".id ${folder_query_set}) temp ${application_query_set}

View File

@ -14,7 +14,7 @@ from (select application."id"::text, application."name",
application.icon application.icon
from application from application
left join "user" on user_id = "user".id left join "user" on user_id = "user".id
where "application".id in (select target where "application".id::text in (select target
from workspace_user_resource_permission ${workspace_user_resource_permission_query_set} from workspace_user_resource_permission ${workspace_user_resource_permission_query_set}
and case and case
when auth_type = 'ROLE' then when auth_type = 'ROLE' then
@ -33,22 +33,5 @@ from (select application."id"::text, application."name",
else else
'VIEW' = any (permission_list) 'VIEW' = any (permission_list)
end) end)) temp
UNION ${application_query_set}
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"
from application_folder
left join "user" on user_id = "user".id ${folder_query_set}) temp ${application_query_set}

View File

@ -88,6 +88,10 @@ class Group(Enum):
OVERVIEW = "OVERVIEW" OVERVIEW = "OVERVIEW"
OPERATION_LOG = "OPERATION_LOG" OPERATION_LOG = "OPERATION_LOG"
APPLICATION_FOLDER = "APPLICATION_FOLDER"
KNOWLEDGE_FOLDER = "KNOWLEDGE_FOLDER"
TOOL_FOLDER = "TOOL_FOLDER"
class SystemGroup(Enum): class SystemGroup(Enum):
""" """
@ -203,8 +207,11 @@ class ResourcePermission(models.TextChoices):
class Resource(models.TextChoices): class Resource(models.TextChoices):
KNOWLEDGE = Group.KNOWLEDGE.value KNOWLEDGE = Group.KNOWLEDGE.value
KNOWLEDGE_FOLDER = Group.KNOWLEDGE_FOLDER.value
APPLICATION = Group.APPLICATION.value APPLICATION = Group.APPLICATION.value
APPLICATION_FOLDER = Group.APPLICATION_FOLDER.value
TOOL = Group.TOOL.value TOOL = Group.TOOL.value
TOOL_FOLDER = Group.TOOL_FOLDER.value
MODEL = Group.MODEL.value MODEL = Group.MODEL.value
def __eq__(self, other): def __eq__(self, other):
@ -222,10 +229,16 @@ class ResourcePermissionGroup:
class ResourcePermissionConst: class ResourcePermissionConst:
KNOWLEDGE_MANGE = ResourcePermissionGroup(Resource.KNOWLEDGE, ResourcePermission.MANAGE) KNOWLEDGE_MANGE = ResourcePermissionGroup(Resource.KNOWLEDGE, ResourcePermission.MANAGE)
KNOWLEDGE_FOLDER_MANGE = ResourcePermissionGroup(Resource.KNOWLEDGE_FOLDER, ResourcePermission.MANAGE)
KNOWLEDGE_FOLDER_VIEW = ResourcePermissionGroup(Resource.KNOWLEDGE_FOLDER, ResourcePermission.VIEW)
KNOWLEDGE_VIEW = ResourcePermissionGroup(Resource.KNOWLEDGE, ResourcePermission.VIEW) KNOWLEDGE_VIEW = ResourcePermissionGroup(Resource.KNOWLEDGE, ResourcePermission.VIEW)
APPLICATION_MANGE = ResourcePermissionGroup(Resource.APPLICATION, ResourcePermission.MANAGE) APPLICATION_MANGE = ResourcePermissionGroup(Resource.APPLICATION, ResourcePermission.MANAGE)
APPLICATION_FOLDER_MANGE = ResourcePermissionGroup(Resource.APPLICATION_FOLDER, ResourcePermission.MANAGE)
APPLICATION_FOLDER_VIEW = ResourcePermissionGroup(Resource.APPLICATION_FOLDER, ResourcePermission.VIEW)
APPLICATION_VIEW = ResourcePermissionGroup(Resource.APPLICATION, ResourcePermission.VIEW) APPLICATION_VIEW = ResourcePermissionGroup(Resource.APPLICATION, ResourcePermission.VIEW)
TOOL_MANGE = ResourcePermissionGroup(Resource.TOOL, ResourcePermission.MANAGE) TOOL_MANGE = ResourcePermissionGroup(Resource.TOOL, ResourcePermission.MANAGE)
TOOL_FOLDER_MANGE = ResourcePermissionGroup(Resource.TOOL_FOLDER, ResourcePermission.MANAGE)
TOOL_FOLDER_VIEW = ResourcePermissionGroup(Resource.TOOL_FOLDER, ResourcePermission.VIEW)
TOOL_VIEW = ResourcePermissionGroup(Resource.TOOL, ResourcePermission.VIEW) TOOL_VIEW = ResourcePermissionGroup(Resource.TOOL, ResourcePermission.VIEW)
MODEL_MANGE = ResourcePermissionGroup(Resource.MODEL, ResourcePermission.MANAGE) MODEL_MANGE = ResourcePermissionGroup(Resource.MODEL, ResourcePermission.MANAGE)
MODEL_VIEW = ResourcePermissionGroup(Resource.MODEL, ResourcePermission.VIEW) MODEL_VIEW = ResourcePermissionGroup(Resource.MODEL, ResourcePermission.VIEW)
@ -437,6 +450,30 @@ class PermissionConstants(Enum):
TOOL = Permission( TOOL = Permission(
group=Group.TOOL, operate=Operate.SELF, role_list=[RoleConstants.ADMIN, RoleConstants.USER], group=Group.TOOL, operate=Operate.SELF, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
) )
APPLICATION_FOLDER_READ = Permission(
group=Group.APPLICATION_FOLDER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_VIEW]
)
APPLICATION_FOLDER_EDIT = Permission(
group=Group.APPLICATION_FOLDER, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_MANGE]
)
KNOWLEDGE_FOLDER_READ = Permission(
group=Group.KNOWLEDGE_FOLDER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_VIEW]
)
KNOWLEDGE_FOLDER_EDIT = Permission(
group=Group.KNOWLEDGE_FOLDER, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_MANGE]
)
TOOL_FOLDER_READ = Permission(
group=Group.TOOL_FOLDER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
resource_permission_group_list=[ResourcePermissionConst.TOOL_VIEW]
)
TOOL_FOLDER_EDIT = Permission(
group=Group.TOOL_FOLDER, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
resource_permission_group_list=[ResourcePermissionConst.TOOL_MANGE]
)
USER_READ = Permission( USER_READ = Permission(
group=Group.USER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER], group=Group.USER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],

View File

@ -2,7 +2,7 @@
import uuid_utils.compat as uuid import uuid_utils.compat as uuid
from django.db import transaction from django.db import transaction
from django.db.models import QuerySet, Q from django.db.models import QuerySet, Q, Func, F
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from rest_framework import serializers from rest_framework import serializers
@ -269,7 +269,8 @@ class FolderTreeSerializer(serializers.Serializer):
return True # 需要重建 return True # 需要重建
return False return False
def get_folder_tree(self, name=None): def get_folder_tree(self,
current_user, name=None):
self.is_valid(raise_exception=True) self.is_valid(raise_exception=True)
Folder = get_folder_type(self.data.get('source')) # noqa Folder = get_folder_type(self.data.get('source')) # noqa
@ -280,15 +281,21 @@ class FolderTreeSerializer(serializers.Serializer):
if self._check_tree_integrity(workspace_folders): if self._check_tree_integrity(workspace_folders):
Folder.objects.rebuild() Folder.objects.rebuild()
workspace_manage = is_workspace_manage(current_user.id, self.data.get('workspace_id'))
base_q = Q(workspace_id=self.data.get('workspace_id'))
if name is not None: if name is not None:
nodes = Folder.objects.filter( base_q &= Q(name__contains=name)
Q(workspace_id=self.data.get('workspace_id')) & if not workspace_manage:
Q(name__contains=name) base_q &= Q(id__in=WorkspaceUserResourcePermission.objects.filter(user_id=current_user.id,
).get_cached_trees() auth_target_type=self.data.get('source'),
else: workspace_id=self.data.get('workspace_id'),
nodes = Folder.objects.filter( permission_list__contains=['VIEW'])
Q(workspace_id=self.data.get('workspace_id')) .values_list(
).get_cached_trees() 'target', flat=True))
nodes = Folder.objects.filter(base_q).get_cached_trees()
TreeSerializer = get_folder_tree_serializer(self.data.get('source')) # noqa TreeSerializer = get_folder_tree_serializer(self.data.get('source')) # noqa
serializer = TreeSerializer(nodes, many=True) serializer = TreeSerializer(nodes, many=True)

View File

@ -6,7 +6,8 @@ from rest_framework.views import APIView
from common.auth import TokenAuth from common.auth import TokenAuth
from common.auth.authentication import has_permissions from common.auth.authentication import has_permissions
from common.constants.permission_constants import Permission, Group, Operate, RoleConstants from common.constants.permission_constants import Permission, Group, Operate, RoleConstants, ViewPermission, \
PermissionConstants, CompareConstants
from common.log.log import log from common.log.log import log
from common.result import result from common.result import result
from folders.api.folder import FolderCreateAPI, FolderEditAPI, FolderReadAPI, FolderTreeReadAPI, FolderDeleteAPI from folders.api.folder import FolderCreateAPI, FolderEditAPI, FolderReadAPI, FolderTreeReadAPI, FolderDeleteAPI
@ -37,9 +38,17 @@ class FolderView(APIView):
tags=[_('Folder')] # type: ignore tags=[_('Folder')] # type: ignore
) )
@has_permissions( @has_permissions(
lambda r, kwargs: Permission(group=Group(kwargs.get('source')), operate=Operate.CREATE, lambda r, kwargs: Permission(group=Group(f"{kwargs.get('source')}_FOLDER"), operate=Operate.EDIT,
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}"), resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('source')}/{r.data.get('parent_id')}"),
RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role() lambda r, kwargs: Permission(group=Group(kwargs.get('source')), operate=Operate.EDIT,
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/ROLE/WORKSPACE_MANAGE"
),
lambda r, kwargs: ViewPermission([RoleConstants.USER.get_workspace_role()],
[Permission(group=Group(f"{kwargs.get('source')}_FOLDER"),
operate=Operate.SELF,
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('source')}/{r.data.get('parent_id')}"
)], CompareConstants.AND),
RoleConstants.WORKSPACE_MANAGE.get_workspace_role()
) )
@log( @log(
menu='folder', operate='Create folder', menu='folder', operate='Create folder',
@ -63,7 +72,8 @@ class FolderView(APIView):
tags=[_('Folder')] # type: ignore tags=[_('Folder')] # type: ignore
) )
@has_permissions( @has_permissions(
lambda r, kwargs: Permission(group=Group(f"{kwargs.get('source')}_WORKSPACE_USER_RESOURCE_PERMISSION"), operate= Operate.READ, lambda r, kwargs: Permission(group=Group(f"{kwargs.get('source')}_WORKSPACE_USER_RESOURCE_PERMISSION"),
operate=Operate.READ,
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}"), resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}"),
lambda r, kwargs: Permission(group=Group(kwargs.get('source')), operate=Operate.READ, lambda r, kwargs: Permission(group=Group(kwargs.get('source')), operate=Operate.READ,
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}"), resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}"),
@ -73,7 +83,7 @@ class FolderView(APIView):
def get(self, request: Request, workspace_id: str, source: str): def get(self, request: Request, workspace_id: str, source: str):
return result.success(FolderTreeSerializer( return result.success(FolderTreeSerializer(
data={'workspace_id': workspace_id, 'source': source} data={'workspace_id': workspace_id, 'source': source}
).get_folder_tree(request.query_params.get('name'))) ).get_folder_tree(request.user, request.query_params.get('name')))
class Operate(APIView): class Operate(APIView):
authentication_classes = [TokenAuth] authentication_classes = [TokenAuth]
@ -90,8 +100,17 @@ class FolderView(APIView):
) )
@has_permissions( @has_permissions(
lambda r, kwargs: Permission(group=Group(kwargs.get('source')), operate=Operate.EDIT, lambda r, kwargs: Permission(group=Group(kwargs.get('source')), operate=Operate.EDIT,
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}"), resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/ROLE/WORKSPACE_MANAGE"
RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role() ),
lambda r, kwargs: Permission(group=Group(f"{kwargs.get('source')}_FOLDER"), operate=Operate.EDIT,
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('source')}/{kwargs.get('folder_id')}"
),
lambda r, kwargs: ViewPermission([RoleConstants.USER.get_workspace_role()],
[Permission(group=Group(f"{kwargs.get('source')}_FOLDER"),
operate=Operate.SELF,
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('source')}/{kwargs.get('folder_id')}"
)], CompareConstants.AND),
RoleConstants.WORKSPACE_MANAGE.get_workspace_role()
) )
@log( @log(
menu='folder', operate='Edit folder', menu='folder', operate='Edit folder',
@ -132,9 +151,18 @@ class FolderView(APIView):
tags=[_('Folder')] # type: ignore tags=[_('Folder')] # type: ignore
) )
@has_permissions( @has_permissions(
lambda r, kwargs: Permission(group=Group(kwargs.get('source')), operate=Operate.DELETE, lambda r, kwargs: Permission(group=Group(kwargs.get('source')), operate=Operate.EDIT,
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}"), resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/ROLE/WORKSPACE_MANAGE"
RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role() ),
lambda r, kwargs: Permission(group=Group(f"{kwargs.get('source')}_FOLDER"), operate=Operate.EDIT,
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('source')}/{kwargs.get('folder_id')}"
),
lambda r, kwargs: ViewPermission([RoleConstants.USER.get_workspace_role()],
[Permission(group=Group(f"{kwargs.get('source')}_FOLDER"),
operate=Operate.SELF,
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('source')}/{kwargs.get('folder_id')}"
)], CompareConstants.AND),
RoleConstants.WORKSPACE_MANAGE.get_workspace_role()
) )
@log( @log(
menu='folder', operate='Delete folder', menu='folder', operate='Delete folder',

View File

@ -161,7 +161,7 @@ class KnowledgeSerializer(serializers.Serializer):
query_set_dict['knowledge_custom_sql'] = QuerySet(model=get_dynamics_model({ query_set_dict['knowledge_custom_sql'] = QuerySet(model=get_dynamics_model({
'knowledge.workspace_id': models.CharField(), 'knowledge.workspace_id': models.CharField(),
})).filter(**{'knowledge.workspace_id': workspace_id}) })).filter(**{'knowledge.workspace_id': workspace_id})
query_set_dict['folder_query_set'] = folder_query_set # query_set_dict['folder_query_set'] = folder_query_set
if not workspace_manage: if not workspace_manage:
query_set_dict['workspace_user_resource_permission_query_set'] = QuerySet( query_set_dict['workspace_user_resource_permission_query_set'] = QuerySet(
WorkspaceUserResourcePermission).filter( WorkspaceUserResourcePermission).filter(
@ -321,7 +321,6 @@ class KnowledgeSerializer(serializers.Serializer):
'knowledge_custom_sql': QuerySet( 'knowledge_custom_sql': QuerySet(
model=get_dynamics_model({'knowledge.id': models.CharField()}) model=get_dynamics_model({'knowledge.id': models.CharField()})
).filter(**{'knowledge.id': self.data.get("knowledge_id")}), ).filter(**{'knowledge.id': self.data.get("knowledge_id")}),
'folder_query_set': QuerySet(KnowledgeFolder)
} }
if not workspace_manage: if not workspace_manage:
query_set_dict['workspace_user_resource_permission_query_set'] = QuerySet( query_set_dict['workspace_user_resource_permission_query_set'] = QuerySet(

View File

@ -28,26 +28,5 @@ FROM (SELECT "temp_knowledge".id::text, "temp_knowledge".name,
GROUP BY knowledge_id) app_knowledge_temp GROUP BY knowledge_id) app_knowledge_temp
ON temp_knowledge."id" = "app_knowledge_temp".knowledge_id ON temp_knowledge."id" = "app_knowledge_temp".knowledge_id
left join "user" on "user".id = temp_knowledge.user_id left join "user" on "user".id = temp_knowledge.user_id
UNION ) temp
SELECT knowledge_folder."id",
knowledge_folder."name",
knowledge_folder."desc",
0 as "type",
'folder' as "resource_type",
knowledge_folder."workspace_id",
knowledge_folder."parent_id" as "folder_id",
knowledge_folder."user_id",
"user"."nick_name" as "nick_name",
knowledge_folder."create_time",
knowledge_folder."update_time",
0 as file_size_limit,
0 as file_count_limit,
'WORKSPACE' as "scope",
'' as "embedding_model_id",
0 as char_length,
'{}'::jsonb as meta,
0 as application_mapping_count,
0 as document_count
from knowledge_folder left join "user"
on "user".id = user_id ${folder_query_set}) temp
${default_sql} ${default_sql}

View File

@ -3,10 +3,11 @@ SELECT
FROM FROM
application application
WHERE WHERE
user_id = %s UNION user_id = %s
UNION
SELECT SELECT
* *
FROM FROM
application application
WHERE WHERE
"id" in (select target from workspace_user_resource_permission where auth_target_type = 'APPLICATION' and 'VIEW' = any (permission_list)) "id"::text in (select target from workspace_user_resource_permission where auth_target_type = 'APPLICATION' and 'VIEW' = any (permission_list))

View File

@ -33,26 +33,5 @@ FROM (SELECT "temp_knowledge".id::text, "temp_knowledge".name,
GROUP BY knowledge_id) app_knowledge_temp GROUP BY knowledge_id) app_knowledge_temp
ON temp_knowledge."id" = "app_knowledge_temp".knowledge_id ON temp_knowledge."id" = "app_knowledge_temp".knowledge_id
left join "user" on "user".id = temp_knowledge.user_id left join "user" on "user".id = temp_knowledge.user_id
UNION ) temp
SELECT knowledge_folder."id",
knowledge_folder."name",
knowledge_folder."desc",
0 as "type",
'folder' as "resource_type",
knowledge_folder."workspace_id",
knowledge_folder."parent_id" as "folder_id",
knowledge_folder."user_id",
"user".nick_name as "nick_name",
knowledge_folder."create_time",
knowledge_folder."update_time",
0 as file_size_limit,
0 as file_count_limit,
'WORKSPACE' as "scope",
'' as embedding_model_id,
0 as char_length,
'{}'::jsonb as meta,
0 as application_mapping_count,
0 as document_count
from knowledge_folder left join "user"
on "user".id = user_id ${folder_query_set}) temp
${default_sql} ${default_sql}

View File

@ -22,7 +22,7 @@ FROM (SELECT "temp_knowledge".id::text, "temp_knowledge".name,
"document_temp".document_count "document_temp".document_count
FROM (SELECT knowledge.* FROM (SELECT knowledge.*
FROM knowledge knowledge ${knowledge_custom_sql} FROM knowledge knowledge ${knowledge_custom_sql}
AND "knowledge".id in (select target AND "knowledge".id::text in (select target
from workspace_user_resource_permission from workspace_user_resource_permission
${workspace_user_resource_permission_query_set} ${workspace_user_resource_permission_query_set}
and case and case
@ -47,26 +47,5 @@ FROM (SELECT "temp_knowledge".id::text, "temp_knowledge".name,
GROUP BY knowledge_id) app_knowledge_temp GROUP BY knowledge_id) app_knowledge_temp
ON temp_knowledge."id" = "app_knowledge_temp".knowledge_id ON temp_knowledge."id" = "app_knowledge_temp".knowledge_id
left join "user" on "user".id = temp_knowledge.user_id left join "user" on "user".id = temp_knowledge.user_id
UNION ) temp
SELECT knowledge_folder."id",
knowledge_folder."name",
knowledge_folder."desc",
0 as "type",
'folder' as "resource_type",
knowledge_folder."workspace_id",
knowledge_folder."parent_id" as "folder_id",
knowledge_folder."user_id",
"user".nick_name as "nick_name",
knowledge_folder."create_time",
knowledge_folder."update_time",
0 as file_size_limit,
0 as file_count_limit,
'WORKSPACE' as "scope",
'' as embedding_model_id,
0 as char_length,
'{}'::jsonb as meta,
0 as application_mapping_count,
0 as document_count
from knowledge_folder left join "user"
on "user".id = user_id ${folder_query_set}) temp
${default_sql} ${default_sql}

View File

@ -13,6 +13,6 @@ FROM (SELECT model."id"::text, model."name",
model.workspace_id model.workspace_id
from model from model
left join "user" on user_id = "user".id left join "user" on user_id = "user".id
where model."id" in (select target where model."id"::text in (select target
from workspace_user_resource_permission ${workspace_user_resource_permission_query_set} from workspace_user_resource_permission ${workspace_user_resource_permission_query_set}
and 'VIEW' = any (permission_list)) ) temp ${model_query_set} and 'VIEW' = any (permission_list)) ) temp ${model_query_set}

View File

@ -13,7 +13,7 @@ FROM (SELECT model."id"::text, model."name",
model.workspace_id model.workspace_id
from model from model
left join "user" on user_id = "user".id left join "user" on user_id = "user".id
where model."id" in (select target where model."id"::text in (select target
from workspace_user_resource_permission ${workspace_user_resource_permission_query_set} from workspace_user_resource_permission ${workspace_user_resource_permission_query_set}
and case and case
when auth_type = 'ROLE' then when auth_type = 'ROLE' then

View File

@ -0,0 +1,18 @@
# Generated by Django 5.2.6 on 2025-10-11 02:54
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('system_manage', '0002_refresh_collation_reindex'),
]
operations = [
migrations.AlterField(
model_name='workspaceuserresourcepermission',
name='target',
field=models.CharField(db_index=True, max_length=128, verbose_name='知识库/应用id'),
),
]

View File

@ -38,7 +38,7 @@ class WorkspaceUserResourcePermission(models.Model):
auth_target_type = models.CharField(verbose_name='授权目标', max_length=128, choices=AuthTargetType.choices, auth_target_type = models.CharField(verbose_name='授权目标', max_length=128, choices=AuthTargetType.choices,
default=AuthTargetType.KNOWLEDGE, db_index=True) default=AuthTargetType.KNOWLEDGE, db_index=True)
# 授权的知识库或者应用的id # 授权的知识库或者应用的id
target = models.UUIDField(max_length=128, verbose_name="知识库/应用id", db_index=True) target = models.CharField(max_length=128, verbose_name="知识库/应用id", db_index=True)
# 授权类型 如果是Role那么就是角色的权限 如果是PERMISSION # 授权类型 如果是Role那么就是角色的权限 如果是PERMISSION
auth_type = models.CharField(default=False, verbose_name="授权类型", choices=ResourceAuthType.choices, auth_type = models.CharField(default=False, verbose_name="授权类型", choices=ResourceAuthType.choices,

View File

@ -73,7 +73,7 @@ class UpdateUserResourcePermissionRequest(serializers.Serializer):
illegal_target_id_list = select_list( illegal_target_id_list = select_list(
get_file_content( get_file_content(
os.path.join(PROJECT_DIR, "apps", "system_manage", 'sql', 'check_member_permission_target_exists.sql')), os.path.join(PROJECT_DIR, "apps", "system_manage", 'sql', 'check_member_permission_target_exists.sql')),
[json.dumps(user_resource_permission_list), workspace_id, workspace_id, workspace_id, workspace_id]) [json.dumps(user_resource_permission_list), workspace_id, workspace_id, workspace_id, workspace_id,workspace_id,workspace_id,workspace_id])
if illegal_target_id_list is not None and len(illegal_target_id_list) > 0: if illegal_target_id_list is not None and len(illegal_target_id_list) > 0:
raise AppApiException(500, raise AppApiException(500,
_('Non-existent id[') + str(illegal_target_id_list) + ']') _('Non-existent id[') + str(illegal_target_id_list) + ']')
@ -85,6 +85,7 @@ m_map = {
'MODEL': Model, 'MODEL': Model,
'APPLICATION': Application, 'APPLICATION': Application,
} }
sql_map = { sql_map = {
"KNOWLEDGE": 'get_knowledge_user_resource_permission.sql', "KNOWLEDGE": 'get_knowledge_user_resource_permission.sql',
'TOOL': 'get_tool_user_resource_permission.sql', 'TOOL': 'get_tool_user_resource_permission.sql',
@ -130,6 +131,8 @@ class UserResourcePermissionSerializer(serializers.Serializer):
return { return {
'query_set': QuerySet(m_map.get(self.data.get('auth_target_type'))).filter( 'query_set': QuerySet(m_map.get(self.data.get('auth_target_type'))).filter(
workspace_id=self.data.get('workspace_id')), workspace_id=self.data.get('workspace_id')),
'folder_query_set': QuerySet(m_map.get(self.data.get('auth_target_type'))).filter(
workspace_id=self.data.get('workspace_id')),
'workspace_user_resource_permission_query_set': QuerySet(WorkspaceUserResourcePermission).filter( 'workspace_user_resource_permission_query_set': QuerySet(WorkspaceUserResourcePermission).filter(
workspace_id=self.data.get('workspace_id'), user=self.data.get('user_id'), workspace_id=self.data.get('workspace_id'), user=self.data.get('user_id'),
auth_target_type=self.data.get('auth_target_type')), auth_target_type=self.data.get('auth_target_type')),

View File

@ -1,37 +1,45 @@
SELECT SELECT static_temp."target_id"::text
static_temp."target_id"::text FROM (SELECT *
FROM FROM json_to_recordset(
(SELECT * FROM json_to_recordset( %s
%s ) AS x(target_id text, auth_target_type text)) static_temp
) AS x(target_id uuid,auth_target_type text)) static_temp LEFT JOIN (SELECT id::text AS id,
LEFT JOIN ( auth_target_type
SELECT FROM (SELECT "id"::text,
"id", 'KNOWLEDGE' AS "auth_target_type"
'KNOWLEDGE' AS "auth_target_type" FROM knowledge
FROM WHERE workspace_id = %s
knowledge UNION
WHERE workspace_id= %s SELECT "id"::text,
UNION 'KNOWLEDGE' AS "auth_target_type"
SELECT FROM knowledge_folder
"id", WHERE workspace_id = %s
'APPLICATION' AS "auth_target_type" UNION
FROM SELECT "id"::text,
application 'APPLICATION' AS "auth_target_type"
WHERE workspace_id= %s FROM application
UNION WHERE workspace_id = %s
SELECT UNION
"id", SELECT "id"::text,
'MODEL' AS "auth_target_type" 'APPLICATION' AS "auth_target_type"
FROM FROM application_folder
model WHERE workspace_id = %s
WHERE workspace_id= %s UNION
UNION SELECT "id"::text,
SELECT 'MODEL' AS "auth_target_type"
"id", FROM model
'TOOL' AS "auth_target_type" WHERE workspace_id = %s
FROM UNION
tool SELECT "id"::text,
WHERE workspace_id= %s 'TOOL' AS "auth_target_type"
) "app_and_knowledge_temp" FROM tool
ON "app_and_knowledge_temp"."id" = static_temp."target_id" and app_and_knowledge_temp."auth_target_type"=static_temp."auth_target_type" WHERE workspace_id = %s
WHERE app_and_knowledge_temp.id is NULL ; UNION
SELECT "id"::text,
'TOOL' AS "auth_target_type"
FROM tool_folder
WHERE workspace_id = %s
) "union_temp") "app_and_knowledge_temp"
ON "app_and_knowledge_temp"."id" = static_temp."target_id" and
app_and_knowledge_temp."auth_target_type" = static_temp."auth_target_type"
WHERE app_and_knowledge_temp.id is NULL;

View File

@ -1,38 +1,44 @@
SELECT SELECT resource_or_folder.*,
app_or_knowledge.*, CASE
CASE WHEN wurp.permission IS NULL THEN 'NOT_AUTH'
WHEN ELSE wurp.permission
wurp."permission" is null then 'NOT_AUTH' END
ELSE wurp."permission"
END
FROM ( FROM (
SELECT SELECT id::text,
"id", "name",
"name", 'APPLICATION' AS "auth_target_type",
'APPLICATION' AS "auth_target_type", 'application' AS "resource_type",
user_id, user_id,
workspace_id, workspace_id,
icon, icon,
folder_id folder_id
FROM FROM application
application ${query_set}
${query_set} UNION
) app_or_knowledge SELECT application_folder."id"::text,
application_folder."name",
'APPLICATION' AS "auth_target_type",
'folder' AS "resource_type",
application_folder."user_id",
application_folder."workspace_id",
NULL AS "icon",
application_folder."parent_id" AS "folder_id"
FROM application_folder
${folder_query_set}
) resource_or_folder
LEFT JOIN ( LEFT JOIN (
SELECT SELECT target,
target, CASE
CASE WHEN auth_type = 'ROLE'
WHEN auth_type = 'ROLE' AND 'ROLE' = ANY (permission_list) THEN 'ROLE'
AND 'ROLE' = ANY(permission_list) THEN 'ROLE' WHEN auth_type = 'RESOURCE_PERMISSION_GROUP'
WHEN auth_type = 'RESOURCE_PERMISSION_GROUP' AND 'MANAGE' = ANY (permission_list) THEN 'MANAGE'
AND 'MANAGE' = ANY(permission_list) THEN 'MANAGE' WHEN auth_type = 'RESOURCE_PERMISSION_GROUP'
WHEN auth_type = 'RESOURCE_PERMISSION_GROUP' AND 'VIEW' = ANY (permission_list) THEN 'VIEW'
AND 'VIEW' = ANY(permission_list) THEN 'VIEW' ELSE NULL
ELSE null END AS permission
END AS permission FROM workspace_user_resource_permission
FROM ${workspace_user_resource_permission_query_set}
workspace_user_resource_permission
${workspace_user_resource_permission_query_set}
) wurp ) wurp
ON wurp.target = app_or_knowledge."id" ON wurp.target::text = resource_or_folder.id
${resource_query_set} ${resource_query_set}

View File

@ -1,23 +1,32 @@
SELECT SELECT resource_or_folder.*,
app_or_knowledge.*,
CASE CASE
WHEN WHEN wurp.permission IS NULL THEN 'NOT_AUTH'
wurp."permission" is null then 'NOT_AUTH' ELSE wurp.permission
ELSE wurp."permission" END
END
FROM ( FROM (
SELECT SELECT
"id", id::text,
"name", "name",
'KNOWLEDGE' AS "auth_target_type", 'KNOWLEDGE' AS "auth_target_type",
user_id, 'knowledge' AS "resource_type",
workspace_id, user_id,
"type"::varchar AS "icon", workspace_id,
folder_id "type"::varchar AS "icon",
FROM folder_id
knowledge FROM knowledge
${query_set} ${query_set}
) app_or_knowledge UNION
SELECT knowledge_folder."id"::text,
knowledge_folder."name",
'KNOWLEDGE' AS "auth_target_type",
'folder' AS "resource_type",
knowledge_folder."user_id",
knowledge_folder."workspace_id",
NULL AS "icon",
knowledge_folder."parent_id" AS "folder_id"
FROM knowledge_folder
${folder_query_set}
) resource_or_folder
LEFT JOIN ( LEFT JOIN (
SELECT SELECT
target, target,
@ -34,5 +43,5 @@ LEFT JOIN (
workspace_user_resource_permission workspace_user_resource_permission
${workspace_user_resource_permission_query_set} ${workspace_user_resource_permission_query_set}
) wurp ) wurp
ON wurp.target = app_or_knowledge."id" ON wurp.target::text = resource_or_folder.id
${resource_query_set} ${resource_query_set}

View File

@ -1,5 +1,5 @@
SELECT SELECT
app_or_knowledge.*, resource_or_folder.*,
CASE CASE
WHEN WHEN
wurp."permission" is null then 'NOT_AUTH' wurp."permission" is null then 'NOT_AUTH'
@ -7,9 +7,10 @@ SELECT
END END
FROM ( FROM (
SELECT SELECT
"id", "id"::text,
"name", "name",
'MODEL' AS "auth_target_type", 'MODEL' AS "auth_target_type",
'model' AS "resource_type",
user_id, user_id,
workspace_id, workspace_id,
provider as icon, provider as icon,
@ -17,7 +18,20 @@ FROM (
FROM FROM
model model
${query_set} ${query_set}
) app_or_knowledge UNION
SELECT
"id"::text,
"name",
'MODEL' AS "auth_target_type",
'folder' AS "resource_type",
user_id,
workspace_id,
provider as icon,
'default' as folder_id
FROM model
${folder_query_set}
AND 1=0
) resource_or_folder
LEFT JOIN ( LEFT JOIN (
SELECT SELECT
target, target,
@ -34,5 +48,5 @@ LEFT JOIN (
workspace_user_resource_permission workspace_user_resource_permission
${workspace_user_resource_permission_query_set} ${workspace_user_resource_permission_query_set}
) wurp ) wurp
ON wurp.target = app_or_knowledge."id" ON wurp.target = resource_or_folder."id"
${resource_query_set} ${resource_query_set}

View File

@ -1,40 +1,48 @@
SELECT SELECT resource_or_folder.*,
app_or_knowledge.*,
CASE CASE
WHEN WHEN wurp."permission" IS NULL THEN 'NOT_AUTH'
wurp."permission" is null then 'NOT_AUTH'
ELSE wurp."permission" ELSE wurp."permission"
END END
FROM ( FROM (
SELECT SELECT "id"::text,
"id", "name",
"name", 'TOOL' AS "auth_target_type",
'TOOL' AS "auth_target_type", 'tool' AS "resource_type",
user_id, user_id,
workspace_id, workspace_id,
icon, icon,
folder_id, folder_id,
tool_type tool_type
FROM FROM tool
tool
${query_set} ${query_set}
) app_or_knowledge UNION
SELECT tool_folder."id"::text,
tool_folder."name",
'TOOL' AS "auth_target_type",
'folder' AS "resource_type",
tool_folder."user_id",
tool_folder."workspace_id",
NULL AS "icon",
tool_folder."parent_id" AS "folder_id",
NULL AS "tool_type"
FROM tool_folder
${folder_query_set}
) resource_or_folder
LEFT JOIN ( LEFT JOIN (
SELECT SELECT target,
target, CASE
CASE WHEN auth_type = 'ROLE'
WHEN auth_type = 'ROLE' AND 'ROLE' = ANY(permission_list) THEN 'ROLE'
AND 'ROLE' = ANY(permission_list) THEN 'ROLE' WHEN auth_type = 'RESOURCE_PERMISSION_GROUP'
WHEN auth_type = 'RESOURCE_PERMISSION_GROUP' AND 'MANAGE' = ANY(permission_list) THEN 'MANAGE'
AND 'MANAGE' = ANY(permission_list) THEN 'MANAGE' WHEN auth_type = 'RESOURCE_PERMISSION_GROUP'
WHEN auth_type = 'RESOURCE_PERMISSION_GROUP' AND 'VIEW' = ANY(permission_list) THEN 'VIEW'
AND 'VIEW' = ANY(permission_list) THEN 'VIEW' ELSE null
ELSE null END AS permission
END AS permission
FROM FROM
workspace_user_resource_permission workspace_user_resource_permission
${workspace_user_resource_permission_query_set} ${workspace_user_resource_permission_query_set}
) wurp ) wurp
ON wurp.target = app_or_knowledge."id" ON wurp.target::text = resource_or_folder."id"
${resource_query_set} ${resource_query_set}

View File

@ -942,7 +942,6 @@ class ToolTreeSerializer(serializers.Serializer):
tool_query_set = tool_query_set.filter(tool_type=tool_type) tool_query_set = tool_query_set.filter(tool_type=tool_type)
query_set_dict = { query_set_dict = {
'folder_query_set': folder_query_set,
'tool_query_set': tool_query_set, 'tool_query_set': tool_query_set,
'default_query_set': default_query_set, 'default_query_set': default_query_set,
} }

View File

@ -20,26 +20,5 @@ from (select tool."id"::text,
tool."is_active" tool."is_active"
from tool from tool
left join "user" on "user".id = user_id ${tool_query_set} left join "user" on "user".id = user_id ${tool_query_set}
UNION ) temp
select tool_folder."id",
tool_folder."name",
tool_folder."desc",
'folder' as "tool_type",
'' as scope,
'folder' as "resource_type",
tool_folder."workspace_id",
tool_folder."parent_id" as "folder_id",
tool_folder."user_id",
"user".nick_name as "nick_name",
'' as "icon",
'' as label,
'' as "template_id",
tool_folder."create_time",
tool_folder."update_time",
'[]'::jsonb as init_field_list,
'[]'::jsonb as input_field_list,
'' as version,
'true' as "is_active"
from tool_folder
left join "user" on "user".id = user_id ${folder_query_set}) temp
${default_query_set} ${default_query_set}

View File

@ -25,27 +25,5 @@ FROM (SELECT tool."id"::text,
${workspace_user_resource_permission_query_set} ${workspace_user_resource_permission_query_set}
AND 'VIEW' = ANY (permission_list))) AS tool AND 'VIEW' = ANY (permission_list))) AS tool
LEFT JOIN "user" ON "user".id = user_id LEFT JOIN "user" ON "user".id = user_id
) temp
UNION
SELECT tool_folder."id",
tool_folder."name",
tool_folder."desc",
'folder' AS "tool_type",
'' AS scope,
'folder' AS "resource_type",
tool_folder."workspace_id",
tool_folder."parent_id" AS "folder_id",
tool_folder."user_id",
"user".nick_name AS "nick_name",
'' AS "icon",
'' AS label,
'' AS "template_id",
tool_folder."create_time",
tool_folder."update_time",
'[]'::jsonb AS init_field_list,
'[]'::jsonb AS input_field_list,
'' AS version,
'true' AS "is_active"
FROM tool_folder
LEFT JOIN "user" ON "user".id = user_id ${folder_query_set}) temp
${default_query_set} ${default_query_set}

View File

@ -20,7 +20,7 @@ FROM (SELECT tool."id"::text,
tool."is_active" tool."is_active"
FROM (SELECT tool.* FROM (SELECT tool.*
FROM tool tool ${tool_query_set} FROM tool tool ${tool_query_set}
AND tool.id IN (SELECT target AND tool.id::text IN (SELECT target
FROM workspace_user_resource_permission ${workspace_user_resource_permission_query_set} FROM workspace_user_resource_permission ${workspace_user_resource_permission_query_set}
AND CASE AND CASE
WHEN auth_type = 'ROLE' THEN WHEN auth_type = 'ROLE' THEN
@ -36,26 +36,5 @@ FROM (SELECT tool."id"::text,
END END
)) AS tool )) AS tool
LEFT JOIN "user" ON "user".id = user_id LEFT JOIN "user" ON "user".id = user_id
UNION ) temp
SELECT tool_folder."id",
tool_folder."name",
tool_folder."desc",
'folder' AS "tool_type",
'' AS scope,
'folder' AS "resource_type",
tool_folder."workspace_id",
tool_folder."parent_id" AS "folder_id",
tool_folder."user_id",
"user".nick_name AS "nick_name",
'' AS "icon",
'' AS label,
'' AS "template_id",
tool_folder."create_time",
tool_folder."update_time",
'[]'::jsonb AS init_field_list,
'[]'::jsonb AS input_field_list,
'' AS version,
'true' AS "is_active"
FROM tool_folder
LEFT JOIN "user" ON "user".id = user_id ${folder_query_set}) temp
${default_query_set} ${default_query_set}