mirror of
https://github.com/EZ-Api/ez-api.git
synced 2026-01-13 17:47:51 +00:00
feat(api): add OAuth token fields and new provider types support
Add support for OAuth-based authentication with access/refresh tokens and expiration tracking for API keys. Extend provider groups with static headers configuration and headers profile options. Changes include: - Add AccessToken, RefreshToken, ExpiresAt, AccountID, ProjectID to APIKey model - Add StaticHeaders and HeadersProfile to ProviderGroup model - Add TokenRefresh configuration for background token management - Support new provider types: ClaudeCode, Codex, GeminiCLI, Antigravity - Update sync service to include new fields in provider snapshots
This commit is contained in:
@@ -33,16 +33,30 @@ func (m *ProviderGroupManager) NormalizeGroup(group model.ProviderGroup) (model.
|
||||
group.BaseURL = strings.TrimSpace(group.BaseURL)
|
||||
group.GoogleProject = strings.TrimSpace(group.GoogleProject)
|
||||
group.GoogleLocation = strings.TrimSpace(group.GoogleLocation)
|
||||
group.StaticHeaders = strings.TrimSpace(group.StaticHeaders)
|
||||
group.HeadersProfile = strings.TrimSpace(group.HeadersProfile)
|
||||
|
||||
switch ptype {
|
||||
case provider.TypeOpenAI:
|
||||
if group.BaseURL == "" {
|
||||
group.BaseURL = "https://api.openai.com/v1"
|
||||
}
|
||||
case provider.TypeAnthropic, provider.TypeClaude:
|
||||
case provider.TypeAnthropic, provider.TypeClaude, provider.TypeClaudeCode:
|
||||
if group.BaseURL == "" {
|
||||
group.BaseURL = "https://api.anthropic.com"
|
||||
}
|
||||
case provider.TypeCodex:
|
||||
if group.BaseURL == "" {
|
||||
group.BaseURL = "https://chatgpt.com"
|
||||
}
|
||||
case provider.TypeGeminiCLI:
|
||||
if group.BaseURL == "" {
|
||||
group.BaseURL = "https://cloudcode-pa.googleapis.com"
|
||||
}
|
||||
case provider.TypeAntigravity:
|
||||
if group.BaseURL == "" {
|
||||
group.BaseURL = "https://daily-cloudcode-pa.googleapis.com"
|
||||
}
|
||||
case provider.TypeCompatible:
|
||||
if group.BaseURL == "" {
|
||||
return model.ProviderGroup{}, fmt.Errorf("base_url required for compatible providers")
|
||||
@@ -72,8 +86,14 @@ func (m *ProviderGroupManager) ValidateAPIKey(group model.ProviderGroup, key mod
|
||||
return fmt.Errorf("provider group type required")
|
||||
}
|
||||
apiKey := strings.TrimSpace(key.APIKey)
|
||||
accessToken := strings.TrimSpace(key.AccessToken)
|
||||
|
||||
switch {
|
||||
case ptype == provider.TypeCodex || ptype == provider.TypeGeminiCLI || ptype == provider.TypeAntigravity || ptype == provider.TypeClaudeCode:
|
||||
if accessToken == "" {
|
||||
return fmt.Errorf("access_token required")
|
||||
}
|
||||
return nil
|
||||
case provider.IsVertexFamily(ptype):
|
||||
// Vertex uses ADC; api_key can be empty.
|
||||
return nil
|
||||
|
||||
@@ -278,8 +278,14 @@ type providerSnapshot struct {
|
||||
Type string `json:"type"`
|
||||
BaseURL string `json:"base_url"`
|
||||
APIKey string `json:"api_key"`
|
||||
AccessToken string `json:"access_token,omitempty"`
|
||||
ExpiresAt int64 `json:"expires_at,omitempty"`
|
||||
AccountID string `json:"account_id,omitempty"`
|
||||
ProjectID string `json:"project_id,omitempty"`
|
||||
GoogleProject string `json:"google_project,omitempty"`
|
||||
GoogleLocation string `json:"google_location,omitempty"`
|
||||
StaticHeaders string `json:"static_headers,omitempty"`
|
||||
HeadersProfile string `json:"headers_profile,omitempty"`
|
||||
GroupID uint `json:"group_id,omitempty"`
|
||||
Group string `json:"group"`
|
||||
Models []string `json:"models"`
|
||||
@@ -333,8 +339,13 @@ func (s *SyncService) writeProvidersSnapshot(ctx context.Context, pipe redis.Pip
|
||||
Type: strings.TrimSpace(g.Type),
|
||||
BaseURL: strings.TrimSpace(g.BaseURL),
|
||||
APIKey: strings.TrimSpace(k.APIKey),
|
||||
AccessToken: strings.TrimSpace(k.AccessToken),
|
||||
GoogleProject: strings.TrimSpace(g.GoogleProject),
|
||||
GoogleLocation: strings.TrimSpace(g.GoogleLocation),
|
||||
StaticHeaders: strings.TrimSpace(g.StaticHeaders),
|
||||
HeadersProfile: strings.TrimSpace(g.HeadersProfile),
|
||||
AccountID: strings.TrimSpace(k.AccountID),
|
||||
ProjectID: strings.TrimSpace(k.ProjectID),
|
||||
GroupID: g.ID,
|
||||
Group: groupName,
|
||||
Models: models,
|
||||
@@ -343,6 +354,9 @@ func (s *SyncService) writeProvidersSnapshot(ctx context.Context, pipe redis.Pip
|
||||
AutoBan: k.AutoBan,
|
||||
BanReason: strings.TrimSpace(k.BanReason),
|
||||
}
|
||||
if k.ExpiresAt != nil {
|
||||
snap.ExpiresAt = k.ExpiresAt.UTC().Unix()
|
||||
}
|
||||
if k.BanUntil != nil {
|
||||
snap.BanUntil = k.BanUntil.UTC().Unix()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user