// Package config holds the on-disk instance configuration shared by
// cmd/gitfed-server and cmd/gitfed-tui.
package config
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"git.neuromancer.ovh/bastien-mrq/gitfed/internal/store"
)
type Config struct {
Domain string `json:"domain"`
DataDir string `json:"data_dir"`
ReposDir string `json:"repos_dir"`
ListenSSH string `json:"listen_ssh"`
ListenHTTP string `json:"listen_http"` // empty disables the well-known HTTP server
Contact string `json:"contact"`
TrustPolicy store.TrustPolicy `json:"trust_policy"`
CertTTLHours int `json:"cert_ttl_hours"`
// InsecureFederation fetches remote .well-known documents over plain
// HTTP instead of HTTPS. Dev/testing only (e.g. federating two local
// instances with no real domain or TLS cert) — never enable this
// against real remote instances.
InsecureFederation bool `json:"insecure_federation"`
}
func Default(domain, dataDir string) Config {
return Config{
Domain: domain,
DataDir: dataDir,
ReposDir: filepath.Join(dataDir, "repos"),
ListenSSH: ":2222",
ListenHTTP: ":8443",
TrustPolicy: store.TrustPolicyWhitelist,
CertTTLHours: 24,
}
}
func (c Config) DBPath() string { return filepath.Join(c.DataDir, "gitfed.db") }
func (c Config) CADir() string { return filepath.Join(c.DataDir, "ca") }
func (c Config) HostKeyPath() string { return filepath.Join(c.DataDir, "host_key") }
func (c Config) AdminSocketPath() string { return filepath.Join(c.DataDir, "admin.sock") }
func Load(path string) (Config, error) {
var c Config
data, err := os.ReadFile(path)
if err != nil {
return c, fmt.Errorf("config: read %s: %w", path, err)
}
if err := json.Unmarshal(data, &c); err != nil {
return c, fmt.Errorf("config: parse %s: %w", path, err)
}
return c, nil
}
func Save(path string, c Config) error {
data, err := json.MarshalIndent(c, "", " ")
if err != nil {
return err
}
if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil {
return err
}
return os.WriteFile(path, data, 0644)
}