mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-08-10 17:18:49 +09:00
5c5c82b27a
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.
64 lines
1.6 KiB
Ruby
64 lines
1.6 KiB
Ruby
class RoomsController < ApplicationController
|
|
before_action :set_room, only: %i[ show destroy ]
|
|
before_action :ensure_can_administer, only: %i[ destroy ]
|
|
before_action :remember_last_room_visited, only: :show
|
|
|
|
def index
|
|
redirect_to room_url(Current.user.rooms.last)
|
|
end
|
|
|
|
def show
|
|
@messages = find_messages
|
|
end
|
|
|
|
def destroy
|
|
@room.destroy
|
|
|
|
broadcast_remove_room
|
|
redirect_to root_url
|
|
end
|
|
|
|
private
|
|
def set_room
|
|
if room = room_scope.find_by(id: params[:room_id] || params[:id])
|
|
@room = room
|
|
else
|
|
redirect_to root_url, alert: "Room not found or inaccessible"
|
|
end
|
|
end
|
|
|
|
# Subclasses narrow this to the room types they're allowed to act on, so that one
|
|
# room namespace can't be used to reach another's rooms.
|
|
def room_scope
|
|
Current.user.rooms
|
|
end
|
|
|
|
def ensure_can_administer
|
|
head :forbidden unless Current.user.can_administer?(@room)
|
|
end
|
|
|
|
def ensure_permission_to_create_rooms
|
|
if Current.account.settings.restrict_room_creation_to_administrators? && !Current.user.administrator?
|
|
head :forbidden
|
|
end
|
|
end
|
|
|
|
def find_messages
|
|
messages = @room.messages.with_creator.with_attachment_details.with_boosts
|
|
|
|
if show_first_message = messages.find_by(id: params[:message_id])
|
|
@messages = messages.page_around(show_first_message)
|
|
else
|
|
@messages = messages.last_page
|
|
end
|
|
end
|
|
|
|
def room_params
|
|
params.require(:room).permit(:name)
|
|
end
|
|
|
|
def broadcast_remove_room
|
|
broadcast_remove_to :rooms, target: [ @room, :list ]
|
|
end
|
|
end
|