157 lines
5 KiB
Python
157 lines
5 KiB
Python
from fastapi import Response, Request
|
|
from typing import Optional
|
|
import logging
|
|
|
|
from config.config import settings
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class CookieManager:
|
|
@staticmethod
|
|
def _get_samesite_value() -> str:
|
|
value = settings.cookie_samesite.lower()
|
|
if value in ("strict", "lax", "none"):
|
|
return value
|
|
return "strict"
|
|
|
|
@staticmethod
|
|
def _should_be_secure() -> bool:
|
|
if settings.is_development and not settings.cookie_secure:
|
|
return False
|
|
return True
|
|
|
|
@classmethod
|
|
def set_access_token(
|
|
cls, response: Response, token: str, max_age: Optional[int] = None
|
|
) -> None:
|
|
if max_age is None:
|
|
max_age = settings.access_token_expire_minutes * 60
|
|
|
|
response.set_cookie(
|
|
key=settings.cookie_access_token_name,
|
|
value=token,
|
|
max_age=max_age,
|
|
expires=max_age,
|
|
path="/",
|
|
domain=settings.cookie_domain,
|
|
secure=cls._should_be_secure(),
|
|
httponly=settings.cookie_httponly,
|
|
samesite=cls._get_samesite_value(),
|
|
)
|
|
logger.debug("Cookie access_token defini")
|
|
|
|
@classmethod
|
|
def set_refresh_token(
|
|
cls, response: Response, token: str, max_age: Optional[int] = None
|
|
) -> None:
|
|
if max_age is None:
|
|
max_age = settings.refresh_token_expire_days * 24 * 60 * 60
|
|
|
|
response.set_cookie(
|
|
key=settings.cookie_refresh_token_name,
|
|
value=token,
|
|
max_age=max_age,
|
|
expires=max_age,
|
|
path="/auth",
|
|
domain=settings.cookie_domain,
|
|
secure=cls._should_be_secure(),
|
|
httponly=settings.cookie_httponly,
|
|
samesite=cls._get_samesite_value(),
|
|
)
|
|
logger.debug("Cookie refresh_token defini")
|
|
|
|
@classmethod
|
|
def set_csrf_token(
|
|
cls, response: Response, token: str, max_age: Optional[int] = None
|
|
) -> None:
|
|
if max_age is None:
|
|
max_age = settings.csrf_token_expire_minutes * 60
|
|
|
|
response.set_cookie(
|
|
key=settings.cookie_csrf_token_name,
|
|
value=token,
|
|
max_age=max_age,
|
|
expires=max_age,
|
|
path="/",
|
|
domain=settings.cookie_domain,
|
|
secure=cls._should_be_secure(),
|
|
httponly=False,
|
|
samesite=cls._get_samesite_value(),
|
|
)
|
|
logger.debug("Cookie csrf_token defini")
|
|
|
|
@classmethod
|
|
def clear_access_token(cls, response: Response) -> None:
|
|
response.delete_cookie(
|
|
key=settings.cookie_access_token_name,
|
|
path="/",
|
|
domain=settings.cookie_domain,
|
|
secure=cls._should_be_secure(),
|
|
httponly=settings.cookie_httponly,
|
|
samesite=cls._get_samesite_value(),
|
|
)
|
|
logger.debug("Cookie access_token supprime")
|
|
|
|
@classmethod
|
|
def clear_refresh_token(cls, response: Response) -> None:
|
|
response.delete_cookie(
|
|
key=settings.cookie_refresh_token_name,
|
|
path="/auth",
|
|
domain=settings.cookie_domain,
|
|
secure=cls._should_be_secure(),
|
|
httponly=settings.cookie_httponly,
|
|
samesite=cls._get_samesite_value(),
|
|
)
|
|
logger.debug("Cookie refresh_token supprime")
|
|
|
|
@classmethod
|
|
def clear_csrf_token(cls, response: Response) -> None:
|
|
response.delete_cookie(
|
|
key=settings.cookie_csrf_token_name,
|
|
path="/",
|
|
domain=settings.cookie_domain,
|
|
secure=cls._should_be_secure(),
|
|
httponly=False,
|
|
samesite=cls._get_samesite_value(),
|
|
)
|
|
logger.debug("Cookie csrf_token supprime")
|
|
|
|
@classmethod
|
|
def clear_all_auth_cookies(cls, response: Response) -> None:
|
|
cls.clear_access_token(response)
|
|
cls.clear_refresh_token(response)
|
|
cls.clear_csrf_token(response)
|
|
logger.debug("Tous les cookies auth supprimes")
|
|
|
|
@classmethod
|
|
def get_access_token(cls, request: Request) -> Optional[str]:
|
|
token = request.cookies.get(settings.cookie_access_token_name)
|
|
if token:
|
|
return token
|
|
|
|
auth_header = request.headers.get("Authorization")
|
|
if auth_header and auth_header.startswith("Bearer "):
|
|
return auth_header[7:]
|
|
|
|
return None
|
|
|
|
@classmethod
|
|
def get_refresh_token(cls, request: Request) -> Optional[str]:
|
|
return request.cookies.get(settings.cookie_refresh_token_name)
|
|
|
|
@classmethod
|
|
def get_csrf_token(cls, request: Request) -> Optional[str]:
|
|
csrf_header = request.headers.get("X-CSRF-Token")
|
|
if csrf_header:
|
|
return csrf_header
|
|
|
|
return request.cookies.get(settings.cookie_csrf_token_name)
|
|
|
|
|
|
def set_auth_cookies(
|
|
response: Response, access_token: str, refresh_token: str, csrf_token: str
|
|
) -> None:
|
|
CookieManager.set_access_token(response, access_token)
|
|
CookieManager.set_refresh_token(response, refresh_token)
|
|
CookieManager.set_csrf_token(response, csrf_token)
|