79 lines
3.2 KiB
Go
79 lines
3.2 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"context"
|
|
"crypto/hmac"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strconv"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"data-terminal-cloud/internal/diagnostics"
|
|
)
|
|
|
|
type fakePlatformHealthProcessor struct {
|
|
calls int
|
|
receipt diagnostics.PlatformHealthReceipt
|
|
err error
|
|
lastInput diagnostics.PlatformHealthInput
|
|
}
|
|
|
|
func (p *fakePlatformHealthProcessor) IngestPlatformHealth(_ context.Context, input diagnostics.PlatformHealthInput, _ []byte, _ time.Time) (diagnostics.PlatformHealthReceipt, error) {
|
|
p.calls++
|
|
p.lastInput = input
|
|
return p.receipt, p.err
|
|
}
|
|
|
|
func TestPlatformHealthCallbackRequiresSignatureAndAcceptsReport(t *testing.T) {
|
|
secret := []byte("01234567890123456789012345678901")
|
|
now := time.Now().UTC().Truncate(time.Second)
|
|
body, _ := json.Marshal(diagnostics.PlatformHealthInput{
|
|
Schema: diagnostics.PlatformHealthSchema, Status: "healthy", ObservedAt: now,
|
|
Checks: []diagnostics.PlatformHealthCheck{{Name: "public_https", Status: "healthy", Value: "http_200"}},
|
|
})
|
|
processor := &fakePlatformHealthProcessor{receipt: diagnostics.PlatformHealthReceipt{ID: "10000000-0000-0000-0000-000000000999", Status: "healthy"}}
|
|
handler := PlatformHealthCallbackHandler(secret, time.Minute, processor)
|
|
|
|
unsigned := httptest.NewRequest(http.MethodPost, "/callbacks/v1/platform-health", strings.NewReader(string(body)))
|
|
unsignedRecorder := httptest.NewRecorder()
|
|
handler.ServeHTTP(unsignedRecorder, unsigned)
|
|
if unsignedRecorder.Code != http.StatusUnauthorized || processor.calls != 0 {
|
|
t.Fatalf("unsigned status=%d calls=%d", unsignedRecorder.Code, processor.calls)
|
|
}
|
|
|
|
timestamp := strconv.FormatInt(now.Unix(), 10)
|
|
signed := httptest.NewRequest(http.MethodPost, "/callbacks/v1/platform-health", strings.NewReader(string(body)))
|
|
signed.Header.Set(HeaderPlatformTimestamp, timestamp)
|
|
signed.Header.Set(HeaderPlatformSignature, signPlatformHealth(secret, timestamp, body))
|
|
recorder := httptest.NewRecorder()
|
|
handler.ServeHTTP(recorder, signed)
|
|
if recorder.Code != http.StatusCreated || processor.calls != 1 || processor.lastInput.Schema != diagnostics.PlatformHealthSchema {
|
|
t.Fatalf("status=%d calls=%d input=%+v body=%s", recorder.Code, processor.calls, processor.lastInput, recorder.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestPlatformHealthCallbackRejectsStaleAndMalformedSignature(t *testing.T) {
|
|
secret := []byte("01234567890123456789012345678901")
|
|
body := []byte(`{"schema":"platform-server-health-v1","status":"healthy","observed_at":"2026-08-26T00:00:00Z","checks":[]}`)
|
|
now := time.Now().UTC()
|
|
staleTimestamp := strconv.FormatInt(now.Add(-10*time.Minute).Unix(), 10)
|
|
if verifyPlatformHealthSignature(secret, staleTimestamp, signPlatformHealth(secret, staleTimestamp, body), body, now, time.Minute) {
|
|
t.Fatal("stale signature accepted")
|
|
}
|
|
if verifyPlatformHealthSignature(secret, strconv.FormatInt(now.Unix(), 10), "sha256=broken", body, now, time.Minute) {
|
|
t.Fatal("malformed signature accepted")
|
|
}
|
|
}
|
|
|
|
func signPlatformHealth(secret []byte, timestamp string, body []byte) string {
|
|
mac := hmac.New(sha256.New, secret)
|
|
_, _ = mac.Write([]byte(timestamp + "."))
|
|
_, _ = mac.Write(body)
|
|
return "sha256=" + hex.EncodeToString(mac.Sum(nil))
|
|
}
|