1aaef71f52
Document-driven MVP with FastAPI backend, Vue H5, WeChat mini shell, product demo, and Docker dev stack. Co-authored-by: Cursor <cursoragent@cursor.com>
55 lines
1.6 KiB
Python
55 lines
1.6 KiB
Python
from fastapi import Depends, HTTPException, Request
|
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.core.response import error
|
|
from app.core.security import decode_access_token
|
|
from app.db.models import User
|
|
from app.db.session import get_db
|
|
|
|
bearer_scheme = HTTPBearer(auto_error=False)
|
|
|
|
|
|
def get_current_user(
|
|
request: Request,
|
|
credentials: HTTPAuthorizationCredentials | None = Depends(bearer_scheme),
|
|
db: Session = Depends(get_db),
|
|
) -> User:
|
|
if credentials is None or credentials.scheme.lower() != "bearer":
|
|
raise HTTPException(
|
|
status_code=401,
|
|
detail=error(10001, "unauthorized", request.state.request_id),
|
|
)
|
|
try:
|
|
payload = decode_access_token(credentials.credentials)
|
|
user_id = int(payload["sub"])
|
|
except Exception as exc:
|
|
raise HTTPException(
|
|
status_code=401,
|
|
detail=error(10001, "invalid_token", request.state.request_id),
|
|
) from exc
|
|
|
|
user = db.get(User, user_id)
|
|
if not user or user.status != "active":
|
|
raise HTTPException(
|
|
status_code=401,
|
|
detail=error(10001, "user_inactive", request.state.request_id),
|
|
)
|
|
return user
|
|
|
|
|
|
def require_staff(
|
|
request: Request,
|
|
user: User = Depends(get_current_user),
|
|
) -> User:
|
|
if user.role in ("coach", "org_admin", "platform_admin"):
|
|
return user
|
|
from app.config import settings
|
|
|
|
if settings.app_debug:
|
|
return user
|
|
raise HTTPException(
|
|
status_code=403,
|
|
detail=error(10009, "forbidden_staff_only", request.state.request_id),
|
|
)
|