Every grant to call a tool is granted again under the call kind, with the credential's own bus user as the last token, and every grant to answer one is granted for calls naming any caller: the caller of a tool call becomes a fact the bus enforces, as ADR 0259 section 3 made the asker of an ask. A kind of its own because every existing tool grant is a wildcard that would match any caller appended. The old tool grants stay for one release so nothing loses its way to a tool (hq issue 464); the controller's own grants move with that issue, since they are also the installer's first user list.
120 lines
5.7 KiB
Go
120 lines
5.7 KiB
Go
package broker
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// **A tool call names its caller, and the bus lets each user name itself alone** (novox/hq issue 365, by ADR
|
|
// 0259 §3's precedent for asks): wherever a principal may call a tool, it may call it on the caller-named
|
|
// subject — kind `call`, its own bus user last, dots written `~` — and on no subject naming anybody else.
|
|
func TestEachCredentialMayCallOnlyInItsOwnName(t *testing.T) {
|
|
ledger := Seat{Name: "node-desk", Scope: "node", Serves: []string{"who"}}
|
|
tracker := Seat{Name: "issue-tracker", Scope: "mesh", Serves: []string{"open"}}
|
|
for _, c := range []struct {
|
|
p Principal
|
|
may []string
|
|
mayNot []string
|
|
subject []string // what it subscribes, to answer calls naming any caller
|
|
}{
|
|
{p: Principal{Kind: KindPerson, Module: "jochen", Invokes: []string{"*"}},
|
|
may: []string{"mesh.mod.ledger.call.who.person~jochen", "mesh.mod.ledger.call.who.anchor.person~jochen",
|
|
"mesh.seat.issue-tracker.call.open.person~jochen", "mesh.seat.node-desk.call.who.anchor.person~jochen"},
|
|
mayNot: []string{"mesh.mod.ledger.call.who.shanks~node-tools", "mesh.mod.ledger.call.who.anchor.controller",
|
|
"mesh.seat.issue-tracker.call.open.person~somebody", "mesh.mod.ledger.call.who.person"}},
|
|
{p: Principal{Kind: KindNodeTools, Node: "shanks", Module: RuntimeModule,
|
|
Carries: []Declared{{Module: "ledger", Holds: []Seat{ledger, tracker}}}},
|
|
may: []string{"mesh.mod.ledger.call.who.shanks~node-tools", "mesh.seat.issue-tracker.call.open.shanks~node-tools"},
|
|
mayNot: []string{"mesh.mod.ledger.call.who.novox~node-tools", "mesh.seat.issue-tracker.call.open.controller"},
|
|
subject: []string{"mesh.mod.ledger.call.who.novox~node-tools", "mesh.seat.node-desk.call.who.shanks.person~jochen", "mesh.seat.issue-tracker.call.open.controller"}},
|
|
{p: Principal{Kind: KindModule, Node: "two", Module: "shop", Invokes: []string{"ledger.who", "seat:issue-tracker.open"}},
|
|
may: []string{"mesh.mod.ledger.call.who.two~shop", "mesh.mod.ledger.call.who.anchor.two~shop",
|
|
"mesh.seat.issue-tracker.call.open.two~shop"},
|
|
mayNot: []string{"mesh.mod.ledger.call.other.two~shop", "mesh.mod.ledger.call.who.one~shop",
|
|
"mesh.seat.issue-tracker.call.open.one~telegram"}},
|
|
{p: Principal{Kind: KindNode, Node: "one", Checks: []string{"ledger.health"}},
|
|
may: []string{"mesh.mod.ledger.call.health.one.node~one"},
|
|
mayNot: []string{"mesh.mod.ledger.call.health.two.node~one", "mesh.mod.ledger.call.health.one.node~two"}},
|
|
{p: Principal{Kind: KindModule, Node: "one", Module: "ledger", Holds: []Seat{ledger, tracker}},
|
|
subject: []string{"mesh.mod.ledger.call.who.person~jochen", "mesh.mod.ledger.call.who.one.controller",
|
|
"mesh.seat.node-desk.call.who.one.two~shop", "mesh.seat.issue-tracker.call.open.two~shop"}},
|
|
} {
|
|
perms, err := PermissionsFor(c.p)
|
|
if err != nil {
|
|
t.Fatalf("%s: %v", c.p.Username(), err)
|
|
}
|
|
for _, s := range c.may {
|
|
if !MayPublish(perms, s) {
|
|
t.Errorf("%s may not call %s, in its own name", c.p.Username(), s)
|
|
}
|
|
}
|
|
for _, s := range c.mayNot {
|
|
if MayPublish(perms, s) {
|
|
t.Errorf("%s may call %s, naming somebody else", c.p.Username(), s)
|
|
}
|
|
}
|
|
for _, s := range c.subject {
|
|
if !MaySubscribe(perms, s) {
|
|
t.Errorf("%s does not hear %s, a call to what it serves", c.p.Username(), s)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// The subjects that name no caller stay granted beside the caller-named ones for one release, so a caller
|
|
// moves over without a gap (their retirement: hq issue 464).
|
|
func TestTheSubjectsThatNameNoCallerStayGrantedForOneRelease(t *testing.T) {
|
|
perms, err := PermissionsFor(Principal{Kind: KindModule, Node: "two", Module: "shop", Invokes: []string{"ledger.who"}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, s := range []string{"mesh.mod.ledger.tool.who", "mesh.mod.ledger.tool.who.anchor"} {
|
|
if !MayPublish(perms, s) {
|
|
t.Errorf("the old subject %s is no longer granted", s)
|
|
}
|
|
}
|
|
}
|
|
|
|
// The desk's hidden prompt is the controller's alone on the caller-named subjects too (the review of
|
|
// 2026-10-09, M4): a grant of every tool does not reach it there either.
|
|
func TestTheDesksPromptIsTheControllersAloneUnderCallToo(t *testing.T) {
|
|
for _, p := range []Principal{{Kind: KindPerson, Module: "jochen", Invokes: []string{"*"}},
|
|
{Kind: KindNodeTools, Node: "shanks", Module: RuntimeModule}} {
|
|
perms, err := PermissionsFor(p)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
token := CallerToken(p.Username())
|
|
for _, s := range []string{"mesh.seat.node-launcher.call.secret.shanks." + token,
|
|
"mesh.mod.shell.call.node-launcher.secret.shanks." + token, "mesh.mod.shell.call.node-launcher.secret." + token} {
|
|
if MayPublish(perms, s) {
|
|
t.Errorf("%s may publish %s, the desk's hidden prompt", p.Username(), s)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// The controller's grants are the installer's first user list too, so they move with hq issue 464: this release
|
|
// it calls and serves on the subjects that name no caller alone, and nobody may call in its name.
|
|
func TestTheControllerKeepsTheSubjectsThatNameNoCallerThisRelease(t *testing.T) {
|
|
perms, err := PermissionsFor(Principal{Kind: KindController})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, s := range append(perms.Publish, perms.Subscribe...) {
|
|
if strings.Contains(s, "."+CallKind+".") {
|
|
t.Errorf("the controller is granted %s, which the installer's first user list does not carry", s)
|
|
}
|
|
}
|
|
for _, p := range []Principal{{Kind: KindPerson, Module: "jochen", Invokes: []string{"*"}},
|
|
{Kind: KindNodeTools, Node: "shanks", Module: RuntimeModule}} {
|
|
perms, err := PermissionsFor(p)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if MayPublish(perms, "mesh.mod.ledger.call.who.controller") || MayPublish(perms, "mesh.seat.mesh-controller.call.status.controller") {
|
|
t.Errorf("%s may call in the controller's name", p.Username())
|
|
}
|
|
}
|
|
}
|