package main import ( "os" "path/filepath" "strings" "testing" ) func manifest(t *testing.T, root, module, body string) { t.Helper() dir := filepath.Join(root, "modules", module) if err := os.MkdirAll(dir, 0o755); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(dir, "module.json"), []byte(body), 0o644); err != nil { t.Fatal(err) } } func check(t *testing.T, root string) []Finding { t.Helper() found, err := Check(root) if err != nil { t.Fatal(err) } return found } // only asserts exactly one finding, of the rule, naming the module and the resource (issue 1024). func only(t *testing.T, found []Finding, rule int, module, id string) { t.Helper() if len(found) != 1 || found[0].Rule != rule || found[0].Module != module || found[0].ID != id || found[0].Why == "" { t.Fatalf("found %+v; want one finding of rule %d for %s/%s with a reason", found, rule, module, id) } } func dir(id, path, rest string) string { return `{"id":"` + id + `","type":"directory","path":"` + path + `"` + rest + `}` } func mod(name string, resources ...string) string { return `{"module":"` + name + `","resources":[` + strings.Join(resources, ",") + `]}` } func TestMissingOrUnknownValueIsRefused(t *testing.T) { root := t.TempDir() manifest(t, root, "a", mod("a", dir("d", "/var/lib/a", ""))) only(t, check(t, root), 1, "a", "d") root = t.TempDir() manifest(t, root, "a", mod("a", `{"id":"z","type":"archive","path":"/opt/a","unknown":"delete"}`)) only(t, check(t, root), 1, "a", "z") } func TestMoveOutOutsideAHomeIsRefused(t *testing.T) { root := t.TempDir() manifest(t, root, "a", mod("a", dir("d", "/etc/a.d", `,"unknown":"move-out"`))) only(t, check(t, root), 2, "a", "d") } func TestMoveOutUnderAHomeIsAllowed(t *testing.T) { root := t.TempDir() manifest(t, root, "a", mod("a", dir("d", "${machine:account-home}/.config/a", `,"unknown":"move-out"`), dir("e", "${dir:d}/sub", `,"unknown":"move-out"`), dir("f", "${machine:agent-home}/x", `,"unknown":"move-out"`), dir("g", "/var/lib/a", `,"unknown":"program"`), dir("h", "${machine:account-home}/.ssh", `,"unknown":"module"`))) if found := check(t, root); len(found) != 0 { t.Fatalf("refused %+v", found) } } func TestBadKnowsIsRefused(t *testing.T) { for _, knows := range []string{`[""]`, `["/abs"]`, `["a/../b"]`, `["./a"]`, `["a//b"]`, `["a","a"]`, `["a","a/"]`} { root := t.TempDir() manifest(t, root, "a", mod("a", dir("d", "${machine:account-home}/.config/a", `,"unknown":"move-out","knows":`+knows))) only(t, check(t, root), 3, "a", "d") } root := t.TempDir() manifest(t, root, "a", mod("a", dir("d", "${machine:account-home}/.config/a", `,"unknown":"move-out","knows":["forge.credentials","kept/"]`))) if found := check(t, root); len(found) != 0 { t.Fatalf("refused %+v", found) } } func TestAnotherModulesPathInsideADirectoryIsRefused(t *testing.T) { root := t.TempDir() manifest(t, root, "owner", mod("owner", dir("ssh", "${machine:account-home}/.ssh", `,"unknown":"module"`))) manifest(t, root, "intruder", mod("intruder", `{"id":"f","type":"file","path":"${machine:account-home}/.ssh/config.d/20"}`)) manifest(t, root, "viahome", mod("viahome", `{"id":"g","type":"file","path":"${machine:agent-home}/.ssh/x"}`)) manifest(t, root, "facty", `{"module":"facty","facts":{"hosts":{"path":".ssh/config.d/00","home":true}}}`) manifest(t, root, "outside", mod("outside", `{"id":"o","type":"file","path":"${machine:account-home}/.sshrc"}`)) got := map[string]int{} for _, f := range check(t, root) { if f.Rule != 4 || f.Why == "" { t.Fatalf("finding %+v", f) } got[f.Module]++ } if len(got) != 3 || got["intruder"] != 1 || got["viahome"] != 1 || got["facty"] != 1 { t.Fatalf("refused %v; want intruder, viahome, facty", got) } } func TestDirReferencesAreResolvedPerModule(t *testing.T) { root := t.TempDir() manifest(t, root, "owner", mod("owner", dir("base", "${machine:account-home}/.config/o", `,"unknown":"move-out"`))) manifest(t, root, "other", mod("other", dir("base", "${machine:account-home}/.config/p", `,"unknown":"move-out"`), `{"id":"f","type":"file","path":"${dir:base}/x"}`)) if found := check(t, root); len(found) != 0 { t.Fatalf("refused %+v", found) } manifest(t, root, "third", mod("third", dir("d", "${machine:account-home}/.config/t", `,"unknown":"move-out"`), `{"id":"f","type":"file","path":"${dir:d}/../o/x"}`)) only(t, check(t, root), 4, "third", "f") } func TestAnArchiveIsNotAContainerAndSameModuleIsFine(t *testing.T) { root := t.TempDir() manifest(t, root, "a", mod("a", `{"id":"arc","type":"archive","path":"/opt/a","unknown":"program"}`, dir("d", "/opt/a2", `,"unknown":"program"`), `{"id":"f","type":"file","path":"/opt/a2/x"}`)) manifest(t, root, "b", mod("b", `{"id":"f","type":"file","path":"/opt/a/x"}`)) if found := check(t, root); len(found) != 0 { t.Fatalf("refused %+v", found) } }