Files
AnonBot/middlewares/validation_middleware.py

134 lines
6.9 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.
"""
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