fix(0006e): call RefreshSession after membership changes in all clients (audit 0008 N4)
A secured bus freezes per-subject permissions at connect time, so a peer that creates or joins a room after connecting cannot pub/sub on it until it reconnects (RefreshSession). No client called it, so under enforce+ACL the demos failed closed — pushing the operator to disable the ACL (a security regression at the operator's discretion). Wire the membership-change contract into every client: - cmd/worker: RefreshSession after CreateRoom, before publishing. - cmd/chat (simple): RefreshSession after CreateRoom+Join, before Subscribe. - cmd/chat (encrypted demo): A refreshes after CreateRoom; B refreshes after the invite+join, both before pub/sub. - local_files/bridge (gateway): RefreshSession after CreateRoom+Join, before Subscribe. - mobile: new Session.RefreshSession wrapper + the contract documented for callers. Contract (documented on the wrappers): after ANY membership change, call RefreshSession BEFORE pub/sub on the new room (it drops active subs, so it must precede Subscribe). On an unsecured/dev bus it is a harmless reconnect. Test: - TestClientCreateRoomRefreshPublishFlow: end-to-end under enforce+ACL, a peer creates a room, refreshes, invites a second peer who joins+refreshes+subscribes, and the publish is received — no manual intervention, the ACL stays on. CGO_ENABLED=0 go build/vet/test green; govulncheck 0 reachable. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -85,6 +85,20 @@ func (s *Session) Join(roomID string) error {
|
||||
return s.c.Join(roomID)
|
||||
}
|
||||
|
||||
// RefreshSession reconnects the data plane so the bus re-derives this peer's
|
||||
// per-subject permissions from its current room membership.
|
||||
//
|
||||
// Membership-change contract (issue 0006e): a secured bus (--bus-auth enforce)
|
||||
// freezes a connection's permissions at connect time. After ANY membership change
|
||||
// — a room you just created, were invited to, or joined — call RefreshSession
|
||||
// BEFORE Publish/Subscribe on that room, or the bus denies the new room's subject.
|
||||
// It also drops active subscriptions, so re-Subscribe afterwards. On an unsecured
|
||||
// bus it is a harmless reconnect. A mobile/gateway caller wires this exactly like
|
||||
// cmd/chat and cmd/worker do: CreateRoom -> RefreshSession -> Subscribe/Publish.
|
||||
func (s *Session) RefreshSession() error {
|
||||
return s.c.RefreshSession()
|
||||
}
|
||||
|
||||
// Publish sends a UTF-8 text message to the room.
|
||||
func (s *Session) Publish(roomID, text string) error {
|
||||
return s.c.Publish(roomID, []byte(text))
|
||||
|
||||
Reference in New Issue
Block a user