Files
openclaw-mission-control/backend/tests/test_gateway_device_identity.py

68 lines
2.2 KiB
Python

from __future__ import annotations
import base64
import pytest
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
from app.services.openclaw.device_identity import (
build_device_auth_payload,
load_or_create_device_identity,
sign_device_payload,
)
def _base64url_decode(value: str) -> bytes:
padding = "=" * ((4 - len(value) % 4) % 4)
return base64.urlsafe_b64decode(f"{value}{padding}")
def test_load_or_create_device_identity_persists_same_identity(
monkeypatch: pytest.MonkeyPatch,
tmp_path,
) -> None:
identity_path = tmp_path / "identity" / "device.json"
monkeypatch.setenv("OPENCLAW_GATEWAY_DEVICE_IDENTITY_PATH", str(identity_path))
first = load_or_create_device_identity()
second = load_or_create_device_identity()
assert identity_path.exists()
assert first.device_id == second.device_id
assert first.public_key_pem.strip() == second.public_key_pem.strip()
assert first.private_key_pem.strip() == second.private_key_pem.strip()
def test_build_device_auth_payload_uses_nonce_for_v2() -> None:
payload = build_device_auth_payload(
device_id="dev",
client_id="gateway-client",
client_mode="backend",
role="operator",
scopes=["operator.read", "operator.admin"],
signed_at_ms=123,
token="token",
nonce="nonce-xyz",
)
assert payload == (
"v2|dev|gateway-client|backend|operator|operator.read,operator.admin|123|token|nonce-xyz"
)
def test_sign_device_payload_produces_valid_ed25519_signature(
monkeypatch: pytest.MonkeyPatch,
tmp_path,
) -> None:
identity_path = tmp_path / "identity" / "device.json"
monkeypatch.setenv("OPENCLAW_GATEWAY_DEVICE_IDENTITY_PATH", str(identity_path))
identity = load_or_create_device_identity()
payload = "v1|device|client|backend|operator|operator.read|1|token"
signature = sign_device_payload(identity.private_key_pem, payload)
loaded = serialization.load_pem_public_key(identity.public_key_pem.encode("utf-8"))
assert isinstance(loaded, Ed25519PublicKey)
loaded.verify(_base64url_decode(signature), payload.encode("utf-8"))