Validate access to derived host roots
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package configkit_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -9,6 +10,61 @@ import (
|
||||
configkit "go.maximumdirect.net/configkit"
|
||||
)
|
||||
|
||||
func TestMainRelativeStandaloneRejectsInaccessibleHostRoot(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
mainPath := filepath.Join(root, "main.yml")
|
||||
if err := os.WriteFile(mainPath, []byte("count: 1\n"), 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.Chmod(root, 0100); err != nil {
|
||||
t.Skipf("cannot set search-only permissions: %v", err)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
if err := os.Chmod(root, 0700); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
})
|
||||
handle, err := os.OpenRoot(root)
|
||||
if err == nil {
|
||||
_ = handle.Close()
|
||||
t.Skip("host allows opening this search-only directory")
|
||||
}
|
||||
if !errors.Is(err, os.ErrPermission) {
|
||||
t.Fatalf("open root = %v, want permission denied", err)
|
||||
}
|
||||
if _, err := os.ReadFile(mainPath); err != nil {
|
||||
t.Skipf("main must remain readable by name: %v", err)
|
||||
}
|
||||
|
||||
main := configkit.Input{Source: configkit.File(mainPath)}
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
filesystem *configkit.FilesystemContext
|
||||
}{
|
||||
{name: "derived"},
|
||||
{name: "explicit", filesystem: &configkit.FilesystemContext{Root: root, BaseDir: root}},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
underlay := configkit.Input{
|
||||
Source: configkit.Bytes("companion", []byte("{}\n")),
|
||||
MainRelative: &configkit.MainRelativeContext{RequireBase: true},
|
||||
Filesystem: tc.filesystem,
|
||||
}
|
||||
_, err := configkit.LoadLayered(main, configkit.LayeredOptions[layeredFacadeConfig]{
|
||||
Underlays: []configkit.Underlay{{Inputs: []configkit.Input{underlay}}},
|
||||
})
|
||||
var failure *configkit.LoadError
|
||||
if !errors.As(err, &failure) {
|
||||
t.Fatalf("error = %v, want a load error", err)
|
||||
}
|
||||
diagnostics := failure.Diagnostics()
|
||||
if len(diagnostics) != 1 || diagnostics[0].Code != configkit.CodeImportPermission {
|
||||
t.Fatalf("diagnostics = %#v, want import.permission", diagnostics)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMainRelativeDiscoveryAndEvidence(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
first, second := filepath.Join(root, "first"), filepath.Join(root, "second")
|
||||
|
||||
Reference in New Issue
Block a user