c92bcb0074
Co-authored-by: Cursor <cursoragent@cursor.com>
40 lines
1.2 KiB
Python
40 lines
1.2 KiB
Python
"""Admin JWT helpers (HS256)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime, timedelta, timezone
|
|
|
|
import jwt
|
|
from fastapi import Depends, HTTPException
|
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
|
|
|
from app import config
|
|
|
|
_bearer = HTTPBearer(auto_error=False)
|
|
|
|
|
|
def create_access_token(*, expires_hours: int | None = None) -> str:
|
|
hours = expires_hours if expires_hours is not None else config.settings.jwt_expire_hours
|
|
now = datetime.now(timezone.utc)
|
|
payload = {
|
|
"sub": "admin",
|
|
"iat": now,
|
|
"exp": now + timedelta(hours=hours),
|
|
}
|
|
return jwt.encode(payload, config.settings.secret_key, algorithm="HS256")
|
|
|
|
|
|
def verify_token(token: str) -> dict:
|
|
try:
|
|
return jwt.decode(token, config.settings.secret_key, algorithms=["HS256"])
|
|
except jwt.PyJWTError as exc:
|
|
raise HTTPException(status_code=401, detail="Unauthorized") from exc
|
|
|
|
|
|
def require_admin(
|
|
creds: HTTPAuthorizationCredentials | None = Depends(_bearer),
|
|
) -> dict:
|
|
if creds is None or creds.scheme.lower() != "bearer" or not creds.credentials:
|
|
raise HTTPException(status_code=401, detail="Unauthorized")
|
|
return verify_token(creds.credentials)
|