first round of files
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user