140 lines
3.3 KiB
Go
140 lines
3.3 KiB
Go
// Package config loads and validates SoloPM's environment-variable configuration.
|
|
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// Config holds every environment-driven setting for the SoloPM server.
|
|
type Config struct {
|
|
DatabaseURL string
|
|
HTTPPort string
|
|
BaseURL string
|
|
SessionSecret string
|
|
UploadDir string
|
|
MaxUploadMB int
|
|
|
|
MeiliURL string
|
|
MeiliKey string
|
|
|
|
SMTPHost string
|
|
SMTPPort string
|
|
SMTPUser string
|
|
SMTPPass string
|
|
SMTPFrom string
|
|
|
|
GitHubClientID string
|
|
GitHubClientSecret string
|
|
|
|
GiteaURL string
|
|
GiteaClientID string
|
|
GiteaClientSecret string
|
|
|
|
CullAfterDays int
|
|
LogLevel string
|
|
}
|
|
|
|
// SearchEnabled reports whether Meilisearch is configured.
|
|
func (c *Config) SearchEnabled() bool {
|
|
return c.MeiliURL != "" && c.MeiliKey != ""
|
|
}
|
|
|
|
// EmailEnabled reports whether SMTP is configured.
|
|
func (c *Config) EmailEnabled() bool {
|
|
return c.SMTPHost != ""
|
|
}
|
|
|
|
// GitHubOAuthEnabled reports whether GitHub OAuth is configured.
|
|
func (c *Config) GitHubOAuthEnabled() bool {
|
|
return c.GitHubClientID != "" && c.GitHubClientSecret != ""
|
|
}
|
|
|
|
// GiteaOAuthEnabled reports whether Gitea OAuth is configured.
|
|
func (c *Config) GiteaOAuthEnabled() bool {
|
|
return c.GiteaURL != "" && c.GiteaClientID != "" && c.GiteaClientSecret != ""
|
|
}
|
|
|
|
// Load reads configuration from the environment, applying defaults and
|
|
// failing fast (returning an error) if a required variable is missing or
|
|
// malformed.
|
|
func Load() (*Config, error) {
|
|
var missing []string
|
|
required := func(key string) string {
|
|
v := os.Getenv(key)
|
|
if v == "" {
|
|
missing = append(missing, key)
|
|
}
|
|
return v
|
|
}
|
|
|
|
c := &Config{
|
|
DatabaseURL: required("DATABASE_URL"),
|
|
HTTPPort: getDefault("HTTP_PORT", "8080"),
|
|
BaseURL: required("BASE_URL"),
|
|
SessionSecret: required("SESSION_SECRET"),
|
|
UploadDir: getDefault("UPLOAD_DIR", "./uploads"),
|
|
|
|
MeiliURL: os.Getenv("MEILI_URL"),
|
|
MeiliKey: os.Getenv("MEILI_KEY"),
|
|
|
|
SMTPHost: os.Getenv("SMTP_HOST"),
|
|
SMTPPort: os.Getenv("SMTP_PORT"),
|
|
SMTPUser: os.Getenv("SMTP_USER"),
|
|
SMTPPass: os.Getenv("SMTP_PASS"),
|
|
SMTPFrom: os.Getenv("SMTP_FROM"),
|
|
|
|
GitHubClientID: os.Getenv("GITHUB_CLIENT_ID"),
|
|
GitHubClientSecret: os.Getenv("GITHUB_CLIENT_SECRET"),
|
|
|
|
GiteaURL: os.Getenv("GITEA_URL"),
|
|
GiteaClientID: os.Getenv("GITEA_CLIENT_ID"),
|
|
GiteaClientSecret: os.Getenv("GITEA_CLIENT_SECRET"),
|
|
|
|
LogLevel: getDefault("LOG_LEVEL", "info"),
|
|
}
|
|
|
|
if len(missing) > 0 {
|
|
return nil, fmt.Errorf("config: missing required environment variable(s): %s", strings.Join(missing, ", "))
|
|
}
|
|
|
|
if len(c.SessionSecret) < 32 {
|
|
return nil, fmt.Errorf("config: SESSION_SECRET must be at least 32 bytes, got %d", len(c.SessionSecret))
|
|
}
|
|
|
|
maxUploadMB, err := getIntDefault("MAX_UPLOAD_MB", 25)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
c.MaxUploadMB = maxUploadMB
|
|
|
|
cullAfterDays, err := getIntDefault("CULL_AFTER_DAYS", 30)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
c.CullAfterDays = cullAfterDays
|
|
|
|
return c, nil
|
|
}
|
|
|
|
func getDefault(key, def string) string {
|
|
if v := os.Getenv(key); v != "" {
|
|
return v
|
|
}
|
|
return def
|
|
}
|
|
|
|
func getIntDefault(key string, def int) (int, error) {
|
|
v := os.Getenv(key)
|
|
if v == "" {
|
|
return def, nil
|
|
}
|
|
n, err := strconv.Atoi(v)
|
|
if err != nil {
|
|
return 0, fmt.Errorf("config: %s must be an integer, got %q", key, v)
|
|
}
|
|
return n, nil
|
|
}
|