Files
aiagent/backend/app/api/deps.py

65 lines
2.1 KiB
Python
Raw Normal View History

"""
FastAPI 依赖注入 Workspace 上下文权限检查
"""
from dataclasses import dataclass
from typing import Optional
from fastapi import Depends, HTTPException, Request
from sqlalchemy.orm import Session
from app.core.database import get_db
from app.core.security import decode_access_token
from app.models.user import User
@dataclass
class WorkspaceContext:
"""工作区上下文 — 包装当前用户 + 当前工作区 ID"""
user: User
workspace_id: str
def get_current_workspace_id(request: Request) -> str:
"""从 JWT 的 `ws` 字段提取当前工作区 ID。"""
auth_header = request.headers.get("Authorization", "")
if not auth_header.startswith("Bearer "):
raise HTTPException(status_code=401, detail="未提供有效的认证令牌")
token = auth_header[7:]
payload = decode_access_token(token)
if payload is None:
raise HTTPException(status_code=401, detail="无效的访问令牌")
ws_id = payload.get("ws")
if not ws_id:
raise HTTPException(status_code=400, detail="令牌中未包含工作区信息,请重新登录")
return ws_id
def get_workspace_context(
request: Request,
db: Session = Depends(get_db),
) -> WorkspaceContext:
"""获取完整的 Workspace 上下文(用户 + 工作区),用于需要 workspace 过滤的接口。"""
auth_header = request.headers.get("Authorization", "")
if not auth_header.startswith("Bearer "):
raise HTTPException(status_code=401, detail="未提供有效的认证令牌")
token = auth_header[7:]
payload = decode_access_token(token)
if payload is None:
raise HTTPException(status_code=401, detail="无效的访问令牌")
user_id = payload.get("sub")
ws_id = payload.get("ws")
if not user_id:
raise HTTPException(status_code=401, detail="无效的访问令牌")
user = db.query(User).filter(User.id == user_id).first()
if not user:
raise HTTPException(status_code=401, detail="用户不存在")
return WorkspaceContext(user=user, workspace_id=ws_id or "")