100 lines
2.5 KiB
Python
100 lines
2.5 KiB
Python
|
|
"""API 公共函数模块
|
||
|
|
|
||
|
|
包含跨 API 模块共享的通用函数和工具。
|
||
|
|
"""
|
||
|
|
from fastapi import HTTPException, Request
|
||
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||
|
|
from sqlalchemy import select
|
||
|
|
from typing import Optional
|
||
|
|
|
||
|
|
from app.models.project import Project
|
||
|
|
from app.logger import get_logger
|
||
|
|
|
||
|
|
logger = get_logger(__name__)
|
||
|
|
|
||
|
|
|
||
|
|
async def verify_project_access(
|
||
|
|
project_id: str,
|
||
|
|
user_id: Optional[str],
|
||
|
|
db: AsyncSession
|
||
|
|
) -> Project:
|
||
|
|
"""
|
||
|
|
验证用户是否有权访问指定项目
|
||
|
|
|
||
|
|
统一的项目访问验证函数,确保:
|
||
|
|
1. 用户已登录
|
||
|
|
2. 项目存在
|
||
|
|
3. 用户有权访问该项目
|
||
|
|
|
||
|
|
Args:
|
||
|
|
project_id: 项目ID
|
||
|
|
user_id: 用户ID(从 request.state.user_id 获取)
|
||
|
|
db: 数据库会话
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Project: 验证通过后返回项目对象
|
||
|
|
|
||
|
|
Raises:
|
||
|
|
HTTPException:
|
||
|
|
- 401: 用户未登录
|
||
|
|
- 404: 项目不存在或用户无权访问
|
||
|
|
"""
|
||
|
|
if not user_id:
|
||
|
|
raise HTTPException(status_code=401, detail="未登录")
|
||
|
|
|
||
|
|
result = await db.execute(
|
||
|
|
select(Project).where(
|
||
|
|
Project.id == project_id,
|
||
|
|
Project.user_id == user_id
|
||
|
|
)
|
||
|
|
)
|
||
|
|
project = result.scalar_one_or_none()
|
||
|
|
|
||
|
|
if not project:
|
||
|
|
logger.warning(f"项目访问被拒绝: project_id={project_id}, user_id={user_id}")
|
||
|
|
raise HTTPException(status_code=404, detail="项目不存在或无权访问")
|
||
|
|
|
||
|
|
return project
|
||
|
|
|
||
|
|
|
||
|
|
def get_user_id(request: Request) -> Optional[str]:
|
||
|
|
"""
|
||
|
|
从请求中获取用户ID
|
||
|
|
|
||
|
|
这是一个便捷函数,用于从 request.state 中提取 user_id。
|
||
|
|
|
||
|
|
Args:
|
||
|
|
request: FastAPI 请求对象
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
用户ID,如果未登录则返回 None
|
||
|
|
"""
|
||
|
|
return getattr(request.state, 'user_id', None)
|
||
|
|
|
||
|
|
|
||
|
|
async def verify_project_access_from_request(
|
||
|
|
project_id: str,
|
||
|
|
request: Request,
|
||
|
|
db: AsyncSession
|
||
|
|
) -> Project:
|
||
|
|
"""
|
||
|
|
从请求中验证项目访问权限(便捷函数)
|
||
|
|
|
||
|
|
结合 get_user_id 和 verify_project_access,简化调用。
|
||
|
|
|
||
|
|
Args:
|
||
|
|
project_id: 项目ID
|
||
|
|
request: FastAPI 请求对象
|
||
|
|
db: 数据库会话
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Project: 验证通过后返回项目对象
|
||
|
|
|
||
|
|
Raises:
|
||
|
|
HTTPException: 401/404
|
||
|
|
|
||
|
|
Usage:
|
||
|
|
project = await verify_project_access_from_request(project_id, request, db)
|
||
|
|
"""
|
||
|
|
user_id = get_user_id(request)
|
||
|
|
return await verify_project_access(project_id, user_id, db)
|