package providers import ( "encoding/json" "fmt" "os" "path/filepath" "sync" ) // ProviderConfig enthält die Konfiguration eines Providers type ProviderConfig struct { Enabled bool `json:"enabled"` Settings map[string]interface{} `json:"settings"` } // SignCSRResult enthält das Ergebnis einer CSR-Signierung type SignCSRResult struct { CertificatePEM string `json:"certificatePEM"` OrderID string `json:"orderId,omitempty"` Status string `json:"status"` Message string `json:"message,omitempty"` } // Provider Interface für alle SSL Certificate Provider type Provider interface { // GetName gibt den Namen des Providers zurück GetName() string // GetDisplayName gibt den Anzeigenamen zurück GetDisplayName() string // GetDescription gibt eine Beschreibung zurück GetDescription() string // ValidateConfig validiert die Konfiguration ValidateConfig(settings map[string]interface{}) error // TestConnection testet die Verbindung zum Provider TestConnection(settings map[string]interface{}) error // GetRequiredSettings gibt die erforderlichen Einstellungen zurück GetRequiredSettings() []SettingField // SignCSR signiert einen CSR und gibt das Zertifikat zurück SignCSR(csrPEM string, settings map[string]interface{}) (*SignCSRResult, error) // GetCertificate ruft ein Zertifikat anhand der Zertifikat-ID ab GetCertificate(certificateID string, settings map[string]interface{}) (string, error) } // ProviderManager verwaltet alle Provider type ProviderManager struct { providers map[string]Provider configs map[string]*ProviderConfig configDir string mu sync.RWMutex } var manager *ProviderManager var once sync.Once // GetManager gibt die Singleton-Instanz des ProviderManagers zurück func GetManager() *ProviderManager { once.Do(func() { manager = &ProviderManager{ providers: make(map[string]Provider), configs: make(map[string]*ProviderConfig), configDir: "./config/providers", } manager.loadAllConfigs() }) return manager } // RegisterProvider registriert einen neuen Provider func (pm *ProviderManager) RegisterProvider(provider Provider) { pm.mu.Lock() defer pm.mu.Unlock() providerID := pm.getProviderID(provider.GetName()) pm.providers[providerID] = provider // Lade Konfiguration falls vorhanden if pm.configs[providerID] == nil { pm.configs[providerID] = &ProviderConfig{ Enabled: false, Settings: make(map[string]interface{}), } } } // GetProvider gibt einen Provider zurück func (pm *ProviderManager) GetProvider(id string) (Provider, bool) { pm.mu.RLock() defer pm.mu.RUnlock() provider, exists := pm.providers[id] return provider, exists } // GetAllProviders gibt alle registrierten Provider zurück func (pm *ProviderManager) GetAllProviders() map[string]Provider { pm.mu.RLock() defer pm.mu.RUnlock() result := make(map[string]Provider) for id, provider := range pm.providers { result[id] = provider } return result } // GetProviderConfig gibt die Konfiguration eines Providers zurück func (pm *ProviderManager) GetProviderConfig(id string) (*ProviderConfig, error) { pm.mu.RLock() defer pm.mu.RUnlock() config, exists := pm.configs[id] if !exists { return &ProviderConfig{ Enabled: false, Settings: make(map[string]interface{}), }, nil } return config, nil } // UpdateProviderConfig aktualisiert die Konfiguration eines Providers func (pm *ProviderManager) UpdateProviderConfig(id string, config *ProviderConfig) error { pm.mu.Lock() defer pm.mu.Unlock() provider, exists := pm.providers[id] if !exists { return fmt.Errorf("provider %s nicht gefunden", id) } // Validiere Konfiguration if err := provider.ValidateConfig(config.Settings); err != nil { return fmt.Errorf("ungültige Konfiguration: %v", err) } pm.configs[id] = config // Speichere Konfiguration in Datei return pm.saveConfig(id, config) } // SetProviderEnabled aktiviert/deaktiviert einen Provider func (pm *ProviderManager) SetProviderEnabled(id string, enabled bool) error { pm.mu.Lock() defer pm.mu.Unlock() if pm.configs[id] == nil { pm.configs[id] = &ProviderConfig{ Enabled: enabled, Settings: make(map[string]interface{}), } } else { pm.configs[id].Enabled = enabled } return pm.saveConfig(id, pm.configs[id]) } // getProviderID erstellt eine ID aus dem Provider-Namen func (pm *ProviderManager) getProviderID(name string) string { return name } // loadAllConfigs lädt alle Konfigurationsdateien func (pm *ProviderManager) loadAllConfigs() { // Stelle sicher, dass das Verzeichnis existiert os.MkdirAll(pm.configDir, 0755) // Lade alle JSON-Dateien im Konfigurationsverzeichnis files, err := filepath.Glob(filepath.Join(pm.configDir, "*.json")) if err != nil { return } for _, file := range files { id := filepath.Base(file[:len(file)-5]) // Entferne .json config, err := pm.loadConfig(id) if err == nil { pm.configs[id] = config } } } // loadConfig lädt eine Konfigurationsdatei func (pm *ProviderManager) loadConfig(id string) (*ProviderConfig, error) { filePath := filepath.Join(pm.configDir, id+".json") data, err := os.ReadFile(filePath) if err != nil { return nil, err } var config ProviderConfig if err := json.Unmarshal(data, &config); err != nil { return nil, err } return &config, nil } // saveConfig speichert eine Konfiguration in eine Datei func (pm *ProviderManager) saveConfig(id string, config *ProviderConfig) error { // Stelle sicher, dass das Verzeichnis existiert os.MkdirAll(pm.configDir, 0755) filePath := filepath.Join(pm.configDir, id+".json") data, err := json.MarshalIndent(config, "", " ") if err != nil { return err } return os.WriteFile(filePath, data, 0644) }