diff --git a/pkg/connectors/microcks_client.go b/pkg/connectors/microcks_client.go index 8ecd4205..02652738 100644 --- a/pkg/connectors/microcks_client.go +++ b/pkg/connectors/microcks_client.go @@ -247,16 +247,25 @@ func (c *microcksClient) GetKeycloakURL() (string, error) { panic(err) } - // Retrieve auth server url and realm name. - enabled := configResp["enabled"].(bool) - authServerURL := configResp["auth-server-url"].(string) - realmName := configResp["realm"].(string) - - // Return a proper URL or 'null' if Keycloak is disables. - if enabled { - return authServerURL + "/realms/" + realmName + "/", nil + // Retrieve auth server url and realm name using comma-ok assertions + // so a malformed response surfaces as a Go error instead of a panic. + enabled, ok := configResp["enabled"].(bool) + if !ok { + return "", fmt.Errorf("Microcks /api/keycloak/config response missing or invalid 'enabled' field") + } + // Return 'null' if Keycloak is disabled. + if !enabled { + return "null", nil + } + authServerURL, ok := configResp["auth-server-url"].(string) + if !ok { + return "", fmt.Errorf("Microcks /api/keycloak/config response missing or invalid 'auth-server-url' field") + } + realmName, ok := configResp["realm"].(string) + if !ok { + return "", fmt.Errorf("Microcks /api/keycloak/config response missing or invalid 'realm' field") } - return "null", nil + return authServerURL + "/realms/" + realmName + "/", nil } func (c *microcksClient) refreshAuthToken(localCfg *config.LocalConfig, ctxName, configPath string) error { diff --git a/pkg/connectors/microcks_client_test.go b/pkg/connectors/microcks_client_test.go index 2fe423e7..36cd5efb 100644 --- a/pkg/connectors/microcks_client_test.go +++ b/pkg/connectors/microcks_client_test.go @@ -102,3 +102,63 @@ func TestDownloadArtifactReturnsResponseBody(t *testing.T) { t.Fatalf("expected response body %q, got %q", expectedBody, msg) } } + +func TestGetKeycloakURL_Enabled(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/api/keycloak/config" { + t.Fatalf("unexpected path: %s", r.URL.Path) + } + if r.Method != http.MethodGet { + t.Fatalf("unexpected method: %s", r.Method) + } + w.Header().Set("Content-Type", "application/json") + _, _ = w.Write([]byte(`{"enabled": true, "auth-server-url": "https://kc", "realm": "microcks"}`)) + })) + defer server.Close() + + client := NewMicrocksClient(server.URL) + + got, err := client.GetKeycloakURL() + if err != nil { + t.Fatalf("GetKeycloakURL returned error: %v", err) + } + if want := "https://kc/realms/microcks/"; got != want { + t.Fatalf("expected %q, got %q", want, got) + } +} + +func TestGetKeycloakURL_Disabled(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + _, _ = w.Write([]byte(`{"enabled": false}`)) + })) + defer server.Close() + + client := NewMicrocksClient(server.URL) + + got, err := client.GetKeycloakURL() + if err != nil { + t.Fatalf("GetKeycloakURL returned error: %v", err) + } + if want := "null"; got != want { + t.Fatalf("expected %q, got %q", want, got) + } +} + +func TestGetKeycloakURL_MalformedResponse(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + _, _ = w.Write([]byte(`{}`)) + })) + defer server.Close() + + client := NewMicrocksClient(server.URL) + + got, err := client.GetKeycloakURL() + if err == nil { + t.Fatalf("expected error for malformed response, got nil (result=%q)", got) + } + if got != "" { + t.Fatalf("expected empty string on error, got %q", got) + } +}