89 lines
3.4 KiB
Go
89 lines
3.4 KiB
Go
package broker
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// The move of the secrets into the vault (design 57's V3, issue 676): each machine's node-engine may ask the
|
|
// vault's move-in in its own name — the subject that names it, and no other machine's — once the vault's holder
|
|
// serves it; it hears the controller's ask to move a value on its own subject; and the controller may copy its
|
|
// record of asks with the vault's move-asks. Composed from the records: a vault that serves neither grants nothing.
|
|
func TestANodeEngineMayMoveItsSecretsIntoTheVaultInItsOwnName(t *testing.T) {
|
|
vault := Declared{Module: "mesh-vault", Holds: []Seat{{Name: "mesh-vault",
|
|
Serves: []string{"get", "accept", "secret-ask", "issued", "rotate", "move-in", "move-asks"}}}}
|
|
users, err := Users(Records{Nodes: []string{"anchor", "shanks"}, Assigned: map[string][]Declared{"anchor": {vault}}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var anchor, controller Principal
|
|
for _, u := range users {
|
|
switch {
|
|
case u.Kind == KindNode && u.Node == "anchor":
|
|
anchor = u
|
|
case u.Kind == KindController:
|
|
controller = u
|
|
}
|
|
}
|
|
p, err := PermissionsFor(anchor)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !MayPublish(p, CalledSubject("mesh.seat.mesh-vault.tool.move-in", "node.anchor")) {
|
|
t.Error("anchor's node-engine may not ask the vault's move-in in its own name")
|
|
}
|
|
for _, s := range []string{CalledSubject("mesh.seat.mesh-vault.tool.move-in", "node.shanks"),
|
|
CalledSubject("mesh.seat.mesh-vault.tool.move-in", ControllerName),
|
|
CalledSubject("mesh.seat.mesh-vault.tool.get", "node.anchor"),
|
|
CalledSubject("mesh.seat.mesh-vault.tool.accept", "node.anchor"),
|
|
"mesh.seat.mesh-vault.tool.move-in"} {
|
|
if MayPublish(p, s) {
|
|
t.Errorf("anchor's node-engine may publish %s", s)
|
|
}
|
|
}
|
|
if !MaySubscribe(p, AskMoveSecretSubject("anchor")) || MaySubscribe(p, AskMoveSecretSubject("shanks")) {
|
|
t.Error("anchor's node-engine does not hear its own move asks alone")
|
|
}
|
|
// The vault's holder hears the call naming the node-engine.
|
|
held := false
|
|
for _, u := range users {
|
|
if u.Kind == KindModule && u.Module == "mesh-vault" {
|
|
held = true
|
|
h, err := PermissionsFor(u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !MaySubscribe(h, CalledSubject("mesh.seat.mesh-vault.tool.move-in", "node.anchor")) {
|
|
t.Error("the vault's holder does not hear move-in asked by a node-engine")
|
|
}
|
|
}
|
|
}
|
|
if !held {
|
|
t.Fatal("no principal holds the vault's seat")
|
|
}
|
|
c, err := PermissionsFor(controller)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !MayPublish(c, CalledSubject("mesh.seat.mesh-vault.tool.move-asks", ControllerName)) {
|
|
t.Error("the controller may not copy its record of asks into the vault")
|
|
}
|
|
if MayPublish(c, CalledSubject("mesh.seat.mesh-vault.tool.move-in", ControllerName)) {
|
|
t.Error("the controller may move a value in itself: it opens none")
|
|
}
|
|
if !MayPublish(c, AskMoveSecretSubject("anchor")) {
|
|
t.Error("the controller may not ask a machine's node-engine to move a value")
|
|
}
|
|
// A vault that serves neither, the running one: no grant for either.
|
|
older := Declared{Module: "mesh-vault", Holds: []Seat{{Name: "mesh-vault", Serves: []string{"get"}}}}
|
|
users, _ = Users(Records{Nodes: []string{"anchor"}, Assigned: map[string][]Declared{"anchor": {older}}})
|
|
for _, u := range users {
|
|
p, _ := PermissionsFor(u)
|
|
for _, s := range p.Publish {
|
|
if strings.Contains(s, "move-in") || strings.Contains(s, "move-asks") {
|
|
t.Errorf("%s may publish %s while the vault serves neither", u.Username(), s)
|
|
}
|
|
}
|
|
}
|
|
}
|