from collections.abc import Awaitable, Callable from typing import Any from maxapi.filters.middleware import BaseMiddleware from maxapi.types.updates.bot_started import BotStarted from maxapi.types.updates.message_created import MessageCreated from database.queries.bot_users import get_bot_user_by_max_id from database.queries.message_log import log_message class AuthMiddleware(BaseMiddleware): """ Проверяет авторизацию пользователя перед передачей события в обработчик. Пропускает без проверки: - BotStarted (первый запуск) - Сообщение с командой /start Для остальных событий: - Блокированные или незарегистрированные → игнорируем - Авторизованные → добавляем bot_user в data и логируем сообщение """ async def __call__( self, handler: Callable[[Any, dict[str, Any]], Awaitable[Any]], event: Any, data: dict[str, Any], ) -> Any: # Пропускаем bot_started — он обрабатывается без авторизации if isinstance(event, BotStarted): return await handler(event, data) # Пропускаем команду /start if isinstance(event, MessageCreated): body = event.message.body text = (body.text or "").strip() if body else "" if text.lower().startswith("/start"): return await handler(event, data) # Получаем user_id из события ids = event.get_ids() user_id = ids[1] if ids else None if user_id is None: return bot_user = await get_bot_user_by_max_id(user_id) if bot_user is None: # Незнакомый пользователь — игнорируем return if bot_user["is_blocked"]: return if not bot_user["is_authorized"]: # Ещё не авторизовался — игнорируем (повторный промпт не нужен) return data["bot_user"] = bot_user # Логируем входящее сообщение if isinstance(event, MessageCreated): chat_id, _ = event.get_ids() body = event.message.body atts = [] if body and body.attachments: for a in body.attachments: atts.append({"type": str(getattr(a, "type", ""))}) await log_message( direction="in", max_user_id=user_id, max_chat_id=chat_id, message_id=event.message.body.mid if body else None, text=body.text if body else None, attachments=atts or None, ) return await handler(event, data)