Feature 04 task 3 (rebased): Household settings seeding and API (#27)
CI / ci (push) Successful in 1m22s
CI / ci (push) Successful in 1m22s
Co-authored-by: dev_agent <dev_agent@cubecraftlabs.com> Co-committed-by: dev_agent <dev_agent@cubecraftlabs.com>
This commit was merged in pull request #27.
This commit is contained in:
@@ -33,6 +33,8 @@ const (
|
||||
EnvSessionMax = "MEALQUEST_SESSION_MAX"
|
||||
|
||||
EnvTrustedProxy = "MEALQUEST_TRUSTED_PROXY"
|
||||
|
||||
EnvDefaultTZ = "MEALQUEST_DEFAULT_TZ"
|
||||
)
|
||||
|
||||
// Session lifetime defaults (D-004): long enough that the kitchen tablet
|
||||
@@ -65,6 +67,12 @@ type Config struct {
|
||||
// TrustedProxy lists the reverse proxies whose X-Forwarded-For and
|
||||
// X-Forwarded-Proto headers are honoured. Empty trusts no peer.
|
||||
TrustedProxy forwarded.Trusted
|
||||
|
||||
// DefaultTZ is the IANA zone the household settings are created with on
|
||||
// first boot. It is optional and not validated here: boot requires and
|
||||
// validates it only while the settings do not exist yet, and ignores it
|
||||
// once they do. Empty when unset.
|
||||
DefaultTZ string
|
||||
}
|
||||
|
||||
// PublicOrigin returns the scheme and host of PublicURL, the only parts of it
|
||||
@@ -97,6 +105,8 @@ func load(lookup func(string) (string, bool)) (Config, error) {
|
||||
SessionMax: r.sessionDuration(EnvSessionMax, DefaultSessionMax),
|
||||
|
||||
TrustedProxy: r.trustedProxy(EnvTrustedProxy),
|
||||
|
||||
DefaultTZ: r.optional(EnvDefaultTZ),
|
||||
}
|
||||
if cfg.SessionIdle > 0 && cfg.SessionMax > 0 && cfg.SessionMax < cfg.SessionIdle {
|
||||
r.fail(EnvSessionMax, "must be at least %s (%s)", EnvSessionIdle, cfg.SessionIdle)
|
||||
@@ -323,6 +333,12 @@ func (r *reader) parseDuration(name, v string) time.Duration {
|
||||
return d
|
||||
}
|
||||
|
||||
// optional returns the variable's value, or "" when it is unset.
|
||||
func (r *reader) optional(name string) string {
|
||||
v, _ := r.lookup(name)
|
||||
return v
|
||||
}
|
||||
|
||||
// secretFile reads a secret from the file named by name, which must end in
|
||||
// _FILE. Setting the secret inline (name without _FILE) is rejected.
|
||||
func (r *reader) secretFile(name string) Secret {
|
||||
|
||||
@@ -68,6 +68,16 @@ func TestLoad(t *testing.T) {
|
||||
name: "all required vars present",
|
||||
env: valid(),
|
||||
},
|
||||
{
|
||||
name: "default time zone set",
|
||||
env: with(map[string]string{EnvDefaultTZ: "America/New_York"}),
|
||||
},
|
||||
{
|
||||
// Validated only when seeding the household settings, so a
|
||||
// stale value cannot stop a boot that no longer uses it.
|
||||
name: "default time zone not an IANA zone",
|
||||
env: with(map[string]string{EnvDefaultTZ: "Mars/Olympus_Mons"}),
|
||||
},
|
||||
{
|
||||
name: "one missing",
|
||||
env: with(nil, EnvHTTPAddr),
|
||||
@@ -410,6 +420,8 @@ func TestLoadValues(t *testing.T) {
|
||||
EnvOIDCClientID: "mealquest",
|
||||
EnvOIDCClientSecretFile: clientSecretPath,
|
||||
EnvOIDCAllowedGroups: " mealquest-admin ,family",
|
||||
|
||||
EnvDefaultTZ: "Europe/London",
|
||||
}
|
||||
cfg, err := load(func(k string) (string, bool) { v, ok := env[k]; return v, ok })
|
||||
if err != nil {
|
||||
@@ -465,6 +477,9 @@ func TestLoadValues(t *testing.T) {
|
||||
if !slices.Equal(cfg.TrustedProxy, want) {
|
||||
t.Errorf("TrustedProxy = %v, want %v", cfg.TrustedProxy, want)
|
||||
}
|
||||
if cfg.DefaultTZ != "Europe/London" {
|
||||
t.Errorf("DefaultTZ = %q, want Europe/London", cfg.DefaultTZ)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSecretRedacted(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user