feat: add validation
This commit is contained in:
@@ -2,43 +2,21 @@ from fastapi import APIRouter, Request, Depends
|
||||
from fastapi.responses import ORJSONResponse
|
||||
from starlette import status
|
||||
from src.application.commands import JwtRefreshCommand
|
||||
from src.application.domain.exceptions import ApplicationException
|
||||
from src.application.domain.exceptions import ApplicationException, RefreshConcurrentException
|
||||
from src.infrastructure.config import settings
|
||||
from src.presentation.decorators import csrf_protect,rate_limit
|
||||
from src.presentation.decorators import csrf_protect, rate_limit
|
||||
from src.presentation.dependencies import get_jwt_refresh_command
|
||||
|
||||
|
||||
jwt_router = APIRouter(prefix='/jwt', tags=['Jwt'])
|
||||
|
||||
|
||||
@jwt_router.post('/refresh', response_class=ORJSONResponse, status_code=status.HTTP_200_OK)
|
||||
@rate_limit(limit=settings.RATE_LIMIT_REQUESTS, window_seconds=settings.RATE_LIMIT_WINDOW, scope='ip')
|
||||
@csrf_protect()
|
||||
async def refresh_tokens(
|
||||
request: Request,
|
||||
command: JwtRefreshCommand = Depends(get_jwt_refresh_command)
|
||||
):
|
||||
refresh_token = request.cookies.get('refresh_token')
|
||||
def _clear_auth_cookies(response: ORJSONResponse) -> None:
|
||||
response.delete_cookie('access_token', path='/', domain=settings.AUTH_COOKIE_DOMAIN)
|
||||
response.delete_cookie('refresh_token', path='/', domain=settings.AUTH_COOKIE_DOMAIN)
|
||||
|
||||
if not refresh_token:
|
||||
response = ORJSONResponse({'ok': False, 'error': 'No refresh token'}, status_code=401)
|
||||
response.delete_cookie('access_token', path='/', domain=settings.AUTH_COOKIE_DOMAIN)
|
||||
response.delete_cookie('refresh_token', path='/', domain=settings.AUTH_COOKIE_DOMAIN)
|
||||
return response
|
||||
|
||||
ip = request.client.host if request.client else None
|
||||
user_agent = request.headers.get('user-agent')
|
||||
|
||||
try:
|
||||
access, refresh = await command(refresh_token=refresh_token, ip=ip, user_agent=user_agent)
|
||||
except ApplicationException:
|
||||
response = ORJSONResponse({'result': False}, status_code=401)
|
||||
response.delete_cookie('access_token', path='/', domain=settings.AUTH_COOKIE_DOMAIN)
|
||||
response.delete_cookie('refresh_token', path='/', domain=settings.AUTH_COOKIE_DOMAIN)
|
||||
return response
|
||||
|
||||
response = ORJSONResponse({'result': True})
|
||||
|
||||
def _set_auth_cookies(response: ORJSONResponse, access: str, refresh: str) -> None:
|
||||
response.set_cookie(
|
||||
key='access_token',
|
||||
value=access,
|
||||
@@ -59,9 +37,37 @@ async def refresh_tokens(
|
||||
domain=settings.AUTH_COOKIE_DOMAIN,
|
||||
max_age=int(settings.JWT_REFRESH_TTL_SECONDS),
|
||||
)
|
||||
return response
|
||||
|
||||
# Usage
|
||||
# @jwt_router.get("/test")
|
||||
# async def profile(auth: AuthContext = Depends(require_access_token)):
|
||||
# return 'ok'
|
||||
|
||||
@jwt_router.post('/refresh', response_class=ORJSONResponse, status_code=status.HTTP_200_OK)
|
||||
@rate_limit(limit=settings.RATE_LIMIT_REQUESTS, window_seconds=settings.RATE_LIMIT_WINDOW, scope='ip')
|
||||
@csrf_protect()
|
||||
async def refresh_tokens(
|
||||
request: Request,
|
||||
command: JwtRefreshCommand = Depends(get_jwt_refresh_command),
|
||||
):
|
||||
refresh_token = request.cookies.get('refresh_token')
|
||||
|
||||
if not refresh_token:
|
||||
response = ORJSONResponse({'ok': False, 'error': 'No refresh token'}, status_code=401)
|
||||
_clear_auth_cookies(response)
|
||||
return response
|
||||
|
||||
ip = request.client.host if request.client else None
|
||||
user_agent = request.headers.get('user-agent')
|
||||
|
||||
try:
|
||||
tokens = await command(refresh_token=refresh_token, ip=ip, user_agent=user_agent)
|
||||
except RefreshConcurrentException:
|
||||
return ORJSONResponse({'result': True, 'concurrent': True}, status_code=status.HTTP_200_OK)
|
||||
except ApplicationException as exc:
|
||||
if exc.status_code == status.HTTP_401_UNAUTHORIZED:
|
||||
response = ORJSONResponse({'result': False}, status_code=401)
|
||||
_clear_auth_cookies(response)
|
||||
return response
|
||||
raise
|
||||
|
||||
access, refresh = tokens
|
||||
response = ORJSONResponse({'result': True})
|
||||
_set_auth_cookies(response, access, refresh)
|
||||
return response
|
||||
|
||||
Reference in New Issue
Block a user