Files
core/auth/handler.py
Untone 5876995838
Some checks failed
Deploy on push / deploy (push) Failing after 2m34s
ci-mypy-fixes
2025-08-12 18:23:53 +03:00

105 lines
5.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from typing import Any
from ariadne.asgi.handlers import GraphQLHTTPHandler
from starlette.requests import Request
from starlette.responses import JSONResponse
from auth.middleware import auth_middleware
from utils.logger import root_logger as logger
class EnhancedGraphQLHTTPHandler(GraphQLHTTPHandler):
"""
Улучшенный GraphQL HTTP обработчик с поддержкой cookie и авторизации.
Расширяет стандартный GraphQLHTTPHandler для:
1. Создания расширенного контекста запроса с авторизационными данными
2. Корректной обработки ответов с cookie и headers
3. Интеграции с AuthMiddleware
"""
async def get_context_for_request(self, request: Request, data: dict) -> dict:
"""
Расширяем контекст для GraphQL запросов.
Добавляет к стандартному контексту:
- Объект response для установки cookie
- Интеграцию с AuthMiddleware
- Расширения для управления авторизацией
Args:
request: Starlette Request объект
data: данные запроса
Returns:
dict: контекст с дополнительными данными для авторизации и cookie
"""
# Безопасно получаем заголовки для диагностики
headers = {}
if hasattr(request, "headers"):
try:
# Используем безопасный способ получения заголовков
for key, value in request.headers.items():
headers[key.lower()] = value
except Exception as e:
logger.debug(f"[graphql] Ошибка при получении заголовков: {e}")
logger.debug(f"[graphql] Заголовки в get_context_for_request: {list(headers.keys())}")
if "authorization" in headers:
logger.debug(f"[graphql] Authorization header найден: {headers['authorization'][:50]}...")
else:
logger.debug("[graphql] Authorization header НЕ найден")
# Получаем стандартный контекст от базового класса
context = await super().get_context_for_request(request, data)
# Создаем объект ответа для установки cookie
response = JSONResponse({})
context["response"] = response
# Интегрируем с AuthMiddleware
auth_middleware.set_context(context)
context["extensions"] = auth_middleware
# Добавляем данные авторизации только если они доступны
# Проверяем наличие данных авторизации в scope
if hasattr(request, "scope") and isinstance(request.scope, dict) and "auth" in request.scope:
auth_cred: Any | None = request.scope.get("auth")
context["auth"] = auth_cred
# Безопасно логируем информацию о типе объекта auth
logger.debug(f"[graphql] Добавлены данные авторизации в контекст из scope: {type(auth_cred).__name__}")
# Проверяем, есть ли токен в auth_cred
if auth_cred is not None and hasattr(auth_cred, "token") and getattr(auth_cred, "token"):
token_val = auth_cred.token
token_len = len(token_val) if hasattr(token_val, "__len__") else 0
logger.debug(f"[graphql] Токен найден в auth_cred: {token_len}")
else:
logger.debug("[graphql] Токен НЕ найден в auth_cred")
# Добавляем author_id в контекст для RBAC
author_id = None
if auth_cred is not None and hasattr(auth_cred, "author_id") and getattr(auth_cred, "author_id"):
author_id = auth_cred.author_id
elif isinstance(auth_cred, dict) and "author_id" in auth_cred:
author_id = auth_cred["author_id"]
if author_id:
# Преобразуем author_id в число для совместимости с RBAC
try:
author_id_int = int(str(author_id).strip())
context["author"] = {"id": author_id_int}
logger.debug(f"[graphql] Добавлен author_id в контекст: {author_id_int}")
except (ValueError, TypeError) as e:
logger.error(f"[graphql] Ошибка преобразования author_id {author_id}: {e}")
context["author"] = {"id": author_id}
logger.debug(f"[graphql] Добавлен author_id как строка: {author_id}")
else:
logger.debug("[graphql] author_id не найден в auth_cred")
else:
logger.debug("[graphql] Данные авторизации НЕ найдены в scope")
logger.debug("[graphql] Подготовлен расширенный контекст для запроса")
return context