ultimate-media-tracker/server/config.go
Tronax 3f07c78316
feat: initial commit for media tracking software
- Setup C++/Qt6 desktop application structure
- Added initial Go proxy backend for TMDB/IGDB integration
2026-06-15 02:02:25 +02:00

89 lines
2.7 KiB
Go

package main
import (
"fmt"
"os"
"strconv"
"strings"
"time"
)
// Config holds all runtime settings, sourced from environment variables so the
// server is easy to run under systemd, Docker or a PaaS without code changes.
type Config struct {
ListenAddr string // e.g. ":8080"
PublicURL string // externally reachable base URL, e.g. https://tmdb.example.com
TMDBKey string // the single shared TMDB v3 API key
TMDBBase string // upstream base, defaults to https://api.themoviedb.org/3
Issuer string // Authentik OIDC issuer URL
ClientID string // OAuth2 client id
ClientSecret string // OAuth2 client secret
RedirectURL string // OAuth2 redirect URL (PublicURL + /callback if empty)
SessionKey []byte // HMAC secret for signing access tokens / state cookies
AllowGroups []string // if set, the user must be in one of these Authentik groups
TokenTTL time.Duration // lifetime of issued desktop-app tokens
}
func getenv(key, def string) string {
if v := strings.TrimSpace(os.Getenv(key)); v != "" {
return v
}
return def
}
func loadConfig() (*Config, error) {
c := &Config{
ListenAddr: getenv("LISTEN_ADDR", ":8080"),
PublicURL: strings.TrimRight(getenv("PUBLIC_URL", "http://localhost:8080"), "/"),
TMDBKey: getenv("TMDB_API_KEY", ""),
TMDBBase: strings.TrimRight(getenv("TMDB_BASE_URL", "https://api.themoviedb.org/3"), "/"),
Issuer: getenv("OIDC_ISSUER", ""),
ClientID: getenv("OIDC_CLIENT_ID", ""),
ClientSecret: getenv("OIDC_CLIENT_SECRET", ""),
RedirectURL: getenv("OIDC_REDIRECT_URL", ""),
}
if c.RedirectURL == "" {
c.RedirectURL = c.PublicURL + "/callback"
}
secret := getenv("SESSION_SECRET", "")
if secret == "" {
return nil, fmt.Errorf("SESSION_SECRET is required (a long random string)")
}
c.SessionKey = []byte(secret)
if groups := getenv("ALLOWED_GROUPS", ""); groups != "" {
for _, g := range strings.Split(groups, ",") {
if g = strings.TrimSpace(g); g != "" {
c.AllowGroups = append(c.AllowGroups, g)
}
}
}
days, err := strconv.Atoi(getenv("TOKEN_TTL_DAYS", "90"))
if err != nil || days <= 0 {
days = 90
}
c.TokenTTL = time.Duration(days) * 24 * time.Hour
// Required fields.
var missing []string
if c.TMDBKey == "" {
missing = append(missing, "TMDB_API_KEY")
}
if c.Issuer == "" {
missing = append(missing, "OIDC_ISSUER")
}
if c.ClientID == "" {
missing = append(missing, "OIDC_CLIENT_ID")
}
if c.ClientSecret == "" {
missing = append(missing, "OIDC_CLIENT_SECRET")
}
if len(missing) > 0 {
return nil, fmt.Errorf("missing required environment variables: %s", strings.Join(missing, ", "))
}
return c, nil
}