mirror of
https://github.com/discourse/discourse.git
synced 2025-03-02 01:09:26 +00:00
After this change, in order to join a chat channel, a user needs to be in a group with at least “Reply” permission for the category. If the user only has “See” permission, they are able to preview the channel, but not join it or send messages. The auto-join function also follows this new restriction. --------- Co-authored-by: Martin Brennan <martin@discourse.org>
80 lines
3.1 KiB
Ruby
80 lines
3.1 KiB
Ruby
# NOTE: When changing auto-join logic, make sure to update the `settings.auto_join_users_info` translation as well.
|
|
# frozen_string_literal: true
|
|
|
|
module Jobs
|
|
class AutoJoinChannelBatch < ::Jobs::Base
|
|
def execute(args)
|
|
return "starts_at or ends_at missing" if args[:starts_at].blank? || args[:ends_at].blank?
|
|
start_user_id = args[:starts_at].to_i
|
|
end_user_id = args[:ends_at].to_i
|
|
|
|
return "End is higher than start" if end_user_id < start_user_id
|
|
|
|
channel =
|
|
ChatChannel.find_by(
|
|
id: args[:chat_channel_id],
|
|
auto_join_users: true,
|
|
chatable_type: "Category",
|
|
)
|
|
|
|
return if !channel
|
|
|
|
category = channel.chatable
|
|
return if !category
|
|
|
|
query_args = {
|
|
chat_channel_id: channel.id,
|
|
start: start_user_id,
|
|
end: end_user_id,
|
|
suspended_until: Time.zone.now,
|
|
last_seen_at: 3.months.ago,
|
|
channel_category: channel.chatable_id,
|
|
permission_type: CategoryGroup.permission_types[:create_post],
|
|
everyone: Group::AUTO_GROUPS[:everyone],
|
|
mode: Chat::UserChatChannelMembership.join_modes[:automatic],
|
|
}
|
|
|
|
new_member_ids = DB.query_single(create_memberships_query(category), query_args)
|
|
# Only do this if we are running auto-join for a single user, if we
|
|
# are doing it for many then we should do it after all batches are
|
|
# complete for the channel in Jobs::AutoJoinChannelMemberships
|
|
if start_user_id == end_user_id
|
|
Chat::ChatChannelMembershipManager.new(channel).recalculate_user_count
|
|
end
|
|
|
|
Chat::Publisher.publish_new_channel(channel.reload, User.where(id: new_member_ids))
|
|
end
|
|
|
|
private
|
|
|
|
def create_memberships_query(category)
|
|
query = <<~SQL
|
|
INSERT INTO user_chat_channel_memberships (user_id, chat_channel_id, following, created_at, updated_at, join_mode)
|
|
SELECT DISTINCT(users.id), :chat_channel_id, TRUE, NOW(), NOW(), :mode
|
|
FROM users
|
|
INNER JOIN user_options uo ON uo.user_id = users.id
|
|
LEFT OUTER JOIN user_chat_channel_memberships uccm ON
|
|
uccm.chat_channel_id = :chat_channel_id AND uccm.user_id = users.id
|
|
|
|
LEFT OUTER JOIN group_users gu ON gu.user_id = users.id
|
|
LEFT OUTER JOIN category_groups cg ON cg.group_id = gu.group_id AND
|
|
cg.permission_type <= :permission_type
|
|
|
|
WHERE (users.id >= :start AND users.id <= :end) AND
|
|
users.staged IS FALSE AND
|
|
users.active AND
|
|
NOT EXISTS(SELECT 1 FROM anonymous_users a WHERE a.user_id = users.id) AND
|
|
(suspended_till IS NULL OR suspended_till <= :suspended_until) AND
|
|
(last_seen_at IS NULL OR last_seen_at > :last_seen_at) AND
|
|
uo.chat_enabled AND
|
|
uccm.id IS NULL AND
|
|
(NOT EXISTS(SELECT 1 FROM category_groups WHERE category_id = :channel_category)
|
|
OR EXISTS (SELECT 1 FROM category_groups WHERE category_id = :channel_category AND group_id = :everyone AND permission_type <= :permission_type)
|
|
OR cg.category_id = :channel_category)
|
|
|
|
RETURNING user_chat_channel_memberships.user_id
|
|
SQL
|
|
end
|
|
end
|
|
end
|