diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index feb1bc07557..57dffffcb1b 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -1582,6 +1582,10 @@ en: tl2_additional_likes_per_day_multiplier: "Increase limit of likes per day for tl2 (member) by multiplying with this number" tl3_additional_likes_per_day_multiplier: "Increase limit of likes per day for tl3 (regular) by multiplying with this number" tl4_additional_likes_per_day_multiplier: "Increase limit of likes per day for tl4 (leader) by multiplying with this number" + tl2_additional_edits_per_day_multiplier: "Increase limit of edits per day for tl2 (member) by multiplying with this number" + tl3_additional_edits_per_day_multiplier: "Increase limit of edits per day for tl3 (regular) by multiplying with this number" + tl4_additional_edits_per_day_multiplier: "Increase limit of edits per day for tl4 (leader) by multiplying with this number" + num_users_to_silence_new_user: "If a new user's posts get num_spam_flags_to_silence_new_user spam flags from this many different users, hide all their posts and prevent future posting. 0 to disable." num_tl3_flags_to_silence_new_user: "If a new user's posts get this many flags from num_tl3_users_to_silence_new_user different trust level 3 users, hide all their posts and prevent future posting. 0 to disable." num_tl3_users_to_silence_new_user: "If a new user's posts get num_tl3_flags_to_silence_new_user flags from this many different trust level 3 users, hide all their posts and prevent future posting. 0 to disable." diff --git a/config/site_settings.yml b/config/site_settings.yml index 3cc158a0e3e..a1538e50851 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -1746,6 +1746,9 @@ rate_limits: tl2_additional_likes_per_day_multiplier: 1.5 tl3_additional_likes_per_day_multiplier: 2 tl4_additional_likes_per_day_multiplier: 3 + tl2_additional_edits_per_day_multiplier: 1.5 + tl3_additional_edits_per_day_multiplier: 2 + tl4_additional_edits_per_day_multiplier: 3 alert_admins_if_errors_per_minute: client: true default: 0 diff --git a/lib/edit_rate_limiter.rb b/lib/edit_rate_limiter.rb index 04d095f66dc..d9769f52621 100644 --- a/lib/edit_rate_limiter.rb +++ b/lib/edit_rate_limiter.rb @@ -3,7 +3,15 @@ require 'rate_limiter' class EditRateLimiter < RateLimiter def initialize(user) - super(user, "edit-post", SiteSetting.max_edits_per_day, 1.day.to_i) + limit = SiteSetting.max_edits_per_day + + if user.trust_level >= 2 + multiplier = SiteSetting.get("tl#{user.trust_level}_additional_edits_per_day_multiplier").to_f + multiplier = 1.0 if multiplier < 1.0 + limit = (limit * multiplier).to_i + end + + super(user, "edit-post", limit, 1.day.to_i) end def build_key(type) diff --git a/spec/components/post_revisor_spec.rb b/spec/components/post_revisor_spec.rb index 5d1fe8bb4a4..551c2bc440a 100644 --- a/spec/components/post_revisor_spec.rb +++ b/spec/components/post_revisor_spec.rb @@ -485,10 +485,58 @@ describe PostRevisor do describe 'rate limiter' do fab!(:changed_by) { Fabricate(:coding_horror) } + before do + RateLimiter.enable + RateLimiter.clear_all! + SiteSetting.editing_grace_period = 0 + end + it "triggers a rate limiter" do EditRateLimiter.any_instance.expects(:performed!) subject.revise!(changed_by, raw: 'updated body') end + + it "raises error when a user gets rate limited" do + SiteSetting.max_edits_per_day = 1 + user = Fabricate(:user, trust_level: 1) + + subject.revise!(user, raw: 'body (edited)') + + expect do + subject.revise!(user, raw: 'body (edited twice) ') + end.to raise_error(RateLimiter::LimitExceeded) + end + + it "edit limits scale up depending on user's trust level" do + SiteSetting.max_edits_per_day = 1 + SiteSetting.tl2_additional_edits_per_day_multiplier = 2 + SiteSetting.tl3_additional_edits_per_day_multiplier = 3 + SiteSetting.tl4_additional_edits_per_day_multiplier = 4 + + user = Fabricate(:user, trust_level: 2) + expect { subject.revise!(user, raw: 'body (edited)') }.to_not raise_error + expect { subject.revise!(user, raw: 'body (edited twice)') }.to_not raise_error + expect do + subject.revise!(user, raw: 'body (edited three times) ') + end.to raise_error(RateLimiter::LimitExceeded) + + user = Fabricate(:user, trust_level: 3) + expect { subject.revise!(user, raw: 'body (edited)') }.to_not raise_error + expect { subject.revise!(user, raw: 'body (edited twice)') }.to_not raise_error + expect { subject.revise!(user, raw: 'body (edited three times)') }.to_not raise_error + expect do + subject.revise!(user, raw: 'body (edited four times) ') + end.to raise_error(RateLimiter::LimitExceeded) + + user = Fabricate(:user, trust_level: 4) + expect { subject.revise!(user, raw: 'body (edited)') }.to_not raise_error + expect { subject.revise!(user, raw: 'body (edited twice)') }.to_not raise_error + expect { subject.revise!(user, raw: 'body (edited three times)') }.to_not raise_error + expect { subject.revise!(user, raw: 'body (edited four times)') }.to_not raise_error + expect do + subject.revise!(user, raw: 'body (edited five times) ') + end.to raise_error(RateLimiter::LimitExceeded) + end end describe "admin editing a new user's post" do