mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-02-15 10:30:09 +00:00
feat: support reading secret env vars from _FILE (#799)
Co-authored-by: Kyle Mendell <ksm@ofkm.us>
This commit is contained in:
committed by
GitHub
parent
d479817b6a
commit
0a3b1c6530
@@ -6,11 +6,30 @@ import (
|
||||
"log/slog"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/caarlos0/env/v11"
|
||||
_ "github.com/joho/godotenv/autoload"
|
||||
)
|
||||
|
||||
func resolveStringOrFile(directValue string, filePath string, varName string, trim bool) (string, error) {
|
||||
if directValue != "" {
|
||||
return directValue, nil
|
||||
}
|
||||
if filePath != "" {
|
||||
content, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to read secret '%s' from file '%s': %w", varName, filePath, err)
|
||||
}
|
||||
|
||||
if trim {
|
||||
return strings.TrimSpace(string(content)), nil
|
||||
}
|
||||
return string(content), nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
type DbProvider string
|
||||
|
||||
const (
|
||||
@@ -28,29 +47,31 @@ const (
|
||||
)
|
||||
|
||||
type EnvConfigSchema struct {
|
||||
AppEnv string `env:"APP_ENV"`
|
||||
AppURL string `env:"APP_URL"`
|
||||
DbProvider DbProvider `env:"DB_PROVIDER"`
|
||||
DbConnectionString string `env:"DB_CONNECTION_STRING"`
|
||||
UploadPath string `env:"UPLOAD_PATH"`
|
||||
KeysPath string `env:"KEYS_PATH"`
|
||||
KeysStorage string `env:"KEYS_STORAGE"`
|
||||
EncryptionKey string `env:"ENCRYPTION_KEY"`
|
||||
EncryptionKeyFile string `env:"ENCRYPTION_KEY_FILE"`
|
||||
Port string `env:"PORT"`
|
||||
Host string `env:"HOST"`
|
||||
UnixSocket string `env:"UNIX_SOCKET"`
|
||||
UnixSocketMode string `env:"UNIX_SOCKET_MODE"`
|
||||
MaxMindLicenseKey string `env:"MAXMIND_LICENSE_KEY"`
|
||||
GeoLiteDBPath string `env:"GEOLITE_DB_PATH"`
|
||||
GeoLiteDBUrl string `env:"GEOLITE_DB_URL"`
|
||||
LocalIPv6Ranges string `env:"LOCAL_IPV6_RANGES"`
|
||||
UiConfigDisabled bool `env:"UI_CONFIG_DISABLED"`
|
||||
MetricsEnabled bool `env:"METRICS_ENABLED"`
|
||||
TracingEnabled bool `env:"TRACING_ENABLED"`
|
||||
LogJSON bool `env:"LOG_JSON"`
|
||||
TrustProxy bool `env:"TRUST_PROXY"`
|
||||
AnalyticsDisabled bool `env:"ANALYTICS_DISABLED"`
|
||||
AppEnv string `env:"APP_ENV"`
|
||||
AppURL string `env:"APP_URL"`
|
||||
DbProvider DbProvider `env:"DB_PROVIDER"`
|
||||
DbConnectionString string `env:"DB_CONNECTION_STRING"`
|
||||
DbConnectionStringFile string `env:"DB_CONNECTION_STRING_FILE"`
|
||||
UploadPath string `env:"UPLOAD_PATH"`
|
||||
KeysPath string `env:"KEYS_PATH"`
|
||||
KeysStorage string `env:"KEYS_STORAGE"`
|
||||
EncryptionKey string `env:"ENCRYPTION_KEY"`
|
||||
EncryptionKeyFile string `env:"ENCRYPTION_KEY_FILE"`
|
||||
Port string `env:"PORT"`
|
||||
Host string `env:"HOST"`
|
||||
UnixSocket string `env:"UNIX_SOCKET"`
|
||||
UnixSocketMode string `env:"UNIX_SOCKET_MODE"`
|
||||
MaxMindLicenseKey string `env:"MAXMIND_LICENSE_KEY"`
|
||||
MaxMindLicenseKeyFile string `env:"MAXMIND_LICENSE_KEY_FILE"`
|
||||
GeoLiteDBPath string `env:"GEOLITE_DB_PATH"`
|
||||
GeoLiteDBUrl string `env:"GEOLITE_DB_URL"`
|
||||
LocalIPv6Ranges string `env:"LOCAL_IPV6_RANGES"`
|
||||
UiConfigDisabled bool `env:"UI_CONFIG_DISABLED"`
|
||||
MetricsEnabled bool `env:"METRICS_ENABLED"`
|
||||
TracingEnabled bool `env:"TRACING_ENABLED"`
|
||||
LogJSON bool `env:"LOG_JSON"`
|
||||
TrustProxy bool `env:"TRUST_PROXY"`
|
||||
AnalyticsDisabled bool `env:"ANALYTICS_DISABLED"`
|
||||
}
|
||||
|
||||
var EnvConfig = defaultConfig()
|
||||
@@ -95,6 +116,29 @@ func parseEnvConfig() error {
|
||||
return fmt.Errorf("error parsing env config: %w", err)
|
||||
}
|
||||
|
||||
// Resolve string/file environment variables
|
||||
EnvConfig.DbConnectionString, err = resolveStringOrFile(
|
||||
EnvConfig.DbConnectionString,
|
||||
EnvConfig.DbConnectionStringFile,
|
||||
"DB_CONNECTION_STRING",
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
EnvConfig.DbConnectionStringFile = ""
|
||||
|
||||
EnvConfig.MaxMindLicenseKey, err = resolveStringOrFile(
|
||||
EnvConfig.MaxMindLicenseKey,
|
||||
EnvConfig.MaxMindLicenseKeyFile,
|
||||
"MAXMIND_LICENSE_KEY",
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
EnvConfig.MaxMindLicenseKeyFile = ""
|
||||
|
||||
// Validate the environment variables
|
||||
switch EnvConfig.DbProvider {
|
||||
case DbProviderSqlite:
|
||||
@@ -122,10 +166,23 @@ func parseEnvConfig() error {
|
||||
case "":
|
||||
EnvConfig.KeysStorage = "file"
|
||||
case "database":
|
||||
// If KeysStorage is "database", a key must be specified
|
||||
if EnvConfig.EncryptionKey == "" && EnvConfig.EncryptionKeyFile == "" {
|
||||
// Resolve encryption key using the same pattern
|
||||
encryptionKey, err := resolveStringOrFile(
|
||||
EnvConfig.EncryptionKey,
|
||||
EnvConfig.EncryptionKeyFile,
|
||||
"ENCRYPTION_KEY",
|
||||
// Do not trim spaces because the file should be interpreted as binary
|
||||
false,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if encryptionKey == "" {
|
||||
return errors.New("ENCRYPTION_KEY or ENCRYPTION_KEY_FILE must be non-empty when KEYS_STORAGE is database")
|
||||
}
|
||||
// Update the config with resolved value
|
||||
EnvConfig.EncryptionKey = encryptionKey
|
||||
EnvConfig.EncryptionKeyFile = ""
|
||||
case "file":
|
||||
// All good, these are valid values
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user