feat(F4): PIN verification on arm/disarm + reset-pin endpoint
Adds PIN checking to arm/disarm endpoints using verify_pin() against cfg.security.pin_hash, and a new POST /system/api/reset-pin endpoint that verifies the recovery passphrase before updating the PIN hash. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
79
tests/unit/test_system_pin.py
Normal file
79
tests/unit/test_system_pin.py
Normal file
@@ -0,0 +1,79 @@
|
||||
"""Tests for PIN verification on arm/disarm endpoints."""
|
||||
|
||||
import pytest
|
||||
from vigilar.alerts.pin import hash_pin
|
||||
from vigilar.config import VigilarConfig, SecurityConfig
|
||||
from vigilar.web.app import create_app
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def app_with_pin():
|
||||
pin_hash = hash_pin("1234")
|
||||
cfg = VigilarConfig(
|
||||
security=SecurityConfig(
|
||||
pin_hash=pin_hash,
|
||||
recovery_passphrase_hash=hash_pin("recover123"),
|
||||
)
|
||||
)
|
||||
app = create_app(cfg)
|
||||
app.config["TESTING"] = True
|
||||
return app
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def app_no_pin():
|
||||
cfg = VigilarConfig()
|
||||
app = create_app(cfg)
|
||||
app.config["TESTING"] = True
|
||||
return app
|
||||
|
||||
|
||||
def test_arm_without_pin_set(app_no_pin):
|
||||
with app_no_pin.test_client() as c:
|
||||
rv = c.post("/system/api/arm", json={"mode": "ARMED_AWAY"})
|
||||
assert rv.status_code == 200
|
||||
assert rv.get_json()["ok"] is True
|
||||
|
||||
|
||||
def test_arm_correct_pin(app_with_pin):
|
||||
with app_with_pin.test_client() as c:
|
||||
rv = c.post("/system/api/arm", json={"mode": "ARMED_AWAY", "pin": "1234"})
|
||||
assert rv.status_code == 200
|
||||
assert rv.get_json()["ok"] is True
|
||||
|
||||
|
||||
def test_arm_wrong_pin(app_with_pin):
|
||||
with app_with_pin.test_client() as c:
|
||||
rv = c.post("/system/api/arm", json={"mode": "ARMED_AWAY", "pin": "0000"})
|
||||
assert rv.status_code == 401
|
||||
|
||||
|
||||
def test_disarm_correct_pin(app_with_pin):
|
||||
with app_with_pin.test_client() as c:
|
||||
rv = c.post("/system/api/disarm", json={"pin": "1234"})
|
||||
assert rv.status_code == 200
|
||||
|
||||
|
||||
def test_disarm_wrong_pin(app_with_pin):
|
||||
with app_with_pin.test_client() as c:
|
||||
rv = c.post("/system/api/disarm", json={"pin": "9999"})
|
||||
assert rv.status_code == 401
|
||||
|
||||
|
||||
def test_reset_pin_correct_passphrase(app_with_pin):
|
||||
with app_with_pin.test_client() as c:
|
||||
rv = c.post("/system/api/reset-pin", json={
|
||||
"recovery_passphrase": "recover123",
|
||||
"new_pin": "5678",
|
||||
})
|
||||
assert rv.status_code == 200
|
||||
assert rv.get_json()["ok"] is True
|
||||
|
||||
|
||||
def test_reset_pin_wrong_passphrase(app_with_pin):
|
||||
with app_with_pin.test_client() as c:
|
||||
rv = c.post("/system/api/reset-pin", json={
|
||||
"recovery_passphrase": "wrong",
|
||||
"new_pin": "5678",
|
||||
})
|
||||
assert rv.status_code == 401
|
||||
Reference in New Issue
Block a user