package securefs_test import ( "errors" "os" "path/filepath" "testing" "proxyctl/internal/securefs" ) func TestAtomicWriteCreatesAndReplacesRegularFile(t *testing.T) { root := t.TempDir() path := filepath.Join(root, "state", "config.json") store := securefs.Store{TrustedRoot: root} if err := store.AtomicWrite(path, []byte("first\n"), 0o640); err != nil { t.Fatal(err) } if err := store.AtomicWrite(path, []byte("second\n"), 0o600); err != nil { t.Fatal(err) } data, err := os.ReadFile(path) if err != nil { t.Fatal(err) } info, err := os.Stat(path) if err != nil { t.Fatal(err) } if string(data) != "second\n" || info.Mode().Perm() != 0o600 { t.Fatalf("content=%q mode=%o", data, info.Mode().Perm()) } } func TestAtomicWriteRejectsSymlinkWithoutChangingVictim(t *testing.T) { root := t.TempDir() victim := filepath.Join(root, "victim") if err := os.WriteFile(victim, []byte("unchanged"), 0o600); err != nil { t.Fatal(err) } path := filepath.Join(root, "managed") if err := os.Symlink(victim, path); err != nil { t.Fatal(err) } store := securefs.Store{TrustedRoot: root} if err := store.AtomicWrite(path, []byte("replaced"), 0o600); err == nil { t.Fatal("AtomicWrite followed a final symlink") } data, err := os.ReadFile(victim) if err != nil { t.Fatal(err) } if string(data) != "unchanged" { t.Fatalf("victim changed: %q", data) } } func TestStoreRejectsPathsOutsideTrustedRoot(t *testing.T) { root := t.TempDir() outside := filepath.Join(t.TempDir(), "outside") store := securefs.Store{TrustedRoot: root} if err := store.AtomicWrite(outside, []byte("data"), 0o600); err == nil { t.Fatal("AtomicWrite escaped TrustedRoot") } if _, err := os.Stat(outside); !errors.Is(err, os.ErrNotExist) { t.Fatalf("outside path changed: %v", err) } }