91 lines
2.5 KiB
Go
91 lines
2.5 KiB
Go
package adminbootstrap
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestLoadConfigRequiresExplicitSafeInputs(t *testing.T) {
|
|
secret := randomSecret(t)
|
|
base := map[string]string{
|
|
"CHORUS_DSN": "mysql-test-dsn",
|
|
"CHORUS_ADMIN_USERNAME": "admin-test",
|
|
"CHORUS_ADMIN_PASSWORD": secret,
|
|
}
|
|
|
|
for name := range base {
|
|
t.Run("missing_"+name, func(t *testing.T) {
|
|
values := mapsWithout(base, name)
|
|
_, err := LoadConfig(lookup(values))
|
|
if err == nil || !strings.Contains(err.Error(), name) {
|
|
t.Fatalf("LoadConfig() error = %v, want %s validation error", err, name)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLoadConfigRequiresExplicitResetFlag(t *testing.T) {
|
|
values := map[string]string{
|
|
"CHORUS_DSN": "mysql-test-dsn",
|
|
"CHORUS_ADMIN_USERNAME": "admin-test",
|
|
"CHORUS_ADMIN_PASSWORD": randomSecret(t),
|
|
"CHORUS_ADMIN_RESET_PASSWORD": "true",
|
|
}
|
|
if _, err := LoadConfig(lookup(values)); err == nil || !strings.Contains(err.Error(), "CHORUS_ADMIN_RESET_PASSWORD") {
|
|
t.Fatalf("LoadConfig() error = %v, want reset flag validation error", err)
|
|
}
|
|
}
|
|
|
|
func TestConfigErrorsDoNotExposeSensitiveValues(t *testing.T) {
|
|
dsn := "sensitive-dsn-value"
|
|
password := randomSecret(t)
|
|
_, err := LoadConfig(lookup(map[string]string{
|
|
"CHORUS_DSN": dsn,
|
|
"CHORUS_ADMIN_USERNAME": strings.Repeat("a", 65),
|
|
"CHORUS_ADMIN_PASSWORD": password,
|
|
}))
|
|
if err == nil {
|
|
t.Fatal("LoadConfig() error = nil, want validation error")
|
|
}
|
|
for _, sensitive := range []string{dsn, password} {
|
|
if strings.Contains(err.Error(), sensitive) {
|
|
t.Fatalf("validation error exposes a sensitive value")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestBootstrapRejectsInvalidConfigBeforeDatabaseUse(t *testing.T) {
|
|
_, err := Bootstrap(t.Context(), nil, Config{})
|
|
if err == nil || !strings.Contains(err.Error(), "CHORUS_DSN") {
|
|
t.Fatalf("Bootstrap() error = %v, want configuration error", err)
|
|
}
|
|
}
|
|
|
|
func TestBootstrapRejectsUnavailableDatabase(t *testing.T) {
|
|
_, err := Bootstrap(t.Context(), nil, Config{
|
|
DSN: "mysql-test-dsn",
|
|
Username: "admin-test",
|
|
Password: randomSecret(t),
|
|
})
|
|
if err != ErrDatabaseUnavailable {
|
|
t.Fatalf("Bootstrap() error = %v, want ErrDatabaseUnavailable", err)
|
|
}
|
|
}
|
|
|
|
func lookup(values map[string]string) func(string) (string, bool) {
|
|
return func(name string) (string, bool) {
|
|
value, ok := values[name]
|
|
return value, ok
|
|
}
|
|
}
|
|
|
|
func mapsWithout(values map[string]string, excluded string) map[string]string {
|
|
result := make(map[string]string, len(values)-1)
|
|
for name, value := range values {
|
|
if name != excluded {
|
|
result[name] = value
|
|
}
|
|
}
|
|
return result
|
|
}
|