81 lines
3.1 KiB
Python
81 lines
3.1 KiB
Python
from typing import Callable, Dict, Any, Awaitable
|
|
from aiogram import BaseMiddleware
|
|
from aiogram.types import Message, CallbackQuery
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select
|
|
from database.connection import async_session_maker
|
|
from database.models import User
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class AuthMiddleware(BaseMiddleware):
|
|
"""
|
|
Middleware для проверки авторизации пользователя.
|
|
Пропускает команду /start и проверяет наличие telegram_id в БД для остальных запросов.
|
|
"""
|
|
|
|
async def __call__(
|
|
self,
|
|
handler: Callable[[Message | CallbackQuery, Dict[str, Any]], Awaitable[Any]],
|
|
event: Message | CallbackQuery,
|
|
data: Dict[str, Any]
|
|
) -> Any:
|
|
# Пропускаем команду /start
|
|
if isinstance(event, Message) and event.text and event.text.startswith('/start'):
|
|
return await handler(event, data)
|
|
|
|
# Пропускаем callback'и регистрации и входа
|
|
if isinstance(event, CallbackQuery) and event.data:
|
|
if event.data in ['login', 'register', 'main_menu']:
|
|
return await handler(event, data)
|
|
|
|
# Проверяем авторизацию
|
|
telegram_id = event.from_user.id
|
|
|
|
try:
|
|
async with async_session_maker() as session:
|
|
result = await session.execute(
|
|
select(User).where(User.telegram_id == telegram_id)
|
|
)
|
|
user = result.scalar_one_or_none()
|
|
|
|
if not user:
|
|
if isinstance(event, CallbackQuery):
|
|
await event.answer("⛔ Сначала авторизуйтесь через /start", show_alert=True)
|
|
else:
|
|
await event.answer("⛔ Сначала авторизуйтесь через /start")
|
|
return
|
|
|
|
# Добавляем пользователя в данные
|
|
data['user'] = user
|
|
data['session'] = session
|
|
|
|
except Exception as e:
|
|
logger.error(f"Ошибка в AuthMiddleware: {e}")
|
|
if isinstance(event, CallbackQuery):
|
|
await event.answer("❌ Ошибка проверки авторизации", show_alert=True)
|
|
else:
|
|
await event.answer("❌ Ошибка проверки авторизации")
|
|
return
|
|
|
|
return await handler(event, data)
|
|
|
|
|
|
class DatabaseMiddleware(BaseMiddleware):
|
|
"""
|
|
Middleware для предоставления сессии БД в обработчики.
|
|
"""
|
|
|
|
async def __call__(
|
|
self,
|
|
handler: Callable[[Message | CallbackQuery, Dict[str, Any]], Awaitable[Any]],
|
|
event: Message | CallbackQuery,
|
|
data: Dict[str, Any]
|
|
) -> Any:
|
|
async with async_session_maker() as session:
|
|
data['session'] = session
|
|
return await handler(event, data)
|
|
|