Refactor admin handlers to improve access control and state management. Added checks for admin rights in ban functions and streamlined router inclusion order in main bot file. Updated keyboard layouts for better user experience and removed unused state definitions.

This commit is contained in:
2025-08-27 00:28:32 +03:00
parent 62af3b73c6
commit 9688cdd85f
8 changed files with 1026 additions and 386 deletions

View File

@@ -41,10 +41,12 @@ async def admin_panel(message: types.Message, state: FSMContext):
reply_markup=markup)
else:
await message.answer('Доступ запрещен, досвидания!')
await state.set_state("START")
except Exception as e:
logger.error(f"Ошибка при запуске админ панели: {e}")
await message.bot.send_message(IMPORTANT_LOGS,
f'Ошибка в функции admin_panel {e}. Traceback: {traceback.format_exc()}')
await state.set_state("START")
@admin_router.message(
@@ -52,7 +54,12 @@ async def admin_panel(message: types.Message, state: FSMContext):
StateFilter("ADMIN"),
F.text == 'Бан (Список)'
)
async def get_last_users(message: types.Message):
async def get_last_users(message: types.Message, state: FSMContext):
# Дополнительная проверка на админские права
if not check_access(message.from_user.id, BotDB):
await message.answer('Доступ запрещен!')
await state.set_state("START")
return
logger.info(
f"Попытка получения списка последних пользователей. Текст сообщения: {message.text} Имя автора сообщения: {message.from_user.full_name})")
list_users = BotDB.get_last_users_from_db()
@@ -67,6 +74,11 @@ async def get_last_users(message: types.Message):
F.text == 'Бан по нику'
)
async def ban_by_nickname(message: types.Message, state: FSMContext):
# Дополнительная проверка на админские права
if not check_access(message.from_user.id, BotDB):
await message.answer('Доступ запрещен!')
await state.set_state("START")
return
await message.answer('Пришли мне username блокируемого пользователя')
await state.set_state('PRE_BAN')
@@ -77,25 +89,29 @@ async def ban_by_nickname(message: types.Message, state: FSMContext):
F.text == 'Бан по ID'
)
async def ban_by_id(message: types.Message, state: FSMContext):
# Дополнительная проверка на админские права
if not check_access(message.from_user.id, BotDB):
await message.answer('Доступ запрещен!')
await state.set_state("START")
return
await message.answer('Пришли мне ID блокируемого пользователя')
await state.set_state('PRE_BAN_ID')
@admin_router.message(
ChatTypeFilter(chat_type=["private"]),
StateFilter("ADMIN"),
F.text == 'Тестовый бан'
)
async def ban_by_forward(message: types.Message, state: FSMContext):
await message.answer('Перешлите мне сообщение от пользователя, которого хотите заблокировать')
await state.set_state('PRE_BAN_FORWARD')
@admin_router.message(
ChatTypeFilter(chat_type=["private"]),
StateFilter("PRE_BAN", "PRE_BAN_ID", "BAN_2"),
F.text == 'Отменить'
)
async def decline_ban(message: types.Message, state: FSMContext):
# Дополнительная проверка на админские права
if not check_access(message.from_user.id, BotDB):
await message.answer('Доступ запрещен!')
await state.set_state("START")
return
current_state = await state.get_state()
await state.set_data({})
await state.set_state("ADMIN")
@@ -109,6 +125,11 @@ async def decline_ban(message: types.Message, state: FSMContext):
StateFilter("PRE_BAN")
)
async def ban_by_nickname_step_2(message: types.Message, state: FSMContext):
# Дополнительная проверка на админские права
if not check_access(message.from_user.id, BotDB):
await message.answer('Доступ запрещен!')
await state.set_state("START")
return
logger.info(
f"Функция ban_by_nickname_2. Получен никнейм пользователя: {message.text}")
user_name = message.text
@@ -132,6 +153,11 @@ async def ban_by_nickname_step_2(message: types.Message, state: FSMContext):
StateFilter("PRE_BAN_ID")
)
async def ban_by_id_step_2(message: types.Message, state: FSMContext):
# Дополнительная проверка на админские права
if not check_access(message.from_user.id, BotDB):
await message.answer('Доступ запрещен!')
await state.set_state("START")
return
try:
user_id = int(message.text)
logger.info(f"Функция ban_by_id_step_2. Получен ID пользователя: {user_id}")
@@ -168,73 +194,10 @@ async def ban_by_id_step_2(message: types.Message, state: FSMContext):
await message.answer('Вернулись в меню', reply_markup=markup)
@admin_router.message(
ChatTypeFilter(chat_type=["private"]),
StateFilter("PRE_BAN_FORWARD"),
F.forward_from
)
async def ban_by_forward_step_2(message: types.Message, state: FSMContext):
"""Обработчик пересланных сообщений для бана пользователя"""
try:
# Получаем информацию о пользователе из пересланного сообщения
forwarded_user = message.forward_from
if not forwarded_user:
await message.answer("Не удалось получить информацию о пользователе из пересланного сообщения. Возможно, пользователь скрыл возможность пересылки своих сообщений.")
await state.set_state('ADMIN')
markup = get_reply_keyboard_admin()
await message.answer('Вернулись в меню', reply_markup=markup)
return
user_id = forwarded_user.id
user_name = forwarded_user.username or "private_username"
full_name = forwarded_user.full_name or "Неизвестно"
logger.info(f"Функция ban_by_forward_step_2. Получен пользователь из пересланного сообщения: ID={user_id}, username={user_name}, full_name={full_name}")
# Проверяем, существует ли пользователь в базе
user_info = BotDB.get_user_info_by_id(user_id)
if not user_info:
# Если пользователя нет в базе, используем информацию из пересланного сообщения
logger.info(f"Пользователь с ID {user_id} не найден в базе данных, используем данные из пересланного сообщения")
user_name = user_name
full_name = full_name
else:
# Если пользователь есть в базе, используем данные из базы
user_name = user_info.get('username', user_name)
full_name = user_info.get('full_name', full_name)
await state.update_data(user_id=user_id, user_name=user_name, message_for_user=None,
date_to_unban=None)
markup = create_keyboard_for_ban_reason()
# Экранируем потенциально проблемные символы
user_name_escaped = html.escape(str(user_name))
full_name_escaped = html.escape(str(full_name))
await message.answer(
text=f"<b>Выбран пользователь из пересланного сообщения:\nid:</b> {user_id}\n<b>username:</b> {user_name_escaped}\n"
f"Имя:{full_name_escaped}\nВыбери причину бана из списка или напиши ее в чат",
reply_markup=markup)
await state.set_state('BAN_2')
except Exception as e:
logger.error(f"Ошибка при обработке пересланного сообщения: {e}")
await message.answer("Произошла ошибка при обработке пересланного сообщения.")
await state.set_state('ADMIN')
markup = get_reply_keyboard_admin()
await message.answer('Вернулись в меню', reply_markup=markup)
@admin_router.message(
ChatTypeFilter(chat_type=["private"]),
StateFilter("PRE_BAN_FORWARD")
)
async def ban_by_forward_invalid(message: types.Message, state: FSMContext):
"""Обработчик для случаев, когда сообщение не является пересланным или не содержит информацию о пользователе"""
if message.forward_from_chat:
await message.answer("Пересланное сообщение из канала или группы не содержит информацию о конкретном пользователе. Пожалуйста, перешлите сообщение из приватного чата.")
else:
await message.answer("Пожалуйста, перешлите сообщение от пользователя, которого хотите заблокировать. Обычное сообщение не подходит.")
@admin_router.message(