Let a module declare a stream of its own and restrict who hears it by a trusted config value (hq issue 718, ADR 0363)
mesh-mail's events must live on a stream of their own and reach only the modules the operator granted an account (ADR 0359 §2, §4). The controller now creates a module's declared stream, publishes its events on mesh.stream.<module>.event.<event>, and composes a consumer's durable consumer, filters and bus grants on a restricted stream only where its consumes asks and the provider's trusted value names it; a consumer that loses its grant has its consumer removed on the next assertion. Nothing changes while no manifest declares a stream.
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
package inventory
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"slices"
|
||||
"testing"
|
||||
|
||||
"github.com/novox/mesh-controller/internal/catalogue"
|
||||
)
|
||||
|
||||
// A machine's layer wins over the mesh's for the setting that restricts a stream (novox/hq ADR 0363 §5).
|
||||
func TestARestrictingSettingIsReadMachineOverMesh(t *testing.T) {
|
||||
layers := []catalogue.Layer{
|
||||
{From: catalogue.MeshWideLayer, Values: map[string]any{"grants": "mesh", "other": 1}},
|
||||
{From: "novox", Values: map[string]any{"grants": "novox"}},
|
||||
}
|
||||
if v, set := settingValue(layers, "grants"); !set || v != "novox" {
|
||||
t.Fatalf("read %v, %v", v, set)
|
||||
}
|
||||
if _, set := settingValue(layers[:1], "absent"); set {
|
||||
t.Fatal("a key no layer sets read as set")
|
||||
}
|
||||
}
|
||||
|
||||
// What a consumer hears is composed into the bus's subjects, and what a stream carries leaves EVENTS.
|
||||
func TestWhatAModuleHearsIsComposedOntoTheStreamsSubjects(t *testing.T) {
|
||||
provider := catalogue.Manifest{Module: "mesh-mail", Streams: []catalogue.StreamDeclaration{{Name: "mail",
|
||||
Events: []string{"mail.*.message.added"}, Grant: &catalogue.StreamGrant{Config: "grants", Events: "mail.{key}.**"}}}}
|
||||
var value any
|
||||
_ = json.Unmarshal([]byte(`{"mesh":["reader"]}`), &value)
|
||||
grants := grantValues{"mesh-mail/grants": {value}}
|
||||
reader := catalogue.Manifest{Module: "reader"}
|
||||
hears, touches, onEvents := hearsOf(reader, map[string]catalogue.Manifest{"mesh-mail": provider}, "ace", grants,
|
||||
[]string{"mesh-mail.mail.**", "billing.paid"})
|
||||
if !touches || len(hears) != 1 || hears[0].Stream != "MAIL" ||
|
||||
!slices.Equal(hears[0].Filters, []string{"mesh.stream.mesh-mail.event.mail.mesh.message.added"}) {
|
||||
t.Fatalf("heard %+v", hears)
|
||||
}
|
||||
if !slices.Equal(onEvents, []string{"billing.paid"}) {
|
||||
t.Fatalf("left on EVENTS: %v", onEvents)
|
||||
}
|
||||
if got := streamsOf(provider); len(got) != 1 || got[0].Name != "MAIL" || got[0].MaxAgeDays != 7 || !got[0].Restricted {
|
||||
t.Fatalf("the provider's stream: %+v", got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user