go-guess/backend/internal/config/config.go
2026-10-03 04:39:14 +02:00

91 lines
2.3 KiB
Go

package config
import (
"fmt"
"os"
"strconv"
"strings"
"time"
)
type Config struct {
Address string
DatabaseURL string
JWTSecret string
TokenTTL time.Duration
MaxUploadMB int64
FrontendURL string
RabbitMQURL string
GoLoose GoLooseConfig
}
type GoLooseConfig struct {
AuthDomain string
AppDomain string
CAFile string
Tenants map[string]GoLooseTenant
}
type GoLooseTenant struct {
ClientID string
ClientSecret string
}
// GoLooseCredentialEnv returns the environment variable names holding the Go
// Loose client credentials of a tenant.
func GoLooseCredentialEnv(slug string) (idEnv, secretEnv string) {
prefix := "GO_LOOSE_" + strings.ToUpper(slug)
return prefix + "_CLIENT_ID", prefix + "_CLIENT_SECRET"
}
func Load() (Config, error) {
ttl, err := time.ParseDuration(env("TOKEN_TTL", "8h"))
if err != nil {
return Config{}, fmt.Errorf("parse TOKEN_TTL: %w", err)
}
maxUploadMB, err := strconv.ParseInt(env("MAX_UPLOAD_MB", "10"), 10, 64)
if err != nil || maxUploadMB < 1 {
return Config{}, fmt.Errorf("MAX_UPLOAD_MB must be a positive integer")
}
cfg := Config{
Address: env("ADDRESS", ":8080"),
DatabaseURL: env("DATABASE_URL", "postgres://go_guess:go_guess@localhost:5432/?sslmode=disable"),
JWTSecret: os.Getenv("JWT_SECRET"),
TokenTTL: ttl,
MaxUploadMB: maxUploadMB,
FrontendURL: env("FRONTEND_URL", "http://localhost:5173"),
RabbitMQURL: env("RABBITMQ_URL", "amqp://guest:guest@localhost:5672/"),
GoLoose: loadGoLoose(),
}
if len(cfg.JWTSecret) < 32 {
return Config{}, fmt.Errorf("JWT_SECRET must contain at least 32 characters")
}
return cfg, nil
}
func loadGoLoose() GoLooseConfig {
cfg := GoLooseConfig{
AuthDomain: env("GO_LOOSE_AUTH_DOMAIN", "auth.dev"),
AppDomain: env("GO_LOOSE_APP_DOMAIN", "guess.dev"),
CAFile: os.Getenv("GO_LOOSE_CA_FILE"),
Tenants: map[string]GoLooseTenant{},
}
add := func(slug string) {
idEnv, secretEnv := GoLooseCredentialEnv(slug)
id, secret := os.Getenv(idEnv), os.Getenv(secretEnv)
if id == "" || secret == "" {
return
}
cfg.Tenants[slug] = GoLooseTenant{ClientID: id, ClientSecret: secret}
}
add("nmbs")
add("ypto")
return cfg
}
func env(key, fallback string) string {
if value := os.Getenv(key); value != "" {
return value
}
return fallback
}