package link import ( "strings" "testing" "time" ) // The subject and the signing context the controller holds the same words for (mesh-controller internal/link). func TestTheDirectoryJudgementAskKeepsItsSubjectAndContext(t *testing.T) { if AskJudgeDirectoriesSubject("laptop") != "mesh.node.laptop.ask.judge-directories" { t.Fatalf("the subject is %q", AskJudgeDirectoriesSubject("laptop")) } if JudgeDirectoriesContext != "novox-mesh judge-directories v1\n" || JudgeDirectoriesContext == HandOverContext || JudgeDirectoriesContext == SetuidSearchContext { t.Fatalf("the signing context is %q", JudgeDirectoriesContext) } } // A judgement ask is believed as a hand-over is: signed by the mesh under its own context, for this node, // unexpired, once, and naming no path. func TestADirectoryJudgementAskIsBelievedOnlySignedForThisNodeAndOnce(t *testing.T) { m, key := aMember(t) now := time.Date(2026, 10, 12, 14, 0, 0, 0, time.UTC) var asked []string handle := func(by string) (string, error) { asked = append(asked, by); return "3 directories declared", nil } check := HandOverCheck{Signer: m.Signer, Node: "n1", Now: func() time.Time { return now }, Nonces: &Nonces{}} good := HandOverAsk{Node: "n1", By: "jo", Expires: now.Add(HandOverGood), Nonce: aNonce} for name, body := range map[string][]byte{ "a setuid search's signature": signedSearch(t, key, SetuidSearchContext, good), "another node": signedSearch(t, key, JudgeDirectoriesContext, HandOverAsk{Node: "n2", By: "jo", Expires: good.Expires, Nonce: aNonce}), "a path": signedSearch(t, key, JudgeDirectoriesContext, HandOverAsk{Node: "n1", Path: "/x", By: "jo", Expires: good.Expires, Nonce: aNonce}), "expired": signedSearch(t, key, JudgeDirectoriesContext, HandOverAsk{Node: "n1", By: "jo", Expires: now, Nonce: aNonce}), } { if a := AnswerJudgeDirectories(check, handle, body); !strings.HasSuffix(a.Refused, "nothing was judged") || a.Said != "" { t.Errorf("%s: %+v", name, a) } } if len(asked) != 0 { t.Fatalf("a refused ask reached the handler: %v", asked) } body := signedSearch(t, key, JudgeDirectoriesContext, good) if a := AnswerJudgeDirectories(check, handle, body); a.Said != "3 directories declared" || len(asked) != 1 { t.Fatalf("the good ask: %+v, %v", a, asked) } if a := AnswerJudgeDirectories(check, handle, body); !strings.Contains(a.Refused, "taken already") { t.Fatalf("the same ask again: %+v", a) } if _, answer := JudgeDirectoriesReply(check, handle, "", body); answer { t.Fatal("a request with no reply subject was answered") } }