initial upload
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
ListenAddr string
|
||||
PublicURL *url.URL
|
||||
DatabaseDSN string
|
||||
GiteaURL *url.URL
|
||||
GiteaClientID string
|
||||
GiteaClientSecret string
|
||||
GiteaPackageOwner string
|
||||
GiteaPackageUser string
|
||||
GiteaPackageToken string
|
||||
AllowedGiteaUsers map[string]struct{}
|
||||
CookieSecret []byte
|
||||
DefaultDuration time.Duration
|
||||
DefaultHostLimit int
|
||||
MaxHostLimit int
|
||||
TrustProxyHeaders bool
|
||||
}
|
||||
|
||||
func LoadConfig() (Config, error) {
|
||||
var cfg Config
|
||||
var err error
|
||||
|
||||
cfg.ListenAddr = envDefault("TAPM_LISTEN_ADDR", ":8080")
|
||||
cfg.DatabaseDSN = os.Getenv("TAPM_DATABASE_DSN")
|
||||
cfg.GiteaClientID = os.Getenv("TAPM_GITEA_CLIENT_ID")
|
||||
cfg.GiteaClientSecret = os.Getenv("TAPM_GITEA_CLIENT_SECRET")
|
||||
cfg.GiteaPackageOwner = envDefault("TAPM_GITEA_PACKAGE_OWNER", "TAI")
|
||||
cfg.GiteaPackageUser = os.Getenv("TAPM_GITEA_PACKAGE_USERNAME")
|
||||
cfg.GiteaPackageToken = os.Getenv("TAPM_GITEA_PACKAGE_TOKEN")
|
||||
cfg.CookieSecret = []byte(os.Getenv("TAPM_COOKIE_SECRET"))
|
||||
|
||||
cfg.PublicURL, err = parseAbsoluteURL("TAPM_PUBLIC_URL")
|
||||
if err != nil {
|
||||
return cfg, err
|
||||
}
|
||||
cfg.GiteaURL, err = parseAbsoluteURL("TAPM_GITEA_URL")
|
||||
if err != nil {
|
||||
return cfg, err
|
||||
}
|
||||
|
||||
cfg.DefaultDuration, err = time.ParseDuration(
|
||||
envDefault("TAPM_DEFAULT_DURATION", "3h"),
|
||||
)
|
||||
if err != nil || cfg.DefaultDuration <= 0 {
|
||||
return cfg, fmt.Errorf("TAPM_DEFAULT_DURATION must be positive")
|
||||
}
|
||||
cfg.DefaultHostLimit, err = envInt("TAPM_DEFAULT_HOST_LIMIT", 3)
|
||||
if err != nil {
|
||||
return cfg, err
|
||||
}
|
||||
cfg.MaxHostLimit, err = envInt("TAPM_MAX_HOST_LIMIT", 25)
|
||||
if err != nil {
|
||||
return cfg, err
|
||||
}
|
||||
if cfg.DefaultHostLimit < 1 || cfg.MaxHostLimit < cfg.DefaultHostLimit {
|
||||
return cfg, fmt.Errorf("invalid default or maximum host limit")
|
||||
}
|
||||
|
||||
cfg.TrustProxyHeaders, err = strconv.ParseBool(
|
||||
envDefault("TAPM_TRUST_PROXY_HEADERS", "false"),
|
||||
)
|
||||
if err != nil {
|
||||
return cfg, fmt.Errorf("TAPM_TRUST_PROXY_HEADERS: %w", err)
|
||||
}
|
||||
|
||||
cfg.AllowedGiteaUsers = make(map[string]struct{})
|
||||
for _, user := range strings.Split(
|
||||
envDefault("TAPM_ALLOWED_GITEA_USERS", "taiadmin"),
|
||||
",",
|
||||
) {
|
||||
user = strings.ToLower(strings.TrimSpace(user))
|
||||
if user != "" {
|
||||
cfg.AllowedGiteaUsers[user] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
required := map[string]string{
|
||||
"TAPM_DATABASE_DSN": cfg.DatabaseDSN,
|
||||
"TAPM_GITEA_CLIENT_ID": cfg.GiteaClientID,
|
||||
"TAPM_GITEA_CLIENT_SECRET": cfg.GiteaClientSecret,
|
||||
"TAPM_GITEA_PACKAGE_USERNAME": cfg.GiteaPackageUser,
|
||||
"TAPM_GITEA_PACKAGE_TOKEN": cfg.GiteaPackageToken,
|
||||
}
|
||||
for name, value := range required {
|
||||
if strings.TrimSpace(value) == "" {
|
||||
return cfg, fmt.Errorf("%s is required", name)
|
||||
}
|
||||
}
|
||||
if len(cfg.CookieSecret) < 32 {
|
||||
return cfg, fmt.Errorf("TAPM_COOKIE_SECRET must contain at least 32 bytes")
|
||||
}
|
||||
if len(cfg.AllowedGiteaUsers) == 0 {
|
||||
return cfg, fmt.Errorf("at least one Gitea user must be allowed")
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func parseAbsoluteURL(name string) (*url.URL, error) {
|
||||
raw := os.Getenv(name)
|
||||
parsed, err := url.Parse(raw)
|
||||
if err != nil || parsed.Scheme != "https" || parsed.Host == "" {
|
||||
return nil, fmt.Errorf("%s must be an absolute HTTPS URL", name)
|
||||
}
|
||||
return parsed, nil
|
||||
}
|
||||
|
||||
func envDefault(name, fallback string) string {
|
||||
if value := os.Getenv(name); value != "" {
|
||||
return value
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func envInt(name string, fallback int) (int, error) {
|
||||
raw := envDefault(name, strconv.Itoa(fallback))
|
||||
value, err := strconv.Atoi(raw)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("%s must be an integer", name)
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
Reference in New Issue
Block a user