package panelacl import "testing" func newStore(t *testing.T) *Store { t.Helper() s, err := New(t.TempDir()) if err != nil { t.Fatal("New:", err) } return s } func TestUnmanagedPanelIsOpen(t *testing.T) { s := newStore(t) if got := s.PanelPerm("legacy", "alice", nil); got != PermWrite { t.Fatalf("unmanaged panel perm = %v, want write", got) } } func TestOwnerAlwaysWrites(t *testing.T) { s := newStore(t) if err := s.CreatePanel("p1", "alice"); err != nil { t.Fatal(err) } if got := s.PanelPerm("p1", "alice", nil); got != PermWrite { t.Fatalf("owner perm = %v, want write", got) } // A freshly created panel is private to its owner. if got := s.PanelPerm("p1", "bob", nil); got != PermNone { t.Fatalf("non-owner perm on private panel = %v, want none", got) } } func TestPublicAndGrants(t *testing.T) { s := newStore(t) if err := s.CreatePanel("p1", "alice"); err != nil { t.Fatal(err) } grants := []Grant{ {Kind: "user", Name: "bob", Perm: "write"}, {Kind: "group", Name: "ops", Perm: "read"}, } if err := s.SetPanel("p1", "alice", "", "read", grants); err != nil { t.Fatal(err) } // Public read applies to anyone. if got := s.PanelPerm("p1", "carol", nil); got != PermRead { t.Fatalf("public perm = %v, want read", got) } // Direct user grant raises bob to write. if got := s.PanelPerm("p1", "bob", nil); got != PermWrite { t.Fatalf("granted user perm = %v, want write", got) } // Group membership grants read. if got := s.PanelPerm("p1", "dave", []string{"ops"}); got != PermRead { t.Fatalf("group perm = %v, want read", got) } } func TestFolderInheritance(t *testing.T) { s := newStore(t) f, err := s.CreateFolder("f1", "Shared", "", "alice") if err != nil { t.Fatal(err) } if err := s.UpdateFolder(f.ID, f.Name, "", "read", nil); err != nil { t.Fatal(err) } if err := s.CreatePanel("p1", "alice"); err != nil { t.Fatal(err) } if err := s.SetPanel("p1", "alice", f.ID, "", nil); err != nil { t.Fatal(err) } // The panel inherits the folder's public-read level. if got := s.PanelPerm("p1", "bob", nil); got != PermRead { t.Fatalf("inherited perm = %v, want read", got) } } func TestFolderCycleRejected(t *testing.T) { s := newStore(t) a, _ := s.CreateFolder("a", "A", "", "alice") b, _ := s.CreateFolder("b", "B", a.ID, "alice") // Re-parenting A under its own descendant B must be rejected. if err := s.UpdateFolder(a.ID, a.Name, b.ID, "", nil); err == nil { t.Fatal("expected cycle rejection, got nil") } } func TestDeleteFolderReparents(t *testing.T) { s := newStore(t) a, _ := s.CreateFolder("a", "A", "", "alice") b, _ := s.CreateFolder("b", "B", a.ID, "alice") if err := s.CreatePanel("p1", "alice"); err != nil { t.Fatal(err) } if err := s.SetPanel("p1", "alice", b.ID, "", nil); err != nil { t.Fatal(err) } if err := s.DeleteFolder(b.ID); err != nil { t.Fatal(err) } // B's panel should reparent to A (B's former parent), not orphan. if acl := s.GetPanel("p1"); acl == nil || acl.Folder != a.ID { t.Fatalf("panel folder after delete = %+v, want %s", acl, a.ID) } }