Files
HSAP/platform/as_platform/auth/deps.py
Chengfang Lu e72bc061c5 feat: HSAP platform v2 — modular navigation, quality review, audit log, world model simulation
Major changes:
- New frontend (platform/web/): Vite + React 18 + TypeScript + Tailwind
- 4-module navigation: 数据送标 / 模型管理 / 车队管理 / 系统管理
- Data catalog with charts (DMS/ADAS/Lane 3-tab view)
- Quality review workflow (标注质检): Good/Fine/Bad scoring with auto-advance
- Audit enhancements: batch operations, rejection categories, Feishu notifications
- Operation audit log (操作日志)
- World model simulation studio (仿真工坊)
- Dataset version management with snapshots and diff
- ADAS 7-class dataset integration (138K images organized + compressed)
- User management with Feishu integration and pagination
- CRUD/search/filter on all pages, card layout redesign
- PIL-optimized image overlay rendering
- Auto-snapshot on build, in_review workflow stage
- Removed embedded algorithm code (now in workspace)
2026-06-03 11:40:21 +08:00

74 lines
2.3 KiB
Python

"""FastAPI 认证依赖。"""
from __future__ import annotations
from typing import Annotated
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from sqlalchemy.orm import Session, joinedload
from as_platform.auth.jwt import decode_access_token
from as_platform.config import DEV_AUTH_ENABLED
from as_platform.db.engine import get_db
from as_platform.db.init_db import user_has_permission
from as_platform.db.models import Role, User
_bearer = HTTPBearer(auto_error=False)
def _load_user(db: Session, user_id: int) -> User | None:
return (
db.query(User)
.options(joinedload(User.roles).joinedload(Role.permissions))
.filter(User.id == user_id, User.is_active.is_(True))
.first()
)
def get_current_user_optional(
creds: Annotated[HTTPAuthorizationCredentials | None, Depends(_bearer)],
db: Annotated[Session, Depends(get_db)],
) -> User | None:
if not creds:
return None
payload = decode_access_token(creds.credentials)
if not payload or "sub" not in payload:
return None
return _load_user(db, int(payload["sub"]))
def get_current_user(
user: Annotated[User | None, Depends(get_current_user_optional)],
) -> User:
if not user:
raise HTTPException(status.HTTP_401_UNAUTHORIZED, detail="未登录,请先飞书登录")
return user
def require_permission(permission: str):
def _dep(user: Annotated[User, Depends(get_current_user)]) -> User:
if not user_has_permission(user, permission):
raise HTTPException(status.HTTP_403_FORBIDDEN, detail=f"缺少权限: {permission}")
return user
return _dep
def require_any_permission(*permissions: str):
def _dep(user: Annotated[User, Depends(get_current_user)]) -> User:
if any(user_has_permission(user, p) for p in permissions):
return user
raise HTTPException(status.HTTP_403_FORBIDDEN, detail="权限不足")
return _dep
def can_submit_action(user: User, action: str) -> bool:
if user_has_permission(user, "write:approval_submit"):
return True
if action == "register_batch" and user_has_permission(user, "write:approval_submit:register"):
return True
if action == "delivery_ingest" and user_has_permission(user, "write:delivery_submit"):
return True
return False