From 855220fae5917301b17bc3f9bc65c4d9690fa4b3 Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Sat, 4 Jul 2026 08:32:15 +0800 Subject: [PATCH] =?UTF-8?q?fix(api):=20=E9=A1=B9=E7=9B=AE=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E6=8E=A5=E5=8F=A3=E5=A2=9E=E5=8A=A0=E6=9D=83=E9=99=90?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=20+=20=E6=96=B0=E5=A2=9E=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. GET /projects/{id} 增加权限校验:非项目所有者且未被共享时返回403 (此前任何登录用户都可查看任意项目,存在越权访问漏洞) 2. 新增 DELETE /projects/{id} 接口:仅项目所有者可删除,返回403/404 - 新增 DeleteProjectUseCase(application层) - 仓储层 delete 方法已存在,直接复用 - 与素材库等模块的权限校验模式保持一致 --- apps/api/app/api/routes/projects.py | 22 ++++++++++++++++++++++ packages/application/projects.py | 13 +++++++++++++ 2 files changed, 35 insertions(+) mode change 100644 => 100755 apps/api/app/api/routes/projects.py mode change 100644 => 100755 packages/application/projects.py diff --git a/apps/api/app/api/routes/projects.py b/apps/api/app/api/routes/projects.py old mode 100644 new mode 100755 index 7e8e502b0..3cfa6f359 --- a/apps/api/app/api/routes/projects.py +++ b/apps/api/app/api/routes/projects.py @@ -12,6 +12,7 @@ from fastapi import APIRouter, Depends, HTTPException, status from packages.application import ( CreateProjectCommand, CreateProjectUseCase, + DeleteProjectUseCase, GetProjectUseCase, ListProjectsUseCase, ) @@ -39,6 +40,8 @@ def get_project( project = use_case.execute(project_id) if project is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Project not found") + if not project.can_access(authenticated_user.user.id): + raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Access denied to project") return _to_project_response(project) @@ -67,3 +70,22 @@ def create_project( owner_user_id=authenticated_user.user.id, ) return _to_project_response(project) + + +@router.delete("/{project_id}") +def delete_project( + project_id: str, + authenticated_user: AuthenticatedUser = Depends(get_current_user), + project_repository: Any = Depends(get_project_repository), +): + use_case = DeleteProjectUseCase(project_repository) + try: + deleted = use_case.execute(project_id, authenticated_user.user.id) + except PermissionError: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="Only the project owner can delete this project", + ) + if not deleted: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Project not found") + return {"message": "Project deleted successfully"} \ No newline at end of file diff --git a/packages/application/projects.py b/packages/application/projects.py old mode 100644 new mode 100755 index 842c97eb7..84235c26c --- a/packages/application/projects.py +++ b/packages/application/projects.py @@ -61,6 +61,19 @@ class ShareProjectUseCase: return project +class DeleteProjectUseCase: + def __init__(self, project_repository: ProjectRepository): + self.project_repository = project_repository + + def execute(self, project_id: str, user_id: str) -> bool: + project = self.project_repository.find_by_id(project_id) + if not project: + return False + if not project.is_owner(user_id): + raise PermissionError("只有项目所有者可以删除项目") + return self.project_repository.delete(project_id) + + class UnshareProjectUseCase: def __init__(self, project_repository: ProjectRepository): self.project_repository = project_repository