Files

73 lines
2.4 KiB
Python

from fastapi import Depends, HTTPException, status, Query
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from sqlalchemy.orm import Session
from jose import JWTError, jwt
from database import get_db, SECRET_KEY, ALGORITHM
from models import User
security = HTTPBearer()
async def get_current_user(
credentials: HTTPAuthorizationCredentials = Depends(security),
db: Session = Depends(get_db)
) -> User:
"""Validate JWT token and return current user."""
token = credentials.credentials
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid or expired token",
headers={"WWW-Authenticate": "Bearer"},
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
user_id_str = payload.get("sub")
if user_id_str is None:
raise credentials_exception
try:
user_id = int(user_id_str)
except (ValueError, TypeError):
raise credentials_exception
except JWTError:
raise credentials_exception
user = db.query(User).filter(User.id == user_id, User.is_active == True).first()
if user is None:
raise credentials_exception
return user
async def get_current_admin(current_user: User = Depends(get_current_user)) -> User:
"""Ensure current user is an admin."""
if current_user.role != "admin":
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Admin access required"
)
return current_user
async def get_current_user_from_query(
token: str = Query(...),
db: Session = Depends(get_db)
) -> User:
"""Validate JWT token from query parameter and return current user."""
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid or expired token",
headers={"WWW-Authenticate": "Bearer"},
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
user_id_str = payload.get("sub")
if user_id_str is None:
raise credentials_exception
user_id = int(user_id_str)
except (JWTError, ValueError, TypeError):
raise credentials_exception
user = db.query(User).filter(User.id == user_id, User.is_active == True).first()
if user is None:
raise credentials_exception
return user