package auth import ( "crypto/hmac" "crypto/sha256" "encoding/hex" "encoding/json" "io" "net/http" "net/http/httptest" "strings" "testing" ) func TestServerMainAPIKeyUsesSignedCurrentContract(t *testing.T) { const key = "gateway-test" const secret = "server-main-internal-secret" server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, request *http.Request) { if request.URL.Path != "/internal/auth/verify-apikey" || request.Header.Get("X-Internal-Key") != key { t.Fatalf("unexpected request %s", request.URL.Path) } body, _ := io.ReadAll(request.Body) hash := sha256.Sum256(body) text := strings.Join([]string{ request.Method, request.URL.RequestURI(), request.Header.Get("X-Timestamp"), request.Header.Get("X-Nonce"), hex.EncodeToString(hash[:]), key, }, "\n") mac := hmac.New(sha256.New, []byte(secret)) _, _ = mac.Write([]byte(text)) if !hmac.Equal([]byte(request.Header.Get("X-Signature")), []byte(hex.EncodeToString(mac.Sum(nil)))) { t.Fatal("invalid internal request signature") } _ = json.NewEncoder(w).Encode(map[string]any{"success": true, "data": map[string]any{"user": map[string]any{ "sub": "server-user", "username": "server", "role": []string{"user"}, "tenantId": "server-tenant", }}}) })) t.Cleanup(server.Close) authenticator := New("jwt", server.URL, "") authenticator.ServerMainInternalKey = key authenticator.ServerMainInternalSecret = secret request := httptest.NewRequest(http.MethodGet, "/api/v1/me", nil) request.Header.Set("Authorization", "Bearer sk-server-main") user, err := authenticator.Authenticate(request) if err != nil { t.Fatal(err) } if user.ID != "server-user" || user.Source != "server-main" || user.TenantID != "server-tenant" { t.Fatalf("user = %#v", user) } }