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>
67 lines
2.3 KiB
Python
67 lines
2.3 KiB
Python
"""US-035: tracker web dashboard — served from any tracker, embedded asset."""
|
|
|
|
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
|
|
|
|
PANELS = [
|
|
"Tracker hive", "Nodes & coverage", "Client balances",
|
|
"Node pending payouts", "Settlement history",
|
|
"Strikes / bans / forfeitures", "Model usage", "Node throughput",
|
|
]
|
|
|
|
|
|
def test_dashboard_served_with_all_panels():
|
|
tracker = TrackerServer(billing=BillingLedger())
|
|
port = tracker.start()
|
|
try:
|
|
html = urllib.request.urlopen(
|
|
f"http://127.0.0.1:{port}/dashboard"
|
|
).read().decode()
|
|
for panel in PANELS:
|
|
assert panel in html
|
|
assert "<script>" in html # polling client embedded, no build step
|
|
finally:
|
|
tracker.stop()
|
|
|
|
|
|
def test_dashboard_served_by_follower():
|
|
"""A tracker that is not the leader (unreachable peers → never elected)
|
|
still serves the dashboard from its own replicated state."""
|
|
tracker = TrackerServer(
|
|
billing=BillingLedger(),
|
|
cluster_peers=["http://127.0.0.1:1", "http://127.0.0.1:2"],
|
|
)
|
|
port = tracker.start()
|
|
try:
|
|
response = urllib.request.urlopen(f"http://127.0.0.1:{port}/dashboard")
|
|
assert response.status == 200
|
|
assert "meshnet tracker" in response.read().decode()
|
|
finally:
|
|
tracker.stop()
|
|
|
|
|
|
def test_registry_wallets_endpoint():
|
|
contracts = LocalSolanaContracts()
|
|
contracts.registry.submit_stake("wallet-a", 100)
|
|
contracts.registry.record_strike("wallet-a")
|
|
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:
|
|
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:
|
|
tracker.stop()
|