97 lines
1.8 KiB
Go
97 lines
1.8 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
)
|
|
|
|
type Config struct {
|
|
// Server
|
|
Port string
|
|
|
|
// Database
|
|
DatabaseURL string
|
|
|
|
// Storage
|
|
RepoRoot string
|
|
|
|
// Security
|
|
SessionSecret string // must be 32 or 64 bytes for AES-GCM
|
|
CSRFSecret string // must be 32 bytes
|
|
|
|
// OIDC (optional)
|
|
OIDCIssuer string
|
|
OIDCClientID string
|
|
OIDCClientSecret string
|
|
|
|
// Federation
|
|
InstanceURL string
|
|
InstanceName string
|
|
|
|
// Dev
|
|
Debug bool
|
|
}
|
|
|
|
func Load() (*Config, error) {
|
|
cfg := &Config{
|
|
Port: getEnv("PORT", "8080"),
|
|
RepoRoot: getEnv("REPO_ROOT", "/var/lib/forgebucket/repos"),
|
|
Debug: getEnvBool("DEBUG", false),
|
|
|
|
InstanceURL: getEnv("INSTANCE_URL", ""),
|
|
InstanceName: getEnv("INSTANCE_NAME", "ForgeBucket"),
|
|
}
|
|
|
|
var missing []string
|
|
|
|
cfg.DatabaseURL = requireEnv("DATABASE_URL", &missing)
|
|
cfg.SessionSecret = requireEnv("SESSION_SECRET", &missing)
|
|
cfg.CSRFSecret = requireEnv("CSRF_SECRET", &missing)
|
|
|
|
// Optional OIDC
|
|
cfg.OIDCIssuer = os.Getenv("OIDC_ISSUER")
|
|
cfg.OIDCClientID = os.Getenv("OIDC_CLIENT_ID")
|
|
cfg.OIDCClientSecret = os.Getenv("OIDC_CLIENT_SECRET")
|
|
|
|
if len(missing) > 0 {
|
|
return nil, fmt.Errorf("missing required env vars: %v", missing)
|
|
}
|
|
|
|
if len(cfg.SessionSecret) < 32 {
|
|
return nil, fmt.Errorf("SESSION_SECRET must be at least 32 characters")
|
|
}
|
|
if len(cfg.CSRFSecret) != 32 {
|
|
return nil, fmt.Errorf("CSRF_SECRET must be exactly 32 characters")
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|
|
|
|
func requireEnv(key string, missing *[]string) string {
|
|
v := os.Getenv(key)
|
|
if v == "" {
|
|
*missing = append(*missing, key)
|
|
}
|
|
return v
|
|
}
|
|
|
|
func getEnv(key, fallback string) string {
|
|
if v := os.Getenv(key); v != "" {
|
|
return v
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func getEnvBool(key string, fallback bool) bool {
|
|
v := os.Getenv(key)
|
|
if v == "" {
|
|
return fallback
|
|
}
|
|
b, err := strconv.ParseBool(v)
|
|
if err != nil {
|
|
return fallback
|
|
}
|
|
return b
|
|
}
|