feat(security): ограничение ИИ-юриста только для админа и пользователей с правом has_ai_access

This commit is contained in:
Admin 2026-10-13 12:28:44 +04:00
parent 401fb3b32a
commit 99fd5ebe88

View file

@ -106,6 +106,14 @@ async def determine_user_role(user_id: int) -> str:
@router.message(F.text.casefold().startswith(("/юрист", "/jurist"))) @router.message(F.text.casefold().startswith(("/юрист", "/jurist")))
async def cmd_legal_advisor(message: Message, state: FSMContext, bot: Bot): async def cmd_legal_advisor(message: Message, state: FSMContext, bot: Bot):
role = await determine_user_role(message.from_user.id) role = await determine_user_role(message.from_user.id)
if role not in ("admin", "lawyer"):
await message.answer(
"🔒 <b>Модуль юридической аналитики находится в режиме калибровки Советом Дома.</b>\n\n"
"Доступ открывается индивидуально администратором (@ktybdsq).\n"
"Если вам требуется консультация по протечкам, тарифам или судебным спорам — напишите председателю Совета Дома.",
parse_mode='HTML'
)
return
# Проверяем, не задал ли пользователь вопрос прямо в команде: /юрист Какой срок ответа? # Проверяем, не задал ли пользователь вопрос прямо в команде: /юрист Какой срок ответа?
parts = (message.text or "").split(maxsplit=1) parts = (message.text or "").split(maxsplit=1)
@ -125,7 +133,6 @@ async def cmd_legal_advisor(message: Message, state: FSMContext, bot: Bot):
role_desc = { role_desc = {
"admin": "👑 <b>Режим Стратегического Аналитика (Администратор)</b>", "admin": "👑 <b>Режим Стратегического Аналитика (Администратор)</b>",
"lawyer": "⚖️ <b>Режим Судебного Юриста (Совет дома / Активист)</b>", "lawyer": "⚖️ <b>Режим Судебного Юриста (Совет дома / Активист)</b>",
"resident": "🏡 <b>Соседский Юридический Помощник</b>"
}.get(role, "🏡 <b>Юридический Помощник</b>") }.get(role, "🏡 <b>Юридический Помощник</b>")
text = ( text = (
@ -141,10 +148,18 @@ async def cmd_legal_advisor(message: Message, state: FSMContext, bot: Bot):
async def cb_legal_advisor(callback: CallbackQuery, state: FSMContext): async def cb_legal_advisor(callback: CallbackQuery, state: FSMContext):
await callback.answer() await callback.answer()
role = await determine_user_role(callback.from_user.id) role = await determine_user_role(callback.from_user.id)
if role not in ("admin", "lawyer"):
await callback.message.answer(
"🔒 <b>Модуль юридической аналитики находится в режиме калибровки Советом Дома.</b>\n\n"
"Доступ открывается индивидуально администратором (@ktybdsq).\n"
"Если вам требуется консультация по протечкам, тарифам или судебным спорам — напишите председателю Совета Дома.",
parse_mode='HTML'
)
return
role_desc = { role_desc = {
"admin": "👑 <b>Режим Стратегического Аналитика (Администратор)</b>", "admin": "👑 <b>Режим Стратегического Аналитика (Администратор)</b>",
"lawyer": "⚖️ <b>Режим Судебного Юриста (Совет дома / Активист)</b>", "lawyer": "⚖️ <b>Режим Судебного Юриста (Совет дома / Активист)</b>",
"resident": "🏡 <b>Соседский Юридический Помощник</b>"
}.get(role, "🏡 <b>Юридический Помощник</b>") }.get(role, "🏡 <b>Юридический Помощник</b>")
text = ( text = (
@ -162,6 +177,15 @@ async def cb_legal_advisor(callback: CallbackQuery, state: FSMContext):
async def process_text_legal_question(message: Message, state: FSMContext, bot: Bot): async def process_text_legal_question(message: Message, state: FSMContext, bot: Bot):
user_id = message.from_user.id user_id = message.from_user.id
role = await determine_user_role(user_id) role = await determine_user_role(user_id)
if role not in ("admin", "lawyer"):
await message.answer(
"🔒 <b>Модуль юридической аналитики находится в режиме калибровки Советом Дома.</b>\n\n"
"Доступ открывается индивидуально администратором (@ktybdsq).",
parse_mode='HTML'
)
await state.clear()
return
question = message.text question = message.text
status_msg = await message.answer( status_msg = await message.answer(
@ -197,18 +221,26 @@ async def process_text_legal_question(message: Message, state: FSMContext, bot:
) )
else: else:
# В личном диалоге отвечаем напрямую # В личном диалоге отвечаем напрямую
header = f"⚖️ <b>Юридический совет ({result.get('latency_sec')} сек):</b>" header = f"⚖️ <b>Юридический ответ ({result.get('latency_sec')} сек):</b>"
await send_split_message(message, header, result["text"]) await send_split_message(message, header, result["text"])
await state.clear() await state.clear()
# === ОБРАБОТКА ГОЛОСОВЫХ ВОПРОСОВ (НА ТИВНОЕ МУЛЬТИМОДАЛЬНОЕ РАСПОЗНАВАНИЕ) === # === ОБРАБОТКА ГОЛОСОВЫХ ВОПРОСОВ (НАТИВНОЕ МУЛЬТИМОДАЛЬНОЕ РАСПОЗНАВАНИЕ) ===
@router.message(LegalQuestionState.waiting_for_question, F.voice) @router.message(LegalQuestionState.waiting_for_question, F.voice)
@router.message(F.voice & F.chat.type == "private") @router.message(F.voice & F.chat.type == "private")
async def process_voice_legal_question(message: Message, state: FSMContext, bot: Bot): async def process_voice_legal_question(message: Message, state: FSMContext, bot: Bot):
user_id = message.from_user.id user_id = message.from_user.id
role = await determine_user_role(user_id) role = await determine_user_role(user_id)
if role not in ("admin", "lawyer"):
await message.answer(
"🔒 <b>Модуль юридической аналитики находится в режиме калибровки Советом Дома.</b>\n\n"
"Доступ открывается индивидуально администратором (@ktybdsq).",
parse_mode='HTML'
)
await state.clear()
return
status_msg = await message.answer( status_msg = await message.answer(
"🎙 <i>Слушаю голосовое сообщение и сопоставляю с законами РФ...</i>", "🎙 <i>Слушаю голосовое сообщение и сопоставляю с законами РФ...</i>",