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 ...@@ -483,11 +483,12 @@ class ProjectsController < Projects::ApplicationController
def export_rate_limit def export_rate_limit
prefixed_action = "project_#{params[:action]}".to_sym 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) 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.') render plain: _('This endpoint has been requested too many times. Try again later.'), status: :too_many_requests
redirect_to edit_project_path(@project)
end end
end end
......
---
title: Rate limit project export by user
merge_request: 31719
author:
type: changed
...@@ -45,7 +45,7 @@ module API ...@@ -45,7 +45,7 @@ module API
end end
end end
post ':id/export' do 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) project_export_params = declared_params(include_missing: false)
after_export_params = project_export_params.delete(:upload) || {} after_export_params = project_export_params.delete(:upload) || {}
......
...@@ -1159,17 +1159,18 @@ describe ProjectsController do ...@@ -1159,17 +1159,18 @@ describe ProjectsController do
end end
shared_examples 'rate limits project export endpoint' do 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 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) 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
end end
...@@ -1226,7 +1227,18 @@ describe ProjectsController do ...@@ -1226,7 +1227,18 @@ describe ProjectsController do
end end
context 'when the endpoint receives requests above the limit', :clean_gitlab_redis_cache do 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 end
end end
......
...@@ -44,19 +44,6 @@ describe API::ProjectExport, :clean_gitlab_redis_cache do ...@@ -44,19 +44,6 @@ describe API::ProjectExport, :clean_gitlab_redis_cache do
it_behaves_like '404 response' it_behaves_like '404 response'
end 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 describe 'GET /projects/:project_id/export' do
shared_examples_for 'get project export status not found' do shared_examples_for 'get project export status not found' do
it_behaves_like '404 response' do it_behaves_like '404 response' do
...@@ -247,7 +234,16 @@ describe API::ProjectExport, :clean_gitlab_redis_cache do ...@@ -247,7 +234,16 @@ describe API::ProjectExport, :clean_gitlab_redis_cache do
context 'when rate limit is exceeded' do context 'when rate limit is exceeded' do
let(:request) { get api(download_path, admin) } 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
end end
...@@ -360,10 +356,17 @@ describe API::ProjectExport, :clean_gitlab_redis_cache do ...@@ -360,10 +356,17 @@ describe API::ProjectExport, :clean_gitlab_redis_cache do
it_behaves_like 'post project export start' it_behaves_like 'post project export start'
context 'when rate limit is exceeded' do context 'when rate limit is exceeded across projects' do
let(:request) { post api(path, admin) } it 'prevents requesting project export' do
post api(path_none, admin)
include_examples 'when rate limit is exceeded' expect(response).not_to have_gitlab_http_status(:too_many_requests)
post api(path, admin)
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
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