A module waiting for the operator's secret failed its first-node gate, held every later walk and was said as 'nothing for you to do'. The node-engine's new waiting state is checked against the manifest and the secrets given, read by the gate as a wait for a person, and raised as needs-operator naming the act. A secret family gives each part its own one-line secret, which the mesh never makes, so the desk prompt can take each password.
77 lines
2.8 KiB
Go
77 lines
2.8 KiB
Go
package inventory
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/novox/mesh-controller/internal/catalogue"
|
|
)
|
|
|
|
// A member of a secret family is given by its full name, at the desk too, and a name outside the family is refused
|
|
// (novox/hq ADR 0283).
|
|
func TestAMemberIsGivableAtTheDeskAndANameOutsideTheFamilyIsNot(t *testing.T) {
|
|
m := catalogue.Manifest{Module: "mounts", OwnSecrets: catalogue.OwnSecrets{
|
|
"smb-password-*": {Path: "/s/smb-password-*.secret", IssuedBy: catalogue.IssuedOutside},
|
|
}}
|
|
if err := GivableAtDesk(m, "smb-password-games"); err != nil {
|
|
t.Fatalf("a member was refused: %v", err)
|
|
}
|
|
for _, name := range []string{"smb-password-*", "smb-password-", "smb-password-a/b", "smb-password-A", "smb-credentials"} {
|
|
err := GivableAtDesk(m, name)
|
|
if err == nil {
|
|
t.Errorf("%q was givable", name)
|
|
} else if !strings.Contains(err.Error(), "smb-password-<name>") {
|
|
t.Errorf("%q: the refusal does not say the family's form: %v", name, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// A member given is read back as given, sealed to the machine's key; the mesh makes none, so nothing else is.
|
|
func TestAMemberGivenIsReadAsGivenAndNothingElseIs(t *testing.T) {
|
|
inv := fresh(t)
|
|
ctx := t.Context()
|
|
node, err := inv.AddNode(ctx, "workstation")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
key, _ := aSealingKey(t)
|
|
if err := inv.RecordSealingKey(ctx, node.ID, key); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
m := catalogue.Manifest{Module: "mounts", Version: "1", OwnSecrets: catalogue.OwnSecrets{
|
|
"smb-password-*": {Path: "/s/smb-password-*.secret", IssuedBy: catalogue.IssuedOutside},
|
|
"token": {Path: "/s/token", IssuedBy: catalogue.IssuedOutside},
|
|
}}
|
|
if err := inv.RegisterModule(ctx, m, Source{}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := inv.AcceptSecretForModule(ctx, "workstation", "mounts", "smb-password-games", "hunter2"); err != nil {
|
|
t.Fatalf("a member was refused: %v", err)
|
|
}
|
|
if err := inv.AcceptSecretForModule(ctx, "workstation", "mounts", "smb-pass", "x"); err == nil {
|
|
t.Fatal("a name of no family was accepted")
|
|
}
|
|
members, err := inv.GivenMembers(ctx, "workstation", "mounts", "smb-password-*")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(members) != 1 || members[0].Name != "smb-password-games" || !members[0].Current || members[0].Sealed == "" ||
|
|
strings.Contains(members[0].Sealed, "hunter2") {
|
|
t.Fatalf("members: %+v", members)
|
|
}
|
|
given, err := inv.GivenOwnSecrets(ctx, "workstation", "mounts")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, was := given["smb-password-games"]; !was || len(given) != 1 {
|
|
t.Fatalf("given: %v", given)
|
|
}
|
|
// A value the mesh made is not one a person gave.
|
|
if _, err := inv.SecretForModule(ctx, "workstation", "mounts", "token"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if given, _ := inv.GivenOwnSecrets(ctx, "workstation", "mounts"); len(given) != 1 {
|
|
t.Fatalf("a value the mesh made counted as given: %v", given)
|
|
}
|
|
}
|