feat: Allow assigned admins to access admin panel via command and buttons
Some checks failed
continuous-integration/drone/pr Build is failing

- Modified check_admin_access() to check both super admins (.env) and assigned admins (DB)
- Updated /admin command handler to support both admin types
- Replaced all is_admin() checks with async check_admin_access() in admin panel
- Assigned admins can now use /admin command and navigate via buttons
- Super admin check (is_super_admin) remains unchanged for admin management
- Added proper async/await for database queries in all admin checks
This commit is contained in:
2026-02-18 13:28:29 +09:00
parent e1b4465f89
commit 6b24388faa
3 changed files with 146 additions and 107 deletions

1
.gitignore vendored
View File

@@ -60,3 +60,4 @@ venv.bak/
# Системные файлы # Системные файлы
.DS_Store .DS_Store
Thumbs.db.bot.pid Thumbs.db.bot.pid
*.bak

21
main.py
View File

@@ -192,7 +192,26 @@ async def btn_main_menu(message: Message):
async def cmd_admin(message: Message): async def cmd_admin(message: Message):
"""Обработчик команды /admin (регистронезависимо) - перенаправляет в admin_panel""" """Обработчик команды /admin (регистронезависимо) - перенаправляет в admin_panel"""
from src.core.config import ADMIN_IDS from src.core.config import ADMIN_IDS
if message.from_user.id not in ADMIN_IDS: from src.core.database import async_session_maker
from src.core.models import User
from sqlalchemy import select
# Проверяем, является ли пользователь главным администратором из .env
user_id = message.from_user.id
is_super_admin = user_id in ADMIN_IDS
# Проверяем, является ли пользователь назначенным администратором
is_assigned_admin = False
if not is_super_admin:
async with async_session_maker() as session:
user = await session.execute(
select(User).where(User.telegram_id == user_id)
)
user = user.scalar_one_or_none()
is_assigned_admin = user and user.is_admin
# Если не администратор ни того, ни другого типа
if not (is_super_admin or is_assigned_admin):
await message.answer("❌ Недостаточно прав для доступа к админ панели") await message.answer("❌ Недостаточно прав для доступа к админ панели")
return return

View File

@@ -109,7 +109,7 @@ admin_router = Router()
def is_admin(user_id: int) -> bool: def is_admin(user_id: int) -> bool:
"""Проверка прав администратора""" """Проверка прав администратора (быстрая проверка только .env)"""
return user_id in ADMIN_IDS return user_id in ADMIN_IDS
@@ -118,6 +118,25 @@ def is_super_admin(user_id: int) -> bool:
return user_id in ADMIN_IDS return user_id in ADMIN_IDS
async def check_admin_access(user_id: int) -> bool:
"""
Асинхронная проверка доступа администратора.
Проверяет как главных администраторов (.env), так и назначенных (БД)
"""
# Сначала проверяем главных администраторов
if user_id in ADMIN_IDS:
return True
# Затем проверяем назначенных администраторов в БД
async with async_session_maker() as session:
from sqlalchemy import select
result = await session.execute(
select(User).where(User.telegram_id == user_id, User.is_admin == True)
)
user = result.scalar_one_or_none()
return user is not None
def get_admin_main_keyboard() -> InlineKeyboardMarkup: def get_admin_main_keyboard() -> InlineKeyboardMarkup:
"""Главная админ-панель""" """Главная админ-панель"""
buttons = [ buttons = [
@@ -178,7 +197,7 @@ def get_winner_management_keyboard() -> InlineKeyboardMarkup:
@admin_router.callback_query(F.data == "admin_panel") @admin_router.callback_query(F.data == "admin_panel")
async def show_admin_panel(callback: CallbackQuery): async def show_admin_panel(callback: CallbackQuery):
"""Показать админ-панель""" """Показать админ-панель"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -213,7 +232,7 @@ async def show_admin_panel(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_lotteries") @admin_router.callback_query(F.data == "admin_lotteries")
async def show_lottery_management(callback: CallbackQuery): async def show_lottery_management(callback: CallbackQuery):
"""Управление розыгрышами""" """Управление розыгрышами"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -232,7 +251,7 @@ async def start_create_lottery(callback: CallbackQuery, state: FSMContext):
# Сразу отвечаем на callback # Сразу отвечаем на callback
await callback.answer() await callback.answer()
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
logging.warning(f"⚠️ Пользователь {callback.from_user.id} не является админом") logging.warning(f"⚠️ Пользователь {callback.from_user.id} не является админом")
await callback.message.answer("❌ Недостаточно прав") await callback.message.answer("❌ Недостаточно прав")
return return
@@ -260,7 +279,7 @@ async def start_create_lottery(callback: CallbackQuery, state: FSMContext):
@admin_router.message(StateFilter(AdminStates.lottery_title)) @admin_router.message(StateFilter(AdminStates.lottery_title))
async def process_lottery_title(message: Message, state: FSMContext): async def process_lottery_title(message: Message, state: FSMContext):
"""Обработка названия розыгрыша (создание или редактирование)""" """Обработка названия розыгрыша (создание или редактирование)"""
if not is_admin(message.from_user.id): if not await check_admin_access(message.from_user.id):
await message.answer("❌ Недостаточно прав") await message.answer("❌ Недостаточно прав")
return return
@@ -308,7 +327,7 @@ async def process_lottery_title(message: Message, state: FSMContext):
@admin_router.message(StateFilter(AdminStates.lottery_description)) @admin_router.message(StateFilter(AdminStates.lottery_description))
async def process_lottery_description(message: Message, state: FSMContext): async def process_lottery_description(message: Message, state: FSMContext):
"""Обработка описания розыгрыша (создание или редактирование)""" """Обработка описания розыгрыша (создание или редактирование)"""
if not is_admin(message.from_user.id): if not await check_admin_access(message.from_user.id):
await message.answer("❌ Недостаточно прав") await message.answer("❌ Недостаточно прав")
return return
@@ -366,7 +385,7 @@ async def process_lottery_description(message: Message, state: FSMContext):
@admin_router.message(StateFilter(AdminStates.lottery_prizes)) @admin_router.message(StateFilter(AdminStates.lottery_prizes))
async def process_lottery_prizes(message: Message, state: FSMContext): async def process_lottery_prizes(message: Message, state: FSMContext):
"""Обработка призов розыгрыша (создание или редактирование)""" """Обработка призов розыгрыша (создание или редактирование)"""
if not is_admin(message.from_user.id): if not await check_admin_access(message.from_user.id):
await message.answer("❌ Недостаточно прав") await message.answer("❌ Недостаточно прав")
return return
@@ -429,7 +448,7 @@ async def process_lottery_prizes(message: Message, state: FSMContext):
@admin_router.callback_query(F.data == "confirm_create_lottery", StateFilter(AdminStates.lottery_confirm)) @admin_router.callback_query(F.data == "confirm_create_lottery", StateFilter(AdminStates.lottery_confirm))
async def confirm_create_lottery(callback: CallbackQuery, state: FSMContext): async def confirm_create_lottery(callback: CallbackQuery, state: FSMContext):
"""Подтверждение создания розыгрыша""" """Подтверждение создания розыгрыша"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -472,7 +491,7 @@ async def confirm_create_lottery(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data == "admin_list_all_lotteries") @admin_router.callback_query(F.data == "admin_list_all_lotteries")
async def list_all_lotteries(callback: CallbackQuery): async def list_all_lotteries(callback: CallbackQuery):
"""Список всех розыгрышей""" """Список всех розыгрышей"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -522,7 +541,7 @@ async def list_all_lotteries(callback: CallbackQuery):
@admin_router.callback_query(F.data.startswith("admin_lottery_detail_")) @admin_router.callback_query(F.data.startswith("admin_lottery_detail_"))
async def show_lottery_detail(callback: CallbackQuery): async def show_lottery_detail(callback: CallbackQuery):
"""Детальная информация о розыгрыше""" """Детальная информация о розыгрыше"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -604,7 +623,7 @@ async def show_lottery_detail(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_participants") @admin_router.callback_query(F.data == "admin_participants")
async def show_participant_management(callback: CallbackQuery): async def show_participant_management(callback: CallbackQuery):
"""Управление участниками""" """Управление участниками"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -618,7 +637,7 @@ async def show_participant_management(callback: CallbackQuery):
@admin_router.callback_query(F.data.startswith("admin_participants_")) @admin_router.callback_query(F.data.startswith("admin_participants_"))
async def show_lottery_participants(callback: CallbackQuery): async def show_lottery_participants(callback: CallbackQuery):
"""Показать участников конкретного розыгрыша""" """Показать участников конкретного розыгрыша"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -670,7 +689,7 @@ async def show_lottery_participants(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_bulk_operations") @admin_router.callback_query(F.data == "admin_bulk_operations")
async def show_bulk_operations_menu(callback: CallbackQuery): async def show_bulk_operations_menu(callback: CallbackQuery):
"""Подменю массовых операций""" """Подменю массовых операций"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -697,7 +716,7 @@ async def show_bulk_operations_menu(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_add_participant") @admin_router.callback_query(F.data == "admin_add_participant")
async def start_add_participant(callback: CallbackQuery, state: FSMContext): async def start_add_participant(callback: CallbackQuery, state: FSMContext):
"""Начать добавление участника""" """Начать добавление участника"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -735,7 +754,7 @@ async def start_add_participant(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data.startswith("admin_add_part_to_")) @admin_router.callback_query(F.data.startswith("admin_add_part_to_"))
async def choose_user_to_add(callback: CallbackQuery, state: FSMContext): async def choose_user_to_add(callback: CallbackQuery, state: FSMContext):
"""Выбор пользователя для добавления""" """Выбор пользователя для добавления"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -763,7 +782,7 @@ async def choose_user_to_add(callback: CallbackQuery, state: FSMContext):
@admin_router.message(StateFilter(AdminStates.add_participant_user)) @admin_router.message(StateFilter(AdminStates.add_participant_user))
async def process_add_participant(message: Message, state: FSMContext): async def process_add_participant(message: Message, state: FSMContext):
"""Обработка добавления участника""" """Обработка добавления участника"""
if not is_admin(message.from_user.id): if not await check_admin_access(message.from_user.id):
await message.answer("❌ Недостаточно прав") await message.answer("❌ Недостаточно прав")
return return
@@ -818,7 +837,7 @@ async def process_add_participant(message: Message, state: FSMContext):
@admin_router.callback_query(F.data == "admin_remove_participant") @admin_router.callback_query(F.data == "admin_remove_participant")
async def remove_participant_start(callback: CallbackQuery): async def remove_participant_start(callback: CallbackQuery):
"""Начало процесса удаления участника""" """Начало процесса удаления участника"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -853,7 +872,7 @@ async def remove_participant_start(callback: CallbackQuery):
@admin_router.callback_query(F.data.startswith("admin_remove_part_from_")) @admin_router.callback_query(F.data.startswith("admin_remove_part_from_"))
async def remove_participant_select_lottery(callback: CallbackQuery, state: FSMContext): async def remove_participant_select_lottery(callback: CallbackQuery, state: FSMContext):
"""Выбор розыгрыша для удаления участника""" """Выбор розыгрыша для удаления участника"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -884,7 +903,7 @@ async def remove_participant_select_lottery(callback: CallbackQuery, state: FSMC
@admin_router.message(StateFilter(AdminStates.remove_participant_user)) @admin_router.message(StateFilter(AdminStates.remove_participant_user))
async def process_remove_participant(message: Message, state: FSMContext): async def process_remove_participant(message: Message, state: FSMContext):
"""Обработка удаления участника""" """Обработка удаления участника"""
if not is_admin(message.from_user.id): if not await check_admin_access(message.from_user.id):
await message.answer("❌ Недостаточно прав") await message.answer("❌ Недостаточно прав")
return return
@@ -949,7 +968,7 @@ async def process_remove_participant(message: Message, state: FSMContext):
@admin_router.callback_query(F.data == "admin_list_all_participants") @admin_router.callback_query(F.data == "admin_list_all_participants")
async def list_all_participants(callback: CallbackQuery): async def list_all_participants(callback: CallbackQuery):
"""Список всех участников""" """Список всех участников"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -998,7 +1017,7 @@ async def list_all_participants(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_participants_report") @admin_router.callback_query(F.data == "admin_participants_report")
async def generate_participants_report(callback: CallbackQuery): async def generate_participants_report(callback: CallbackQuery):
"""Генерация отчета по участникам""" """Генерация отчета по участникам"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -1083,7 +1102,7 @@ async def generate_participants_report(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_export_participants") @admin_router.callback_query(F.data == "admin_export_participants")
async def export_participants_data(callback: CallbackQuery): async def export_participants_data(callback: CallbackQuery):
"""Экспорт данных участников""" """Экспорт данных участников"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -1136,7 +1155,7 @@ async def export_participants_data(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_search_participants") @admin_router.callback_query(F.data == "admin_search_participants")
async def start_search_participants(callback: CallbackQuery, state: FSMContext): async def start_search_participants(callback: CallbackQuery, state: FSMContext):
"""Начать поиск участников""" """Начать поиск участников"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -1159,7 +1178,7 @@ async def start_search_participants(callback: CallbackQuery, state: FSMContext):
@admin_router.message(StateFilter(AdminStates.participant_search)) @admin_router.message(StateFilter(AdminStates.participant_search))
async def process_search_participants(message: Message, state: FSMContext): async def process_search_participants(message: Message, state: FSMContext):
"""Обработка поиска участников""" """Обработка поиска участников"""
if not is_admin(message.from_user.id): if not await check_admin_access(message.from_user.id):
await message.answer("❌ Недостаточно прав") await message.answer("❌ Недостаточно прав")
return return
@@ -1210,7 +1229,7 @@ async def process_search_participants(message: Message, state: FSMContext):
@admin_router.callback_query(F.data == "admin_bulk_add_participant") @admin_router.callback_query(F.data == "admin_bulk_add_participant")
async def start_bulk_add_participant(callback: CallbackQuery, state: FSMContext): async def start_bulk_add_participant(callback: CallbackQuery, state: FSMContext):
"""Начать массовое добавление участников""" """Начать массовое добавление участников"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -1248,7 +1267,7 @@ async def start_bulk_add_participant(callback: CallbackQuery, state: FSMContext)
@admin_router.callback_query(F.data.startswith("admin_bulk_add_to_")) @admin_router.callback_query(F.data.startswith("admin_bulk_add_to_"))
async def choose_users_bulk_add(callback: CallbackQuery, state: FSMContext): async def choose_users_bulk_add(callback: CallbackQuery, state: FSMContext):
"""Выбор пользователей для массового добавления""" """Выбор пользователей для массового добавления"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -1277,7 +1296,7 @@ async def choose_users_bulk_add(callback: CallbackQuery, state: FSMContext):
@admin_router.message(StateFilter(AdminStates.add_participant_bulk)) @admin_router.message(StateFilter(AdminStates.add_participant_bulk))
async def process_bulk_add_participant(message: Message, state: FSMContext): async def process_bulk_add_participant(message: Message, state: FSMContext):
"""Обработка массового добавления участников""" """Обработка массового добавления участников"""
if not is_admin(message.from_user.id): if not await check_admin_access(message.from_user.id):
await message.answer("❌ Недостаточно прав") await message.answer("❌ Недостаточно прав")
return return
@@ -1331,7 +1350,7 @@ async def process_bulk_add_participant(message: Message, state: FSMContext):
@admin_router.callback_query(F.data == "admin_bulk_remove_participant") @admin_router.callback_query(F.data == "admin_bulk_remove_participant")
async def start_bulk_remove_participant(callback: CallbackQuery, state: FSMContext): async def start_bulk_remove_participant(callback: CallbackQuery, state: FSMContext):
"""Начать массовое удаление участников""" """Начать массовое удаление участников"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -1379,7 +1398,7 @@ async def start_bulk_remove_participant(callback: CallbackQuery, state: FSMConte
@admin_router.callback_query(F.data.startswith("admin_bulk_remove_from_")) @admin_router.callback_query(F.data.startswith("admin_bulk_remove_from_"))
async def choose_users_bulk_remove(callback: CallbackQuery, state: FSMContext): async def choose_users_bulk_remove(callback: CallbackQuery, state: FSMContext):
"""Выбор пользователей для массового удаления""" """Выбор пользователей для массового удаления"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -1408,7 +1427,7 @@ async def choose_users_bulk_remove(callback: CallbackQuery, state: FSMContext):
@admin_router.message(StateFilter(AdminStates.remove_participant_bulk)) @admin_router.message(StateFilter(AdminStates.remove_participant_bulk))
async def process_bulk_remove_participant(message: Message, state: FSMContext): async def process_bulk_remove_participant(message: Message, state: FSMContext):
"""Обработка массового удаления участников""" """Обработка массового удаления участников"""
if not is_admin(message.from_user.id): if not await check_admin_access(message.from_user.id):
await message.answer("❌ Недостаточно прав") await message.answer("❌ Недостаточно прав")
return return
@@ -1466,7 +1485,7 @@ async def process_bulk_remove_participant(message: Message, state: FSMContext):
@admin_router.callback_query(F.data == "admin_bulk_add_accounts") @admin_router.callback_query(F.data == "admin_bulk_add_accounts")
async def start_bulk_add_accounts(callback: CallbackQuery, state: FSMContext): async def start_bulk_add_accounts(callback: CallbackQuery, state: FSMContext):
"""Начать массовое добавление участников по номерам счетов""" """Начать массовое добавление участников по номерам счетов"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -1504,7 +1523,7 @@ async def start_bulk_add_accounts(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data.startswith("admin_bulk_add_accounts_to_")) @admin_router.callback_query(F.data.startswith("admin_bulk_add_accounts_to_"))
async def choose_accounts_bulk_add(callback: CallbackQuery, state: FSMContext): async def choose_accounts_bulk_add(callback: CallbackQuery, state: FSMContext):
"""Выбор номеров счетов для массового добавления""" """Выбор номеров счетов для массового добавления"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -1535,7 +1554,7 @@ async def choose_accounts_bulk_add(callback: CallbackQuery, state: FSMContext):
@admin_router.message(StateFilter(AdminStates.add_participant_bulk_accounts)) @admin_router.message(StateFilter(AdminStates.add_participant_bulk_accounts))
async def process_bulk_add_accounts(message: Message, state: FSMContext): async def process_bulk_add_accounts(message: Message, state: FSMContext):
"""Обработка массового добавления участников по номерам счетов""" """Обработка массового добавления участников по номерам счетов"""
if not is_admin(message.from_user.id): if not await check_admin_access(message.from_user.id):
await message.answer("❌ Недостаточно прав") await message.answer("❌ Недостаточно прав")
return return
@@ -1592,7 +1611,7 @@ async def process_bulk_add_accounts(message: Message, state: FSMContext):
@admin_router.callback_query(F.data == "admin_bulk_remove_accounts") @admin_router.callback_query(F.data == "admin_bulk_remove_accounts")
async def start_bulk_remove_accounts(callback: CallbackQuery, state: FSMContext): async def start_bulk_remove_accounts(callback: CallbackQuery, state: FSMContext):
"""Начать массовое удаление участников по номерам счетов""" """Начать массовое удаление участников по номерам счетов"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -1630,7 +1649,7 @@ async def start_bulk_remove_accounts(callback: CallbackQuery, state: FSMContext)
@admin_router.callback_query(F.data.startswith("admin_bulk_remove_accounts_from_")) @admin_router.callback_query(F.data.startswith("admin_bulk_remove_accounts_from_"))
async def choose_accounts_bulk_remove(callback: CallbackQuery, state: FSMContext): async def choose_accounts_bulk_remove(callback: CallbackQuery, state: FSMContext):
"""Выбор номеров счетов для массового удаления""" """Выбор номеров счетов для массового удаления"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -1660,7 +1679,7 @@ async def choose_accounts_bulk_remove(callback: CallbackQuery, state: FSMContext
@admin_router.message(StateFilter(AdminStates.remove_participant_bulk_accounts)) @admin_router.message(StateFilter(AdminStates.remove_participant_bulk_accounts))
async def process_bulk_remove_accounts(message: Message, state: FSMContext): async def process_bulk_remove_accounts(message: Message, state: FSMContext):
"""Обработка массового удаления участников по номерам счетов""" """Обработка массового удаления участников по номерам счетов"""
if not is_admin(message.from_user.id): if not await check_admin_access(message.from_user.id):
await message.answer("❌ Недостаточно прав") await message.answer("❌ Недостаточно прав")
return return
@@ -1721,7 +1740,7 @@ async def process_bulk_remove_accounts(message: Message, state: FSMContext):
@admin_router.callback_query(F.data == "admin_participants_by_lottery") @admin_router.callback_query(F.data == "admin_participants_by_lottery")
async def show_participants_by_lottery(callback: CallbackQuery): async def show_participants_by_lottery(callback: CallbackQuery):
"""Показать участников по розыгрышам""" """Показать участников по розыгрышам"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -1765,7 +1784,7 @@ async def show_participants_by_lottery(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_participants_report") @admin_router.callback_query(F.data == "admin_participants_report")
async def show_participants_report(callback: CallbackQuery): async def show_participants_report(callback: CallbackQuery):
"""Отчет по участникам""" """Отчет по участникам"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -1832,7 +1851,7 @@ async def show_participants_report(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_edit_lottery") @admin_router.callback_query(F.data == "admin_edit_lottery")
async def start_edit_lottery(callback: CallbackQuery, state: FSMContext): async def start_edit_lottery(callback: CallbackQuery, state: FSMContext):
"""Начать редактирование розыгрыша""" """Начать редактирование розыгрыша"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -1869,7 +1888,7 @@ async def start_edit_lottery(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data.startswith("admin_edit_field_")) @admin_router.callback_query(F.data.startswith("admin_edit_field_"))
async def handle_edit_field(callback: CallbackQuery, state: FSMContext): async def handle_edit_field(callback: CallbackQuery, state: FSMContext):
"""Обработка выбора поля для редактирования""" """Обработка выбора поля для редактирования"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -1910,7 +1929,7 @@ async def handle_edit_field(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data.startswith("admin_edit_")) @admin_router.callback_query(F.data.startswith("admin_edit_"))
async def redirect_to_edit_lottery(callback: CallbackQuery, state: FSMContext): async def redirect_to_edit_lottery(callback: CallbackQuery, state: FSMContext):
"""Редирект на редактирование розыгрыша из детального просмотра""" """Редирект на редактирование розыгрыша из детального просмотра"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -1931,7 +1950,7 @@ async def redirect_to_edit_lottery(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data.startswith("admin_edit_lottery_select_")) @admin_router.callback_query(F.data.startswith("admin_edit_lottery_select_"))
async def choose_edit_field(callback: CallbackQuery, state: FSMContext): async def choose_edit_field(callback: CallbackQuery, state: FSMContext):
"""Выбор поля для редактирования""" """Выбор поля для редактирования"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -1967,7 +1986,7 @@ async def choose_edit_field(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data.startswith("admin_toggle_active_")) @admin_router.callback_query(F.data.startswith("admin_toggle_active_"))
async def toggle_lottery_active(callback: CallbackQuery, state: FSMContext): async def toggle_lottery_active(callback: CallbackQuery, state: FSMContext):
"""Переключить активность розыгрыша""" """Переключить активность розыгрыша"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -1993,7 +2012,7 @@ async def toggle_lottery_active(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data == "admin_finish_lottery") @admin_router.callback_query(F.data == "admin_finish_lottery")
async def start_finish_lottery(callback: CallbackQuery): async def start_finish_lottery(callback: CallbackQuery):
"""Завершить розыгрыш""" """Завершить розыгрыш"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2031,7 +2050,7 @@ async def start_finish_lottery(callback: CallbackQuery):
@admin_router.callback_query(F.data.startswith("admin_confirm_finish_")) @admin_router.callback_query(F.data.startswith("admin_confirm_finish_"))
async def confirm_finish_lottery(callback: CallbackQuery): async def confirm_finish_lottery(callback: CallbackQuery):
"""Подтвердить завершение розыгрыша""" """Подтвердить завершение розыгрыша"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2060,7 +2079,7 @@ async def confirm_finish_lottery(callback: CallbackQuery):
@admin_router.callback_query(F.data.startswith("admin_do_finish_")) @admin_router.callback_query(F.data.startswith("admin_do_finish_"))
async def do_finish_lottery(callback: CallbackQuery): async def do_finish_lottery(callback: CallbackQuery):
"""Выполнить завершение розыгрыша""" """Выполнить завершение розыгрыша"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2091,7 +2110,7 @@ async def do_finish_lottery(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_delete_lottery") @admin_router.callback_query(F.data == "admin_delete_lottery")
async def start_delete_lottery(callback: CallbackQuery): async def start_delete_lottery(callback: CallbackQuery):
"""Удаление розыгрыша""" """Удаление розыгрыша"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2131,7 +2150,7 @@ async def start_delete_lottery(callback: CallbackQuery):
@admin_router.callback_query(F.data.startswith("admin_confirm_delete_")) @admin_router.callback_query(F.data.startswith("admin_confirm_delete_"))
async def confirm_delete_lottery(callback: CallbackQuery): async def confirm_delete_lottery(callback: CallbackQuery):
"""Подтвердить удаление розыгрыша""" """Подтвердить удаление розыгрыша"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2163,7 +2182,7 @@ async def confirm_delete_lottery(callback: CallbackQuery):
@admin_router.callback_query(F.data.startswith("admin_do_delete_")) @admin_router.callback_query(F.data.startswith("admin_do_delete_"))
async def do_delete_lottery(callback: CallbackQuery): async def do_delete_lottery(callback: CallbackQuery):
"""Выполнить удаление розыгрыша""" """Выполнить удаление розыгрыша"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2200,7 +2219,7 @@ async def do_delete_lottery(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_winners") @admin_router.callback_query(F.data == "admin_winners")
async def show_winner_management(callback: CallbackQuery): async def show_winner_management(callback: CallbackQuery):
"""Управление победителями""" """Управление победителями"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2214,7 +2233,7 @@ async def show_winner_management(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_set_manual_winner") @admin_router.callback_query(F.data == "admin_set_manual_winner")
async def start_set_manual_winner(callback: CallbackQuery, state: FSMContext): async def start_set_manual_winner(callback: CallbackQuery, state: FSMContext):
"""Начать установку ручного победителя""" """Начать установку ручного победителя"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2258,7 +2277,7 @@ async def start_set_manual_winner(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data.startswith("admin_set_winner_")) @admin_router.callback_query(F.data.startswith("admin_set_winner_"))
async def handle_set_winner_from_lottery(callback: CallbackQuery, state: FSMContext): async def handle_set_winner_from_lottery(callback: CallbackQuery, state: FSMContext):
"""Обработчик для кнопки 'Установить победителя' из карточки розыгрыша""" """Обработчик для кнопки 'Установить победителя' из карточки розыгрыша"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2272,7 +2291,7 @@ async def handle_set_winner_from_lottery(callback: CallbackQuery, state: FSMCont
@admin_router.callback_query(F.data.startswith("admin_choose_winner_lottery_")) @admin_router.callback_query(F.data.startswith("admin_choose_winner_lottery_"))
async def choose_winner_place(callback: CallbackQuery, state: FSMContext): async def choose_winner_place(callback: CallbackQuery, state: FSMContext):
"""Выбор места для победителя""" """Выбор места для победителя"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2309,7 +2328,7 @@ async def choose_winner_place(callback: CallbackQuery, state: FSMContext):
@admin_router.message(StateFilter(AdminStates.set_winner_place)) @admin_router.message(StateFilter(AdminStates.set_winner_place))
async def process_winner_place(message: Message, state: FSMContext): async def process_winner_place(message: Message, state: FSMContext):
"""Обработка места победителя""" """Обработка места победителя"""
if not is_admin(message.from_user.id): if not await check_admin_access(message.from_user.id):
await message.answer("❌ Недостаточно прав") await message.answer("❌ Недостаточно прав")
return return
@@ -2357,7 +2376,7 @@ async def process_winner_place(message: Message, state: FSMContext):
@admin_router.message(StateFilter(AdminStates.set_winner_user)) @admin_router.message(StateFilter(AdminStates.set_winner_user))
async def process_winner_user(message: Message, state: FSMContext): async def process_winner_user(message: Message, state: FSMContext):
"""Обработка пользователя-победителя (по ID, username или номеру счета)""" """Обработка пользователя-победителя (по ID, username или номеру счета)"""
if not is_admin(message.from_user.id): if not await check_admin_access(message.from_user.id):
await message.answer("❌ Недостаточно прав") await message.answer("❌ Недостаточно прав")
return return
@@ -2457,7 +2476,7 @@ async def process_winner_user(message: Message, state: FSMContext):
@admin_router.callback_query(F.data == "admin_list_winners") @admin_router.callback_query(F.data == "admin_list_winners")
async def list_all_winners(callback: CallbackQuery): async def list_all_winners(callback: CallbackQuery):
"""Список всех победителей""" """Список всех победителей"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2524,7 +2543,7 @@ async def list_all_winners(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_edit_winner") @admin_router.callback_query(F.data == "admin_edit_winner")
async def edit_winner_start(callback: CallbackQuery): async def edit_winner_start(callback: CallbackQuery):
"""Начало редактирования победителя""" """Начало редактирования победителя"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2570,7 +2589,7 @@ async def edit_winner_start(callback: CallbackQuery):
@admin_router.callback_query(F.data.startswith("admin_edit_winner_lottery_")) @admin_router.callback_query(F.data.startswith("admin_edit_winner_lottery_"))
async def edit_winner_select_place(callback: CallbackQuery, state: FSMContext): async def edit_winner_select_place(callback: CallbackQuery, state: FSMContext):
"""Выбор места победителя для редактирования""" """Выбор места победителя для редактирования"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2604,7 +2623,7 @@ async def edit_winner_select_place(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data.startswith("admin_edit_winner_id_")) @admin_router.callback_query(F.data.startswith("admin_edit_winner_id_"))
async def edit_winner_details(callback: CallbackQuery): async def edit_winner_details(callback: CallbackQuery):
"""Показать детали победителя (пока просто информационное сообщение)""" """Показать детали победителя (пока просто информационное сообщение)"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2647,7 +2666,7 @@ async def edit_winner_details(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_remove_winner") @admin_router.callback_query(F.data == "admin_remove_winner")
async def remove_winner_start(callback: CallbackQuery): async def remove_winner_start(callback: CallbackQuery):
"""Начало удаления победителя""" """Начало удаления победителя"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2693,7 +2712,7 @@ async def remove_winner_start(callback: CallbackQuery):
@admin_router.callback_query(F.data.startswith("admin_remove_winner_lottery_")) @admin_router.callback_query(F.data.startswith("admin_remove_winner_lottery_"))
async def remove_winner_select_place(callback: CallbackQuery): async def remove_winner_select_place(callback: CallbackQuery):
"""Выбор победителя для удаления""" """Выбор победителя для удаления"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2727,7 +2746,7 @@ async def remove_winner_select_place(callback: CallbackQuery):
@admin_router.callback_query(F.data.startswith("admin_confirm_remove_winner_")) @admin_router.callback_query(F.data.startswith("admin_confirm_remove_winner_"))
async def confirm_remove_winner(callback: CallbackQuery): async def confirm_remove_winner(callback: CallbackQuery):
"""Подтверждение удаления победителя""" """Подтверждение удаления победителя"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2769,7 +2788,7 @@ async def confirm_remove_winner(callback: CallbackQuery):
@admin_router.callback_query(F.data.startswith("admin_do_remove_winner_")) @admin_router.callback_query(F.data.startswith("admin_do_remove_winner_"))
async def do_remove_winner(callback: CallbackQuery): async def do_remove_winner(callback: CallbackQuery):
"""Выполнение удаления победителя""" """Выполнение удаления победителя"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2815,7 +2834,7 @@ async def do_remove_winner(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_conduct_draw") @admin_router.callback_query(F.data == "admin_conduct_draw")
async def choose_lottery_for_draw(callback: CallbackQuery): async def choose_lottery_for_draw(callback: CallbackQuery):
"""Выбор розыгрыша для проведения""" """Выбор розыгрыша для проведения"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2854,7 +2873,7 @@ async def choose_lottery_for_draw(callback: CallbackQuery):
@admin_router.callback_query(F.data.regexp(r"^admin_conduct_\d+$")) @admin_router.callback_query(F.data.regexp(r"^admin_conduct_\d+$"))
async def conduct_lottery_draw_confirm(callback: CallbackQuery): async def conduct_lottery_draw_confirm(callback: CallbackQuery):
"""Запрос подтверждения проведения розыгрыша""" """Запрос подтверждения проведения розыгрыша"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -2912,7 +2931,7 @@ async def conduct_lottery_draw(callback: CallbackQuery):
logger.info(f"🎯 conduct_lottery_draw HANDLER TRIGGERED! data={callback.data}, user={callback.from_user.id}") logger.info(f"🎯 conduct_lottery_draw HANDLER TRIGGERED! data={callback.data}, user={callback.from_user.id}")
logger.info(f"conduct_lottery_draw вызван: callback.data={callback.data}, user_id={callback.from_user.id}") logger.info(f"conduct_lottery_draw вызван: callback.data={callback.data}, user_id={callback.from_user.id}")
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -3004,7 +3023,7 @@ async def conduct_lottery_draw(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_stats") @admin_router.callback_query(F.data == "admin_stats")
async def show_detailed_stats(callback: CallbackQuery): async def show_detailed_stats(callback: CallbackQuery):
"""Подробная статистика""" """Подробная статистика"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -3080,7 +3099,7 @@ async def show_detailed_stats(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_settings") @admin_router.callback_query(F.data == "admin_settings")
async def show_admin_settings(callback: CallbackQuery): async def show_admin_settings(callback: CallbackQuery):
"""Настройки админ-панели""" """Настройки админ-панели"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -3112,7 +3131,7 @@ async def show_admin_settings(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_export_data") @admin_router.callback_query(F.data == "admin_export_data")
async def export_data(callback: CallbackQuery): async def export_data(callback: CallbackQuery):
"""Экспорт данных из системы""" """Экспорт данных из системы"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -3165,7 +3184,7 @@ async def export_data(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_cleanup") @admin_router.callback_query(F.data == "admin_cleanup")
async def cleanup_old_data(callback: CallbackQuery): async def cleanup_old_data(callback: CallbackQuery):
"""Очистка старых данных""" """Очистка старых данных"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -3186,7 +3205,7 @@ async def cleanup_old_data(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_cleanup_old_lotteries") @admin_router.callback_query(F.data == "admin_cleanup_old_lotteries")
async def cleanup_old_lotteries(callback: CallbackQuery): async def cleanup_old_lotteries(callback: CallbackQuery):
"""Очистка старых завершённых розыгрышей""" """Очистка старых завершённых розыгрышей"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -3234,7 +3253,7 @@ async def cleanup_old_lotteries(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_cleanup_inactive_users") @admin_router.callback_query(F.data == "admin_cleanup_inactive_users")
async def cleanup_inactive_users(callback: CallbackQuery): async def cleanup_inactive_users(callback: CallbackQuery):
"""Очистка неактивных пользователей""" """Очистка неактивных пользователей"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -3295,7 +3314,7 @@ async def cleanup_inactive_users(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_cleanup_old_participations") @admin_router.callback_query(F.data == "admin_cleanup_old_participations")
async def cleanup_old_participations(callback: CallbackQuery): async def cleanup_old_participations(callback: CallbackQuery):
"""Очистка старых участий""" """Очистка старых участий"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -3344,7 +3363,7 @@ async def cleanup_old_participations(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_system_info") @admin_router.callback_query(F.data == "admin_system_info")
async def show_system_info(callback: CallbackQuery): async def show_system_info(callback: CallbackQuery):
"""Системная информация""" """Системная информация"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -3374,7 +3393,7 @@ async def show_system_info(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_winner_display_settings") @admin_router.callback_query(F.data == "admin_winner_display_settings")
async def show_winner_display_settings(callback: CallbackQuery, state: FSMContext): async def show_winner_display_settings(callback: CallbackQuery, state: FSMContext):
"""Настройка отображения победителей для розыгрышей""" """Настройка отображения победителей для розыгрышей"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -3416,7 +3435,7 @@ async def show_winner_display_settings(callback: CallbackQuery, state: FSMContex
@admin_router.callback_query(F.data.startswith("admin_set_display_")) @admin_router.callback_query(F.data.startswith("admin_set_display_"))
async def choose_display_type(callback: CallbackQuery, state: FSMContext): async def choose_display_type(callback: CallbackQuery, state: FSMContext):
"""Выбор типа отображения для конкретного розыгрыша""" """Выбор типа отображения для конкретного розыгрыша"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -3455,7 +3474,7 @@ async def apply_display_type(callback: CallbackQuery, state: FSMContext):
logger.info(f"🎭 Попытка смены типа отображения. Callback data: {callback.data}") logger.info(f"🎭 Попытка смены типа отображения. Callback data: {callback.data}")
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
logger.warning(f"🚫 Отказ в доступе пользователю {callback.from_user.id}") logger.warning(f"🚫 Отказ в доступе пользователю {callback.from_user.id}")
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -3519,7 +3538,7 @@ async def apply_display_type(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data == "admin_messages") @admin_router.callback_query(F.data == "admin_messages")
async def show_messages_menu(callback: CallbackQuery): async def show_messages_menu(callback: CallbackQuery):
"""Показать меню управления сообщениями""" """Показать меню управления сообщениями"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -3542,7 +3561,7 @@ async def show_messages_menu(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_messages_recent") @admin_router.callback_query(F.data == "admin_messages_recent")
async def show_recent_messages(callback: CallbackQuery, page: int = 0): async def show_recent_messages(callback: CallbackQuery, page: int = 0):
"""Показать последние сообщения""" """Показать последние сообщения"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -3591,7 +3610,7 @@ async def show_recent_messages(callback: CallbackQuery, page: int = 0):
@admin_router.callback_query(F.data.startswith("admin_message_view_")) @admin_router.callback_query(F.data.startswith("admin_message_view_"))
async def view_message(callback: CallbackQuery): async def view_message(callback: CallbackQuery):
"""Просмотр конкретного сообщения""" """Просмотр конкретного сообщения"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -3677,7 +3696,7 @@ async def view_message(callback: CallbackQuery):
@admin_router.callback_query(F.data.startswith("admin_message_delete_")) @admin_router.callback_query(F.data.startswith("admin_message_delete_"))
async def delete_message(callback: CallbackQuery): async def delete_message(callback: CallbackQuery):
"""Удалить сообщение пользователя""" """Удалить сообщение пользователя"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -3743,7 +3762,7 @@ async def delete_message(callback: CallbackQuery):
@admin_router.callback_query(F.data.startswith("admin_messages_user_")) @admin_router.callback_query(F.data.startswith("admin_messages_user_"))
async def show_user_messages(callback: CallbackQuery): async def show_user_messages(callback: CallbackQuery):
"""Показать все сообщения конкретного пользователя""" """Показать все сообщения конкретного пользователя"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Недостаточно прав", show_alert=True) await callback.answer("❌ Недостаточно прав", show_alert=True)
return return
@@ -3893,7 +3912,7 @@ async def _notify_all_participants_about_results(bot, session: AsyncSession, lot
@admin_router.callback_query(F.data == "admin_export_users") @admin_router.callback_query(F.data == "admin_export_users")
async def admin_export_users(callback: CallbackQuery): async def admin_export_users(callback: CallbackQuery):
"""Экспорт всех пользователей в XLSX""" """Экспорт всех пользователей в XLSX"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Доступ запрещен", show_alert=True) await callback.answer("❌ Доступ запрещен", show_alert=True)
return return
@@ -3991,7 +4010,7 @@ async def admin_export_users(callback: CallbackQuery):
@admin_router.callback_query(F.data == "admin_import_users") @admin_router.callback_query(F.data == "admin_import_users")
async def admin_import_users_start(callback: CallbackQuery, state: FSMContext): async def admin_import_users_start(callback: CallbackQuery, state: FSMContext):
"""Начать импорт пользователей""" """Начать импорт пользователей"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Доступ запрещен", show_alert=True) await callback.answer("❌ Доступ запрещен", show_alert=True)
return return
@@ -4024,7 +4043,7 @@ async def admin_import_users_start(callback: CallbackQuery, state: FSMContext):
@admin_router.message(StateFilter(AdminStates.import_users_json), F.document) @admin_router.message(StateFilter(AdminStates.import_users_json), F.document)
async def admin_import_users_process(message: Message, state: FSMContext): async def admin_import_users_process(message: Message, state: FSMContext):
"""Обработка импорта пользователей из XLSX""" """Обработка импорта пользователей из XLSX"""
if not is_admin(message.from_user.id): if not await check_admin_access(message.from_user.id):
return return
# Проверяем формат файла # Проверяем формат файла
@@ -4198,7 +4217,7 @@ async def admin_import_users_process(message: Message, state: FSMContext):
@admin_router.callback_query(F.data == "admin_broadcast") @admin_router.callback_query(F.data == "admin_broadcast")
async def admin_broadcast_menu(callback: CallbackQuery, state: FSMContext): async def admin_broadcast_menu(callback: CallbackQuery, state: FSMContext):
"""Меню массовой рассылки""" """Меню массовой рассылки"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Доступ запрещен", show_alert=True) await callback.answer("❌ Доступ запрещен", show_alert=True)
return return
@@ -4245,7 +4264,7 @@ async def admin_broadcast_menu(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data == "admin_broadcast_start") @admin_router.callback_query(F.data == "admin_broadcast_start")
async def admin_broadcast_start(callback: CallbackQuery, state: FSMContext): async def admin_broadcast_start(callback: CallbackQuery, state: FSMContext):
"""Выбор типа рассылки""" """Выбор типа рассылки"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Доступ запрещен", show_alert=True) await callback.answer("❌ Доступ запрещен", show_alert=True)
return return
@@ -4274,7 +4293,7 @@ async def admin_broadcast_start(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data == "broadcast_type_direct") @admin_router.callback_query(F.data == "broadcast_type_direct")
async def broadcast_type_direct(callback: CallbackQuery, state: FSMContext): async def broadcast_type_direct(callback: CallbackQuery, state: FSMContext):
"""Рассылка в ЛС - запрос сообщения""" """Рассылка в ЛС - запрос сообщения"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Доступ запрещен", show_alert=True) await callback.answer("❌ Доступ запрещен", show_alert=True)
return return
@@ -4308,7 +4327,7 @@ async def broadcast_type_direct(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data.startswith("broadcast_type_")) @admin_router.callback_query(F.data.startswith("broadcast_type_"))
async def broadcast_type_channel_or_group(callback: CallbackQuery, state: FSMContext): async def broadcast_type_channel_or_group(callback: CallbackQuery, state: FSMContext):
"""Выбор канала или группы для рассылки""" """Выбор канала или группы для рассылки"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Доступ запрещен", show_alert=True) await callback.answer("❌ Доступ запрещен", show_alert=True)
return return
@@ -4362,7 +4381,7 @@ async def broadcast_type_channel_or_group(callback: CallbackQuery, state: FSMCon
@admin_router.callback_query(F.data.startswith("broadcast_select_channel_")) @admin_router.callback_query(F.data.startswith("broadcast_select_channel_"))
async def broadcast_select_channel(callback: CallbackQuery, state: FSMContext): async def broadcast_select_channel(callback: CallbackQuery, state: FSMContext):
"""Выбран канал/группа - запрос сообщения""" """Выбран канал/группа - запрос сообщения"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Доступ запрещен", show_alert=True) await callback.answer("❌ Доступ запрещен", show_alert=True)
return return
@@ -4407,7 +4426,7 @@ async def broadcast_select_channel(callback: CallbackQuery, state: FSMContext):
@admin_router.message(StateFilter(AdminStates.broadcast_message), F.text | F.photo | F.video | F.document) @admin_router.message(StateFilter(AdminStates.broadcast_message), F.text | F.photo | F.video | F.document)
async def admin_broadcast_send(message: Message, state: FSMContext): async def admin_broadcast_send(message: Message, state: FSMContext):
"""Обработка и отправка рассылки""" """Обработка и отправка рассылки"""
if not is_admin(message.from_user.id): if not await check_admin_access(message.from_user.id):
return return
data = await state.get_data() data = await state.get_data()
@@ -4550,7 +4569,7 @@ async def _broadcast_channel(message: Message, state: FSMContext, data: dict):
@admin_router.callback_query(F.data == "admin_broadcast_channels") @admin_router.callback_query(F.data == "admin_broadcast_channels")
async def admin_broadcast_channels_menu(callback: CallbackQuery, state: FSMContext): async def admin_broadcast_channels_menu(callback: CallbackQuery, state: FSMContext):
"""Меню управления каналами""" """Меню управления каналами"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Доступ запрещен", show_alert=True) await callback.answer("❌ Доступ запрещен", show_alert=True)
return return
@@ -4594,7 +4613,7 @@ async def admin_broadcast_channels_menu(callback: CallbackQuery, state: FSMConte
@admin_router.callback_query(F.data == "admin_broadcast_add_channel") @admin_router.callback_query(F.data == "admin_broadcast_add_channel")
async def admin_broadcast_add_channel_start(callback: CallbackQuery, state: FSMContext): async def admin_broadcast_add_channel_start(callback: CallbackQuery, state: FSMContext):
"""Начать добавление канала""" """Начать добавление канала"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Доступ запрещен", show_alert=True) await callback.answer("❌ Доступ запрещен", show_alert=True)
return return
@@ -4625,7 +4644,7 @@ async def admin_broadcast_add_channel_start(callback: CallbackQuery, state: FSMC
@admin_router.message(StateFilter(AdminStates.broadcast_add_channel_id), F.text) @admin_router.message(StateFilter(AdminStates.broadcast_add_channel_id), F.text)
async def admin_broadcast_add_channel_id(message: Message, state: FSMContext): async def admin_broadcast_add_channel_id(message: Message, state: FSMContext):
"""Обработка ID канала""" """Обработка ID канала"""
if not is_admin(message.from_user.id): if not await check_admin_access(message.from_user.id):
return return
try: try:
@@ -4691,7 +4710,7 @@ async def admin_broadcast_add_channel_id(message: Message, state: FSMContext):
@admin_router.message(StateFilter(AdminStates.broadcast_add_channel_title), F.text) @admin_router.message(StateFilter(AdminStates.broadcast_add_channel_title), F.text)
async def admin_broadcast_add_channel_description(message: Message, state: FSMContext): async def admin_broadcast_add_channel_description(message: Message, state: FSMContext):
"""Обработка описания канала""" """Обработка описания канала"""
if not is_admin(message.from_user.id): if not await check_admin_access(message.from_user.id):
return return
data = await state.get_data() data = await state.get_data()
@@ -4755,7 +4774,7 @@ async def admin_broadcast_add_channel_description(message: Message, state: FSMCo
@admin_router.callback_query(F.data == "admin_broadcast_stats") @admin_router.callback_query(F.data == "admin_broadcast_stats")
async def admin_broadcast_stats(callback: CallbackQuery, state: FSMContext): async def admin_broadcast_stats(callback: CallbackQuery, state: FSMContext):
"""Статистика рассылок""" """Статистика рассылок"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Доступ запрещен", show_alert=True) await callback.answer("❌ Доступ запрещен", show_alert=True)
return return
@@ -4809,7 +4828,7 @@ async def admin_broadcast_stats(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data == "admin_broadcast_inactive") @admin_router.callback_query(F.data == "admin_broadcast_inactive")
async def admin_broadcast_inactive(callback: CallbackQuery, state: FSMContext): async def admin_broadcast_inactive(callback: CallbackQuery, state: FSMContext):
"""Статистика по неактивным пользователям""" """Статистика по неактивным пользователям"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Доступ запрещен", show_alert=True) await callback.answer("❌ Доступ запрещен", show_alert=True)
return return
@@ -4857,7 +4876,7 @@ async def admin_broadcast_inactive(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data == "admin_check_inactive_now") @admin_router.callback_query(F.data == "admin_check_inactive_now")
async def admin_check_inactive_now(callback: CallbackQuery, state: FSMContext): async def admin_check_inactive_now(callback: CallbackQuery, state: FSMContext):
"""Запустить проверку неактивных пользователей вручную""" """Запустить проверку неактивных пользователей вручную"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Доступ запрещен", show_alert=True) await callback.answer("❌ Доступ запрещен", show_alert=True)
return return
@@ -4890,7 +4909,7 @@ async def admin_check_inactive_now(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data == "admin_users") @admin_router.callback_query(F.data == "admin_users")
async def admin_users_menu(callback: CallbackQuery, state: FSMContext): async def admin_users_menu(callback: CallbackQuery, state: FSMContext):
"""Меню управления пользователями""" """Меню управления пользователями"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Доступ запрещен", show_alert=True) await callback.answer("❌ Доступ запрещен", show_alert=True)
return return
@@ -4927,7 +4946,7 @@ async def admin_users_menu(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data == "admin_users_search") @admin_router.callback_query(F.data == "admin_users_search")
async def admin_users_search_prompt(callback: CallbackQuery, state: FSMContext): async def admin_users_search_prompt(callback: CallbackQuery, state: FSMContext):
"""Запрос поискового запроса""" """Запрос поискового запроса"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Доступ запрещен", show_alert=True) await callback.answer("❌ Доступ запрещен", show_alert=True)
return return
@@ -4958,7 +4977,7 @@ async def admin_users_search_prompt(callback: CallbackQuery, state: FSMContext):
@admin_router.message(AdminStates.user_management_search) @admin_router.message(AdminStates.user_management_search)
async def admin_users_search_process(message: Message, state: FSMContext): async def admin_users_search_process(message: Message, state: FSMContext):
"""Обработка поискового запроса""" """Обработка поискового запроса"""
if not is_admin(message.from_user.id): if not await check_admin_access(message.from_user.id):
return return
query = message.text.strip() query = message.text.strip()
@@ -5026,7 +5045,7 @@ async def admin_users_search_process(message: Message, state: FSMContext):
@admin_router.callback_query(F.data.startswith("admin_users_list:")) @admin_router.callback_query(F.data.startswith("admin_users_list:"))
async def admin_users_list(callback: CallbackQuery, state: FSMContext): async def admin_users_list(callback: CallbackQuery, state: FSMContext):
"""Список всех пользователей с пагинацией""" """Список всех пользователей с пагинацией"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Доступ запрещен", show_alert=True) await callback.answer("❌ Доступ запрещен", show_alert=True)
return return
@@ -5085,7 +5104,7 @@ async def admin_users_list(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data.startswith("admin_users_banned:")) @admin_router.callback_query(F.data.startswith("admin_users_banned:"))
async def admin_users_banned_list(callback: CallbackQuery, state: FSMContext): async def admin_users_banned_list(callback: CallbackQuery, state: FSMContext):
"""Список заблокированных пользователей""" """Список заблокированных пользователей"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Доступ запрещен", show_alert=True) await callback.answer("❌ Доступ запрещен", show_alert=True)
return return
@@ -5149,7 +5168,7 @@ async def admin_users_banned_list(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data.startswith("admin_user_view:")) @admin_router.callback_query(F.data.startswith("admin_user_view:"))
async def admin_user_view(callback: CallbackQuery, state: FSMContext): async def admin_user_view(callback: CallbackQuery, state: FSMContext):
"""Просмотр информации о пользователе""" """Просмотр информации о пользователе"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Доступ запрещен", show_alert=True) await callback.answer("❌ Доступ запрещен", show_alert=True)
return return
@@ -5193,7 +5212,7 @@ async def admin_user_view(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data.startswith("admin_user_ban:")) @admin_router.callback_query(F.data.startswith("admin_user_ban:"))
async def admin_user_ban(callback: CallbackQuery, state: FSMContext): async def admin_user_ban(callback: CallbackQuery, state: FSMContext):
"""Заблокировать пользователя в чате""" """Заблокировать пользователя в чате"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Доступ запрещен", show_alert=True) await callback.answer("❌ Доступ запрещен", show_alert=True)
return return
@@ -5215,7 +5234,7 @@ async def admin_user_ban(callback: CallbackQuery, state: FSMContext):
@admin_router.callback_query(F.data.startswith("admin_user_unban:")) @admin_router.callback_query(F.data.startswith("admin_user_unban:"))
async def admin_user_unban(callback: CallbackQuery, state: FSMContext): async def admin_user_unban(callback: CallbackQuery, state: FSMContext):
"""Разблокировать пользователя в чате""" """Разблокировать пользователя в чате"""
if not is_admin(callback.from_user.id): if not await check_admin_access(callback.from_user.id):
await callback.answer("❌ Доступ запрещен", show_alert=True) await callback.answer("❌ Доступ запрещен", show_alert=True)
return return