Source code for src.models.auth

"""Data models for authentication."""
from typing import Optional

from fastapi import HTTPException, Request, status
from fastapi.openapi.models import OAuthFlowPassword
from fastapi.openapi.models import OAuthFlows as OAuthFlowsModel
from fastapi.security import OAuth2
from fastapi.security.utils import get_authorization_scheme_param
from pydantic import BaseModel

from ..config.config import config


[docs]class CsrfSettings(BaseModel): """Cross-site request forgery protection config""" secret_key: str = config.SECRET_KEY cookie_secure: bool = config.SECURE_COOKIES
# NOTE: Should this be moved to internal/auth.py?
[docs]class OAuth2PasswordBearerWithCookie(OAuth2): """Custom OAuth2PasswordBearer class to allow cookie authentication""" def __init__( self, tokenUrl: str, scheme_name: Optional[str] = None, scopes: Optional[dict] = None, auto_error: bool = True, ): """Custom OAuth2PasswordBearer class to allow cookie authentication Args: tokenUrl (str): Auth token URL scheme_name (Optional[str], optional): OAuth2 Scheme. Defaults to None. scopes (Optional[dict], optional): OAuth2 scopes. Defaults to None. auto_error (bool, optional): If should throw exception on failure. Defaults to True. """ if not scopes: scopes = {} flows = OAuthFlowsModel( password=OAuthFlowPassword(tokenUrl=tokenUrl, scopes=scopes) ) super().__init__(flows=flows, scheme_name=scheme_name, auto_error=auto_error) async def __call__(self, request: Request) -> Optional[str]: """Intercept request and check for access token in cookie to validate user Args: request (Request): Incoming HTTP request Raises: HTTPException: If no authorization header is found Returns: Optional[str]: Encoded JWT """ authorization: Optional[str] = request.cookies.get("access_token") scheme, param = get_authorization_scheme_param(authorization or "") if not authorization or scheme.lower() != "bearer": if self.auto_error: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Not authenticated", headers={"WWW-Authenticate": "Bearer"}, ) else: return None return param