Enforce rate limit for API calls which make changes

This commit is contained in:
Tom Hughes 2023-10-29 16:11:23 +00:00
parent 2f11b77309
commit ba503e02d2
6 changed files with 22 additions and 1 deletions

View file

@ -92,6 +92,10 @@ module Api
diff_reader = DiffReader.new(request.raw_post, changeset)
Changeset.transaction do
result = diff_reader.commit
# the number of changes in this changeset has already been
# updated and is visible in this transaction so we don't need
# to allow for any more when checking the limit
check_rate_limit(0)
render :xml => result.to_s
end
end

View file

@ -14,6 +14,7 @@ module Api
around_action :api_call_handle_error, :api_call_timeout
before_action :set_request_formats, :except => [:create, :update, :delete]
before_action :check_rate_limit, :only => [:create, :update, :delete]
# Dump the details on many nodes whose ids are given in the "nodes" parameter.
def index

View file

@ -12,6 +12,7 @@ module Api
around_action :api_call_handle_error, :api_call_timeout
before_action :set_request_formats, :except => [:create, :update, :delete]
before_action :check_rate_limit, :only => [:create, :update, :delete]
def index
raise OSM::APIBadUserInput, "The parameter relations is required, and must be of the form relations=id[,id[,id...]]" unless params["relations"]

View file

@ -12,6 +12,7 @@ module Api
around_action :api_call_handle_error, :api_call_timeout
before_action :set_request_formats, :except => [:create, :update, :delete]
before_action :check_rate_limit, :only => [:create, :update, :delete]
def index
raise OSM::APIBadUserInput, "The parameter ways is required, and must be of the form ways=id[,id[,id...]]" unless params["ways"]

View file

@ -192,4 +192,14 @@ class ApiController < ApplicationController
ActiveRecord::Base.connection.raw_connection.cancel
raise OSM::APITimeoutError
end
##
# check the api change rate limit
def check_rate_limit(new_changes = 1)
max_changes = ActiveRecord::Base.connection.select_value(
"SELECT api_rate_limit($1)", "api_rate_limit", [current_user.id]
)
raise OSM::APIRateLimitExceeded if new_changes > max_changes
end
end

View file

@ -2183,7 +2183,11 @@ module Api
# check that a changeset can contain a certain max number of changes.
## FIXME should be changed to an integration test due to the with_controller
def test_changeset_limits
auth_header = basic_authorization_header create(:user).email, "test"
user = create(:user)
auth_header = basic_authorization_header user.email, "test"
# create an old changeset to ensure we have the maximum rate limit
create(:changeset, :user => user, :created_at => Time.now.utc - 28.days)
# open a new changeset
xml = "<osm><changeset/></osm>"