Загрузка данных


from dmr.controller import Controller
from dmr.components import Body, Cookie, ResponseContext
from django.http import JsonResponse

from .schemas import (
    LoginRequestSchema, LoginResponseSchema,
    RefreshResponseSchema, LogoutResponseSchema
)
from .services import AuthService

class AuthController(Controller):
    """Контроллер управления сессиями и JWT-токенами."""

    async def post_login(
        self, 
        # Компонент Body автоматически парсит и валидирует входящий JSON
        body: Body[LoginRequestSchema], 
        # Контекст для работы с заголовками ответа и Set-Cookie
        ctx: ResponseContext,
    ) -> LoginResponseSchema:
        """Аутентификация пользователя и выдача пары токенов."""
        
        # Достаем провалидированные данные
        payload = body.value
        user = await AuthService.authenticate_user(email=payload.email, password=payload.password)
        
        access_token = await AuthService.generate_access_token(user)
        refresh_token = await AuthService.generate_refresh_token(user)
        
        # Устанавливаем куку через контекст ответа django-modern-rest
        ctx.set_cookie(
            key="refresh",
            value=refresh_token,
            httponly=True,
            secure=True,
            samesite="Lax",
            path="/api/v1/auth/refresh/",
            max_age=604800
        )
        
        # Возвращаем объект схемы (библиотека сама сериализует его)
        return LoginResponseSchema(access=access_token)

    async def post_refresh(
        self,
        # Компонент Cookie автоматически извлекает refresh из кук запроса
        refresh_cookie: Cookie[str, "refresh"],
    ) -> RefreshResponseSchema:
        """Обновление сессии по Refresh-токену из куки."""
        
        try:
            new_access_token = await AuthService.refresh_session(refresh_cookie.value)
            return RefreshResponseSchema(access=new_access_token)
        except AuthService.InvalidTokenError:
            # Превращается в валидный 401 ответ через встроенный обработчик ошибок DMR
            return JsonResponse({"detail": "Invalid or expired refresh token"}, status=401)

    async def post_logout(self, ctx: ResponseContext) -> LogoutResponseSchema:
        """Выход из системы с затиранием авторизационной куки."""
        
        ctx.set_cookie(
            key="refresh",
            value="",
            httponly=True,
            secure=True,
            samesite="Lax",
            path="/api/v1/auth/refresh/",
            max_age=0
        )
        return LogoutResponseSchema(detail="Successfully logged out.")