Files
mesh-host/internal/link/logins_test.go
T
jschoubben c7468656af The engine dials as the login the vault's node-logins names
A membership may name its Logins (ADR 0583 §1): the login in use and the password of each login held, kept beside the
identity, so a restart dials as the login in use. The engine follows its own key of node-logins as a watch on every link
and dials as the login it names when it holds its value, with the node's one inbox; with no key, or a key naming the first
login, it dials node.<n> with the membership's password as before. A change of the login in use drops the link so it is
opened again as the new one, and the vault is asked in the name of the login dialled (the subject names the caller).
Tests: one added, paid by merging the pinned-broker test with the malformed-pin test (two into one).

(issue 774, 774/S61)

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 01:49:01 +01:00

50 lines
2.3 KiB
Go

package link
import (
"strings"
"testing"
"git.novox.be/novox/mesh-sdk/go/delivery"
)
// 774/S61/AC1 and AC2 (ADR 0583 §1): with no node-logins key, or one that names the first login, the engine dials as node.<n>
// with the membership's password as before; with a key naming node.<n>--b in use it dials as that login (whose value it
// holds), with the node's one inbox; a login whose value it does not hold is not dialled, and said.
func TestTheLoginDialledIsTheOneNodeLoginsNames(t *testing.T) {
var saved LoginsState
l := NewLogins("ace", "first-secret", LoginsState{}, func(s LoginsState) error { saved = s; return nil })
m := Membership{Node: "ace", Password: "first-secret", Logins: l}
if u, p := m.Credential(); u != "node.ace" || p != "first-secret" {
t.Fatalf("no key: %s %s", u, p)
}
if u, p := (Membership{Node: "ace", Password: "plain"}).Credential(); u != "node.ace" || p != "plain" {
t.Fatalf("no logins at all: %s %s", u, p)
}
if said := l.Heard(delivery.NodeLogin{Node: "ace", Login: "node.ace"}); said != "" || m.User() != "node.ace" {
t.Errorf("the first login named: %q, %s", said, m.User())
}
if said := l.Heard(delivery.NodeLogin{Node: "ace", Login: "node.ace--b"}); !strings.Contains(said, "cannot dial as it") || m.User() != "node.ace" {
t.Errorf("a login held no value for: %q, %s", said, m.User())
}
if err := l.Hold("node.ace--b", "second-secret"); err != nil {
t.Fatal(err)
}
if err := l.Hold("node.g14", "x"); err == nil {
t.Error("another node's login was kept")
}
if said := l.Heard(delivery.NodeLogin{Node: "ace", Login: "node.ace--b"}); !strings.Contains(said, "dialled as it") {
t.Errorf("said %q", said)
}
if u, p := m.Credential(); u != "node.ace--b" || p != "second-secret" || saved.Current != "node.ace--b" {
t.Errorf("node-logins names --b: %s %s, kept %+v", u, p, saved)
}
// A restart dials as the login kept, and the engine's own first password stays held until the vault says done.
again := NewLogins("ace", "first-secret", saved, nil)
if u, _ := again.Current(); u != "node.ace--b" || len(again.Held()) != 2 {
t.Errorf("after a restart: %s, held %v", u, again.Held())
}
if CalledVaultSubjectAs("own", m.User()) != "mesh.seat.mesh-vault.call.own.node~ace--b" {
t.Errorf("the vault is asked in the name of the login in use: %s", CalledVaultSubjectAs("own", m.User()))
}
}