package rest import ( "errors" "fmt" "net/http" "net/http/httptest" "testing" "github.com/open-policy-agent/opa/v1/keys" ) func TestGCPMetadataAuthPlugin(t *testing.T) { idToken := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.Et9HFtf9R3GEMA0IICOfFMVXY7kkTX1wr4qCyhIf58U" s := httptest.NewServer(http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {})) defer s.Close() ts := httptest.NewServer(http.Handler(&gcpMetadataHandler{idToken})) defer ts.Close() config := fmt.Sprintf(`{ "name": "foo", "url": "%s", "allow_insecure_tls": true, "credentials": { "gcp_metadata": { "audience": "https://example.org", "endpoint": "%s" } } }`, s.URL, ts.URL) client, err := New([]byte(config), map[string]*keys.Config{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } ctx := t.Context() _, err = client.Do(ctx, "GET", "test") if err != nil { t.Fatalf("Unexpected error: %v", err) } } func TestIdentityTokenFromMetadataService(t *testing.T) { token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.Et9HFtf9R3GEMA0IICOfFMVXY7kkTX1wr4qCyhIf58U" ts := httptest.NewServer(http.Handler(&gcpMetadataHandler{token})) defer ts.Close() tests := []struct { audience string identityToken string identityTokenPath string err error }{ {"https://example.org", token, defaultIdentityTokenPath, nil}, {"", "", defaultIdentityTokenPath, errGCPMetadataInvalidRequest}, {"https://example.org", "", "/status/bad/request", errGCPMetadataInvalidRequest}, {"https://example.org", "", "/status/not/found", errGCPMetadataNotFound}, {"https://example.org", "", "/status/internal/server/error", errGCPMetadataUnexpected}, } for _, tt := range tests { token, err := identityTokenFromMetadataService(ts.URL, tt.identityTokenPath, tt.audience) if !errors.Is(err, tt.err) { t.Fatalf("Unexpected error, got %v, want %v", err, tt.err) } if token != tt.identityToken { t.Fatalf("Unexpected id token, got %v, want %v", token, tt.identityToken) } } } type gcpMetadataHandler struct { identityToken string } func (h *gcpMetadataHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { path := r.URL.Path audience := r.URL.Query()["audience"][0] if audience == "" { http.Error(w, "", http.StatusBadRequest) return } switch path { case defaultIdentityTokenPath: fmt.Fprint(w, h.identityToken) case "/status/bad/request": http.Error(w, "", http.StatusBadRequest) case "/status/not/found": http.Error(w, "", http.StatusNotFound) case "/status/internal/server/error": http.Error(w, "", http.StatusInternalServerError) default: http.Error(w, "", http.StatusNotFound) } }