| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- // Package config 负责从环境变量加载并校验后端配置。
- //
- // 依据 docs/architecture.md 第四节:所有配置通过环境变量提供,
- // 不引入配置文件;缺失必填项时拒绝启动。
- //
- // cookie 名、有效期、bcrypt cost 等常量不在此暴露,直接写在代码里。
- package config
- import (
- "fmt"
- "os"
- "strconv"
- "strings"
- )
- // Config 是后端启动所需的全部配置。
- type Config struct {
- // 必填
- ListenAddr string // HAVEN_LISTEN_ADDR
- DBDSN string // HAVEN_DB_DSN
- FrontendDir string // HAVEN_FRONTEND_DIR
- GogsBaseURL string // HAVEN_GOGS_BASE_URL
- CookieDomain string // HAVEN_COOKIE_DOMAIN
- // 可选,带默认值
- CookieSecure bool // HAVEN_COOKIE_SECURE,默认 true
- TotpIssuer string // HAVEN_TOTP_ISSUER,默认 Haven
- LogLevel string // HAVEN_LOG_LEVEL,默认 info
- }
- // Load 从环境变量读取并校验配置。
- // 任一必填项缺失或取值非法都返回错误,由调用方拒绝启动。
- func Load() (Config, error) {
- var cfg Config
- var missing []string
- cfg.ListenAddr = strings.TrimSpace(os.Getenv("HAVEN_LISTEN_ADDR"))
- if cfg.ListenAddr == "" {
- missing = append(missing, "HAVEN_LISTEN_ADDR")
- }
- cfg.DBDSN = strings.TrimSpace(os.Getenv("HAVEN_DB_DSN"))
- if cfg.DBDSN == "" {
- missing = append(missing, "HAVEN_DB_DSN")
- }
- cfg.FrontendDir = strings.TrimSpace(os.Getenv("HAVEN_FRONTEND_DIR"))
- if cfg.FrontendDir == "" {
- missing = append(missing, "HAVEN_FRONTEND_DIR")
- }
- cfg.GogsBaseURL = strings.TrimSpace(strings.TrimSuffix(os.Getenv("HAVEN_GOGS_BASE_URL"), "/"))
- if cfg.GogsBaseURL == "" {
- missing = append(missing, "HAVEN_GOGS_BASE_URL")
- }
- cfg.CookieDomain = strings.TrimSpace(os.Getenv("HAVEN_COOKIE_DOMAIN"))
- if cfg.CookieDomain == "" {
- missing = append(missing, "HAVEN_COOKIE_DOMAIN")
- }
- if len(missing) > 0 {
- return Config{}, fmt.Errorf("缺少必填环境变量: %s", strings.Join(missing, ", "))
- }
- cfg.CookieSecure = true
- if raw := strings.TrimSpace(os.Getenv("HAVEN_COOKIE_SECURE")); raw != "" {
- v, err := strconv.ParseBool(raw)
- if err != nil {
- return Config{}, fmt.Errorf("HAVEN_COOKIE_SECURE 取值非法 %q,应为 true 或 false", raw)
- }
- cfg.CookieSecure = v
- }
- cfg.TotpIssuer = strings.TrimSpace(os.Getenv("HAVEN_TOTP_ISSUER"))
- if cfg.TotpIssuer == "" {
- cfg.TotpIssuer = "Haven"
- }
- cfg.LogLevel = strings.ToLower(strings.TrimSpace(os.Getenv("HAVEN_LOG_LEVEL")))
- if cfg.LogLevel == "" {
- cfg.LogLevel = "info"
- }
- switch cfg.LogLevel {
- case "debug", "info", "warn", "error":
- default:
- return Config{}, fmt.Errorf("HAVEN_LOG_LEVEL 取值非法 %q,应为 debug / info / warn / error", cfg.LogLevel)
- }
- return cfg, nil
- }
|