103 lines
2.6 KiB
Go
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 != ""
|
|
}
|