fix: prioritize database provider configs and implement API key encryption
- Added AES-GCM encryption/decryption for provider API keys in the database. - Implemented RefreshProviders to load provider configs from the database with precedence over environment variables. - Updated dashboard handlers to encrypt keys on save and trigger in-memory provider refresh. - Updated Grok test model to grok-3-mini for better compatibility.
This commit is contained in:
@@ -54,28 +54,102 @@ func NewServer(cfg *config.Config, database *db.DB) *Server {
|
||||
}
|
||||
}()
|
||||
|
||||
// Initialize providers
|
||||
if cfg.Providers.OpenAI.Enabled {
|
||||
apiKey, _ := cfg.GetAPIKey("openai")
|
||||
s.providers["openai"] = providers.NewOpenAIProvider(cfg.Providers.OpenAI, apiKey)
|
||||
}
|
||||
if cfg.Providers.Gemini.Enabled {
|
||||
apiKey, _ := cfg.GetAPIKey("gemini")
|
||||
s.providers["gemini"] = providers.NewGeminiProvider(cfg.Providers.Gemini, apiKey)
|
||||
}
|
||||
if cfg.Providers.DeepSeek.Enabled {
|
||||
apiKey, _ := cfg.GetAPIKey("deepseek")
|
||||
s.providers["deepseek"] = providers.NewDeepSeekProvider(cfg.Providers.DeepSeek, apiKey)
|
||||
}
|
||||
if cfg.Providers.Grok.Enabled {
|
||||
apiKey, _ := cfg.GetAPIKey("grok")
|
||||
s.providers["grok"] = providers.NewGrokProvider(cfg.Providers.Grok, apiKey)
|
||||
// Initialize providers from DB and Config
|
||||
if err := s.RefreshProviders(); err != nil {
|
||||
fmt.Printf("Warning: Failed to initial refresh providers: %v\n", err)
|
||||
}
|
||||
|
||||
s.setupRoutes()
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Server) RefreshProviders() error {
|
||||
var dbConfigs []db.ProviderConfig
|
||||
err := s.database.Select(&dbConfigs, "SELECT * FROM provider_configs")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to fetch provider configs from db: %w", err)
|
||||
}
|
||||
|
||||
dbMap := make(map[string]db.ProviderConfig)
|
||||
for _, cfg := range dbConfigs {
|
||||
dbMap[cfg.ID] = cfg
|
||||
}
|
||||
|
||||
providerIDs := []string{"openai", "gemini", "deepseek", "grok"}
|
||||
for _, id := range providerIDs {
|
||||
// Default values from config
|
||||
enabled := false
|
||||
baseURL := ""
|
||||
apiKey := ""
|
||||
|
||||
switch id {
|
||||
case "openai":
|
||||
enabled = s.cfg.Providers.OpenAI.Enabled
|
||||
baseURL = s.cfg.Providers.OpenAI.BaseURL
|
||||
apiKey, _ = s.cfg.GetAPIKey("openai")
|
||||
case "gemini":
|
||||
enabled = s.cfg.Providers.Gemini.Enabled
|
||||
baseURL = s.cfg.Providers.Gemini.BaseURL
|
||||
apiKey, _ = s.cfg.GetAPIKey("gemini")
|
||||
case "deepseek":
|
||||
enabled = s.cfg.Providers.DeepSeek.Enabled
|
||||
baseURL = s.cfg.Providers.DeepSeek.BaseURL
|
||||
apiKey, _ = s.cfg.GetAPIKey("deepseek")
|
||||
case "grok":
|
||||
enabled = s.cfg.Providers.Grok.Enabled
|
||||
baseURL = s.cfg.Providers.Grok.BaseURL
|
||||
apiKey, _ = s.cfg.GetAPIKey("grok")
|
||||
}
|
||||
|
||||
// Overrides from DB
|
||||
if dbCfg, ok := dbMap[id]; ok {
|
||||
enabled = dbCfg.Enabled
|
||||
if dbCfg.BaseURL != nil && *dbCfg.BaseURL != "" {
|
||||
baseURL = *dbCfg.BaseURL
|
||||
}
|
||||
if dbCfg.APIKey != nil && *dbCfg.APIKey != "" {
|
||||
key := *dbCfg.APIKey
|
||||
if dbCfg.APIKeyEncrypted {
|
||||
decrypted, err := utils.Decrypt(key, s.cfg.KeyBytes)
|
||||
if err == nil {
|
||||
key = decrypted
|
||||
} else {
|
||||
fmt.Printf("Warning: Failed to decrypt API key for %s: %v\n", id, err)
|
||||
}
|
||||
}
|
||||
apiKey = key
|
||||
}
|
||||
}
|
||||
|
||||
if !enabled {
|
||||
delete(s.providers, id)
|
||||
continue
|
||||
}
|
||||
|
||||
// Initialize provider
|
||||
switch id {
|
||||
case "openai":
|
||||
cfg := s.cfg.Providers.OpenAI
|
||||
cfg.BaseURL = baseURL
|
||||
s.providers["openai"] = providers.NewOpenAIProvider(cfg, apiKey)
|
||||
case "gemini":
|
||||
cfg := s.cfg.Providers.Gemini
|
||||
cfg.BaseURL = baseURL
|
||||
s.providers["gemini"] = providers.NewGeminiProvider(cfg, apiKey)
|
||||
case "deepseek":
|
||||
cfg := s.cfg.Providers.DeepSeek
|
||||
cfg.BaseURL = baseURL
|
||||
s.providers["deepseek"] = providers.NewDeepSeekProvider(cfg, apiKey)
|
||||
case "grok":
|
||||
cfg := s.cfg.Providers.Grok
|
||||
cfg.BaseURL = baseURL
|
||||
s.providers["grok"] = providers.NewGrokProvider(cfg, apiKey)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) setupRoutes() {
|
||||
s.router.Use(middleware.AuthMiddleware(s.database))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user