Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NBHF4R9EAejDJUMdwr6C68
96 lines
2.6 KiB
Go
96 lines
2.6 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func noEnv(string) string { return "" }
|
|
|
|
func writeConfig(t *testing.T, body string) string {
|
|
t.Helper()
|
|
dir := t.TempDir()
|
|
p := filepath.Join(dir, "config.yaml")
|
|
if err := os.WriteFile(p, []byte(body), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.Chmod(p, 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return p
|
|
}
|
|
|
|
func TestLoadRejectsWorldReadableConfig(t *testing.T) {
|
|
p := writeConfig(t, minimalYAML)
|
|
if err := os.Chmod(p, 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := Load(p, noEnv); err == nil {
|
|
t.Fatal("0644-Config muss den Start abbrechen")
|
|
}
|
|
}
|
|
|
|
func TestLoadResolvesSecretFiles(t *testing.T) {
|
|
dir := t.TempDir()
|
|
secret := filepath.Join(dir, "apisecret")
|
|
if err := os.WriteFile(secret, []byte(" FROM-FILE\n"), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.Chmod(secret, 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
body := strings.Replace(minimalYAML,
|
|
` api_secret: "SECRET"`, ` api_secret_file: "`+secret+`"`, 1)
|
|
cfg, err := Load(writeConfig(t, body), noEnv)
|
|
if err != nil {
|
|
t.Fatalf("Load: %v", err)
|
|
}
|
|
if cfg.OPNsense.APISecret != "FROM-FILE" {
|
|
t.Errorf("APISecret = %q, want FROM-FILE (getrimmt)", cfg.OPNsense.APISecret)
|
|
}
|
|
}
|
|
|
|
func TestLoadRejectsLooseSecretFile(t *testing.T) {
|
|
dir := t.TempDir()
|
|
secret := filepath.Join(dir, "apisecret")
|
|
if err := os.WriteFile(secret, []byte("x"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.Chmod(secret, 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
body := strings.Replace(minimalYAML,
|
|
` api_secret: "SECRET"`, ` api_secret_file: "`+secret+`"`, 1)
|
|
if _, err := Load(writeConfig(t, body), noEnv); err == nil {
|
|
t.Fatal("Secret-Datei mit 0644 muss abgelehnt werden")
|
|
}
|
|
}
|
|
|
|
func TestLoadEnvOverridesEverything(t *testing.T) {
|
|
env := map[string]string{
|
|
"VPNPORTAL_OPNSENSE_API_SECRET": "FROM-ENV",
|
|
"VPNPORTAL_AD_BIND_PASSWORD": "ENV-PW",
|
|
}
|
|
cfg, err := Load(writeConfig(t, minimalYAML), func(k string) string { return env[k] })
|
|
if err != nil {
|
|
t.Fatalf("Load: %v", err)
|
|
}
|
|
if cfg.OPNsense.APISecret != "FROM-ENV" {
|
|
t.Errorf("APISecret = %q, want FROM-ENV", cfg.OPNsense.APISecret)
|
|
}
|
|
if cfg.AD.BindPassword != "ENV-PW" {
|
|
t.Errorf("BindPassword = %q, want ENV-PW", cfg.AD.BindPassword)
|
|
}
|
|
}
|
|
|
|
func TestLoadRejectsBothInlineAndFile(t *testing.T) {
|
|
body := strings.Replace(minimalYAML,
|
|
` api_secret: "SECRET"`,
|
|
" api_secret: \"SECRET\"\n api_secret_file: \"/tmp/x\"", 1)
|
|
_, err := Load(writeConfig(t, body), noEnv)
|
|
if err == nil || !strings.Contains(err.Error(), "api_secret") {
|
|
t.Fatalf("gleichzeitig gesetzte api_secret/api_secret_file müssen abgelehnt werden, got: %v", err)
|
|
}
|
|
}
|