Archived
Keep a join token nowhere but in its caller's answer
The calls the controller serves are kept on the bus with their answers, and calls answers anyone who may call its seat. A token is the one-time right to become a machine of the mesh, so the token verb's answer is kept as withheld (novox/hq ADR 0169).
This commit is contained in:
@@ -302,9 +302,26 @@ func (l *CallLog) finish(c *Call, answer []byte, failed, answeredAlready bool) {
|
|||||||
} else {
|
} else {
|
||||||
c.State = CallAnswered
|
c.State = CallAnswered
|
||||||
}
|
}
|
||||||
|
if shownOnce[c.Seat+"."+c.Verb] {
|
||||||
|
// **A secret shown once is never kept on the bus** (novox/hq ADR 0169): a join token is the
|
||||||
|
// one-time right to become a machine of the mesh, and `calls` answers anyone who may call the
|
||||||
|
// seat. Its caller was sent it; kept in this process's memory only when its caller has not
|
||||||
|
// had it yet — told the call was still running — and then until a restart, never beyond.
|
||||||
|
withheld, _ := json.Marshal(map[string]any{"not kept": "a secret shown once, to its caller"})
|
||||||
|
onTheBus := *c
|
||||||
|
onTheBus.Answer = withheld
|
||||||
|
if !answeredAlready {
|
||||||
|
c.Answer = withheld
|
||||||
|
}
|
||||||
|
l.keep(onTheBus)
|
||||||
|
return
|
||||||
|
}
|
||||||
l.keep(*c)
|
l.keep(*c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// shownOnce are the verbs whose answer is a secret shown once to its caller, as `<seat>.<verb>`.
|
||||||
|
var shownOnce = map[string]bool{"mesh-controller.token": true}
|
||||||
|
|
||||||
// Recent is the kept calls, newest first, as copies: this process's from memory, and, when they are
|
// Recent is the kept calls, newest first, as copies: this process's from memory, and, when they are
|
||||||
// kept durably, every other the bus holds — a call a controller before this one served included.
|
// kept durably, every other the bus holds — a call a controller before this one served included.
|
||||||
// Memory wins for a call in both, being the newer word on it. A bus that cannot be read is said in
|
// Memory wins for a call in both, being the newer word on it. A bus that cannot be read is said in
|
||||||
|
|||||||
@@ -199,3 +199,27 @@ func TestAHandoverRefusalIsMarkedRetryable(t *testing.T) {
|
|||||||
t.Fatal("an ordinary refusal was marked to be asked again")
|
t.Fatal("an ordinary refusal was marked to be asked again")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// **A join token is shown to its caller and kept nowhere** (novox/hq ADR 0169): `calls` answers anyone
|
||||||
|
// who may call the seat, and a token is the one-time right to become a machine of the mesh.
|
||||||
|
func TestAJoinTokenIsShownToItsCallerAndNotKept(t *testing.T) {
|
||||||
|
l, a := NewCallLog(), newAnswers(t)
|
||||||
|
writes := make(chan Call, 4)
|
||||||
|
l.writes = writes
|
||||||
|
l.serveCall("mesh-controller", "token", json.RawMessage(`{"new":"laptop"}`), "_INBOX.x.1",
|
||||||
|
func(context.Context, json.RawMessage) (any, error) { return "token for laptop: s3cret-join", nil },
|
||||||
|
a.respond, nil)
|
||||||
|
if got, _ := a.only()["result"].(string); !strings.Contains(got, "s3cret-join") {
|
||||||
|
t.Fatalf("its caller was not shown the token: %v", got)
|
||||||
|
}
|
||||||
|
recent, _ := l.Recent()
|
||||||
|
if len(recent) != 1 || strings.Contains(string(recent[0].Answer), "s3cret-join") {
|
||||||
|
t.Fatalf("the token was kept in memory: %+v", recent)
|
||||||
|
}
|
||||||
|
close(writes)
|
||||||
|
for c := range writes {
|
||||||
|
if strings.Contains(string(c.Answer), "s3cret-join") {
|
||||||
|
t.Fatalf("the token was sent to be kept on the bus: %s", c.Answer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user