64 lines
2.1 KiB
Python
64 lines
2.1 KiB
Python
from hmac import compare_digest
|
||
|
||
from telegram import Update
|
||
from telegram.constants import ChatType
|
||
from telegram.ext import ApplicationHandlerStop, ContextTypes
|
||
|
||
from .telegram_utils import get_storage, reply_markdown, require_user_id
|
||
|
||
|
||
def passwords_match(candidate: str, expected: str) -> bool:
|
||
return compare_digest(
|
||
candidate.encode("utf-8"),
|
||
expected.encode("utf-8"),
|
||
)
|
||
|
||
|
||
async def authentication_guard(
|
||
update: Update,
|
||
context: ContextTypes.DEFAULT_TYPE,
|
||
) -> None:
|
||
user_id = require_user_id(update)
|
||
if user_id is None:
|
||
raise ApplicationHandlerStop
|
||
|
||
storage = get_storage(context)
|
||
if storage.is_user_authorized(user_id):
|
||
return
|
||
|
||
message = update.effective_message
|
||
chat = update.effective_chat
|
||
if chat is not None and chat.type != ChatType.PRIVATE:
|
||
if message:
|
||
await reply_markdown(
|
||
message,
|
||
"🔐 **Сначала авторизуйся в личном чате с ботом.**",
|
||
)
|
||
raise ApplicationHandlerStop
|
||
|
||
candidate = message.text.strip() if message and message.text else ""
|
||
password = str(context.application.bot_data["assistant_password"])
|
||
if candidate and passwords_match(candidate, password):
|
||
storage.authorize_user(user_id)
|
||
await reply_markdown(
|
||
message,
|
||
"✅ **Пароль принят.** Доступ открыт — повторно вводить его не нужно.",
|
||
)
|
||
raise ApplicationHandlerStop
|
||
|
||
if candidate and not candidate.startswith("/"):
|
||
await reply_markdown(
|
||
message,
|
||
"🔐 **Неверный пароль.** Попробуй ещё раз.",
|
||
)
|
||
raise ApplicationHandlerStop
|
||
|
||
if message:
|
||
await reply_markdown(
|
||
message,
|
||
"🔐 **Для доступа к боту введи пароль** одним текстовым сообщением.",
|
||
)
|
||
elif update.inline_query:
|
||
await update.inline_query.answer([], cache_time=0)
|
||
raise ApplicationHandlerStop
|