mirror of
https://github.com/discourse/discourse.git
synced 2026-08-08 17:53:55 +08:00
Previously the rebake endpoint in Chat::ChatController used before_action callbacks to look up the message before checking channel access. This ordering allowed distinguishing whether a message existed in an inaccessible channel via differing HTTP status codes (403 vs 404). This commit extracts the rebake logic into a Chat::RebakeMessage service following the Service::Base pattern. The service checks channel access before message lookup, ensuring unauthorized users always receive 403 regardless of message existence. It also removes the now-unused find_chat_message and preloaded_chat_message_query private methods from the controller.
59 lines
1.4 KiB
Ruby
Vendored
59 lines
1.4 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
module Chat
|
|
# Service responsible for rebaking a chat message.
|
|
#
|
|
# @example
|
|
# Chat::RebakeMessage.call(params: { message_id: 2, chat_channel_id: 1 }, guardian: guardian)
|
|
#
|
|
class RebakeMessage
|
|
include Service::Base
|
|
|
|
# @!method self.call(guardian:, params:)
|
|
# @param [Guardian] guardian
|
|
# @param [Hash] params
|
|
# @option params [Integer] :message_id
|
|
# @option params [Integer] :chat_channel_id
|
|
# @return [Service::Base::Context]
|
|
|
|
params do
|
|
attribute :message_id, :integer
|
|
attribute :chat_channel_id, :integer
|
|
|
|
validates :message_id, presence: true
|
|
validates :chat_channel_id, presence: true
|
|
end
|
|
|
|
model :channel
|
|
policy :can_access_channel
|
|
model :message
|
|
policy :can_rebake
|
|
|
|
step :rebake_message
|
|
|
|
private
|
|
|
|
def fetch_channel(params:)
|
|
Chat::Channel.includes(:chatable).find_by(id: params.chat_channel_id)
|
|
end
|
|
|
|
def can_access_channel(guardian:, channel:)
|
|
guardian.can_join_chat_channel?(channel)
|
|
end
|
|
|
|
def fetch_message(params:, channel:)
|
|
Chat::Message
|
|
.includes(chat_channel: :chatable)
|
|
.with_deleted
|
|
.find_by(id: params.message_id, chat_channel_id: channel.id)
|
|
end
|
|
|
|
def can_rebake(guardian:, message:)
|
|
guardian.can_rebake_chat_message?(message)
|
|
end
|
|
|
|
def rebake_message(message:)
|
|
message.rebake!(invalidate_oneboxes: true)
|
|
end
|
|
end
|
|
end
|