Files
Solo_bot/handlers/captcha.py
T
Zakhar Izmaylov 83870a2022 Refactor and improve security with cryptographically secure random generation
- Replace `random` module with `secrets` for cryptographically secure random choices
- Update type hints for async API methods in client.py
- Optimize file reading with aiofiles in multiple handlers
- Improve error handling and logging in various modules
- Update Python target version to 3.12 in pyproject.toml
- Remove unused imports and improve code quality
2025-01-30 22:35:09 +03:00

71 lines
2.8 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.
import random
import secrets
from typing import Any
from aiogram import F, Router
from aiogram.fsm.context import FSMContext
from aiogram.types import CallbackQuery, Message
from aiogram.utils.keyboard import InlineKeyboardBuilder
from config import CAPTCHA_EMOJIS
from logger import logger
router = Router()
async def generate_captcha(message: Message, state: FSMContext):
"""Генерирует новую капчу и сохраняет правильный ответ в состоянии
Пример словаря CAPTCHA_EMOJIS:
{
"🐶": "собаку", # Собака
"🐱": "кошку", # Кошка
"🐭": "мышь", # Мышь
"🐹": "хомяка", # Хомяк
"🐰": "кролика", # Кролик
...
}
"""
# Выбираем случайный эмодзи и его описание из конфига
correct_emoji, correct_text = secrets.choice(list(CAPTCHA_EMOJIS.items()))
# Получаем 3 случайных неправильных эмодзи
wrong_emojis = random.sample([e for e in CAPTCHA_EMOJIS.keys() if e != correct_emoji], 3)
# Создаем список всех эмодзи и перемешиваем их
all_emojis = [correct_emoji] + wrong_emojis
random.shuffle(all_emojis)
# Сохраняем правильный ответ в состоянии
await state.update_data(correct_emoji=correct_emoji)
await state.update_data(message=message)
# Создаем клавиатуру
builder = InlineKeyboardBuilder()
for emoji in all_emojis:
builder.button(text=emoji, callback_data=f"captcha_{emoji}")
builder.adjust(2, 2)
return {
"text": f"🔒 Для подтверждения что вы не робот,\nвыберите кнопку с {correct_text}",
"markup": builder.as_markup(),
}
@router.callback_query(F.data.startswith("captcha_"))
async def check_captcha(callback: CallbackQuery, state: FSMContext, session: Any, admin: bool):
from handlers.start import start_command
selected_emoji = callback.data.split("captcha_")[1]
state_data = await state.get_data()
correct_emoji = state_data.get("correct_emoji")
message = state_data.get("message", callback.message)
if selected_emoji == correct_emoji:
logger.info(f"Пользователь {callback.message.chat.id} успешно прошел капчу")
await start_command(message, state, session, admin, False)
else:
logger.warning(f"Пользователь {callback.message.chat.id} неверно ответил на капчу")
captcha = await generate_captcha(message, state)
await callback.message.answer(text=captcha["text"], reply_markup=captcha["markup"])