← full-stack-fastapi-template / backend/app/api/deps.py
| 1 | from collections.abc import Generator |
| 2 | from typing import Annotated |
| 3 | |
| 4 | import jwt |
| 5 | from fastapi import Depends, HTTPException, status |
| 6 | from fastapi.security import OAuth2PasswordBearer |
| 7 | from jwt.exceptions import InvalidTokenError |
| 8 | from pydantic import ValidationError |
| 9 | from sqlmodel import Session |
| 10 | |
| 11 | from app.core import security |
| 12 | from app.core.config import settings |
| 13 | from app.core.db import engine |
| 14 | from app.models import TokenPayload, User |
| 15 | |
| 16 | reusable_oauth2 = OAuth2PasswordBearer( |
| 17 | tokenUrl=f"{settings.API_V1_STR}/login/access-token" |
| 18 | ) |
| 19 | |
| 20 | |
| 21 | def get_db() -> Generator[Session, None, None]: |
| 22 | with Session(engine) as session: |
| 23 | yield session |
| 24 | |
| 25 | |
| 26 | SessionDep = Annotated[Session, Depends(get_db)] |
| 27 | TokenDep = Annotated[str, Depends(reusable_oauth2)] |
| 28 | |
| 29 | |
| 30 | def get_current_user(session: SessionDep, token: TokenDep) -> User: |
| 31 | try: |
| 32 | payload = jwt.decode( |
| 33 | token, settings.SECRET_KEY, algorithms=[security.ALGORITHM] |
| 34 | ) |
| 35 | token_data = TokenPayload(**payload) |
| 36 | except (InvalidTokenError, ValidationError): |
| 37 | raise HTTPException( |
| 38 | status_code=status.HTTP_403_FORBIDDEN, |
| 39 | detail="Could not validate credentials", |
| 40 | ) |
| 41 | user = session.get(User, token_data.sub) |
| 42 | if not user: |
| 43 | raise HTTPException(status_code=404, detail="User not found") |
| 44 | if not user.is_active: |
| 45 | raise HTTPException(status_code=400, detail="Inactive user") |
| 46 | return user |
| 47 | |
| 48 | |
| 49 | CurrentUser = Annotated[User, Depends(get_current_user)] |
| 50 | |
| 51 | |
| 52 | def get_current_active_superuser(current_user: CurrentUser) -> User: |
| 53 | if not current_user.is_superuser: |
| 54 | raise HTTPException( |
| 55 | status_code=403, detail="The user doesn't have enough privileges" |
| 56 | ) |
| 57 | return current_user |
| 58 |