diff --git a/cmd/dex/config.go b/cmd/dex/config.go index a328d66e..dd91bf1e 100644 --- a/cmd/dex/config.go +++ b/cmd/dex/config.go @@ -5,11 +5,11 @@ import ( "encoding/json" "fmt" "os" - "strconv" "strings" "golang.org/x/crypto/bcrypt" + "github.com/dexidp/dex/pkg/featureflags" "github.com/dexidp/dex/pkg/log" "github.com/dexidp/dex/server" "github.com/dexidp/dex/storage" @@ -195,12 +195,10 @@ var ( func getORMBasedSQLStorage(normal, entBased StorageConfig) func() StorageConfig { return func() StorageConfig { - switch os.Getenv("DEX_ENT_ENABLED") { - case "true", "yes": + if featureflags.EntEnabled.Enabled() { return entBased - default: - return normal } + return normal } } @@ -213,19 +211,6 @@ var storages = map[string]func() StorageConfig{ "mysql": getORMBasedSQLStorage(&sql.MySQL{}, &ent.MySQL{}), } -// isExpandEnvEnabled returns if os.ExpandEnv should be used for each storage and connector config. -// Disabling this feature avoids surprises e.g. if the LDAP bind password contains a dollar character. -// Returns false if the env variable "DEX_EXPAND_ENV" is a falsy string, e.g. "false". -// Returns true if the env variable is unset or a truthy string, e.g. "true", or can't be parsed as bool. -func isExpandEnvEnabled() bool { - enabled, err := strconv.ParseBool(os.Getenv("DEX_EXPAND_ENV")) - if err != nil { - // Unset, empty string or can't be parsed as bool: Default = true. - return true - } - return enabled -} - // UnmarshalJSON allows Storage to implement the unmarshaler interface to // dynamically determine the type of the storage config. func (s *Storage) UnmarshalJSON(b []byte) error { @@ -244,7 +229,7 @@ func (s *Storage) UnmarshalJSON(b []byte) error { storageConfig := f() if len(store.Config) != 0 { data := []byte(store.Config) - if isExpandEnvEnabled() { + if featureflags.ExpandEnv.Enabled() { // Caution, we're expanding in the raw JSON/YAML source. This may not be what the admin expects. data = []byte(os.ExpandEnv(string(store.Config))) } @@ -290,7 +275,7 @@ func (c *Connector) UnmarshalJSON(b []byte) error { connConfig := f() if len(conn.Config) != 0 { data := []byte(conn.Config) - if isExpandEnvEnabled() { + if featureflags.ExpandEnv.Enabled() { // Caution, we're expanding in the raw JSON/YAML source. This may not be what the admin expects. data = []byte(os.ExpandEnv(string(conn.Config))) } diff --git a/pkg/featureflags/flag.go b/pkg/featureflags/flag.go new file mode 100644 index 00000000..98729ac9 --- /dev/null +++ b/pkg/featureflags/flag.go @@ -0,0 +1,33 @@ +package featureflags + +import ( + "os" + "strconv" + "strings" +) + +type flag struct { + Name string + Default bool +} + +func (f *flag) env() string { + return "DEX_" + strings.ToUpper(f.Name) +} + +func (f *flag) Enabled() bool { + raw := os.Getenv(f.env()) + if raw == "" { + return f.Default + } + + res, err := strconv.ParseBool(raw) + if err != nil { + return f.Default + } + return res +} + +func newFlag(s string, d bool) *flag { + return &flag{Name: s, Default: d} +} diff --git a/pkg/featureflags/set.go b/pkg/featureflags/set.go new file mode 100644 index 00000000..1a31040a --- /dev/null +++ b/pkg/featureflags/set.go @@ -0,0 +1,11 @@ +package featureflags + +var ( + // EntEnabled enables experimental ent-based engine for the database storages. + // https://entgo.io/ + EntEnabled = newFlag("ent_enabled", false) + + // ExpandEnv can enable or disable env expansion in the config which can be useful in environments where, e.g., + // $ sign is a part of the password for LDAP user. + ExpandEnv = newFlag("expand_env", true) +)