From b97dfaa95d6e167746ecddcd83afa1a365352cd8 Mon Sep 17 00:00:00 2001 From: duxingchen Date: Tue, 11 Aug 2026 17:39:30 +0800 Subject: [PATCH] =?UTF-8?q?fix(backend):=20=E5=AE=8F=E8=A7=82=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E6=9D=83=E9=99=90=E6=A0=A1=E9=AA=8C=20=E2=80=94=20?= =?UTF-8?q?=E6=A0=B9=E9=99=A4=20current=5Fuser=20=E7=A9=BA=E5=80=BC?= =?UTF-8?q?=E7=BB=95=E8=BF=87=E6=BC=8F=E6=B4=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: if current_user: 在 Python 中 None/空dict均为falsy, 一旦 current_user 为空则整个权限块被跳过直接放行。 修复: 1. if not current_user → 直接 raise 401 2. 反转 SUPER_ADMIN 判断: if user_role != 'SUPER_ADMIN' 进入校验 (避免 if/else/pass 空分支带来的逻辑歧义) 3. main_task is not None 显式判断 (替代隐式 truthy) --- backend/app/services/product_service.py | 61 +++++++++++++------------ 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/backend/app/services/product_service.py b/backend/app/services/product_service.py index fec49c7..a30275b 100644 --- a/backend/app/services/product_service.py +++ b/backend/app/services/product_service.py @@ -301,37 +301,40 @@ async def update_overall_status( if not product: raise HTTPException(status_code=404, detail=f"未找到序列号 {serial_number} 的产品") - # ── 权限校验 ── - if current_user: - user_role = current_user.get("role", "") - user_username = current_user.get("username", "") + # ── 权限校验(无 current_user 一律拒绝,杜绝空 dict 绕过)── + if not current_user: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="请先登录", + ) - # SUPER_ADMIN 直接放行 - if user_role == "SUPER_ADMIN": - pass - else: - # 检查当前用户是否是该产品主线任务的负责人 - from sqlalchemy import or_ - main_task_result = await db.execute( - select(Task).where( - Task.product_id == product.id, - Task.status.in_(["WIP", "PENDING"]), - or_( - Task.parent_task_id.is_(None), - Task.task_type.in_(["TRANSFER", "RECOVERY"]), - ), - ).order_by(Task.created_at.desc()).limit(1) + user_role = current_user.get("role", "") + user_username = current_user.get("username", "") + + # SUPER_ADMIN 直接放行 + if user_role != "SUPER_ADMIN": + # 检查当前用户是否是该产品主线任务的负责人 + from sqlalchemy import or_ + main_task_result = await db.execute( + select(Task).where( + Task.product_id == product.id, + Task.status.in_(["WIP", "PENDING"]), + or_( + Task.parent_task_id.is_(None), + Task.task_type.in_(["TRANSFER", "RECOVERY"]), + ), + ).order_by(Task.created_at.desc()).limit(1) + ) + main_task = main_task_result.scalar_one_or_none() + has_permission = ( + main_task is not None + and main_task.assignee_id == user_username + ) + if not has_permission: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="只有 SUPER_ADMIN 或当前操作该产品主线任务的人才能修改宏观状态", ) - main_task = main_task_result.scalar_one_or_none() - has_permission = ( - main_task - and main_task.assignee_id == user_username - ) - if not has_permission: - raise HTTPException( - status_code=status.HTTP_403_FORBIDDEN, - detail="只有 SUPER_ADMIN 或当前操作该产品主线任务的人才能修改宏观状态", - ) product.overall_status = status_value await db.commit()