Prove on a server under the composed grants that a module writes its bound bucket (issue 1966)
The integration case after created proved only that the binding is in the membership, never that the account can use it (design 25 § 12.7). Under the list the composer writes, the keeper creates mod-c_kept, mod-c's own account binds and writes it, and another module reads nothing of it. Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
@@ -16,6 +16,7 @@ import (
|
||||
|
||||
"git.novox.be/novox/mesh-delivery/modules/mesh-grants/grantsstate"
|
||||
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||
"git.novox.be/novox/mesh-sdk/go/membership"
|
||||
"git.novox.be/novox/mesh-sdk/go/process"
|
||||
"git.novox.be/novox/mesh-sdk/go/seal"
|
||||
"github.com/nats-io/nats-server/v2/server"
|
||||
@@ -37,7 +38,10 @@ func theBusNodeFollowsTheSealedListUnderTheComposedGrants(t *testing.T) {
|
||||
"novox": {{Module: buscompose.GrantsModule, State: []buscompose.Bucket{{Module: buscompose.GrantsModule, Name: "user-list"}}}},
|
||||
"ace": {{Module: "plex", Reads: []string{buscompose.ComposedRead}},
|
||||
{Module: "mesh-delivery-view", Reads: []string{buscompose.ComposedRead}, ReadsObjects: []string{"mesh-knowledge_sections"}},
|
||||
{Module: "mesh-knowledge", Objects: []buscompose.ObjectBucket{{Module: "mesh-knowledge", Name: "sections", MaxMiB: 1, Restricted: true}}}},
|
||||
{Module: "mesh-knowledge", Objects: []buscompose.ObjectBucket{{Module: "mesh-knowledge", Name: "sections", MaxMiB: 1, Restricted: true}}},
|
||||
// Issue 1966: a module whose state is asked in `requires`, bound as the bus module said it created it.
|
||||
{Module: "mod-c", Bindings: []membership.BusBinding{{Local: "kept", Storage: catalogue.StorageKeyValue,
|
||||
Template: catalogue.TemplateState, Bucket: "mod-c_kept"}}}},
|
||||
},
|
||||
}
|
||||
// The bus module and the router as the part composes them from their own manifests (testdata: the catalogue's
|
||||
@@ -50,6 +54,10 @@ func theBusNodeFollowsTheSealedListUnderTheComposedGrants(t *testing.T) {
|
||||
}
|
||||
records.Assigned["novox"] = append(records.Assigned["novox"], fromManifests.Assigned["novox"]...)
|
||||
records.BusState = fromManifests.BusState
|
||||
if records.BusState == nil {
|
||||
records.BusState = map[string][]catalogue.BusStateEntry{}
|
||||
}
|
||||
records.BusState["mod-c"] = []catalogue.BusStateEntry{{Name: "kept", Storage: catalogue.StorageKeyValue, Template: catalogue.TemplateState}}
|
||||
// The node-engine's state as the part's records carry it: every node's compositions (ADR 0593 §6).
|
||||
records.Engine = &buscompose.Declared{Module: buscompose.EngineModule, State: buscompose.EngineComposedBuckets(records.Nodes)}
|
||||
users, err := buscompose.Users(records)
|
||||
@@ -388,6 +396,34 @@ func theBusNodeFollowsTheSealedListUnderTheComposedGrants(t *testing.T) {
|
||||
if _, err := plex.GetLastMsg(sections.Stream(), "$O."+sections.Bucket()+".M.x", nats.DirectGet()); err == nil {
|
||||
t.Error("a module the grant does not name read the bucket")
|
||||
}
|
||||
// Issue 1966 (ADR 0595 §1, design 25 § 12.7, the binding's usable half): the bus module's keeper creates a key-value
|
||||
// entry asked in `requires` under its own account, and the module's own account, granted it from its binding, binds the
|
||||
// bucket by its bus name and writes and reads a key; another module reads nothing of it.
|
||||
keeperJS, err := jetstream.New(dial("novox.nats.keeper"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := keeperJS.CreateStream(ctx, jetstream.StreamConfig{Name: "KV_mod-c_kept", Subjects: []string{"$KV.mod-c_kept.>"},
|
||||
MaxMsgsPerSubject: 1, AllowDirect: true, AllowRollup: true, DenyDelete: true, Discard: jetstream.DiscardNew}); err != nil {
|
||||
t.Fatalf("the keeper creates mod-c's bound bucket: %v", err)
|
||||
}
|
||||
modC, err := jetstream.New(dial("ace.mod-c"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
bound, err := modC.KeyValue(ctx, "mod-c_kept")
|
||||
if err != nil {
|
||||
t.Fatalf("mod-c's own account binds its bound bucket: %v", err)
|
||||
}
|
||||
if _, err := bound.Put(ctx, "k", []byte("v")); err != nil {
|
||||
t.Fatalf("mod-c's own account writes its bound bucket: %v", err)
|
||||
}
|
||||
if e, err := bound.Get(ctx, "k"); err != nil || string(e.Value()) != "v" {
|
||||
t.Errorf("mod-c reads back %v, %v", e, err)
|
||||
}
|
||||
if _, err := plex.GetLastMsg("KV_mod-c_kept", "$KV.mod-c_kept.k", nats.DirectGet()); err == nil {
|
||||
t.Error("another module read mod-c's bound bucket")
|
||||
}
|
||||
}
|
||||
|
||||
// manifestIn is a module's manifest as testdata keeps it.
|
||||
|
||||
Reference in New Issue
Block a user