invokes: a manifest word that becomes exactly the publish grant a person's account gets (ADR 0152), derived by the same composition; refused at parse when it names no tool. module check <file|dir>... runs what registration runs with no store, for a manifest in any repository (hq issue 148).
93 lines
3.3 KiB
Go
93 lines
3.3 KiB
Go
package broker
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// A module that says it calls a tool may publish exactly that subject (novox/hq ADR 0152): the same
|
|
// grant a person gets, derived the same way, so one list answers "what may this ask" for everybody.
|
|
func TestAModuleMayAskOnlyTheToolsItInvokes(t *testing.T) {
|
|
perms, err := PermissionsFor(Principal{Kind: KindModule, Node: "desk", Module: "mesh-console",
|
|
Invokes: []string{"shop.price"}, PasswordHash: "x"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
has(t, perms.Publish, "mesh.mod.shop.tool.price")
|
|
hasNot(t, perms.Publish, "mesh.mod.shop.tool.refund")
|
|
hasNot(t, perms.Publish, "mesh.mod.*.tool.>")
|
|
}
|
|
|
|
// The console's grant: every tool, as one subject, and it reads as one.
|
|
func TestAModuleInvokingEverythingMayAskAnyTool(t *testing.T) {
|
|
perms, err := PermissionsFor(Principal{Kind: KindModule, Node: "desk", Module: "mesh-console",
|
|
Invokes: []string{"*"}, PasswordHash: "x"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
has(t, perms.Publish, "mesh.mod.*.tool.>")
|
|
}
|
|
|
|
// **A grant to call widens nothing else.** A module that invokes may not publish an event it did not
|
|
// declare, may not answer as another module, and subscribes nothing it did not consume — the
|
|
// difference between the console and a person is that the console is on a machine, not that it may
|
|
// do more.
|
|
func TestInvokingGrantsNothingButTheCall(t *testing.T) {
|
|
perms, err := PermissionsFor(Principal{Kind: KindModule, Node: "desk", Module: "mesh-console",
|
|
Invokes: []string{"*"}, PasswordHash: "x"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, p := range perms.Publish {
|
|
if strings.Contains(p, ".event.") {
|
|
t.Errorf("a module that only invokes may publish %q, an event it never declared", p)
|
|
}
|
|
if strings.HasPrefix(p, "mesh.seat.") {
|
|
t.Errorf("a module that only invokes may publish %q, a seat it neither holds nor uses", p)
|
|
}
|
|
}
|
|
for _, s := range perms.Subscribe {
|
|
if strings.Contains(s, ".tool.") && !strings.HasPrefix(s, "mesh.mod.mesh-console.") {
|
|
t.Errorf("a module that invokes may subscribe %q, another module's tools", s)
|
|
}
|
|
}
|
|
}
|
|
|
|
// A module that declares no invokes calls nothing, which is every module but the console.
|
|
func TestAModuleThatInvokesNothingCallsNothing(t *testing.T) {
|
|
perms, err := PermissionsFor(Principal{Kind: KindModule, Node: "one", Module: "shop",
|
|
Emits: []string{"order.placed"}, PasswordHash: "x"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, p := range perms.Publish {
|
|
if strings.Contains(p, ".tool.") {
|
|
t.Errorf("a module with no invokes may publish %q", p)
|
|
}
|
|
}
|
|
}
|
|
|
|
// The malformed entry is refused for a module as it is for a person, and in the same words.
|
|
func TestAModulesToolGrantThatNamesNoToolIsRefused(t *testing.T) {
|
|
if _, err := PermissionsFor(Principal{Kind: KindModule, Node: "one", Module: "shop",
|
|
Invokes: []string{"telegram"}, PasswordHash: "x"}); err == nil {
|
|
t.Fatal("a grant naming a module but no tool was accepted")
|
|
}
|
|
}
|
|
|
|
// What a declaration says reaches the composed user, so a manifest's `invokes` is the grant.
|
|
func TestADeclaredInvokeReachesTheComposedUser(t *testing.T) {
|
|
users, err := Users(Records{
|
|
Nodes: []string{"desk"},
|
|
Assigned: map[string][]Declared{"desk": {{Module: "mesh-console", Invokes: []string{"*"}}}},
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
perms, err := PermissionsFor(users[len(users)-1])
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
has(t, perms.Publish, "mesh.mod.*.tool.>")
|
|
}
|