Release / update-version (push) Has been cancelled
Release / build-frontend (push) Has been cancelled
Release / release (push) Has been cancelled
Release / sync-version-file (push) Has been cancelled
CI / shell (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
Security Scan / backend-security (push) Canceled after 0s
Security Scan / frontend-security (push) Canceled after 0s
327 lines
11 KiB
Go
327 lines
11 KiB
Go
//go:build unit
|
|
|
|
package service
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/Wei-Shaw/sub2api/internal/config"
|
|
"github.com/Wei-Shaw/sub2api/internal/pkg/xai"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestGrokAPIKeyURLPolicyFollowsGlobalSecurityConfig(t *testing.T) {
|
|
account := &Account{
|
|
Platform: PlatformGrok,
|
|
Type: AccountTypeAPIKey,
|
|
Credentials: map[string]any{
|
|
"base_url": "http://grok.example.test/v1",
|
|
},
|
|
}
|
|
|
|
t.Run("insecure HTTP enabled with allowlist disabled", func(t *testing.T) {
|
|
cfg := &config.Config{}
|
|
cfg.Security.URLAllowlist.Enabled = false
|
|
cfg.Security.URLAllowlist.AllowInsecureHTTP = true
|
|
|
|
responsesURL, err := buildGrokResponsesURL(account, cfg)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "http://grok.example.test/v1/responses", responsesURL)
|
|
|
|
chatURL, err := buildGrokChatCompletionsURL(account, cfg)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "http://grok.example.test/v1/chat/completions", chatURL)
|
|
|
|
mediaURL, err := buildGrokMediaURL(account, cfg, GrokMediaEndpointImagesGenerations, "")
|
|
require.NoError(t, err)
|
|
require.Equal(t, "http://grok.example.test/v1/images/generations", mediaURL)
|
|
|
|
contentURL, err := buildGrokMediaURL(account, cfg, GrokMediaEndpointVideoContent, "request 123")
|
|
require.NoError(t, err)
|
|
require.Equal(t, "http://grok.example.test/v1/videos/request%20123/content", contentURL)
|
|
})
|
|
|
|
t.Run("insecure HTTP disabled", func(t *testing.T) {
|
|
cfg := &config.Config{}
|
|
cfg.Security.URLAllowlist.Enabled = false
|
|
cfg.Security.URLAllowlist.AllowInsecureHTTP = false
|
|
|
|
_, err := buildGrokResponsesURL(account, cfg)
|
|
require.EqualError(t, err, "invalid base url: base URL rejected by URL security policy")
|
|
})
|
|
|
|
t.Run("enabled allowlist remains HTTPS only", func(t *testing.T) {
|
|
cfg := &config.Config{}
|
|
cfg.Security.URLAllowlist.Enabled = true
|
|
cfg.Security.URLAllowlist.AllowInsecureHTTP = true
|
|
cfg.Security.URLAllowlist.UpstreamHosts = []string{"grok.example.test"}
|
|
|
|
_, err := buildGrokResponsesURL(account, cfg)
|
|
require.EqualError(t, err, "invalid base url: base URL rejected by URL security policy")
|
|
})
|
|
}
|
|
|
|
func TestGrokAPIKeyURLPolicyAppliesAllowlistAndPrivateHostControls(t *testing.T) {
|
|
account := &Account{
|
|
Platform: PlatformGrok,
|
|
Type: AccountTypeAPIKey,
|
|
Credentials: map[string]any{
|
|
"base_url": "https://grok.example.test/v1",
|
|
},
|
|
}
|
|
cfg := &config.Config{}
|
|
cfg.Security.URLAllowlist.Enabled = true
|
|
cfg.Security.URLAllowlist.UpstreamHosts = []string{"grok.example.test"}
|
|
|
|
target, err := buildGrokResponsesURL(account, cfg)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "https://grok.example.test/v1/responses", target)
|
|
|
|
cfg.Security.URLAllowlist.UpstreamHosts = []string{"other.example.test"}
|
|
_, err = buildGrokResponsesURL(account, cfg)
|
|
require.EqualError(t, err, "invalid base url: base URL rejected by URL security policy")
|
|
|
|
account.Credentials["base_url"] = "https://127.0.0.1/v1"
|
|
cfg.Security.URLAllowlist.UpstreamHosts = []string{"127.0.0.1"}
|
|
_, err = buildGrokResponsesURL(account, cfg)
|
|
require.EqualError(t, err, "invalid base url: base URL rejected by URL security policy")
|
|
|
|
cfg.Security.URLAllowlist.AllowPrivateHosts = true
|
|
target, err = buildGrokResponsesURL(account, cfg)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "https://127.0.0.1/v1/responses", target)
|
|
}
|
|
|
|
func TestGrokAPIKeyURLPolicyRedactsMalformedConfiguredURL(t *testing.T) {
|
|
account := &Account{
|
|
Platform: PlatformGrok,
|
|
Type: AccountTypeAPIKey,
|
|
Credentials: map[string]any{
|
|
"base_url": "https://%zz:secret@grok.example.test/v1",
|
|
},
|
|
}
|
|
cfg := &config.Config{}
|
|
cfg.Security.URLAllowlist.AllowInsecureHTTP = true
|
|
|
|
_, err := buildGrokResponsesURL(account, cfg)
|
|
require.EqualError(t, err, "invalid base url: base URL rejected by URL security policy")
|
|
require.NotContains(t, err.Error(), "secret")
|
|
}
|
|
|
|
func TestGrokOAuthURLPolicy(t *testing.T) {
|
|
t.Run("default CLI gateway always allowed under restrictive allowlist", func(t *testing.T) {
|
|
account := &Account{
|
|
Platform: PlatformGrok,
|
|
Type: AccountTypeOAuth,
|
|
Credentials: map[string]any{},
|
|
}
|
|
cfg := &config.Config{}
|
|
cfg.Security.URLAllowlist.Enabled = true
|
|
cfg.Security.URLAllowlist.UpstreamHosts = []string{"other.example.test"}
|
|
|
|
target, err := buildGrokResponsesURL(account, cfg)
|
|
require.NoError(t, err)
|
|
require.Equal(t, xai.DefaultCLIBaseURL+"/responses", target)
|
|
})
|
|
|
|
t.Run("stored official API endpoint is honored (manual endpoint switch)", func(t *testing.T) {
|
|
account := &Account{
|
|
Platform: PlatformGrok,
|
|
Type: AccountTypeOAuth,
|
|
Credentials: map[string]any{
|
|
"base_url": xai.DefaultBaseURL,
|
|
},
|
|
}
|
|
cfg := &config.Config{}
|
|
|
|
target, err := buildGrokResponsesURL(account, cfg)
|
|
require.NoError(t, err)
|
|
require.Equal(t, xai.DefaultBaseURL+"/responses", target)
|
|
})
|
|
|
|
t.Run("stored regional API endpoint is trusted even under restrictive allowlist", func(t *testing.T) {
|
|
account := &Account{
|
|
Platform: PlatformGrok,
|
|
Type: AccountTypeOAuth,
|
|
Credentials: map[string]any{
|
|
"base_url": "https://us-west-2.api.x.ai/v1",
|
|
},
|
|
}
|
|
cfg := &config.Config{}
|
|
cfg.Security.URLAllowlist.Enabled = true
|
|
cfg.Security.URLAllowlist.UpstreamHosts = []string{"other.example.test"}
|
|
|
|
target, err := buildGrokResponsesURL(account, cfg)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "https://us-west-2.api.x.ai/v1/responses", target)
|
|
})
|
|
|
|
t.Run("custom forwarding address follows operator policy", func(t *testing.T) {
|
|
account := &Account{
|
|
Platform: PlatformGrok,
|
|
Type: AccountTypeOAuth,
|
|
Credentials: map[string]any{
|
|
"base_url": "https://relay.example.test/v1",
|
|
},
|
|
}
|
|
cfg := &config.Config{}
|
|
cfg.Security.URLAllowlist.Enabled = false
|
|
|
|
target, err := buildGrokResponsesURL(account, cfg)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "https://relay.example.test/v1/responses", target)
|
|
})
|
|
|
|
t.Run("custom path prefix is preserved", func(t *testing.T) {
|
|
account := &Account{
|
|
Platform: PlatformGrok,
|
|
Type: AccountTypeOAuth,
|
|
Credentials: map[string]any{
|
|
"base_url": "https://relay.example.test/xai/v1",
|
|
},
|
|
}
|
|
cfg := &config.Config{}
|
|
|
|
target, err := buildGrokResponsesURL(account, cfg)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "https://relay.example.test/xai/v1/responses", target)
|
|
})
|
|
|
|
t.Run("custom forwarding address rejected by allowlist", func(t *testing.T) {
|
|
account := &Account{
|
|
Platform: PlatformGrok,
|
|
Type: AccountTypeOAuth,
|
|
Credentials: map[string]any{
|
|
"base_url": "https://relay.example.test/v1",
|
|
},
|
|
}
|
|
cfg := &config.Config{}
|
|
cfg.Security.URLAllowlist.Enabled = true
|
|
cfg.Security.URLAllowlist.UpstreamHosts = []string{"other.example.test"}
|
|
|
|
_, err := buildGrokResponsesURL(account, cfg)
|
|
require.EqualError(t, err, "invalid base url: base URL rejected by URL security policy")
|
|
})
|
|
|
|
t.Run("insecure HTTP custom address requires operator opt-in", func(t *testing.T) {
|
|
account := &Account{
|
|
Platform: PlatformGrok,
|
|
Type: AccountTypeOAuth,
|
|
Credentials: map[string]any{
|
|
"base_url": "http://relay.example.test/v1",
|
|
},
|
|
}
|
|
cfg := &config.Config{}
|
|
cfg.Security.URLAllowlist.Enabled = false
|
|
cfg.Security.URLAllowlist.AllowInsecureHTTP = false
|
|
|
|
_, err := buildGrokResponsesURL(account, cfg)
|
|
require.EqualError(t, err, "invalid base url: base URL rejected by URL security policy")
|
|
|
|
cfg.Security.URLAllowlist.AllowInsecureHTTP = true
|
|
target, err := buildGrokResponsesURL(account, cfg)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "http://relay.example.test/v1/responses", target)
|
|
})
|
|
|
|
t.Run("unsafe override switch does not relax the operator allowlist for custom hosts", func(t *testing.T) {
|
|
// XAI_ALLOW_UNSAFE_URL_OVERRIDES relaxes the trusted-host validator to
|
|
// accept-any; a custom OAuth forwarding host must still be governed by
|
|
// the operator allowlist so the bearer token cannot reach arbitrary hosts.
|
|
t.Setenv(xai.EnvAllowUnsafeURLOverrides, "true")
|
|
cfg := &config.Config{}
|
|
cfg.Security.URLAllowlist.Enabled = true
|
|
cfg.Security.URLAllowlist.UpstreamHosts = []string{"cli-chat-proxy.grok.com"}
|
|
|
|
custom := &Account{
|
|
Platform: PlatformGrok,
|
|
Type: AccountTypeOAuth,
|
|
Credentials: map[string]any{
|
|
"base_url": "http://10.0.0.1/v1",
|
|
},
|
|
}
|
|
_, err := buildGrokResponsesURL(custom, cfg)
|
|
require.EqualError(t, err, "invalid base url: base URL rejected by URL security policy")
|
|
|
|
// The official gateway still resolves even under the restrictive allowlist.
|
|
official := &Account{
|
|
Platform: PlatformGrok,
|
|
Type: AccountTypeOAuth,
|
|
Credentials: map[string]any{},
|
|
}
|
|
target, err := buildGrokResponsesURL(official, cfg)
|
|
require.NoError(t, err)
|
|
require.Equal(t, xai.DefaultCLIBaseURL+"/responses", target)
|
|
})
|
|
}
|
|
|
|
func TestBuildGrokBillingURLUsesCLIForOfficialAPIHosts(t *testing.T) {
|
|
for _, baseURL := range []string{xai.DefaultBaseURL, "https://us-west-2.api.x.ai/v1"} {
|
|
account := &Account{Platform: PlatformGrok, Type: AccountTypeOAuth, Credentials: map[string]any{"base_url": baseURL}}
|
|
|
|
weekly, err := buildGrokBillingURL(account, &config.Config{}, true)
|
|
require.NoError(t, err)
|
|
require.Equal(t, xai.DefaultCLIBaseURL+xai.BillingWeeklyPath, weekly)
|
|
}
|
|
}
|
|
|
|
func TestBuildGrokBillingURLKeepsCustomRelay(t *testing.T) {
|
|
account := &Account{Platform: PlatformGrok, Type: AccountTypeOAuth, Credentials: map[string]any{
|
|
"base_url": "https://relay.example.test/xai/v1",
|
|
}}
|
|
|
|
monthly, err := buildGrokBillingURL(account, &config.Config{}, false)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "https://relay.example.test/xai/v1"+xai.BillingMonthlyPath, monthly)
|
|
}
|
|
|
|
func TestGrokBillingURLFollowsAccountBaseURL(t *testing.T) {
|
|
t.Run("oauth default stays on CLI gateway", func(t *testing.T) {
|
|
account := &Account{
|
|
Platform: PlatformGrok,
|
|
Type: AccountTypeOAuth,
|
|
Credentials: map[string]any{},
|
|
}
|
|
|
|
weeklyURL, err := buildGrokBillingURL(account, nil, true)
|
|
require.NoError(t, err)
|
|
require.Equal(t, xai.DefaultCLIBaseURL+"/billing?format=credits", weeklyURL)
|
|
|
|
monthlyURL, err := buildGrokBillingURL(account, nil, false)
|
|
require.NoError(t, err)
|
|
require.Equal(t, xai.DefaultCLIBaseURL+"/billing", monthlyURL)
|
|
})
|
|
|
|
t.Run("oauth custom forwarding address carries billing probes", func(t *testing.T) {
|
|
account := &Account{
|
|
Platform: PlatformGrok,
|
|
Type: AccountTypeOAuth,
|
|
Credentials: map[string]any{
|
|
"base_url": "https://relay.example.test/v1",
|
|
},
|
|
}
|
|
|
|
weeklyURL, err := buildGrokBillingURL(account, nil, true)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "https://relay.example.test/v1/billing?format=credits", weeklyURL)
|
|
})
|
|
|
|
t.Run("billing probe honors the operator allowlist like forwarding", func(t *testing.T) {
|
|
// Probe paths must share the forwarding URL policy so a custom host the
|
|
// allowlist rejects cannot receive the OAuth bearer via a billing probe.
|
|
account := &Account{
|
|
Platform: PlatformGrok,
|
|
Type: AccountTypeOAuth,
|
|
Credentials: map[string]any{
|
|
"base_url": "https://relay.example.test/v1",
|
|
},
|
|
}
|
|
cfg := &config.Config{}
|
|
cfg.Security.URLAllowlist.Enabled = true
|
|
cfg.Security.URLAllowlist.UpstreamHosts = []string{"cli-chat-proxy.grok.com"}
|
|
|
|
_, err := buildGrokBillingURL(account, cfg, true)
|
|
require.EqualError(t, err, "invalid base url: base URL rejected by URL security policy")
|
|
})
|
|
}
|