porkbacon/internal/config/config.go
2026-01-26 21:45:35 +00:00

103 lines
2.6 KiB
Go

package config
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"git.juancwu.dev/juancwu/porkbacon/internal/security"
)
type Config struct {
EncryptedApiKey string `json:"encrypted_api_key"`
EncryptedSecretApiKey string `json:"encrypted_secret_api_key"`
filename string `json:"-"`
}
func Load() (*Config, error) {
userConfigDir, err := os.UserConfigDir()
if err != nil {
return nil, fmt.Errorf("failed to get user configuration directory: %w", err)
}
configDir := filepath.Join(userConfigDir, "porkbacon")
if err := os.MkdirAll(configDir, 0700); err != nil {
return nil, fmt.Errorf("failed to create config directory: %w", err)
}
filename := filepath.Join(configDir, "config.json")
// If file doesn't exist, return empty config with filename set
if _, err := os.Stat(filename); os.IsNotExist(err) {
return &Config{filename: filename}, nil
}
fileData, err := os.ReadFile(filename)
if err != nil {
return nil, fmt.Errorf("failed to read config file: %w", err)
}
var cfg Config
err = json.Unmarshal(fileData, &cfg)
if err != nil {
// If JSON is invalid, return empty config (overwrite) or error?
// Let's return error so user knows something is wrong.
return nil, fmt.Errorf("failed to unmarshal config file: %w", err)
}
cfg.filename = filename
return &cfg, nil
}
func (cfg *Config) Save() error {
fileData, err := json.MarshalIndent(cfg, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal config: %w", err)
}
err = os.WriteFile(cfg.filename, fileData, 0600)
if err != nil {
return fmt.Errorf("failed to write config file: %w", err)
}
return nil
}
func (cfg *Config) SetCredentials(apiKey, secretKey, password string) error {
encApiKey, err := security.Encrypt(apiKey, password)
if err != nil {
return err
}
encSecretKey, err := security.Encrypt(secretKey, password)
if err != nil {
return err
}
cfg.EncryptedApiKey = encApiKey
cfg.EncryptedSecretApiKey = encSecretKey
return nil
}
func (cfg *Config) GetCredentials(password string) (apiKey, secretKey string, err error) {
if cfg.EncryptedApiKey == "" || cfg.EncryptedSecretApiKey == "" {
return "", "", fmt.Errorf("credentials not set")
}
apiKey, err = security.Decrypt(cfg.EncryptedApiKey, password)
if err != nil {
return "", "", fmt.Errorf("invalid password or corrupted api key")
}
secretKey, err = security.Decrypt(cfg.EncryptedSecretApiKey, password)
if err != nil {
return "", "", fmt.Errorf("invalid password or corrupted secret key")
}
return apiKey, secretKey, nil
}
func (cfg *Config) HasCredentials() bool {
return cfg.EncryptedApiKey != "" && cfg.EncryptedSecretApiKey != ""
}