From f660b23a8ff43270e8c91b1719bc92d5454827f8 Mon Sep 17 00:00:00 2001 From: Joffrey JAFFEUX Date: Sun, 13 Nov 2022 00:52:41 +0100 Subject: [PATCH 1/3] FEATURE: introduces `chat_max_direct_message_users` setting This setting limits the number of users in a direct message. 0 means you can only create a direct message with yourself. --- plugins/chat/config/locales/server.en.yml | 4 ++ plugins/chat/config/settings.yml | 5 ++ .../lib/direct_message_channel_creator.rb | 15 +++++ .../direct_message_channel_creator_spec.rb | 56 +++++++++++++++++++ 4 files changed, 80 insertions(+) diff --git a/plugins/chat/config/locales/server.en.yml b/plugins/chat/config/locales/server.en.yml index ea2349f2b7fd..fb741d9cc973 100644 --- a/plugins/chat/config/locales/server.en.yml +++ b/plugins/chat/config/locales/server.en.yml @@ -17,6 +17,7 @@ en: default_emoji_reactions: "Default emoji reactions for chat messages. Add up to 5 emojis for quick reaction." direct_message_enabled_groups: "Allow users within these groups to create user-to-user Personal Chats. Note: staff can always create Personal Chats, and users will be able to reply to Personal Chats initiated by users who have permission to create them." chat_message_flag_allowed_groups: "Users in these groups are allowed to flag chat messages." + chat_max_direct_message_users: "Users cannot add more than this number of other users when creating a new direct message. Set to 0 to only allow self messaging. Staff are exempt from this setting." errors: chat_default_channel: "The default chat channel must be a public channel." direct_message_enabled_groups_invalid: "You must specify at least one group for this setting. If you do not want anyone except staff to send direct messages, choose the staff group." @@ -56,6 +57,9 @@ en: actor_disallowed_dms: "You have chosen to prevent users from sending you private and direct messages, so you cannot create new direct messages." actor_preventing_target_user_from_dm: "You have chosen to prevent %{username} from sending you private and direct messages, so you cannot create new direct messages to them." user_cannot_send_direct_messages: "Sorry, you cannot send direct messages." + over_chat_max_direct_message_users: + one: "You can only create a direct message with yourself." + other: "You can't create a direct message with more than %{count} users." reviewables: message_already_handled: "Thanks, but we've already reviewed this message and determined it does not need to be flagged again." actions: diff --git a/plugins/chat/config/settings.yml b/plugins/chat/config/settings.yml index 0ded290e0e38..feeb0f34421a 100644 --- a/plugins/chat/config/settings.yml +++ b/plugins/chat/config/settings.yml @@ -20,6 +20,11 @@ chat: client: true max: 3652 # 10 years min: 0 + chat_max_direct_message_users: + default: 20 + min: 0 + max: 100 + client: true chat_dm_retention_days: default: 0 client: true diff --git a/plugins/chat/lib/direct_message_channel_creator.rb b/plugins/chat/lib/direct_message_channel_creator.rb index 06315b8a476d..63342e3cfb70 100644 --- a/plugins/chat/lib/direct_message_channel_creator.rb +++ b/plugins/chat/lib/direct_message_channel_creator.rb @@ -11,6 +11,7 @@ def self.create!(acting_user:, target_users:) if direct_message chat_channel = ChatChannel.find_by!(chatable: direct_message) else + enforce_max_direct_message_users!(acting_user, target_users) ensure_actor_can_communicate!(acting_user, target_users) direct_message = DirectMessage.create!(user_ids: target_users.map(&:id)) chat_channel = direct_message.create_chat_channel! @@ -24,6 +25,20 @@ def self.create!(acting_user:, target_users:) private + def self.enforce_max_direct_message_users!(acting_user, target_users) + # We never want to prevent the actor from communicating with themself. + target_users = target_users.reject { |user| user.id == acting_user.id } + + if !acting_user.staff? && target_users.size > SiteSetting.chat_max_direct_message_users + raise NotAllowed.new( + I18n.t( + "chat.errors.over_chat_max_direct_message_users", + count: SiteSetting.chat_max_direct_message_users + 1, # +1 for the acting_user + ), + ) + end + end + def self.update_memberships(acting_user, target_users, chat_channel_id) sql_params = { acting_user_id: acting_user.id, diff --git a/plugins/chat/spec/lib/direct_message_channel_creator_spec.rb b/plugins/chat/spec/lib/direct_message_channel_creator_spec.rb index efdb0310a63d..1b88cce79838 100644 --- a/plugins/chat/spec/lib/direct_message_channel_creator_spec.rb +++ b/plugins/chat/spec/lib/direct_message_channel_creator_spec.rb @@ -178,6 +178,62 @@ }.by(1).and change { UserChatChannelMembership.count }.by(1) end + context "when number of users is over the limit" do + before { SiteSetting.chat_max_direct_message_users = 1 } + + it "raises an error" do + expect { + subject.create!(acting_user: user_1, target_users: [user_1, user_2, user_3]) + }.to raise_error( + Chat::DirectMessageChannelCreator::NotAllowed, + I18n.t("chat.errors.over_chat_max_direct_message_users", count: 2), + ) + end + + context "when acting user is staff" do + fab!(:admin) { Fabricate(:admin) } + + it "creates a new chat channel" do + expect { + subject.create!(acting_user: admin, target_users: [admin, user_1, user_2]) + }.to change { ChatChannel.count }.by(1) + end + end + + context "when limit is zero" do + before { SiteSetting.chat_max_direct_message_users = 0 } + + it "raises an error" do + expect { + subject.create!(acting_user: user_1, target_users: [user_1, user_2]) + }.to raise_error( + Chat::DirectMessageChannelCreator::NotAllowed, + I18n.t("chat.errors.over_chat_max_direct_message_users", count: 1), + ) + end + end + end + + context "when number of users is at the limit" do + before { SiteSetting.chat_max_direct_message_users = 0 } + + it "creates a new chat channel" do + expect { subject.create!(acting_user: user_1, target_users: [user_1]) }.to change { + ChatChannel.count + }.by(1) + end + end + + context "when number of users is under the limit" do + before { SiteSetting.chat_max_direct_message_users = 1 } + + it "creates a new chat channel" do + expect { subject.create!(acting_user: user_1, target_users: [user_1]) }.to change { + ChatChannel.count + }.by(1) + end + end + context "when the user is not a member of direct_message_enabled_groups" do before { SiteSetting.direct_message_enabled_groups = Group::AUTO_GROUPS[:trust_level_4] } From 49bba72125a6ab704021c000f090a8be482eec67 Mon Sep 17 00:00:00 2001 From: Joffrey JAFFEUX Date: Sun, 13 Nov 2022 19:54:34 +0100 Subject: [PATCH 2/3] Update plugins/chat/config/locales/server.en.yml Co-authored-by: David McClure --- plugins/chat/config/locales/server.en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/chat/config/locales/server.en.yml b/plugins/chat/config/locales/server.en.yml index fb741d9cc973..e7b670d2b13e 100644 --- a/plugins/chat/config/locales/server.en.yml +++ b/plugins/chat/config/locales/server.en.yml @@ -17,7 +17,7 @@ en: default_emoji_reactions: "Default emoji reactions for chat messages. Add up to 5 emojis for quick reaction." direct_message_enabled_groups: "Allow users within these groups to create user-to-user Personal Chats. Note: staff can always create Personal Chats, and users will be able to reply to Personal Chats initiated by users who have permission to create them." chat_message_flag_allowed_groups: "Users in these groups are allowed to flag chat messages." - chat_max_direct_message_users: "Users cannot add more than this number of other users when creating a new direct message. Set to 0 to only allow self messaging. Staff are exempt from this setting." + chat_max_direct_message_users: "Users cannot add more than this number of other users when creating a new direct message. Set to 0 to only allow messages to oneself. Staff are exempt from this setting." errors: chat_default_channel: "The default chat channel must be a public channel." direct_message_enabled_groups_invalid: "You must specify at least one group for this setting. If you do not want anyone except staff to send direct messages, choose the staff group." From 4c7c7813336c7b1e62ddf2017367cb9a3b4c464e Mon Sep 17 00:00:00 2001 From: Joffrey JAFFEUX Date: Sun, 13 Nov 2022 19:54:46 +0100 Subject: [PATCH 3/3] Update plugins/chat/config/locales/server.en.yml Co-authored-by: David McClure --- plugins/chat/config/locales/server.en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/chat/config/locales/server.en.yml b/plugins/chat/config/locales/server.en.yml index e7b670d2b13e..ce78276f8656 100644 --- a/plugins/chat/config/locales/server.en.yml +++ b/plugins/chat/config/locales/server.en.yml @@ -59,7 +59,7 @@ en: user_cannot_send_direct_messages: "Sorry, you cannot send direct messages." over_chat_max_direct_message_users: one: "You can only create a direct message with yourself." - other: "You can't create a direct message with more than %{count} users." + other: "You can't create a direct message with more than %{count} other users." reviewables: message_already_handled: "Thanks, but we've already reviewed this message and determined it does not need to be flagged again." actions: