add password authentication for bot users

This commit is contained in:
kandrusyak
2026-07-25 15:57:30 +03:00
parent c04fb9480b
commit 053b124a9a
8 changed files with 210 additions and 0 deletions

75
tests/test_auth.py Normal file
View File

@@ -0,0 +1,75 @@
import tempfile
import unittest
from pathlib import Path
from types import SimpleNamespace
from typing import Any
from unittest.mock import AsyncMock
from telegram.constants import ChatType
from telegram.ext import ApplicationHandlerStop
from assistant_bot.auth import authentication_guard
from assistant_bot.storage import AssistantStorage
class AuthenticationGuardTests(unittest.IsolatedAsyncioTestCase):
def setUp(self) -> None:
self.temporary_directory = tempfile.TemporaryDirectory()
self.storage = AssistantStorage(
Path(self.temporary_directory.name) / "assistant.sqlite3"
)
def tearDown(self) -> None:
self.temporary_directory.cleanup()
def make_update_and_context(self, text: str) -> tuple[Any, Any]:
message = SimpleNamespace(text=text, reply_text=AsyncMock())
update = SimpleNamespace(
effective_user=SimpleNamespace(id=42),
effective_chat=SimpleNamespace(type=ChatType.PRIVATE),
effective_message=message,
inline_query=None,
)
context = SimpleNamespace(
application=SimpleNamespace(
bot_data={
"storage": self.storage,
"assistant_password": "секрет",
}
)
)
return update, context
async def test_correct_password_authorizes_user(self) -> None:
update, context = self.make_update_and_context("секрет")
with self.assertRaises(ApplicationHandlerStop):
await authentication_guard(update, context)
self.assertTrue(self.storage.is_user_authorized(42))
update.effective_message.reply_text.assert_awaited_once_with(
"Пароль принят. Доступ открыт — повторно вводить его не нужно."
)
async def test_wrong_password_does_not_authorize_user(self) -> None:
update, context = self.make_update_and_context("неверно")
with self.assertRaises(ApplicationHandlerStop):
await authentication_guard(update, context)
self.assertFalse(self.storage.is_user_authorized(42))
update.effective_message.reply_text.assert_awaited_once_with(
"Неверный пароль. Попробуй еще раз."
)
async def test_authorized_user_passes_guard(self) -> None:
self.storage.authorize_user(42)
update, context = self.make_update_and_context("обычное сообщение")
await authentication_guard(update, context)
update.effective_message.reply_text.assert_not_awaited()
if __name__ == "__main__":
unittest.main()