| 303 | |
| 304 | |
| 305 | class FolderTreeSerializer(serializers.Serializer): |
| 306 | workspace_id = serializers.CharField(required=True, allow_null=True, allow_blank=True, label=_('workspace id')) |
| 307 | source = serializers.CharField(required=True, label=_('source')) |
| 308 | |
| 309 | @staticmethod |
| 310 | def _check_tree_integrity(queryset): |
| 311 | """检查树结构完整性""" |
| 312 | for folder in queryset: |
| 313 | if folder.lft >= folder.rght: |
| 314 | return True # 需要重建 |
| 315 | if folder.is_leaf_node() and folder.get_children().exists(): |
| 316 | return True # 需要重建 |
| 317 | return False |
| 318 | |
| 319 | @staticmethod |
| 320 | def _having_read_permission_by_role(user_id: str, workspace_id: str, source: str): |
| 321 | workspace_user_role_mapping_model = DatabaseModelManage.get_model("workspace_user_role_mapping") |
| 322 | role_permission_mapping_model = DatabaseModelManage.get_model("role_permission_mapping_model") |
| 323 | is_x_pack_ee = workspace_user_role_mapping_model is not None and role_permission_mapping_model is not None |
| 324 | if is_x_pack_ee: |
| 325 | return QuerySet(workspace_user_role_mapping_model).select_related('role', 'user').filter( |
| 326 | Q(role__rolepermission__permission_id=f"{source}_FOLDER:READ") | Q(role__internal=True), |
| 327 | workspace_id=workspace_id, |
| 328 | user_id=user_id, |
| 329 | role__type=RoleConstants.USER.value.__str__(), |
| 330 | ).exists() |
| 331 | |
| 332 | return False |
| 333 | |
| 334 | def get_folder_tree(self, |
| 335 | current_user, name=None): |
| 336 | self.is_valid(raise_exception=True) |
| 337 | user_id = current_user.id |
| 338 | workspace_id = self.data.get('workspace_id') |
| 339 | source = self.data.get('source') |
| 340 | |
| 341 | Folder = get_folder_type(source) # noqa |
| 342 | |
| 343 | # 检查特定工作空间的树结构完整性 |
| 344 | workspace_folders = Folder.objects.filter(workspace_id=workspace_id) |
| 345 | # 如果发现数据不一致,重建整个表(这是 MPTT 的限制) |
| 346 | if self._check_tree_integrity(workspace_folders): |
| 347 | Folder.objects.rebuild() |
| 348 | |
| 349 | workspace_manage = is_workspace_manage(user_id, workspace_id) |
| 350 | |
| 351 | base_q = Q(workspace_id=workspace_id) |
| 352 | |
| 353 | if name is not None: |
| 354 | base_q &= Q(name__contains=name) |
| 355 | if not workspace_manage: |
| 356 | having_read_permission_by_role = has_exact_permission_by_role(user_id, workspace_id, |
| 357 | f"{source}_FOLDER:READ", |
| 358 | RoleConstants.USER.value.__str__()) |
| 359 | permission_condition = ['VIEW'] |
| 360 | if having_read_permission_by_role: |
| 361 | permission_condition = ['VIEW', 'ROLE'] |
| 362 | |