Files
AetherForge/server/internal/api/recon_deploy_kit_test.go
AetherForge f3e5a9a07d
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Add browser deploy recon backend with port scan, web crawl, and deploy lane recommendations.
POST /api/v1/recon/scan probes fleet ports from the server host, crawls owned HTTP targets, maps findings to spread lanes, and records optional oath ledger rows.
2026-06-07 11:23:10 -07:00

111 lines
3.4 KiB
Go

package api
import (
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
"crypto-miner-server/internal/db"
"crypto-miner-server/internal/models"
)
func testReconSpreadHandler(t *testing.T) (*SpreadHandler, *DeployPlanHandler) {
t.Helper()
dir := t.TempDir()
root := t.TempDir()
writeSpreadTemplates(t, root)
artifact := filepath.Join(dir, "worker.exe")
if err := os.WriteFile(artifact, []byte("recon-kit-payload"), 0644); err != nil {
t.Fatal(err)
}
database, err := db.New(dir)
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { _ = database.Close() })
if err := database.InsertBuild(&models.BuildRecord{
ID: "build-recon", WorkerName: "recon-worker", Platform: "windows",
FilePath: artifact, Pinned: true,
}); err != nil {
t.Fatal(err)
}
deployH := NewDeployPlanHandler(database, dir, root,
func() string { return "https://deck.example" },
func() string { return "fleet-secret" },
func() map[string]ServiceDeployLane { return NormalizeServiceDeployAllowlist(nil) },
)
spreadH := NewSpreadHandler(database, dir, root, nil)
spreadH.BindDeployPlan(deployH, func() string { return "https://deck.example" }, func() map[string]ServiceDeployLane {
return NormalizeServiceDeployAllowlist(nil)
})
return spreadH, deployH
}
func TestGetDeployKitWinRM(t *testing.T) {
spreadH, _ := testReconSpreadHandler(t)
req := httptest.NewRequest(http.MethodGet, "/api/v1/recon/deploy-kit?host=10.1.2.50&finding=WinRM", nil)
rec := httptest.NewRecorder()
spreadH.GetDeployKit(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status %d body %s", rec.Code, rec.Body.String())
}
var out map[string]interface{}
if err := json.Unmarshal(rec.Body.Bytes(), &out); err != nil {
t.Fatal(err)
}
if out["join_lane"] != "winrm" {
t.Fatalf("join_lane: %v", out["join_lane"])
}
dropper, ok := out["dropper_urls"].(map[string]interface{})
if !ok || dropper["install_ps1"] == "" {
t.Fatalf("dropper_urls: %v", out["dropper_urls"])
}
if out["spread_kit_zip"] == nil {
t.Fatal("expected spread_kit_zip")
}
if out["deploy_plan_template"] == nil {
t.Fatal("expected deploy_plan_template")
}
}
func TestGetDeployKitSSM(t *testing.T) {
spreadH, _ := testReconSpreadHandler(t)
req := httptest.NewRequest(http.MethodGet, "/api/v1/recon/deploy-kit?host=10.1.2.99&finding=ssm", nil)
rec := httptest.NewRecorder()
spreadH.GetDeployKit(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status %d body %s", rec.Code, rec.Body.String())
}
var out map[string]interface{}
if err := json.Unmarshal(rec.Body.Bytes(), &out); err != nil {
t.Fatal(err)
}
if out["join_lane"] != "ssm_document" {
t.Fatalf("join_lane: %v", out["join_lane"])
}
}
func TestGetDeployKitRequiresHost(t *testing.T) {
spreadH, _ := testReconSpreadHandler(t)
req := httptest.NewRequest(http.MethodGet, "/api/v1/recon/deploy-kit?finding=WinRM", nil)
rec := httptest.NewRecorder()
spreadH.GetDeployKit(rec, req)
if rec.Code != http.StatusBadRequest {
t.Fatalf("want 400 got %d", rec.Code)
}
}
func TestResolveReconFinding(t *testing.T) {
matched, lane, ok := resolveReconFinding("gpsvc", NormalizeServiceDeployAllowlist(nil))
if !ok || lane.Lane != "gpo" {
t.Fatalf("gpsvc → gpo: matched=%q lane=%q ok=%v", matched, lane.Lane, ok)
}
_, lane, ok = resolveReconFinding("", NormalizeServiceDeployAllowlist(nil))
if !ok || lane.Lane != "bits_curl" {
t.Fatalf("empty finding default: %v", lane.Lane)
}
}