mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
There are many situations that may cause users to lose permission to send messages in a chat channel. Until now we have relied on security checks in `Chat::ChatChannelFetcher` to remove channels which the user may have a `UserChatChannelMembership` record for but which they do not have access to. This commit takes a more proactive approach. Now any of these following `DiscourseEvent` triggers may cause `UserChatChannelMembership` records to be deleted: * `category_updated` - Permissions of the category changed (i.e. CategoryGroup records changed) * `user_removed_from_group` - Means the user may not be able to access the channel based on `GroupUser` or also `chat_allowed_groups` * `site_setting_changed` - The `chat_allowed_groups` was updated, some users may no longer be in groups that can access chat. * `group_destroyed` - Means the user may not be able to access the channel based on `GroupUser` or also `chat_allowed_groups` All of these are handled in a distinct service run in a background job. Users removed are logged via `StaffActionLog` and then we publish messages on a per-channel basis to users who had their memberships deleted. When the user has a channel they are kicked from open, we show a dialog saying "You no longer have access to this channel". When they click OK we redirect them either: * To their first other public channel, if they have any followed * The chat browse page if they don't This is to save on tons of requests from kicked out users getting messages from other channels. When the user does not have the kicked channel open, we can just silently yoink it out of their sidebar and turn off subscriptions.
144 lines
3.3 KiB
Ruby
144 lines
3.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class ChatChannelSerializer < ApplicationSerializer
|
|
attributes :id,
|
|
:auto_join_users,
|
|
:allow_channel_wide_mentions,
|
|
:chatable,
|
|
:chatable_id,
|
|
:chatable_type,
|
|
:chatable_url,
|
|
:description,
|
|
:title,
|
|
:slug,
|
|
:last_message_sent_at,
|
|
:status,
|
|
:archive_failed,
|
|
:archive_completed,
|
|
:archived_messages,
|
|
:total_messages,
|
|
:archive_topic_id,
|
|
:memberships_count,
|
|
:current_user_membership,
|
|
:meta,
|
|
:threading_enabled
|
|
|
|
def threading_enabled
|
|
SiteSetting.enable_experimental_chat_threaded_discussions && object.threading_enabled
|
|
end
|
|
|
|
def initialize(object, opts)
|
|
super(object, opts)
|
|
|
|
@opts = opts
|
|
@current_user_membership = opts[:membership]
|
|
end
|
|
|
|
def include_description?
|
|
object.description.present?
|
|
end
|
|
|
|
def memberships_count
|
|
object.user_count
|
|
end
|
|
|
|
def chatable_url
|
|
object.chatable_url
|
|
end
|
|
|
|
def title
|
|
object.name || object.title(scope.user)
|
|
end
|
|
|
|
def chatable
|
|
case object.chatable_type
|
|
when "Category"
|
|
BasicCategorySerializer.new(object.chatable, root: false).as_json
|
|
when "DirectMessage"
|
|
DirectMessageSerializer.new(object.chatable, scope: scope, root: false).as_json
|
|
when "Site"
|
|
nil
|
|
end
|
|
end
|
|
|
|
def archive
|
|
object.chat_channel_archive
|
|
end
|
|
|
|
def include_archive_status?
|
|
!object.direct_message_channel? && scope.is_staff? && archive.present?
|
|
end
|
|
|
|
def archive_completed
|
|
archive.complete?
|
|
end
|
|
|
|
def archive_failed
|
|
archive.failed?
|
|
end
|
|
|
|
def archived_messages
|
|
archive.archived_messages
|
|
end
|
|
|
|
def total_messages
|
|
archive.total_messages
|
|
end
|
|
|
|
def archive_topic_id
|
|
archive.destination_topic_id
|
|
end
|
|
|
|
def include_auto_join_users?
|
|
scope.can_edit_chat_channel?
|
|
end
|
|
|
|
def include_current_user_membership?
|
|
@current_user_membership.present?
|
|
end
|
|
|
|
def current_user_membership
|
|
@current_user_membership.chat_channel = object
|
|
|
|
BaseChatChannelMembershipSerializer.new(
|
|
@current_user_membership,
|
|
scope: scope,
|
|
root: false,
|
|
).as_json
|
|
end
|
|
|
|
def meta
|
|
{
|
|
message_bus_last_ids: {
|
|
new_messages: new_messages_message_bus_id,
|
|
new_mentions: new_mentions_message_bus_id,
|
|
kick: kick_message_bus_id,
|
|
channel_message_bus_last_id: MessageBus.last_id("/chat/#{object.id}"),
|
|
},
|
|
}
|
|
end
|
|
|
|
alias_method :include_archive_topic_id?, :include_archive_status?
|
|
alias_method :include_total_messages?, :include_archive_status?
|
|
alias_method :include_archived_messages?, :include_archive_status?
|
|
alias_method :include_archive_failed?, :include_archive_status?
|
|
alias_method :include_archive_completed?, :include_archive_status?
|
|
|
|
private
|
|
|
|
def new_messages_message_bus_id
|
|
@opts[:new_messages_message_bus_last_id] ||
|
|
MessageBus.last_id(Chat::Publisher.new_messages_message_bus_channel(object.id))
|
|
end
|
|
|
|
def new_mentions_message_bus_id
|
|
@opts[:new_mentions_message_bus_last_id] ||
|
|
MessageBus.last_id(Chat::Publisher.new_mentions_message_bus_channel(object.id))
|
|
end
|
|
|
|
def kick_message_bus_id
|
|
@opts[:kick_message_bus_last_id] ||
|
|
MessageBus.last_id(Chat::Publisher.kick_users_message_bus_channel(object.id))
|
|
end
|
|
end
|