feat: update

This commit is contained in:
2026-06-05 14:47:41 +03:00
parent fdae3ca554
commit 4d5506db4d
12 changed files with 52 additions and 244 deletions

View File

@@ -1,10 +1,9 @@
from fastapi import APIRouter, Depends, Request, status
from fastapi import APIRouter, Depends, status
from fastapi.responses import ORJSONResponse
from src.application.commands import AdminJwtRefreshCommand, AdminLoginCommand, GetAdminMeCommand
from src.application.domain.dto import AdminAuthContext
from src.application.domain.exceptions import ApplicationException, RefreshConcurrentException
from src.presentation.auth_cookies import set_auth_cookies, set_device_id_cookie
from src.presentation.auth_cookies import set_auth_cookies
from src.presentation.decorators.admin_auth import require_admin_access
from src.presentation.dependencies.commands import (
get_admin_jwt_refresh_command,
@@ -22,26 +21,12 @@ from src.presentation.schemas.admin_auth import (
auth_router = APIRouter(prefix='/auth', tags=['auth'])
def _client_ip(request: Request) -> str | None:
xff = request.headers.get('x-forwarded-for')
if xff:
return xff.split(',')[0].strip()
return request.client.host if request.client else None
@auth_router.post('/login', response_model=AdminLoginResponse, status_code=status.HTTP_200_OK)
async def admin_login(
body: AdminLoginRequest,
request: Request,
command: AdminLoginCommand = Depends(get_admin_login_command),
):
dto = await command(
login=body.login,
password=body.password,
device_id=request.cookies.get('device_id'),
ip=_client_ip(request),
user_agent=request.headers.get('user-agent'),
)
dto = await command(login=body.login, password=body.password)
response = ORJSONResponse(
AdminLoginResponse(
access_token=dto.access_token,
@@ -54,31 +39,20 @@ async def admin_login(
).model_dump()
)
set_auth_cookies(response, dto.access_token, dto.refresh_token)
set_device_id_cookie(response, dto.device_id)
return response
@auth_router.post('/refresh', response_model=AdminRefreshResponse, status_code=status.HTTP_200_OK)
async def admin_refresh(
body: AdminRefreshRequest,
request: Request,
command: AdminJwtRefreshCommand = Depends(get_admin_jwt_refresh_command),
):
try:
access, refresh = await command(
refresh_token=body.refresh_token,
ip=_client_ip(request),
user_agent=request.headers.get('user-agent'),
)
except RefreshConcurrentException:
raise ApplicationException(status_code=409, message='Refresh already in progress')
access, refresh = await command(refresh_token=body.refresh_token)
return AdminRefreshResponse(access_token=access, refresh_token=refresh)
@auth_router.post('/logout', response_class=ORJSONResponse, status_code=status.HTTP_200_OK)
async def admin_logout():
"""Клиент удаляет access_token локально. Сервер stateless."""
return {'ok': True}

View File

@@ -3,20 +3,13 @@ from fastapi.responses import ORJSONResponse
from starlette import status
from src.application.commands import AdminJwtRefreshCommand
from src.application.domain.exceptions import ApplicationException, RefreshConcurrentException
from src.application.domain.exceptions import ApplicationException
from src.presentation.auth_cookies import clear_auth_cookies, set_auth_cookies
from src.presentation.dependencies.commands import get_admin_jwt_refresh_command
jwt_router = APIRouter(prefix='/jwt', tags=['jwt'])
def _client_ip(request: Request) -> str | None:
xff = request.headers.get('x-forwarded-for')
if xff:
return xff.split(',')[0].strip()
return request.client.host if request.client else None
@jwt_router.post('/refresh', response_class=ORJSONResponse, status_code=status.HTTP_200_OK)
async def refresh_tokens(
request: Request,
@@ -29,13 +22,7 @@ async def refresh_tokens(
return response
try:
tokens = await command(
refresh_token=refresh_token,
ip=_client_ip(request),
user_agent=request.headers.get('user-agent'),
)
except RefreshConcurrentException:
return ORJSONResponse({'result': True, 'concurrent': True}, status_code=status.HTTP_200_OK)
access, refresh = await command(refresh_token=refresh_token)
except ApplicationException as exc:
if exc.status_code == status.HTTP_401_UNAUTHORIZED:
response = ORJSONResponse({'result': False}, status_code=401)
@@ -43,7 +30,6 @@ async def refresh_tokens(
return response
raise
access, refresh = tokens
response = ORJSONResponse({'result': True})
set_auth_cookies(response, access, refresh)
return response