From 4a8fffaf7d16ff3acaae4832bbf295175357980c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E6=BD=AE?= Date: Wed, 11 Feb 2026 22:43:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4id?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- create_tables.sql | 2 -- routes/bot_manager.py | 72 ++++++++++++++++++++++++++++-------------- utils/fastapi_utils.py | 4 +-- 3 files changed, 50 insertions(+), 28 deletions(-) diff --git a/create_tables.sql b/create_tables.sql index cfc82c3..6c38a87 100644 --- a/create_tables.sql +++ b/create_tables.sql @@ -20,7 +20,6 @@ CREATE INDEX IF NOT EXISTS idx_agent_user_is_active ON agent_user(is_active); CREATE TABLE IF NOT EXISTS agent_bots ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(255) NOT NULL, - bot_id VARCHAR(255) NOT NULL UNIQUE, settings JSONB DEFAULT '{"language": "zh", "enable_memori": false, "enable_thinking": false, "tool_response": false}'::jsonb, owner_id UUID NOT NULL REFERENCES agent_user(id) ON DELETE RESTRICT, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), @@ -28,7 +27,6 @@ CREATE TABLE IF NOT EXISTS agent_bots ( ); -- agent_bots 索引 -CREATE INDEX IF NOT EXISTS idx_agent_bots_bot_id ON agent_bots(bot_id); CREATE INDEX IF NOT EXISTS idx_agent_bots_owner_id ON agent_bots(owner_id); -- 3. 创建 agent_user_tokens 表 diff --git a/routes/bot_manager.py b/routes/bot_manager.py index 05e0ff6..57dc9de 100644 --- a/routes/bot_manager.py +++ b/routes/bot_manager.py @@ -27,7 +27,7 @@ TOKEN_EXPIRE_HOURS = 24 # ============== 认证函数 ============== -async def verify_admin_auth(authorization: Optional[str]) -> tuple[bool, Optional[str]]: +async def verify_admin_auth(authorization: Optional[str]) -> tuple[bool, Optional[str], Optional[str]]: """ 验证管理员认证 @@ -35,17 +35,17 @@ async def verify_admin_auth(authorization: Optional[str]) -> tuple[bool, Optiona authorization: Authorization header 值 Returns: - tuple[bool, Optional[str]]: (是否有效, 用户名) + tuple[bool, Optional[str], Optional[str]]: (是否有效, 用户名, 用户ID) """ provided_token = extract_api_key_from_auth(authorization) if not provided_token: - return False, None + return False, None, None pool = get_db_pool_manager().pool async with pool.connection() as conn: async with conn.cursor() as cursor: - # 检查 token 是否有效且未过期 + # 先检查 admin token 表 await cursor.execute(""" SELECT username, expires_at FROM agent_admin_tokens @@ -54,10 +54,32 @@ async def verify_admin_auth(authorization: Optional[str]) -> tuple[bool, Optiona """, (provided_token,)) row = await cursor.fetchone() - if not row: - return False, None + if row: + # admin token 有效,返回 admin 用户信息 + username = row[0] + # 获取 admin 用户在 agent_user 表中的 ID + await cursor.execute(""" + SELECT id FROM agent_user WHERE username = %s + """, (username,)) + user_row = await cursor.fetchone() + user_id = str(user_row[0]) if user_row else None + return True, username, user_id - return True, row[0] + # 如果 admin token 无效,再检查普通用户 token + await cursor.execute(""" + SELECT u.id, u.username, u.is_admin, t.expires_at + FROM agent_user_tokens t + JOIN agent_user u ON t.user_id = u.id + WHERE t.token = %s + AND t.expires_at > NOW() + AND u.is_active = TRUE + """, (provided_token,)) + user_row = await cursor.fetchone() + + if user_row: + return True, user_row[1], str(user_row[0]) + + return False, None, None def verify_auth(authorization: Optional[str]) -> None: @@ -154,7 +176,7 @@ async def is_admin_user(authorization: Optional[str]) -> bool: Returns: bool: 是否是管理员 """ - admin_valid, _ = await verify_admin_auth(authorization) + admin_valid, _, admin_user_id = await verify_admin_auth(authorization) if admin_valid: return True @@ -232,7 +254,7 @@ async def is_bot_owner(bot_id: str, user_id: str) -> bool: 检查用户是否是 Bot 的所有者 Args: - bot_id: Bot UUID + bot_id: Bot UUID (可能是 bot_id 字段) user_id: 用户 UUID Returns: @@ -1219,7 +1241,7 @@ async def get_bots(authorization: Optional[str] = Header(None)): List[BotResponse]: Bot 列表 """ # 支持管理员认证和用户认证 - admin_valid, admin_username = await verify_admin_auth(authorization) + admin_valid, admin_username, admin_user_id = await verify_admin_auth(authorization) user_valid, user_id, user_username = await verify_user_auth(authorization) if not admin_valid and not user_valid: @@ -1245,9 +1267,9 @@ async def get_bots(authorization: Optional[str] = Header(None)): return [ BotResponse( - id=str(row[0]), + id=str(row[0]), # 使用 UUID 主键 name=row[1], - bot_id=row[2], + bot_id=str(row[0]), # bot_id 也指向主键 id is_owner=True, is_shared=False, owner={"id": str(row[6]), "username": row[7]} if row[6] else None, @@ -1276,9 +1298,9 @@ async def get_bots(authorization: Optional[str] = Header(None)): return [ BotResponse( - id=str(row[0]), + id=str(row[0]), # 使用 UUID 主键 name=row[1], - bot_id=row[2], + bot_id=str(row[0]), # bot_id 也指向主键 id is_owner=(str(row[6]) == user_id if row[6] else False), is_shared=(str(row[6]) != user_id and row[8] is not None) if row[6] else False, owner={"id": str(row[6]), "username": row[7]} if row[6] else None, @@ -1307,7 +1329,7 @@ async def create_bot(request: BotCreate, authorization: Optional[str] = Header(N BotResponse: 创建的 Bot 信息 """ # 支持管理员认证和用户认证 - admin_valid, admin_username = await verify_admin_auth(authorization) + admin_valid, admin_username, admin_user_id = await verify_admin_auth(authorization) user_valid, user_id, user_username = await verify_user_auth(authorization) if not admin_valid and not user_valid: @@ -1369,7 +1391,7 @@ async def update_bot( BotResponse: 更新后的 Bot 信息 """ # 支持管理员认证和用户认证 - admin_valid, admin_username = await verify_admin_auth(authorization) + admin_valid, admin_username, admin_user_id = await verify_admin_auth(authorization) user_valid, user_id, user_username = await verify_user_auth(authorization) if not admin_valid and not user_valid: @@ -1444,7 +1466,7 @@ async def delete_bot(bot_uuid: str, authorization: Optional[str] = Header(None)) SuccessResponse: 删除结果 """ # 支持管理员认证和用户认证 - admin_valid, admin_username = await verify_admin_auth(authorization) + admin_valid, admin_username, admin_user_id = await verify_admin_auth(authorization) user_valid, user_id, user_username = await verify_user_auth(authorization) if not admin_valid and not user_valid: @@ -1491,7 +1513,7 @@ async def get_bot_settings(bot_uuid: str, authorization: Optional[str] = Header( BotSettingsResponse: Bot 设置信息 """ # 支持管理员认证和用户认证 - admin_valid, admin_username = await verify_admin_auth(authorization) + admin_valid, admin_username, admin_user_id = await verify_admin_auth(authorization) user_valid, user_id, user_username = await verify_user_auth(authorization) if not admin_valid and not user_valid: @@ -1500,8 +1522,11 @@ async def get_bot_settings(bot_uuid: str, authorization: Optional[str] = Header( detail="Unauthorized" ) - # 用户需要检查是否有 read 权限 - if user_valid: + # 获取实际的用户ID(优先使用 admin 的 user_id) + actual_user_id = admin_user_id if admin_user_id else user_id + + # 如果是普通用户(非 admin),检查是否有 read 权限 + if user_valid and not admin_user_id: if not await check_bot_access(bot_uuid, user_id, 'read'): raise HTTPException( status_code=403, @@ -1587,7 +1612,7 @@ async def update_bot_settings( SuccessResponse: 更新结果 """ # 支持管理员认证和用户认证 - admin_valid, admin_username = await verify_admin_auth(authorization) + admin_valid, admin_username, admin_user_id = await verify_admin_auth(authorization) user_valid, user_id, user_username = await verify_user_auth(authorization) if not admin_valid and not user_valid: @@ -1648,7 +1673,6 @@ async def update_bot_settings( async with pool.connection() as conn: async with conn.cursor() as cursor: - # 检查 Bot 是否存在 await cursor.execute("SELECT id, settings FROM agent_bots WHERE id = %s", (bot_uuid,)) row = await cursor.fetchone() @@ -2027,7 +2051,7 @@ async def admin_verify(authorization: Optional[str] = Header(None)): Returns: AdminVerifyResponse: 验证结果 """ - valid, username = await verify_admin_auth(authorization) + valid, username, admin_user_id = await verify_admin_auth(authorization) return AdminVerifyResponse( valid=valid, @@ -2307,7 +2331,7 @@ async def search_users( List[UserSearchResponse]: 用户列表 """ # 支持管理员认证��用户认证 - admin_valid, _ = await verify_admin_auth(authorization) + admin_valid, _, admin_user_id = await verify_admin_auth(authorization) user_valid, user_id, _ = await verify_user_auth(authorization) if not admin_valid and not user_valid: diff --git a/utils/fastapi_utils.py b/utils/fastapi_utils.py index b905092..c1a71fc 100644 --- a/utils/fastapi_utils.py +++ b/utils/fastapi_utils.py @@ -463,7 +463,7 @@ async def fetch_bot_config_from_db(bot_user_id: str) -> Dict[str, Any]: await cursor.execute( """ SELECT id, name, settings - FROM agent_bots WHERE bot_id = %s + FROM agent_bots WHERE id = %s """, (bot_user_id,) ) @@ -472,7 +472,7 @@ async def fetch_bot_config_from_db(bot_user_id: str) -> Dict[str, Any]: if not bot_row: raise HTTPException( status_code=404, - detail=f"Bot with bot_id '{bot_user_id}' not found" + detail=f"Bot with id '{bot_user_id}' not found" ) bot_uuid = bot_row[0]