Historical working copy retained for audit before consolidation into main. The canonicalized plugin architecture and later fixes already live in main; this snapshot is not a release or a request to restore obsolete source layout.
112 lines
4.0 KiB
Python
112 lines
4.0 KiB
Python
import copy
|
|
import json
|
|
import secrets
|
|
import threading
|
|
from datetime import UTC, datetime, timedelta
|
|
|
|
import pytest
|
|
|
|
from k1link.fleet.device_enrollment import DeviceEnrollment, validate
|
|
from k1link.fleet.trust import PairingError
|
|
|
|
|
|
class Fleet:
|
|
def __init__(self):
|
|
self.lock = threading.RLock()
|
|
self.row = {
|
|
"id": "vehicle",
|
|
"node_id": "node-1",
|
|
"binding": {"binding_id": "binding-1"},
|
|
"device_enrollment": {"available": True, "runtime_id": "runtime-1"},
|
|
}
|
|
|
|
def find(self, _identifier):
|
|
return self.row
|
|
|
|
def public(self, row):
|
|
return {"connectivity": "online"}
|
|
|
|
|
|
def command():
|
|
# Synthetic value constructed at runtime; never a real WLAN credential.
|
|
return {
|
|
"operation_id": "op_" + "a" * 32,
|
|
"node_id": "node-1",
|
|
"runtime_id": "runtime-1",
|
|
"action": "connect",
|
|
"deadline_at": (datetime.now(UTC) + timedelta(seconds=60)).isoformat(),
|
|
"parameters": {
|
|
"device_id": "AA:BB:CC:DD:EE:FF",
|
|
"discovery_generation": 1,
|
|
"mode_revision": 0,
|
|
"ssid": "test-net",
|
|
"password": secrets.token_urlsafe(20),
|
|
},
|
|
}
|
|
|
|
|
|
def test_password_only_lives_in_pending_delivery_and_never_in_fleet_or_result():
|
|
fleet, bus, request = Fleet(), DeviceEnrollment(), command()
|
|
secret = request["parameters"]["password"]
|
|
public = bus.submit(fleet, "vehicle", request)
|
|
assert secret not in json.dumps(public)
|
|
assert secret not in json.dumps(fleet.row)
|
|
envelope = bus.heartbeat(fleet.row, {})
|
|
assert envelope["enrollment_commands"][0]["parameters"]["password"] == secret
|
|
bus.heartbeat(
|
|
fleet.row,
|
|
{"enrollment_results": [{"operation_id": request["operation_id"], "state": "running"}]},
|
|
)
|
|
assert secret not in json.dumps(list(bus.pending.values()))
|
|
assert not bus.heartbeat(fleet.row, {})["enrollment_commands"]
|
|
|
|
|
|
def test_unknown_after_core_restart_does_not_recreate_command():
|
|
fleet, bus, request = Fleet(), DeviceEnrollment(), command()
|
|
bus.submit(fleet, "vehicle", request)
|
|
restarted = DeviceEnrollment()
|
|
assert restarted.operation(fleet, "vehicle", request["operation_id"])["state"] == "unknown"
|
|
assert not restarted.heartbeat(fleet.row, {})["enrollment_commands"]
|
|
|
|
|
|
def test_fences_board_runtime_and_deadline_and_forbids_host_actions():
|
|
for change in (
|
|
{"node_id": "node-2"},
|
|
{"runtime_id": "runtime-2"},
|
|
{"action": "quick-connect"},
|
|
{"deadline_at": datetime.now(UTC).isoformat()},
|
|
):
|
|
fleet, bus, request = Fleet(), DeviceEnrollment(), command()
|
|
request.update(change)
|
|
with pytest.raises(PairingError):
|
|
bus.submit(fleet, "vehicle", request)
|
|
request = command()
|
|
request["parameters"]["allow_host_wifi_switch"] = True
|
|
with pytest.raises(PairingError):
|
|
validate(request)
|
|
|
|
|
|
def test_rebinding_drops_delivery_and_old_results():
|
|
fleet, bus, request = Fleet(), DeviceEnrollment(), command()
|
|
bus.submit(fleet, "vehicle", request)
|
|
fleet.row["binding"]["binding_id"] = "binding-2"
|
|
assert not bus.heartbeat(fleet.row, {})["enrollment_commands"]
|
|
assert bus.operation(fleet, "vehicle", request["operation_id"])["state"] == "unknown"
|
|
|
|
|
|
def test_expiry_drops_secret_without_automatic_retry():
|
|
fleet, bus, request = Fleet(), DeviceEnrollment(), command()
|
|
bus.submit(fleet, "vehicle", request)
|
|
bus.pending[("vehicle", request["operation_id"])]["deadline"] = 0
|
|
assert bus.operation(fleet, "vehicle", request["operation_id"])["state"] == "unknown"
|
|
assert bus.pending[("vehicle", request["operation_id"])]["payload"] is None
|
|
|
|
|
|
def test_duplicate_id_cannot_replace_original_secret():
|
|
fleet, bus, request = Fleet(), DeviceEnrollment(), command()
|
|
bus.submit(fleet, "vehicle", request)
|
|
duplicate = copy.deepcopy(request)
|
|
duplicate["parameters"]["password"] += "changed"
|
|
bus.submit(fleet, "vehicle", duplicate)
|
|
assert bus.pending[("vehicle", request["operation_id"])]["payload"] == request
|