diff --git a/internal/broker/process_state_watch_test.go b/internal/broker/process_state_watch_test.go new file mode 100644 index 00000000..3f9b2081 --- /dev/null +++ b/internal/broker/process_state_watch_test.go @@ -0,0 +1,41 @@ +package broker + +import "testing" + +// 1840/AC9: a process account declaring the state `x` may watch and list the keys of its module's own bucket (a consumer +// created and deleted on KV__x), read and write it, and has no grant on another module's bucket or on a mirror of the +// controller's, whatever it is named after. +func TestAProcessMayWatchItsOwnStateAndNoOthers(t *testing.T) { + p := Principal{Kind: KindProcess, Node: "novox", Module: "mesh-mail", Process: "send", State: []string{"x"}} + got := perms(t, p) + for _, s := range []string{ + "$JS.API.CONSUMER.CREATE.KV_mesh-mail_x", + "$JS.API.CONSUMER.CREATE.KV_mesh-mail_x.watcher", + "$JS.API.CONSUMER.CREATE.KV_mesh-mail_x.watcher.$KV.mesh-mail_x.>", + "$JS.API.CONSUMER.DELETE.KV_mesh-mail_x.watcher", + "$JS.API.DIRECT.GET.KV_mesh-mail_x.$KV.mesh-mail_x.key", + "$JS.API.STREAM.INFO.KV_mesh-mail_x", + "$JS.FC.KV_mesh-mail_x.watcher", + "$KV.mesh-mail_x.key", + } { + if !allowed(got.Publish, s) { + t.Errorf("the process may not publish %s, so it cannot watch or list its own state", s) + } + } + for _, other := range []string{"mesh-other_x", "mesh-mail_y", DeclaredPackagesBucket, AssignmentsBucket} { + for _, s := range []string{ + "$JS.API.CONSUMER.CREATE.KV_" + other, + "$JS.API.CONSUMER.CREATE.KV_" + other + ".watcher", + "$JS.API.CONSUMER.CREATE.KV_" + other + ".watcher.$KV." + other + ".>", + "$JS.API.CONSUMER.DELETE.KV_" + other + ".watcher", + "$JS.API.DIRECT.GET.KV_" + other + ".$KV." + other + ".key", + "$JS.API.STREAM.INFO.KV_" + other, + "$JS.FC.KV_" + other + ".watcher", + "$KV." + other + ".key", + } { + if allowed(got.Publish, s) { + t.Errorf("the process may publish %s, on a bucket that is not its own state", s) + } + } + } +}