Files
once-campfire/app/controllers/rooms/directs_controller.rb
T
Jeremy Daer 5c5c82b27a Scope room lookup to the type each controller administers
Rooms::DirectsController relaxes ensure_can_administer to true, because every
participant in a direct room may administer it. set_room was inherited unscoped,
though, so that relaxation applied to any room the caller was merely a member of:
DELETE /rooms/directs/<id> destroyed open and closed rooms and all their messages.

The same unscoped lookup let a direct room be loaded by the opens and closeds
controllers, where force_room_type promoted it. Promoting a DM to open grants every
user on the account membership and republishes the whole conversation, including the
other participant's messages; converting it to closed lets the initiator revise who
is in it and lock the other participant out.

Each controller now narrows room_scope to the types it may act on. Opens and closeds
keep reach into each other, since converting between them is a feature. Neither can
reach a direct room, and directs can only reach directs.

Room also refuses to change type away from Rooms::Direct, so the invariant holds for
any future caller of becomes! rather than only these two controllers.
2026-08-03 14:55:04 -07:00

42 lines
998 B
Ruby

class Rooms::DirectsController < RoomsController
before_action :set_room, only: %i[ edit destroy ]
def new
@room = Rooms::Direct.new
end
def create
room = Rooms::Direct.find_or_create_for(selected_users)
broadcast_create_room(room)
redirect_to room_url(room)
end
def edit
end
private
def selected_users
User.where(id: selected_users_ids.including(Current.user.id))
end
def selected_users_ids
params.fetch(:user_ids, [])
end
def broadcast_create_room(room)
room.memberships.each do |membership|
membership.broadcast_prepend_to membership.user, :rooms, target: :direct_rooms, partial: "users/sidebars/rooms/direct"
end
end
# All users in a direct room can administer it. Only direct rooms, though: this
# relaxation is why room_scope below has to keep every other type out of reach.
def ensure_can_administer
true
end
def room_scope
Current.user.rooms.directs
end
end