from fastapi import APIRouter, Depends, HTTPException, Request, status from admin_app.api.dependencies import ( get_auth_service, get_current_staff_context, get_current_staff_principal, ) from admin_app.api.schemas import ( AdminAuthenticatedStaffResponse, AdminLoginRequest, AdminLogoutResponse, AdminRefreshTokenRequest, AdminSessionResponse, ) from admin_app.core import AuthenticatedStaffContext, AuthenticatedStaffPrincipal from admin_app.services import AuthService router = APIRouter(prefix="/auth", tags=["auth"]) def _extract_request_metadata(request: Request) -> tuple[str | None, str | None]: ip_address = request.client.host if request.client else None user_agent = request.headers.get("user-agent") return ip_address, user_agent @router.post("/login", response_model=AdminSessionResponse) def login( payload: AdminLoginRequest, request: Request, auth_service: AuthService = Depends(get_auth_service), ): ip_address, user_agent = _extract_request_metadata(request) session = auth_service.login( email=payload.email, password=payload.password, ip_address=ip_address, user_agent=user_agent, ) if session is None: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Credenciais administrativas invalidas.", ) return AdminSessionResponse( session_id=session.session_id, access_token=session.access_token, refresh_token=session.refresh_token, token_type=session.token_type, expires_in_seconds=session.expires_in_seconds, staff_account=AdminAuthenticatedStaffResponse(**session.principal.model_dump()), ) @router.post("/refresh", response_model=AdminSessionResponse) def refresh( payload: AdminRefreshTokenRequest, request: Request, auth_service: AuthService = Depends(get_auth_service), ): ip_address, user_agent = _extract_request_metadata(request) session = auth_service.refresh_session( refresh_token=payload.refresh_token, ip_address=ip_address, user_agent=user_agent, ) if session is None: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Refresh token administrativo invalido.", ) return AdminSessionResponse( session_id=session.session_id, access_token=session.access_token, refresh_token=session.refresh_token, token_type=session.token_type, expires_in_seconds=session.expires_in_seconds, staff_account=AdminAuthenticatedStaffResponse(**session.principal.model_dump()), ) @router.post("/logout", response_model=AdminLogoutResponse) def logout( request: Request, current_context: AuthenticatedStaffContext = Depends(get_current_staff_context), auth_service: AuthService = Depends(get_auth_service), ): ip_address, user_agent = _extract_request_metadata(request) auth_service.logout( current_context.session_id, actor_staff_account_id=current_context.principal.id, ip_address=ip_address, user_agent=user_agent, ) return AdminLogoutResponse( service="orquestrador-admin", status="ok", message="Sessao administrativa encerrada.", session_id=current_context.session_id, ) @router.get("/me", response_model=AdminAuthenticatedStaffResponse) def current_staff( current_staff_account: AuthenticatedStaffPrincipal = Depends(get_current_staff_principal), ): return AdminAuthenticatedStaffResponse(**current_staff_account.model_dump())