fix(oidcgate): quality fixes — rune-safe snake-upper, drop dead import, listen validation, nested-struct test

This commit is contained in:
2026-05-19 13:40:24 +01:00
parent 17c28fd574
commit 8f458b4f6e
2 changed files with 40 additions and 11 deletions
+11 -11
View File
@@ -4,8 +4,8 @@ import (
"encoding/json"
"fmt"
"os"
"strconv"
"strings"
"unicode"
"github.com/lukaszraczylo/traefikoidc"
"gopkg.in/yaml.v3"
@@ -78,6 +78,10 @@ func Load(path string) (*Config, error) {
applyEnvOverrides(cfg)
applyDefaults(cfg)
if cfg.Listen == "" {
return nil, fmt.Errorf("config: missing required 'listen' (or OIDCGATE_LISTEN env var)")
}
// Force standalone semantics: trust X-Forwarded-Uri.
cfg.OIDC.TrustForwardedURI = true
return cfg, nil
@@ -152,8 +156,6 @@ func setScalarField(cfg *Config, field, value string) {
case "CACertPEM":
cfg.OIDC.CACertPEM = value
}
// strconv reserved for future int/bool fields when added to the allow-list.
_ = strconv.Atoi
}
func applyDefaults(cfg *Config) {
@@ -170,22 +172,20 @@ func applyDefaults(cfg *Config) {
// Multi-letter acronyms keep their grouping: "OIDCEndSessionURL" →
// "OIDC_END_SESSION_URL", "CACertPEM" → "CA_CERT_PEM".
func camelToSnakeUpper(s string) string {
runes := []rune(s)
var b strings.Builder
for i, r := range s {
for i, r := range runes {
if i > 0 && isUpper(r) {
prev := rune(s[i-1])
prev := runes[i-1]
next := rune(0)
if i+1 < len(s) {
next = rune(s[i+1])
if i+1 < len(runes) {
next = runes[i+1]
}
if !isUpper(prev) || (next != 0 && !isUpper(next)) {
b.WriteByte('_')
}
}
if r >= 'a' && r <= 'z' {
r -= 32
}
b.WriteRune(r)
b.WriteRune(unicode.ToUpper(r))
}
return b.String()
}
+29
View File
@@ -106,3 +106,32 @@ func TestLoad_MissingFile(t *testing.T) {
t.Fatal("expected error for missing file")
}
}
func TestLoad_NestedStructRoundTrip(t *testing.T) {
dir := t.TempDir()
path := filepath.Join(dir, "config.yaml")
if err := os.WriteFile(path, []byte(`
listen: ":8080"
providerURL: "https://idp.example"
clientID: "abc"
clientSecret: "secret"
sessionEncryptionKey: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
callbackURL: "/oauth2/callback"
logoutURL: "/oauth2/logout"
redis:
address: "redis:6379"
password: "redispw"
`), 0o600); err != nil {
t.Fatal(err)
}
cfg, err := Load(path)
if err != nil {
t.Fatal(err)
}
if cfg.OIDC.Redis == nil {
t.Fatal("redis block should populate cfg.OIDC.Redis")
}
if cfg.OIDC.Redis.Address != "redis:6379" {
t.Errorf("redis address: want redis:6379, got %q", cfg.OIDC.Redis.Address)
}
}