fix: Folder auth permission

This commit is contained in:
zhangzhanwei 2025-12-25 11:09:02 +08:00
parent 4ffdb46b0a
commit 526290b722
3 changed files with 44 additions and 20 deletions

View File

@ -558,7 +558,7 @@ class PermissionConstants(Enum):
)
TOOL_FOLDER_READ = Permission(
group=Group.TOOL_FOLDER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
parent_group=[WorkspaceGroup.TOOL, UserGroup.TOOL],
parent_group=[UserGroup.TOOL],
resource_permission_group_list=[ResourcePermissionConst.TOOL_VIEW]
)
TOOL_FOLDER_CREATE = Permission(
@ -629,7 +629,7 @@ class PermissionConstants(Enum):
KNOWLEDGE_FOLDER_READ = Permission(
group=Group.KNOWLEDGE_FOLDER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_VIEW],
parent_group = [WorkspaceGroup.KNOWLEDGE, UserGroup.KNOWLEDGE]
parent_group = [UserGroup.KNOWLEDGE]
)
KNOWLEDGE_FOLDER_CREATE = Permission(
group=Group.KNOWLEDGE_FOLDER, operate=Operate.CREATE, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
@ -961,7 +961,7 @@ class PermissionConstants(Enum):
)
APPLICATION_FOLDER_READ = Permission(group=Group.APPLICATION_FOLDER, operate=Operate.READ,
role_list=[RoleConstants.ADMIN, RoleConstants.USER],
parent_group=[WorkspaceGroup.APPLICATION, UserGroup.APPLICATION],
parent_group=[UserGroup.APPLICATION],
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_VIEW]
)
APPLICATION_FOLDER_CREATE = Permission(group=Group.APPLICATION_FOLDER, operate=Operate.CREATE,

View File

@ -10,7 +10,8 @@ from rest_framework import serializers
from application.models.application import Application, ApplicationFolder
from application.serializers.application import ApplicationOperateSerializer
from application.serializers.application_folder import ApplicationFolderTreeSerializer
from common.constants.permission_constants import Group, ResourcePermission, ResourcePermissionRole
from common.constants.permission_constants import Group, ResourcePermission, ResourcePermissionRole, RoleConstants
from common.database_model_manage.database_model_manage import DatabaseModelManage
from common.exception.app_exception import AppApiException
from folders.api.folder import FolderCreateRequest
from knowledge.models import KnowledgeFolder, Knowledge
@ -300,30 +301,52 @@ class FolderTreeSerializer(serializers.Serializer):
return True # 需要重建
return False
@staticmethod
def _having_read_permission_by_role(user_id: str, workspace_id: str, source: str):
workspace_user_role_mapping_model = DatabaseModelManage.get_model("workspace_user_role_mapping")
role_permission_mapping_model = DatabaseModelManage.get_model("role_permission_mapping_model")
is_x_pack_ee = workspace_user_role_mapping_model is not None and role_permission_mapping_model is not None
if is_x_pack_ee:
return QuerySet(workspace_user_role_mapping_model).select_related('role', 'user').filter(
workspace_id=workspace_id, user_id=user_id,
role__type=RoleConstants.USER.value.__str__(),
role__rolepermission__permission_id=f"{source}_FOLDER:READ"
).exists()
return False
def get_folder_tree(self,
current_user, name=None):
self.is_valid(raise_exception=True)
Folder = get_folder_type(self.data.get('source')) # noqa
user_id = current_user.id
workspace_id = self.data.get('workspace_id')
source = self.data.get('source')
Folder = get_folder_type(source) # noqa
# 检查特定工作空间的树结构完整性
workspace_folders = Folder.objects.filter(workspace_id=self.data.get('workspace_id'))
workspace_folders = Folder.objects.filter(workspace_id=workspace_id)
# 如果发现数据不一致,重建整个表(这是 MPTT 的限制)
if self._check_tree_integrity(workspace_folders):
Folder.objects.rebuild()
workspace_manage = is_workspace_manage(current_user.id, self.data.get('workspace_id'))
workspace_manage = is_workspace_manage(user_id, workspace_id)
base_q = Q(workspace_id=self.data.get('workspace_id'))
base_q = Q(workspace_id=workspace_id)
if name is not None:
base_q &= Q(name__contains=name)
if not workspace_manage:
having_read_permission_by_role = self._having_read_permission_by_role(user_id, workspace_id, source)
permission_condition = ['VIEW']
if having_read_permission_by_role:
permission_condition = ['VIEW', 'ROLE']
base_q &= (Q(id__in=WorkspaceUserResourcePermission.objects.filter(user_id=current_user.id,
auth_target_type=self.data.get('source'),
workspace_id=self.data.get(
'workspace_id'),
permission_list__contains=['VIEW'])
permission_list__overlap=permission_condition)
.values_list(
'target', flat=True)) | Q(id=self.data.get('workspace_id')))
@ -332,4 +355,5 @@ class FolderTreeSerializer(serializers.Serializer):
TreeSerializer = get_folder_tree_serializer(self.data.get('source')) # noqa
serializer = TreeSerializer(nodes, many=True)
return [d for d in serializer.data if d.get('id') == d.get('workspace_id')] if name is None else serializer.data # 这是可序列化的字典
return [d for d in serializer.data if
d.get('id') == d.get('workspace_id')] if name is None else serializer.data # 这是可序列化的字典

View File

@ -120,16 +120,16 @@ class WorkspaceResourceUserPermissionView(APIView):
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}:ROLE/WORKSPACE_MANAGE"),
lambda r, kwargs: Permission(group=Group(kwargs.get('resource')),
operate=Operate.AUTH,
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('resource')}/{kwargs.get('target')}"),
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('resource').replace('_FOLDER','')}/{kwargs.get('target')}"),
ViewPermission([RoleConstants.USER.get_workspace_role()],
[lambda r, kwargs: Permission(group=Group(kwargs.get('resource')),
operate=Operate.SELF,
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('resource')}/{kwargs.get('target')}")],
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('resource').replace('_FOLDER','')}/{kwargs.get('target')}")],
CompareConstants.AND),
RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
def get(self, request: Request, workspace_id: str, target: str, resource: str):
return result.success(ResourceUserPermissionSerializer(
data={'workspace_id': workspace_id, "target": target, 'auth_target_type': resource,
data={'workspace_id': workspace_id, "target": target, 'auth_target_type': resource.replace('_FOLDER',''),
}).list(
{'username': request.query_params.get("username"), 'nick_name': request.query_params.get("nick_name"),
'permission': request.query_params.getlist("permission[]")
@ -154,16 +154,16 @@ class WorkspaceResourceUserPermissionView(APIView):
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}:ROLE/WORKSPACE_MANAGE"),
lambda r, kwargs: Permission(group=Group(kwargs.get('resource')),
operate=Operate.AUTH,
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('resource')}/{kwargs.get('target')}"),
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('resource').replace('_FOLDER','')}/{kwargs.get('target')}"),
ViewPermission([RoleConstants.USER.get_workspace_role()],
[lambda r, kwargs: Permission(group=Group(kwargs.get('resource')),
operate=Operate.SELF,
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('resource')}/{kwargs.get('target')}")],
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('resource').replace('_FOLDER','')}/{kwargs.get('target')}")],
CompareConstants.AND),
RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
def put(self, request: Request, workspace_id: str, target: str, resource: str):
return result.success(ResourceUserPermissionSerializer(
data={'workspace_id': workspace_id, "target": target, 'auth_target_type': resource, })
data={'workspace_id': workspace_id, "target": target, 'auth_target_type': resource.replace('_FOLDER',''), })
.edit(instance=request.data, current_user_id=request.user.id))
class Page(APIView):
@ -184,17 +184,17 @@ class WorkspaceResourceUserPermissionView(APIView):
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}:ROLE/WORKSPACE_MANAGE"),
lambda r, kwargs: Permission(group=Group(kwargs.get('resource')),
operate=Operate.AUTH,
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('resource')}/{kwargs.get('target')}"),
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('resource').replace('_FOLDER','')}/{kwargs.get('target')}"),
ViewPermission([RoleConstants.USER.get_workspace_role()],
[lambda r, kwargs: Permission(group=Group(kwargs.get('resource')),
operate=Operate.SELF,
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('resource')}/{kwargs.get('target')}")],
resource_path=f"/WORKSPACE/{kwargs.get('workspace_id')}/{kwargs.get('resource').replace('_FOLDER','')}/{kwargs.get('target')}")],
CompareConstants.AND),
RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
def get(self, request: Request, workspace_id: str, target: str, resource: str, current_page: int,
page_size: int):
return result.success(ResourceUserPermissionSerializer(
data={'workspace_id': workspace_id, "target": target, 'auth_target_type': resource, }
data={'workspace_id': workspace_id, "target": target, 'auth_target_type': resource.replace('_FOLDER',''), }
).page({'username': request.query_params.get("username"),
'role': request.query_params.get("role"),
'nick_name': request.query_params.get("nick_name"),