feat(tracker): unified auth boundary — gossip HMAC + validator token + admin-gated reads (alpha 01/02/20, ADR-0017)

Wire server.py handlers to the auth helper: forfeit requires validator
service token or admin session (client API keys rejected); billing summary/
settlements/registry-wallets and benchmark endpoints require admin/service;
the three gossip mutation endpoints require a fresh hive HMAC signature and
outgoing gossip pushes are signed. Dashboard sends its session token on
panel fetches. Existing tests updated for the new gates.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Dobromir Popov
2026-07-05 00:08:25 +02:00
parent 7414ce1e29
commit 81719ed84b
12 changed files with 4591 additions and 4557 deletions

View File

@@ -4,6 +4,7 @@ import json
import urllib.request
from meshnet_contracts import LocalSolanaContracts
from meshnet_tracker.accounts import AccountStore
from meshnet_tracker.billing import BillingLedger
from meshnet_tracker.server import TrackerServer
@@ -48,12 +49,17 @@ def test_registry_wallets_endpoint():
contracts = LocalSolanaContracts()
contracts.registry.submit_stake("wallet-a", 100)
contracts.registry.record_strike("wallet-a")
tracker = TrackerServer(contracts=contracts)
accounts = AccountStore()
admin = accounts.register(email="admin@example.com", password="admin-pass-123")
session = accounts.create_session(admin["account_id"])
tracker = TrackerServer(contracts=contracts, accounts=accounts)
port = tracker.start()
try:
data = json.loads(urllib.request.urlopen(
f"http://127.0.0.1:{port}/v1/registry/wallets"
).read())
req = urllib.request.Request(
f"http://127.0.0.1:{port}/v1/registry/wallets",
headers={"Authorization": f"Bearer {session}"},
)
data = json.loads(urllib.request.urlopen(req).read())
assert data["wallets"]["wallet-a"]["strike_count"] == 1
assert data["wallets"]["wallet-a"]["banned"] is False
finally: