aboutsummaryrefslogtreecommitdiff
path: root/internal/admin/correct_audit_fixes_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/admin/correct_audit_fixes_test.go')
-rw-r--r--internal/admin/correct_audit_fixes_test.go31
1 files changed, 30 insertions, 1 deletions
diff --git a/internal/admin/correct_audit_fixes_test.go b/internal/admin/correct_audit_fixes_test.go
index 381fb5c..60073f7 100644
--- a/internal/admin/correct_audit_fixes_test.go
+++ b/internal/admin/correct_audit_fixes_test.go
@@ -1,6 +1,11 @@
package admin
-import "testing"
+import (
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+)
// Regression: the raw file API must canonicalize repeated "/" and "data/"
// prefixes, or "//players/..." reaches the real file while the classifiers
@@ -20,3 +25,27 @@ func TestCanonicalDataRelPathStripsRepeatedPrefixes(t *testing.T) {
}
}
}
+
+// Regression: a valid-but-non-mapping body used to pass through unchanged and
+// blank password_hash. It must now be refused, and a mapping body must keep
+// the on-disk hash.
+func TestRestoreAccountSecretRefusesNonMappingBody(t *testing.T) {
+ dir := t.TempDir()
+ full := filepath.Join(dir, "players", "accounts", "alice.yaml")
+ if err := os.MkdirAll(filepath.Dir(full), 0755); err != nil {
+ t.Fatal(err)
+ }
+ if err := os.WriteFile(full, []byte("name: alice\npassword_hash: secret\n"), 0600); err != nil {
+ t.Fatal(err)
+ }
+ if _, err := restoreAccountSecret("players/accounts/alice.yaml", full, []byte("# comment only\n")); err == nil {
+ t.Fatal("non-mapping body accepted; the password hash would be blanked")
+ }
+ out, err := restoreAccountSecret("players/accounts/alice.yaml", full, []byte("name: alice\npassword_hash: \"[redacted]\"\n"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !strings.Contains(string(out), "secret") {
+ t.Fatalf("password hash not preserved: %s", out)
+ }
+}