[deploy] Rate Limit Classified Listing Creation (#7684)

This commit is contained in:
Molly Struve 2020-05-05 12:01:27 -05:00 committed by GitHub
parent a71d78df6e
commit caadf27288
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 34 additions and 2 deletions

View file

@ -1,5 +1,6 @@
class ClassifiedListingsController < ApplicationController
include ClassifiedListingsToolkit
before_action :check_limit, only: [:create]
JSON_OPTIONS = {
only: %i[
@ -118,4 +119,8 @@ class ClassifiedListingsController < ApplicationController
def process_after_unpublish
redirect_to "/listings/dashboard"
end
def check_limit
rate_limit!(:listing_creation)
end
end

View file

@ -113,6 +113,7 @@ module ClassifiedListingsToolkit
end
if successful_transaction
rate_limiter.track_limit_by_action(:listing_creation)
clear_listings_cache
process_successful_creation
else

View file

@ -74,6 +74,7 @@ class SiteConfig < RailsSettings::Base
# Rate Limits
field :rate_limit_follow_count_daily, type: :integer, default: 500
field :rate_limit_comment_creation, type: :integer, default: 9
field :rate_limit_listing_creation, type: :integer, default: 1
field :rate_limit_published_article_creation, type: :integer, default: 9
field :rate_limit_organization_creation, type: :integer, default: 1
field :rate_limit_image_upload, type: :integer, default: 9

View file

@ -5,6 +5,7 @@ class RateLimitChecker
ACTION_LIMITERS = {
article_update: { retry_after: 30 },
image_upload: { retry_after: 30 },
listing_creation: { retry_after: 60 },
published_article_creation: { retry_after: 30 },
organization_creation: { retry_after: 300 }
}.with_indifferent_access.freeze
@ -12,6 +13,7 @@ class RateLimitChecker
CONFIGURABLE_RATES = {
rate_limit_follow_count_daily: { min: 0, placeholder: 500, description: "The number of users a person can follow daily" },
rate_limit_comment_creation: { min: 0, placeholder: 9, description: "The number of comments a user can create within 30 seconds" },
rate_limit_listing_creation: { min: 1, placeholder: 1, description: "The number of listings a user can create in 1 minute" },
rate_limit_published_article_creation: { min: 0, placeholder: 9, description: "The number of articles a user can create within 30 seconds" },
rate_limit_image_upload: { min: 0, placeholder: 9, description: "The number of images a user can upload within 30 seconds" },
rate_limit_email_recipient: { min: 0, placeholder: 5, description: "The number of emails we send to a user within 2 minutes" },

View file

@ -5,7 +5,7 @@ RSpec.describe "/listings", type: :request do
let(:organization) { create(:organization) }
let(:cl_category) { create(:classified_listing_category, cost: 1) }
let(:params) do
let(:params) do
{
classified_listing: {
title: "Hey",
@ -14,7 +14,7 @@ RSpec.describe "/listings", type: :request do
tag_list: "ruby, rails, go"
}
}
end
end
describe "GET /listings" do
it "has page content" do
@ -84,6 +84,29 @@ RSpec.describe "/listings", type: :request do
post "/listings", params: params
end.to raise_error Pundit::NotAuthorizedError
end
context "when rate limiting" do
let(:rate_limiter) { RateLimitChecker.new(user) }
before do
allow(RateLimitChecker).to receive(:new).and_return(rate_limiter)
sign_in user
end
it "increments rate limit for listing_creation" do
allow(rate_limiter).to receive(:track_limit_by_action)
post "/listings", params: params
expect(rate_limiter).to have_received(:track_limit_by_action).with(:listing_creation)
end
it "returns a 429 status when rate limit is reached" do
allow(rate_limiter).to receive(:limit_by_action).and_return(true)
post "/listings", params: params
expect(response.status).to eq(429)
end
end
end
describe "GET /listings/edit" do