[deploy] Limit the User Updates (#7892)

This commit is contained in:
Molly Struve 2020-05-18 11:13:38 -05:00 committed by GitHub
parent dbb5c752ab
commit 548fd21768
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 5 deletions

View file

@ -2,9 +2,14 @@ module RateLimitCheckerHelper
CONFIGURABLE_RATES = {
rate_limit_article_update: {
min: 1,
placeholder: 150,
placeholder: 30,
description: "The number of article updates a user can make in 30 seconds"
},
rate_limit_user_update: {
min: 1,
placeholder: 5,
description: "The number of user updates a user can make in 30 seconds"
},
rate_limit_feedback_message_creation: {
min: 1,
placeholder: 5,

View file

@ -81,9 +81,10 @@ class SiteConfig < RailsSettings::Base
field :rate_limit_reaction_creation, type: :integer, default: 10
field :rate_limit_image_upload, type: :integer, default: 9
field :rate_limit_email_recipient, type: :integer, default: 5
field :rate_limit_article_update, type: :integer, default: 150
field :rate_limit_article_update, type: :integer, default: 30
field :rate_limit_send_email_confirmation, type: :integer, default: 2
field :rate_limit_feedback_message_creation, type: :integer, default: 5
field :rate_limit_user_update, type: :integer, default: 5
# Google Analytics Reporting API v4
# <https://developers.google.com/analytics/devguides/reporting/core/v4>

View file

@ -140,6 +140,7 @@ class User < ApplicationRecord
validate :validate_feed_url, if: :feed_url_changed?
validate :validate_mastodon_url
validate :can_send_confirmation_email
validate :update_rate_limit
alias_attribute :positive_reactions_count, :reactions_count
alias_attribute :subscribed_to_welcome_notifications?, :welcome_notifications
@ -624,4 +625,13 @@ class User < ApplicationRecord
rescue RateLimitChecker::LimitReached => e
errors.add(:email, "confirmation could not be sent. #{e.message}")
end
def update_rate_limit
return unless persisted?
rate_limiter.track_limit_by_action(:user_update)
rate_limiter.check_limit!(:user_update)
rescue RateLimitChecker::LimitReached => e
errors.add(:base, "User could not be saved. #{e.message}")
end
end

View file

@ -4,13 +4,14 @@ class RateLimitChecker
# retry_after values are the seconds until a user can retry an action
ACTION_LIMITERS = {
article_update: { retry_after: 30 },
send_email_confirmation: { retry_after: 120 },
feedback_message_creation: { retry_after: 300 },
image_upload: { retry_after: 30 },
listing_creation: { retry_after: 60 },
published_article_creation: { retry_after: 30 },
organization_creation: { retry_after: 300 },
reaction_creation: { retry_after: 30 }
published_article_creation: { retry_after: 30 },
reaction_creation: { retry_after: 30 },
send_email_confirmation: { retry_after: 120 },
user_update: { retry_after: 30 }
}.with_indifferent_access.freeze
def initialize(user = nil)

View file

@ -206,9 +206,25 @@ RSpec.describe User, type: :model do
limiter = RateLimitChecker.new(user)
allow(user).to receive(:rate_limiter).and_return(limiter)
allow(limiter).to receive(:limit_by_action).and_return(true)
allow(limiter).to receive(:track_limit_by_action)
user.update(email: "new_email@yo.com")
expect(user).not_to be_valid
expect(user.errors[:email].to_s).to include("confirmation could not be sent. Rate limit reached")
expect(limiter).to have_received(:track_limit_by_action).with(:send_email_confirmation).twice
end
it "validates update_rate_limit for existing user" do
user = create(:user)
limiter = RateLimitChecker.new(user)
allow(user).to receive(:rate_limiter).and_return(limiter)
allow(limiter).to receive(:limit_by_action).and_return(true)
allow(limiter).to receive(:track_limit_by_action)
user.update(articles_count: 5)
expect(user).not_to be_valid
expect(user.errors[:base].to_s).to include("could not be saved. Rate limit reached")
expect(limiter).to have_received(:track_limit_by_action).with(:user_update).twice
end
end