68 lines
2.7 KiB
Python
68 lines
2.7 KiB
Python
import os
|
|
import subprocess
|
|
import sys
|
|
from dataclasses import replace
|
|
|
|
import pytest
|
|
|
|
from parser_lab.auth import Auth, Unauthorized
|
|
from parser_lab.config import Settings
|
|
from parser_lab.repository import Repository
|
|
from parser_lab import cli
|
|
|
|
|
|
def settings_from_env(monkeypatch, tmp_path):
|
|
monkeypatch.setenv('LAB_ADMIN_USER', 'teacher')
|
|
monkeypatch.setenv('LAB_ADMIN_PASSWORD', "мой пароль $ # ' \\ test")
|
|
monkeypatch.setenv('LAB_SECRET', 'test-secret-at-least-32-characters')
|
|
monkeypatch.setenv('LAB_DATA_DIR', str(tmp_path / 'data'))
|
|
monkeypatch.delenv('LAB_ADMIN_HASH', raising=False)
|
|
return Settings.from_env()
|
|
|
|
|
|
def test_password_env_login_restart_and_change(monkeypatch, tmp_path):
|
|
settings = settings_from_env(monkeypatch, tmp_path)
|
|
password = os.environ['LAB_ADMIN_PASSWORD']
|
|
assert password not in repr(settings)
|
|
repo = Repository(settings.data_dir)
|
|
auth = Auth(settings, repo)
|
|
token = auth.login('teacher', password, 'client')
|
|
assert Auth(Settings.from_env(), repo).check(token) == token
|
|
with pytest.raises(Unauthorized):
|
|
auth.login('teacher', password + 'x', 'client')
|
|
changed = Auth(replace(settings, password='replacement-password'), repo)
|
|
with pytest.raises(Unauthorized):
|
|
changed.check(token)
|
|
with pytest.raises(Unauthorized):
|
|
changed.login('teacher', password, 'client')
|
|
assert changed.login('teacher', 'replacement-password', 'client')
|
|
|
|
|
|
@pytest.mark.parametrize('password', ['', 'short'])
|
|
def test_invalid_env_password(monkeypatch, tmp_path, password):
|
|
settings_from_env(monkeypatch, tmp_path)
|
|
monkeypatch.setenv('LAB_ADMIN_PASSWORD', password)
|
|
with pytest.raises(ValueError, match='LAB_ADMIN_PASSWORD'):
|
|
Settings.from_env()
|
|
|
|
|
|
def test_init_env_plaintext_password_loads_with_uv(monkeypatch, tmp_path):
|
|
path = tmp_path / '.env'
|
|
password = "тест $HOME ${UNKNOWN} # ' \\ end"
|
|
monkeypatch.setattr(sys, 'argv', ['cli', 'init-env', '--path', str(path)])
|
|
monkeypatch.setattr('builtins.input', lambda _: 'teacher')
|
|
monkeypatch.setattr(cli.getpass, 'getpass', lambda _: password)
|
|
cli.main()
|
|
text = path.read_text(encoding='utf-8')
|
|
assert 'LAB_ADMIN_PASSWORD=' in text and 'LAB_ADMIN_HASH=' not in text
|
|
env = {k: v for k, v in os.environ.items() if not k.startswith('LAB_')}
|
|
env['EXPECTED_PASSWORD'] = password
|
|
result = subprocess.run(
|
|
['uv', 'run', '--no-project', '--env-file', str(path), sys.executable, '-c',
|
|
'import os; assert os.environ["LAB_ADMIN_PASSWORD"] == os.environ["EXPECTED_PASSWORD"]'],
|
|
env=env, capture_output=True, text=True,
|
|
)
|
|
assert result.returncode == 0, result.stderr
|
|
with pytest.raises(SystemExit, match='уже существует'):
|
|
cli.main()
|