Commit c12d38f4 authored by Mayra Cabrera's avatar Mayra Cabrera

Merge branch 'jh-rate_limit_project_export' into 'master'

Rate limit project export by user

See merge request gitlab-org/gitlab!31719
parents a89a85d2 2a240bbb
......@@ -483,11 +483,12 @@ class ProjectsController < Projects::ApplicationController
def export_rate_limit
prefixed_action = "project_#{params[:action]}".to_sym
if rate_limiter.throttled?(prefixed_action, scope: [current_user, prefixed_action, @project])
project_scope = params[:action] == :download_export ? @project : nil
if rate_limiter.throttled?(prefixed_action, scope: [current_user, prefixed_action, project_scope].compact)
rate_limiter.log_request(request, "#{prefixed_action}_request_limit".to_sym, current_user)
flash[:alert] = _('This endpoint has been requested too many times. Try again later.')
redirect_to edit_project_path(@project)
render plain: _('This endpoint has been requested too many times. Try again later.'), status: :too_many_requests
end
end
......
---
title: Rate limit project export by user
merge_request: 31719
author:
type: changed
......@@ -45,7 +45,7 @@ module API
end
end
post ':id/export' do
check_rate_limit! :project_export, [current_user, :project_export, user_project]
check_rate_limit! :project_export, [current_user, :project_export]
project_export_params = declared_params(include_missing: false)
after_export_params = project_export_params.delete(:upload) || {}
......
......@@ -1159,17 +1159,18 @@ describe ProjectsController do
end
shared_examples 'rate limits project export endpoint' do
before do
allow(::Gitlab::ApplicationRateLimiter)
.to receive(:throttled?)
.and_return(true)
end
it 'prevents requesting project export' do
post action, params: { namespace_id: project.namespace, id: project }
exportable_project = create(:project)
exportable_project.add_maintainer(user)
post action, params: { namespace_id: exportable_project.namespace, id: exportable_project }
expect(flash[:alert]).to eq('This endpoint has been requested too many times. Try again later.')
expect(response).to have_gitlab_http_status(:found)
post action, params: { namespace_id: project.namespace, id: project }
expect(response.body).to eq('This endpoint has been requested too many times. Try again later.')
expect(response).to have_gitlab_http_status(:too_many_requests)
end
end
......@@ -1226,7 +1227,18 @@ describe ProjectsController do
end
context 'when the endpoint receives requests above the limit', :clean_gitlab_redis_cache do
include_examples 'rate limits project export endpoint'
before do
allow(::Gitlab::ApplicationRateLimiter)
.to receive(:throttled?)
.and_return(true)
end
it 'prevents requesting project export' do
post action, params: { namespace_id: project.namespace, id: project }
expect(response.body).to eq('This endpoint has been requested too many times. Try again later.')
expect(response).to have_gitlab_http_status(:too_many_requests)
end
end
end
end
......
......@@ -44,19 +44,6 @@ describe API::ProjectExport, :clean_gitlab_redis_cache do
it_behaves_like '404 response'
end
shared_examples_for 'when rate limit is exceeded' do
before do
allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(true)
end
it 'prevents requesting project export' do
request
expect(response).to have_gitlab_http_status(:too_many_requests)
expect(json_response['message']['error']).to eq('This endpoint has been requested too many times. Try again later.')
end
end
describe 'GET /projects/:project_id/export' do
shared_examples_for 'get project export status not found' do
it_behaves_like '404 response' do
......@@ -247,7 +234,16 @@ describe API::ProjectExport, :clean_gitlab_redis_cache do
context 'when rate limit is exceeded' do
let(:request) { get api(download_path, admin) }
include_examples 'when rate limit is exceeded'
before do
allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(true)
end
it 'prevents requesting project export' do
request
expect(response).to have_gitlab_http_status(:too_many_requests)
expect(json_response['message']['error']).to eq('This endpoint has been requested too many times. Try again later.')
end
end
end
......@@ -360,10 +356,17 @@ describe API::ProjectExport, :clean_gitlab_redis_cache do
it_behaves_like 'post project export start'
context 'when rate limit is exceeded' do
let(:request) { post api(path, admin) }
context 'when rate limit is exceeded across projects' do
it 'prevents requesting project export' do
post api(path_none, admin)
expect(response).not_to have_gitlab_http_status(:too_many_requests)
post api(path, admin)
include_examples 'when rate limit is exceeded'
expect(response).to have_gitlab_http_status(:too_many_requests)
expect(json_response['message']['error']).to eq('This endpoint has been requested too many times. Try again later.')
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment