From 539282f18ff467ffdac98b5ecbe69ec62d37b5df Mon Sep 17 00:00:00 2001 From: Pine Date: Tue, 8 Sep 2026 00:08:27 +0800 Subject: [PATCH] =?UTF-8?q?security:=20=E5=B9=B3=E5=8F=B0=E4=B8=AD?= =?UTF-8?q?=E7=BB=A7=E4=BB=A4=E7=89=8C=E4=B8=8D=E5=AF=B9=E5=A4=96=E5=B1=95?= =?UTF-8?q?=E7=A4=BA=E3=80=81=E4=B8=8D=E5=85=81=E8=AE=B8=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 平台中继令牌由系统自动创建(name='平台中继令牌'),桌面端智能体 调用模型时使用此令牌。为防止用户复制外泄配额或误删导致桌面端 无法调用模型: 1. GET /opc/compute/tokens:过滤掉 name='平台中继令牌' 的令牌, 不返回给前端展示 2. DELETE /opc/compute/tokens/{id}:删除前校验,若目标令牌是 平台中继令牌,返回 403 拒绝删除 3. 定义常量 PLATFORM_RELAY_TOKEN_NAME 统一管理 --- app/api/routers/rbac_opc.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/app/api/routers/rbac_opc.py b/app/api/routers/rbac_opc.py index d8fc49e..fa005d5 100644 --- a/app/api/routers/rbac_opc.py +++ b/app/api/routers/rbac_opc.py @@ -18,6 +18,9 @@ from ... import config from ...services import compute_client, compute_catalog router = APIRouter(prefix="/opc", tags=["opc"]) +PLATFORM_RELAY_TOKEN_NAME = "平台中继令牌" +# 平台中继令牌:系统自动创建,桌面端智能体调用模型时使用,不对外展示、不允许删除 + @router.get("/dashboard", summary="OPC 工作台总览") @@ -530,6 +533,9 @@ async def opc_compute_tokens(user: dict = Depends(require_roles("opc_member"))): out = [] for it in items or []: it = dict(it) + # 平台中继令牌由系统自动创建,桌面端智能体调用模型时使用,不对外展示、不允许删除 + if str(it.get("name") or "") == PLATFORM_RELAY_TOKEN_NAME: + continue key = str(it.get("key") or it.get("token") or "") if key and not key.startswith("sk-"): it["key"] = f"sk-{key}" @@ -563,6 +569,17 @@ async def opc_compute_tokens_create( @router.delete("/compute/tokens/{token_id}", summary="删除算力令牌") async def opc_compute_tokens_delete(token_id: int, user: dict = Depends(require_roles("opc_member"))): + # 平台中继令牌不允许删除(桌面端智能体依赖此令牌调用模型) + try: + existing = await compute_client.list_user_tokens(user.get("username")) + except compute_client.ComputeError as exc: + raise HTTPException(status_code=502, detail=f"算力引擎对接失败: {exc}") from exc + existing_items = existing if isinstance(existing, list) else existing.get("items", []) + for it in existing_items or []: + if int(dict(it).get("id") or 0) == token_id: + if str(dict(it).get("name") or "") == PLATFORM_RELAY_TOKEN_NAME: + raise HTTPException(status_code=403, detail="平台中继令牌由系统管理,不允许删除") + break try: await compute_client.delete_token(token_id) except compute_client.ComputeError as exc: