package services import ( "context" "encoding/json" "fmt" "net/http" ) type CPanelConfig struct { Host string `json:"host"` Username string `json:"username"` APIToken string `json:"apiToken"` } type CPanelService struct { credentials *CredentialsService } func NewCPanelService(c *CredentialsService) *CPanelService { return &CPanelService{credentials: c} } // GetConfig returns the decrypted cPanel configuration func (s *CPanelService) GetConfig(ctx context.Context) (*CPanelConfig, error) { payload, err := s.credentials.GetDecryptedKey(ctx, "cpanel") if err != nil { return nil, fmt.Errorf("cpanel credentials missing: %w", err) } var cfg CPanelConfig if err := json.Unmarshal([]byte(payload), &cfg); err != nil { return nil, fmt.Errorf("invalid cpanel config: %w", err) } if cfg.Host == "" || cfg.Username == "" || cfg.APIToken == "" { return nil, fmt.Errorf("cpanel not configured") } return &cfg, nil } // Example method: ListEmailAccounts (using API Token authentication) func (s *CPanelService) ListEmailAccounts(ctx context.Context) (map[string]interface{}, error) { cfg, err := s.GetConfig(ctx) if err != nil { return nil, err } url := fmt.Sprintf("%s/execute/Email/list_pops", cfg.Host) req, err := http.NewRequestWithContext(ctx, "GET", url, nil) if err != nil { return nil, err } // cPanel Token Auth Header: Authorization: cpanel : req.Header.Set("Authorization", fmt.Sprintf("cpanel %s:%s", cfg.Username, cfg.APIToken)) client := &http.Client{} resp, err := client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() if resp.StatusCode != 200 { return nil, fmt.Errorf("cpanel api returned %d", resp.StatusCode) } var result map[string]interface{} if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { return nil, err } return result, nil }