106 lines
3.6 KiB
Go
106 lines
3.6 KiB
Go
package config
|
|
|
|
import "testing"
|
|
|
|
func TestSensitiveFieldCatalog(t *testing.T) {
|
|
fields := SensitiveFields()
|
|
if len(fields) < 30 {
|
|
t.Fatalf("sensitive field catalog is incomplete: %d", len(fields))
|
|
}
|
|
seen := map[string]struct{}{}
|
|
for _, field := range fields {
|
|
if _, ok := seen[field.Path]; ok {
|
|
t.Fatalf("duplicate sensitive field: %s", field.Path)
|
|
}
|
|
seen[field.Path] = struct{}{}
|
|
switch field.Policy {
|
|
case PersistenceEncryptedOnly, PersistenceReferenceOnly, PersistenceMemoryOnly, PersistenceHashedOnly:
|
|
default:
|
|
t.Fatalf("invalid policy for %s", field.Path)
|
|
}
|
|
if field.Description == "" {
|
|
t.Fatalf("missing description for %s", field.Path)
|
|
}
|
|
if CanGenericSerialize(field.Path) {
|
|
t.Fatalf("sensitive field can be generically serialized: %s", field.Path)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSensitiveWildcard(t *testing.T) {
|
|
field, ok := ClassifySensitive("plugins.telegram.token")
|
|
if !ok || field.Policy != PersistenceEncryptedOnly {
|
|
t.Fatal("plugin token was not classified")
|
|
}
|
|
if _, ok := ClassifySensitive("plugins.telegram.display_name"); ok {
|
|
t.Fatal("non-sensitive plugin field was classified")
|
|
}
|
|
}
|
|
|
|
func TestSensitivePersistenceRules(t *testing.T) {
|
|
tests := []struct {
|
|
path string
|
|
encrypted bool
|
|
want bool
|
|
}{
|
|
{path: "database.password", encrypted: false, want: false},
|
|
{path: "database.password", encrypted: true, want: true},
|
|
{path: "ssl.private_key", encrypted: true, want: false},
|
|
{path: "verification.code", encrypted: true, want: false},
|
|
{path: "verification.code_hmac", encrypted: true, want: false},
|
|
{path: "verification.process_key", encrypted: true, want: false},
|
|
{path: "public.display_name", encrypted: false, want: true},
|
|
{path: "verification.account_fingerprint", encrypted: true, want: false},
|
|
}
|
|
for _, test := range tests {
|
|
if got := CanPersist(test.path, test.encrypted); got != test.want {
|
|
t.Fatalf("CanPersist(%q, %t) = %t, want %t", test.path, test.encrypted, got, test.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSensitiveRepresentations(t *testing.T) {
|
|
tests := []struct {
|
|
path string
|
|
representation string
|
|
want bool
|
|
}{
|
|
{path: "database.password", representation: "encrypted", want: true},
|
|
{path: "database.password", representation: "hash", want: false},
|
|
{path: "verification.code", representation: "hash", want: false},
|
|
{path: "verification.code", representation: "memory", want: true},
|
|
{path: "verification.email_fingerprint", representation: "hash", want: true},
|
|
{path: "ssl.private_key", representation: "reference", want: true},
|
|
}
|
|
for _, test := range tests {
|
|
if got := CanPersistRepresentation(test.path, test.representation); got != test.want {
|
|
t.Fatalf("CanPersistRepresentation(%q, %q) = %t, want %t", test.path, test.representation, got, test.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRedactPublicValue(t *testing.T) {
|
|
value := map[string]any{
|
|
"database": map[string]any{
|
|
"password": map[string]any{"ciphertext": "enc-secret"},
|
|
"name": "smail",
|
|
},
|
|
"verification": map[string]any{
|
|
"code": "12345678",
|
|
"email_fingerprint": "fingerprint",
|
|
},
|
|
}
|
|
redacted, ok := RedactPublicValue(value).(map[string]any)
|
|
if !ok {
|
|
t.Fatalf("unexpected redacted value type: %T", RedactPublicValue(value))
|
|
}
|
|
database := redacted["database"].(map[string]any)
|
|
if database["password"] != RedactedValue || database["name"] != "smail" {
|
|
t.Fatalf("database public view was not redacted: %#v", database)
|
|
}
|
|
verification := redacted["verification"].(map[string]any)
|
|
if verification["code"] != RedactedValue || verification["email_fingerprint"] != RedactedValue {
|
|
t.Fatalf("verification public view was not redacted: %#v", verification)
|
|
}
|
|
}
|