修复 API Key ACL 开关的 CI 校验
This commit is contained in:
parent
08c8c67df7
commit
1d2445ff52
@ -580,7 +580,29 @@ type SecurityConfig struct {
|
|||||||
ProxyFallback ProxyFallbackConfig `mapstructure:"proxy_fallback"`
|
ProxyFallback ProxyFallbackConfig `mapstructure:"proxy_fallback"`
|
||||||
ProxyProbe ProxyProbeConfig `mapstructure:"proxy_probe"`
|
ProxyProbe ProxyProbeConfig `mapstructure:"proxy_probe"`
|
||||||
TrustForwardedIPForAPIKeyACL bool `mapstructure:"trust_forwarded_ip_for_api_key_acl"`
|
TrustForwardedIPForAPIKeyACL bool `mapstructure:"trust_forwarded_ip_for_api_key_acl"`
|
||||||
TrustForwardedIPForAPIKeyACLLive atomic.Bool `mapstructure:"-"`
|
trustForwardedIPForAPIKeyACLLive *atomic.Bool `mapstructure:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) TrustForwardedIPForAPIKeyACL() bool {
|
||||||
|
if c == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
live := c.Security.trustForwardedIPForAPIKeyACLLive
|
||||||
|
if live == nil {
|
||||||
|
return c.Security.TrustForwardedIPForAPIKeyACL
|
||||||
|
}
|
||||||
|
return live.Load()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) SetTrustForwardedIPForAPIKeyACL(enabled bool) {
|
||||||
|
if c == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Security.TrustForwardedIPForAPIKeyACL = enabled
|
||||||
|
if c.Security.trustForwardedIPForAPIKeyACLLive == nil {
|
||||||
|
c.Security.trustForwardedIPForAPIKeyACLLive = &atomic.Bool{}
|
||||||
|
}
|
||||||
|
c.Security.trustForwardedIPForAPIKeyACLLive.Store(enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
type URLAllowlistConfig struct {
|
type URLAllowlistConfig struct {
|
||||||
@ -1366,7 +1388,7 @@ func load(allowMissingJWTSecret bool) (*Config, error) {
|
|||||||
cfg.Security.ResponseHeaders.AdditionalAllowed = normalizeStringSlice(cfg.Security.ResponseHeaders.AdditionalAllowed)
|
cfg.Security.ResponseHeaders.AdditionalAllowed = normalizeStringSlice(cfg.Security.ResponseHeaders.AdditionalAllowed)
|
||||||
cfg.Security.ResponseHeaders.ForceRemove = normalizeStringSlice(cfg.Security.ResponseHeaders.ForceRemove)
|
cfg.Security.ResponseHeaders.ForceRemove = normalizeStringSlice(cfg.Security.ResponseHeaders.ForceRemove)
|
||||||
cfg.Security.CSP.Policy = strings.TrimSpace(cfg.Security.CSP.Policy)
|
cfg.Security.CSP.Policy = strings.TrimSpace(cfg.Security.CSP.Policy)
|
||||||
cfg.Security.TrustForwardedIPForAPIKeyACLLive.Store(cfg.Security.TrustForwardedIPForAPIKeyACL)
|
cfg.SetTrustForwardedIPForAPIKeyACL(cfg.Security.TrustForwardedIPForAPIKeyACL)
|
||||||
cfg.Log.Level = strings.ToLower(strings.TrimSpace(cfg.Log.Level))
|
cfg.Log.Level = strings.ToLower(strings.TrimSpace(cfg.Log.Level))
|
||||||
cfg.Log.Format = strings.ToLower(strings.TrimSpace(cfg.Log.Format))
|
cfg.Log.Format = strings.ToLower(strings.TrimSpace(cfg.Log.Format))
|
||||||
cfg.Log.ServiceName = strings.TrimSpace(cfg.Log.ServiceName)
|
cfg.Log.ServiceName = strings.TrimSpace(cfg.Log.ServiceName)
|
||||||
|
|||||||
@ -757,6 +757,7 @@ func TestAPIContracts(t *testing.T) {
|
|||||||
"site_logo": "",
|
"site_logo": "",
|
||||||
"site_subtitle": "Subtitle",
|
"site_subtitle": "Subtitle",
|
||||||
"api_base_url": "https://api.example.com",
|
"api_base_url": "https://api.example.com",
|
||||||
|
"api_key_acl_trust_forwarded_ip": false,
|
||||||
"contact_info": "support",
|
"contact_info": "support",
|
||||||
"doc_url": "https://docs.example.com",
|
"doc_url": "https://docs.example.com",
|
||||||
"auth_source_default_email_balance": 0,
|
"auth_source_default_email_balance": 0,
|
||||||
@ -1014,6 +1015,7 @@ func TestAPIContracts(t *testing.T) {
|
|||||||
"site_logo": "",
|
"site_logo": "",
|
||||||
"site_subtitle": "Subscription to API Conversion Platform",
|
"site_subtitle": "Subscription to API Conversion Platform",
|
||||||
"api_base_url": "",
|
"api_base_url": "",
|
||||||
|
"api_key_acl_trust_forwarded_ip": false,
|
||||||
"contact_info": "",
|
"contact_info": "",
|
||||||
"doc_url": "",
|
"doc_url": "",
|
||||||
"home_content": "",
|
"home_content": "",
|
||||||
|
|||||||
@ -90,7 +90,7 @@ func apiKeyAuthWithSubscription(apiKeyService *service.APIKeyService, subscripti
|
|||||||
// 注意:错误信息故意模糊,避免暴露具体的 IP 限制机制
|
// 注意:错误信息故意模糊,避免暴露具体的 IP 限制机制
|
||||||
if len(apiKey.IPWhitelist) > 0 || len(apiKey.IPBlacklist) > 0 {
|
if len(apiKey.IPWhitelist) > 0 || len(apiKey.IPBlacklist) > 0 {
|
||||||
clientIP := ip.GetTrustedClientIP(c)
|
clientIP := ip.GetTrustedClientIP(c)
|
||||||
if cfg != nil && cfg.Security.TrustForwardedIPForAPIKeyACLLive.Load() {
|
if cfg.TrustForwardedIPForAPIKeyACL() {
|
||||||
clientIP = ip.GetClientIP(c)
|
clientIP = ip.GetClientIP(c)
|
||||||
}
|
}
|
||||||
allowed, _ := ip.CheckIPRestrictionWithCompiledRules(clientIP, apiKey.CompiledIPWhitelist, apiKey.CompiledIPBlacklist)
|
allowed, _ := ip.CheckIPRestrictionWithCompiledRules(clientIP, apiKey.CompiledIPWhitelist, apiKey.CompiledIPBlacklist)
|
||||||
|
|||||||
@ -490,8 +490,7 @@ func TestAPIKeyAuthIPRestrictionCanTrustForwardedClientIPForReverseProxy(t *test
|
|||||||
}
|
}
|
||||||
|
|
||||||
cfg := &config.Config{RunMode: config.RunModeSimple}
|
cfg := &config.Config{RunMode: config.RunModeSimple}
|
||||||
cfg.Security.TrustForwardedIPForAPIKeyACL = true
|
cfg.SetTrustForwardedIPForAPIKeyACL(true)
|
||||||
cfg.Security.TrustForwardedIPForAPIKeyACLLive.Store(true)
|
|
||||||
apiKeyService := service.NewAPIKeyService(apiKeyRepo, nil, nil, nil, nil, nil, cfg)
|
apiKeyService := service.NewAPIKeyService(apiKeyRepo, nil, nil, nil, nil, nil, cfg)
|
||||||
router := gin.New()
|
router := gin.New()
|
||||||
require.NoError(t, router.SetTrustedProxies(nil))
|
require.NoError(t, router.SetTrustedProxies(nil))
|
||||||
|
|||||||
@ -604,14 +604,13 @@ func (s *SettingService) LoadAPIKeyACLTrustForwardedIPSetting(ctx context.Contex
|
|||||||
value, err := s.settingRepo.GetValue(ctx, SettingKeyAPIKeyACLTrustForwardedIP)
|
value, err := s.settingRepo.GetValue(ctx, SettingKeyAPIKeyACLTrustForwardedIP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, ErrSettingNotFound) {
|
if errors.Is(err, ErrSettingNotFound) {
|
||||||
s.cfg.Security.TrustForwardedIPForAPIKeyACLLive.Store(s.cfg.Security.TrustForwardedIPForAPIKeyACL)
|
s.cfg.SetTrustForwardedIPForAPIKeyACL(s.cfg.Security.TrustForwardedIPForAPIKeyACL)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("get api key acl forwarded ip setting: %w", err)
|
return fmt.Errorf("get api key acl forwarded ip setting: %w", err)
|
||||||
}
|
}
|
||||||
enabled := value == "true"
|
enabled := value == "true"
|
||||||
s.cfg.Security.TrustForwardedIPForAPIKeyACL = enabled
|
s.cfg.SetTrustForwardedIPForAPIKeyACL(enabled)
|
||||||
s.cfg.Security.TrustForwardedIPForAPIKeyACLLive.Store(enabled)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1888,8 +1887,7 @@ func (s *SettingService) refreshCachedSettings(settings *SystemSettings) {
|
|||||||
expiresAt: time.Now().Add(openAIAdvancedSchedulerSettingCacheTTL).UnixNano(),
|
expiresAt: time.Now().Add(openAIAdvancedSchedulerSettingCacheTTL).UnixNano(),
|
||||||
})
|
})
|
||||||
if s.cfg != nil {
|
if s.cfg != nil {
|
||||||
s.cfg.Security.TrustForwardedIPForAPIKeyACL = settings.APIKeyACLTrustForwardedIP
|
s.cfg.SetTrustForwardedIPForAPIKeyACL(settings.APIKeyACLTrustForwardedIP)
|
||||||
s.cfg.Security.TrustForwardedIPForAPIKeyACLLive.Store(settings.APIKeyACLTrustForwardedIP)
|
|
||||||
}
|
}
|
||||||
if s.onUpdate != nil {
|
if s.onUpdate != nil {
|
||||||
s.onUpdate() // Invalidate cache after settings update
|
s.onUpdate() // Invalidate cache after settings update
|
||||||
|
|||||||
@ -301,7 +301,7 @@ func TestSettingService_UpdateSettings_APIKeyACLTrustForwardedIPRefreshesConfig(
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, "true", repo.updates[SettingKeyAPIKeyACLTrustForwardedIP])
|
require.Equal(t, "true", repo.updates[SettingKeyAPIKeyACLTrustForwardedIP])
|
||||||
require.True(t, cfg.Security.TrustForwardedIPForAPIKeyACL)
|
require.True(t, cfg.Security.TrustForwardedIPForAPIKeyACL)
|
||||||
require.True(t, cfg.Security.TrustForwardedIPForAPIKeyACLLive.Load())
|
require.True(t, cfg.TrustForwardedIPForAPIKeyACL())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSettingService_ParseSettings_APIKeyACLTrustForwardedIPFallsBackToConfigWhenMissing(t *testing.T) {
|
func TestSettingService_ParseSettings_APIKeyACLTrustForwardedIPFallsBackToConfigWhenMissing(t *testing.T) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user