Files
vigilar/tests/unit/test_pin.py
adlee-was-taken 5745388880 fix: address final-review items (status endpoint, docs, tests)
Follow-up to the holistic review of the PIN-unification branch:

- /system/status now reads the real arm state from the arm_state_log
  table via get_current_arm_state, instead of returning a hardcoded
  'DISARMED' stub. Without this, polling after the new async 202
  arm/disarm flow was a UX dead-end — clients never saw the state
  change they just requested. DB read failures degrade gracefully.

- Operator guide: correct the claim that 'vigilar config set-pin'
  populates recovery_passphrase_hash. It doesn't. recovery_passphrase
  _hash has no CLI helper today; it must be set manually.

- Tests: add a fail-closed regression for verify_pin on malformed
  stored hashes, and a companion test confirming the deprecation
  warning stays silent on a fully migrated config.

All address specific review comments on the branch; no scope creep.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 12:58:09 -04:00

51 lines
1.5 KiB
Python

"""Tests for PIN hashing and verification."""
from vigilar.alerts.pin import hash_pin, verify_pin
def test_hash_pin_returns_formatted_string():
result = hash_pin("1234")
parts = result.split("$")
assert len(parts) == 3
assert parts[0] == "pbkdf2_sha256"
assert len(parts[1]) == 32 # 16 bytes hex = 32 chars
assert len(parts[2]) == 64 # 32 bytes hex = 64 chars
def test_verify_pin_correct():
stored = hash_pin("5678")
assert verify_pin("5678", stored) is True
def test_verify_pin_wrong():
stored = hash_pin("5678")
assert verify_pin("0000", stored) is False
def test_verify_pin_empty_hash_returns_true():
assert verify_pin("1234", "") is True
assert verify_pin("", "") is True
def test_hash_pin_different_salts():
h1 = hash_pin("1234")
h2 = hash_pin("1234")
assert h1 != h2
def test_verify_pin_handles_unicode():
stored = hash_pin("p@ss!")
assert verify_pin("p@ss!", stored) is True
assert verify_pin("p@ss?", stored) is False
def test_verify_pin_rejects_malformed_hash():
"""verify_pin must return False (not raise) on malformed stored hashes.
Fail-closed is load-bearing: a misconfigured or partially-migrated
[security] pin_hash must lock out transitions, not grant access."""
assert verify_pin("1234", "sha256:deadbeef") is False
assert verify_pin("1234", "garbage") is False
assert verify_pin("1234", "pbkdf2_sha256$only$two$extra") is False
# Wrong algo prefix
assert verify_pin("1234", "argon2id$salt$dk") is False