From 7cffbc8ba8f72161aed46ef7822baedb86243dde Mon Sep 17 00:00:00 2001 From: Arpit Jalan Date: Wed, 5 Jul 2017 22:39:45 +0530 Subject: [PATCH] FEATURE: new site setting to limit message recipients New site setting `max_allowed_message_recipients` to limit message recipients https://meta.discourse.org/t/one-of-my-users-just-group-messaged-100-other-user-with-a-spam-offer/65612/7?u=techapj --- config/locales/server.en.yml | 3 ++ config/site_settings.yml | 3 ++ lib/post_creator.rb | 6 ++++ spec/components/post_creator_spec.rb | 53 ++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+) diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 395f78bbdf3..a3a2563be4d 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -213,6 +213,7 @@ en: user_is_suspended: "Suspended users are not allowed to post." topic_not_found: "Something has gone wrong. Perhaps this topic was closed or deleted while you were looking at it?" not_accepting_pms: "Sorry, %{username} is not accepting messages at the moment." + max_pm_recepients: "Sorry, you can send a message to maximum %{recipients_limit} recipients." just_posted_that: "is too similar to what you recently posted" invalid_characters: "contains invalid characters" @@ -1498,6 +1499,8 @@ en: code_formatting_style: "Code button in composer will default to this code formatting style" + max_allowed_message_recipients: "Maximum recipients allowed in a message." + default_email_digest_frequency: "How often users receive summary emails by default." default_include_tl0_in_digests: "Include posts from new users in summary emails by default. Users can change this in their preferences." default_email_private_messages: "Send an email when someone messages the user by default." diff --git a/config/site_settings.yml b/config/site_settings.yml index 06100c657a0..ab2db791ae9 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -600,6 +600,9 @@ posting: client: true default: '' type: list + max_allowed_message_recipients: + default: 30 + min: 1 email: email_time_window_mins: diff --git a/lib/post_creator.rb b/lib/post_creator.rb index 7f515a7ee45..405a7e0537a 100644 --- a/lib/post_creator.rb +++ b/lib/post_creator.rb @@ -92,6 +92,12 @@ class PostCreator return false end + # Make sure max_allowed_message_recipients setting is respected + if @opts[:target_usernames].present? && !skip_validations? && !@user.staff? + errors[:base] << I18n.t(:max_pm_recepients, recipients_limit: SiteSetting.max_allowed_message_recipients) if @opts[:target_usernames].split(',').length > SiteSetting.max_allowed_message_recipients + return false if errors[:base].present? + end + # Make sure none of the users have muted the creator names = @opts[:target_usernames] if names.present? && !skip_validations? && !@user.staff? diff --git a/spec/components/post_creator_spec.rb b/spec/components/post_creator_spec.rb index 6ea5228e5f4..5e3441784f5 100644 --- a/spec/components/post_creator_spec.rb +++ b/spec/components/post_creator_spec.rb @@ -997,4 +997,57 @@ describe PostCreator do expect(pc.errors).to be_blank end end + + context "private message recipients limit (max_allowed_message_recipients) reached" do + let(:target_user1) { Fabricate(:coding_horror) } + let(:target_user2) { Fabricate(:evil_trout) } + let(:target_user3) { Fabricate(:walter_white) } + + before do + SiteSetting.max_allowed_message_recipients = 2 + end + + context "for normal user" do + it 'fails when sending message to multiple recipients' do + pc = PostCreator.new( + user, + title: 'this message is for multiple recipients!', + raw: "Lorem ipsum dolor sit amet, id elitr praesent mea, ut ius facilis fierent.", + archetype: Archetype.private_message, + target_usernames: [target_user1.username, target_user2.username, target_user3.username].join(',') + ) + expect(pc).not_to be_valid + expect(pc.errors).to be_present + end + + it 'succeeds when sending message to multiple recipients if skip_validations is true' do + pc = PostCreator.new( + user, + title: 'this message is for multiple recipients!', + raw: "Lorem ipsum dolor sit amet, id elitr praesent mea, ut ius facilis fierent.", + archetype: Archetype.private_message, + target_usernames: [target_user1.username, target_user2.username, target_user3.username].join(','), + skip_validations: true + ) + expect(pc).to be_valid + expect(pc.errors).to be_blank + end + end + + context "always succeeds if the user is staff" do + let(:staff_user) { Fabricate(:admin) } + + it 'when sending message to multiple recipients' do + pc = PostCreator.new( + staff_user, + title: 'this message is for multiple recipients!', + raw: "Lorem ipsum dolor sit amet, id elitr praesent mea, ut ius facilis fierent.", + archetype: Archetype.private_message, + target_usernames: [target_user1.username, target_user2.username, target_user3.username].join(',') + ) + expect(pc).to be_valid + expect(pc.errors).to be_blank + end + end + end end