""" Middleware для валидации входных данных """ from typing import Any, Dict, Callable, Awaitable from aiogram import BaseMiddleware from aiogram.types import TelegramObject, CallbackQuery, Message from services.infrastructure.logger import get_logger from services.validation import InputValidator from services.infrastructure.logging_decorators import log_middleware from services.infrastructure.logging_utils import log_user_action logger = get_logger(__name__) class ValidationMiddleware(BaseMiddleware): """Middleware для валидации входных данных""" def __init__(self, validator: InputValidator): super().__init__() self.validator = validator logger.info("🔍 ValidationMiddleware инициализирован") @log_middleware(log_params=True, log_result=False) async def __call__( self, handler: Callable[[TelegramObject, Dict[str, Any]], Awaitable[Any]], event: TelegramObject, data: Dict[str, Any] ) -> Any: """Валидация входных данных перед обработкой""" try: # Валидация callback queries if isinstance(event, CallbackQuery): await self._validate_callback_query(event, data) # Валидация сообщений elif isinstance(event, Message): await self._validate_message(event, data) # Продолжаем обработку return await handler(event, data) except ValidationError as e: logger.warning(f"⚠️ Ошибка валидации: {e}") await self._handle_validation_error(event, str(e)) return @log_middleware(log_params=True, log_result=False) async def _validate_callback_query(self, callback: CallbackQuery, data: Dict[str, Any]) -> None: """Валидация callback query""" try: # Валидируем callback data validation_result = self.validator.validate_callback_data(callback.data) if not validation_result: logger.warning(f"⚠️ Невалидный callback data от пользователя {callback.from_user.id}: {callback.data}") await callback.answer("❌ Неверные данные", show_alert=True) raise ValidationError(f"Invalid callback data: {validation_result.error_message}") # Валидируем Telegram ID пользователя user_id_validation = self.validator.validate_telegram_id(callback.from_user.id) if not user_id_validation: logger.warning(f"⚠️ Невалидный Telegram ID в callback: {callback.from_user.id}") await callback.answer("❌ Ошибка: недопустимый ID пользователя", show_alert=True) raise ValidationError(f"Invalid Telegram ID: {user_id_validation.error_message}") # Валидируем username если есть if callback.from_user.username: username_validation = self.validator.validate_username(callback.from_user.username) if not username_validation: logger.warning(f"⚠️ Невалидный username в callback: {callback.from_user.username}") # Username не критичен, только логируем logger.debug(f"✅ Callback query от пользователя {callback.from_user.id} прошел валидацию") except Exception as e: if not isinstance(e, ValidationError): logger.error(f"❌ Ошибка валидации callback query: {e}") await callback.answer("❌ Ошибка валидации", show_alert=True) raise ValidationError(f"Callback validation error: {str(e)}") raise @log_middleware(log_params=True, log_result=False) async def _validate_message(self, message: Message, data: Dict[str, Any]) -> None: """Валидация сообщения""" try: # Валидируем Telegram ID пользователя user_id_validation = self.validator.validate_telegram_id(message.from_user.id) if not user_id_validation: logger.warning(f"⚠️ Невалидный Telegram ID в сообщении: {message.from_user.id}") await message.answer("❌ Ошибка: недопустимый ID пользователя") raise ValidationError(f"Invalid Telegram ID: {user_id_validation.error_message}") # Валидируем username если есть if message.from_user.username: username_validation = self.validator.validate_username(message.from_user.username) if not username_validation: logger.warning(f"⚠️ Невалидный username в сообщении: {message.from_user.username}") # Username не критичен, только логируем # Валидируем chat ID chat_id_validation = self.validator.validate_telegram_id(message.chat.id) if not chat_id_validation: logger.warning(f"⚠️ Невалидный chat ID в сообщении: {message.chat.id}") await message.answer("❌ Ошибка: недопустимый ID чата") raise ValidationError(f"Invalid chat ID: {chat_id_validation.error_message}") logger.debug(f"✅ Сообщение от пользователя {message.from_user.id} прошло валидацию") except Exception as e: if not isinstance(e, ValidationError): logger.error(f"❌ Ошибка валидации сообщения: {e}") await message.answer("❌ Ошибка валидации") raise ValidationError(f"Message validation error: {str(e)}") raise @log_middleware(log_params=True, log_result=False) async def _handle_validation_error(self, event: TelegramObject, error_message: str) -> None: """Обработка ошибок валидации""" try: if isinstance(event, CallbackQuery): await event.answer(f"❌ {error_message}", show_alert=True) elif isinstance(event, Message): await event.answer(f"❌ {error_message}") except Exception as e: logger.error(f"❌ Ошибка при отправке сообщения об ошибке валидации: {e}") class ValidationError(Exception): """Исключение для ошибок валидации""" pass