diff --git a/pkg/accessreview/drivers/posthog.go b/pkg/accessreview/drivers/posthog.go index 9f4943239..27b1f0da0 100644 --- a/pkg/accessreview/drivers/posthog.go +++ b/pkg/accessreview/drivers/posthog.go @@ -169,12 +169,12 @@ func (d *PostHogDriver) resolveNextURL(next string) (string, error) { return "", fmt.Errorf("cannot parse posthog next page URL: %w", err) } - base, err := url.Parse(d.baseURL) - if err != nil { - return "", fmt.Errorf("cannot parse posthog base URL: %w", err) - } - if nextURL.IsAbs() { + base, err := url.Parse(d.baseURL) + if err != nil { + return "", fmt.Errorf("cannot parse posthog base URL: %w", err) + } + // Pin pagination to the resolved data host. The connection's bearer // token is attached to every request, so an absolute `next` pointing // at a different host (a compromised or spoofed API response) would @@ -200,6 +200,21 @@ func (d *PostHogDriver) resolveNextURL(next string) (string, error) { return baseURL.ResolveReference(nextURL).String(), nil } +// PostHogRegionBaseURL maps a PostHog Cloud region ("US"/"EU", +// case-insensitive) to its data-API host. It is the single source of truth for +// the regional hosts, shared with the connector-settings resolver so the two +// never drift. Self-hosted instances use a full instance URL instead. +func PostHogRegionBaseURL(region string) (string, bool) { + switch strings.ToLower(region) { + case "us": + return posthogUSBaseURL, true + case "eu": + return posthogEUBaseURL, true + default: + return "", false + } +} + // resolvePostHogRegion probes the PostHog Cloud region hosts with the given // token-bearing client and returns the first that answers 2xx on the @current // organization endpoint. OAuth connections authenticate via the region-agnostic diff --git a/pkg/server/api/console/v1/connector_settings.go b/pkg/server/api/console/v1/connector_settings.go index a636a389e..45c3d8e60 100644 --- a/pkg/server/api/console/v1/connector_settings.go +++ b/pkg/server/api/console/v1/connector_settings.go @@ -19,6 +19,7 @@ import ( "fmt" "net/url" + "go.probo.inc/probo/pkg/accessreview/drivers" "go.probo.inc/probo/pkg/coredata" "go.probo.inc/probo/pkg/server/api/console/v1/types" ) @@ -98,7 +99,7 @@ func apiKeyConnectorSettings(input types.CreateAPIKeyConnectorInput) (json.RawMe return nil, fmt.Errorf("cannot create posthog connector: posthogRegion is required") } - baseURL, ok := posthogRegionBaseURL(*input.PosthogRegion) + baseURL, ok := drivers.PostHogRegionBaseURL(*input.PosthogRegion) if !ok { return nil, fmt.Errorf("cannot create posthog connector: posthogRegion must be US or EU") } @@ -120,20 +121,6 @@ func apiKeyConnectorSettings(input types.CreateAPIKeyConnectorInput) (json.RawMe return nil, nil } -// posthogRegionBaseURL maps a PostHog Cloud region selector to its data-API -// base host. Only US and EU clouds exist; self-hosted instances use the -// dedicated POSTHOG_SELF_HOSTED provider with a full instance URL instead. -func posthogRegionBaseURL(region string) (string, bool) { - switch region { - case "US", "us": - return "https://us.posthog.com", true - case "EU", "eu": - return "https://eu.posthog.com", true - default: - return "", false - } -} - // clientCredentialsConnectorSettings marshals the provider-specific // extra settings for a client-credentials connector. See // apiKeyConnectorSettings for the error contract.