Files
virtuality/tests/test_auth.py
T
Claude 110a37f435 Версия проекта была обновлена до 0.10.0: тесты, CI и документация образа
- tests/: 55 тестов web-панели, авторизации, сети и обновлений,
  все страницы рендерятся на замоканных virsh/systemctl;
- GitHub Actions: pyflakes + pytest на Python 3.11–3.13, shellcheck,
  сборка ISO amd64/arm64 по тегу v* или вручную;
- Makefile: make check / make test / make iso;
- docs/IMAGE.md и README: установка с ISO, продакшен-настройки,
  разработка;
- updates/versions.json: описание версии 0.10.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LEUXMcdZo7b87mjkUsPgg
2026-09-25 06:36:26 +00:00

50 строки
1.8 KiB
Python

import pytest
import auth
# SHA-512 crypt hash of "s3cret" with salt "virtualitysalt".
SHA512_HASH = "$6$virtualitysalt$"
@pytest.fixture()
def password_hash():
computed = auth.crypt_hash("s3cret", SHA512_HASH)
assert computed and computed.startswith(SHA512_HASH)
return computed
def write_shadow(tmp_path, monkeypatch, entries):
shadow = tmp_path / "shadow"
shadow.write_text("".join(f"{user}:{pw}:19000:0:99999:7:::\n" for user, pw in entries))
monkeypatch.setattr(auth, "SHADOW_FILE", shadow)
monkeypatch.setattr(auth, "_stdlib_spwd", None)
def test_libcrypt_fallback_matches(password_hash, monkeypatch):
monkeypatch.setattr(auth, "_stdlib_crypt", None)
assert auth.crypt_hash("s3cret", password_hash) == password_hash
assert auth.crypt_hash("wrong", password_hash) != password_hash
def test_verify_password_with_shadow_file(password_hash, tmp_path, monkeypatch):
write_shadow(tmp_path, monkeypatch, [("root", "*"), ("admin", password_hash), ("locked", "!" + password_hash)])
monkeypatch.setattr(auth, "_stdlib_crypt", None)
assert auth.verify_password("admin", "s3cret")
assert not auth.verify_password("admin", "wrong")
assert not auth.verify_password("admin", "")
assert not auth.verify_password("root", "anything")
assert not auth.verify_password("locked", "s3cret")
assert not auth.verify_password("missing", "s3cret")
def test_throttle_locks_and_resets():
throttle = auth.LoginThrottle(max_failures=3, window_seconds=60, lockout_seconds=60)
for _ in range(2):
throttle.record_failure("1.2.3.4")
assert throttle.retry_after("1.2.3.4") == 0
throttle.record_failure("1.2.3.4")
assert throttle.retry_after("1.2.3.4") > 0
assert throttle.retry_after("5.6.7.8") == 0
throttle.record_success("1.2.3.4")
assert throttle.retry_after("1.2.3.4") == 0