Files
ai-disclosure-standard/internal/app/config.go
T
jbergner 4e2c648ede
release-tag / release-image (push) Has been cancelled
2.0.0 Production-RC
2026-07-24 07:23:59 +02:00

139 lines
3.8 KiB
Go

package app
import (
"os"
"strconv"
"strings"
"time"
"github.com/b1tsblog/license-platform/pkg/licensekit"
)
type Config struct {
ListenAddress string
BaseURL string
OutputBaseURL string
PublicName string
ContactURL string
DefaultLanguage string
TrustProxy bool
ServiceMode string
BulkMaxItems int
BulkMaxBodyBytes int64
BulkRequireAPIKey bool
BulkAPIKey string
APIAllowedOrigin string
RequireLicense bool
WhiteLabel bool
LicenseToken string
LicenseMode licensekit.VerificationMode
LicenseServerURL string
LicenseInstanceID string
LicenseCacheFile string
LicenseRefreshEvery time.Duration
LicenseTimeout time.Duration
}
func ConfigFromEnv() Config {
contactURL := env("CONTACT_URL", "https://b1tsblog.org/page/ai")
baseURL := strings.TrimRight(env("BASE_URL", "http://localhost:8080"), "/")
mode, err := licensekit.ParseMode(env("LICENSE_MODE", "offline"))
if err != nil {
mode = licensekit.ModeOffline
}
return Config{
ListenAddress: env("LISTEN_ADDRESS", ":8080"),
BaseURL: baseURL,
OutputBaseURL: strings.TrimRight(env("OUTPUT_BASE_URL", baseURL), "/"),
PublicName: env("PUBLIC_NAME", "AI Usage Disclosure"),
ContactURL: contactURL,
DefaultLanguage: env("DEFAULT_LANGUAGE", "de"),
TrustProxy: strings.EqualFold(env("TRUST_PROXY", "false"), "true"),
ServiceMode: serviceModeEnv("SERVICE_MODE", "full"),
BulkMaxItems: intEnv("BULK_MAX_ITEMS", 500),
BulkMaxBodyBytes: int64(intEnv("BULK_MAX_BODY_BYTES", 4<<20)),
BulkRequireAPIKey: strings.EqualFold(env("BULK_REQUIRE_API_KEY", "false"), "true"),
BulkAPIKey: secretEnv("BULK_API_KEY"),
APIAllowedOrigin: envAllowEmpty("API_ALLOWED_ORIGIN", "*"),
RequireLicense: strings.EqualFold(env("REQUIRE_LICENSE", "false"), "true"),
WhiteLabel: strings.EqualFold(env("WHITE_LABEL", "false"), "true"),
LicenseToken: secretEnv("LICENSE_TOKEN"),
LicenseMode: mode,
LicenseServerURL: strings.TrimRight(env("LICENSE_SERVER_URL", ""), "/"),
LicenseInstanceID: env("LICENSE_INSTANCE_ID", ""),
LicenseCacheFile: env("LICENSE_CACHE_FILE", "./data/license-lease.json"),
LicenseRefreshEvery: durationEnv("LICENSE_REFRESH_INTERVAL", 15*time.Minute),
LicenseTimeout: durationEnv("LICENSE_REQUEST_TIMEOUT", 5*time.Second),
}
}
func env(key, fallback string) string {
if value := strings.TrimSpace(os.Getenv(key)); value != "" {
return value
}
return fallback
}
func envAllowEmpty(key, fallback string) string {
value, ok := os.LookupEnv(key)
if !ok {
return fallback
}
return strings.TrimSpace(value)
}
func secretEnv(key string) string {
if value := strings.TrimSpace(os.Getenv(key)); value != "" {
return value
}
path := strings.TrimSpace(os.Getenv(key + "_FILE"))
if path == "" {
return ""
}
data, err := os.ReadFile(path)
if err != nil {
return ""
}
return strings.TrimSpace(string(data))
}
func durationEnv(key string, fallback time.Duration) time.Duration {
value := strings.TrimSpace(os.Getenv(key))
if value == "" {
return fallback
}
if duration, err := time.ParseDuration(value); err == nil {
return duration
}
if seconds, err := strconv.ParseInt(value, 10, 64); err == nil {
return time.Duration(seconds) * time.Second
}
return fallback
}
func intEnv(key string, fallback int) int {
value := strings.TrimSpace(os.Getenv(key))
if value == "" {
return fallback
}
n, err := strconv.Atoi(value)
if err != nil || n <= 0 {
return fallback
}
return n
}
func serviceModeEnv(key, fallback string) string {
value := strings.ToLower(strings.TrimSpace(os.Getenv(key)))
switch value {
case "full", "api", "bulk":
return value
case "":
return fallback
default:
return fallback
}
}