Skip to content
Snippets Groups Projects
Commit 111898b8 authored by Rodrigo Tomonari's avatar Rodrigo Tomonari :two:
Browse files

Change project export download rate limit

Previously, the export download rate limit was scoped to the project
namespace. Now it is scoped to individual projects

This change:
- Updates rate limit scope from namespace to project level
- Modifies rate limit checks in ProjectsController and API
- Updates related documentation and tests

Changelog: changed
parent 1fcfd23d
No related branches found
No related tags found
1 merge request!181822Change project export download rate limit
......@@ -599,9 +599,9 @@ def present_project
def check_export_rate_limit!
prefixed_action = "project_#{params[:action]}".to_sym
group_scope = params[:action] == 'download_export' ? @project.namespace : nil
project_scope = params[:action] == 'download_export' ? @project : nil
check_rate_limit!(prefixed_action, scope: [current_user, group_scope].compact)
check_rate_limit!(prefixed_action, scope: [current_user, project_scope].compact)
end
def render_edit
......
......@@ -320,7 +320,7 @@ To help avoid abuse, by default, users are rate limited to:
| Request type | Limit |
|:----------------|:--------------------------------|
| Export | 6 projects per minute |
| Download export | 1 download per group per minute |
| Download export | 1 download per project per minute |
| Import | 6 projects per minute |
## Migrate groups by uploading an export file (deprecated)
......
......@@ -44,7 +44,7 @@ class ProjectExport < ::API::Base
produces %w[application/octet-stream application/json]
end
get ':id/export/download' do
check_rate_limit! :project_download_export, scope: [current_user, user_project.namespace]
check_rate_limit! :project_download_export, scope: [current_user, user_project]
if user_project.export_file_exists?(current_user)
if user_project.export_archive_exists?(current_user)
......
......@@ -1702,7 +1702,7 @@ def update_project_feature
end
it 'prevents requesting project export' do
post action, params: { namespace_id: project.namespace, id: project }
get 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)
......@@ -1710,39 +1710,12 @@ def update_project_feature
end
context 'applies correct scope when throttling', :clean_gitlab_redis_rate_limiting do
before do
stub_application_setting(project_download_export_limit: 1)
travel_to Date.current.beginning_of_day
end
after do
travel_back
end
it 'applies throttle per namespace' do
it 'applies throttle per project' do
expect(Gitlab::ApplicationRateLimiter)
.to receive(:throttled?)
.with(:project_download_export, scope: [user, project.namespace])
post action, params: { namespace_id: project.namespace, id: project }
end
it 'throttles downloads within same namespaces' do
# simulate prior request to the same namespace, which increments the rate limit counter for that scope
Gitlab::ApplicationRateLimiter.throttled?(:project_download_export, scope: [user, project.namespace])
.with(:project_download_export, scope: [user, project])
get action, params: { namespace_id: project.namespace, id: project }
expect(response).to have_gitlab_http_status(:too_many_requests)
end
it 'allows downloads from different namespaces' do
# simulate prior request to a different namespace, which increments the rate limit counter for that scope
Gitlab::ApplicationRateLimiter.throttled?(:project_download_export,
scope: [user, create(:project, :with_export).namespace])
get action, params: { namespace_id: project.namespace, id: project }
expect(response).to have_gitlab_http_status(:ok)
end
end
end
......
......@@ -267,35 +267,15 @@
end
it 'prevents requesting project export' do
expect(Gitlab::ApplicationRateLimiter).to receive(:throttled?)
.with(:project_download_export, scope: [user, project]).and_call_original
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
context 'applies correct scope when throttling' do
before do
stub_application_setting(project_download_export_limit: 1)
end
it 'throttles downloads within same namespaces', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/413230' do
# simulate prior request to the same namespace, which increments the rate limit counter for that scope
Gitlab::ApplicationRateLimiter.throttled?(:project_download_export, scope: [user, project_finished.namespace])
get api(download_path_finished, user, admin_mode: true)
expect(response).to have_gitlab_http_status(:too_many_requests)
end
it 'allows downloads from different namespaces' do
# simulate prior request to a different namespace, which increments the rate limit counter for that scope
Gitlab::ApplicationRateLimiter.throttled?(:project_download_export,
scope: [user, create(:project, :with_export, export_user: user).namespace])
get api(download_path_finished, user, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
end
end
end
context 'when user is a maintainer' do
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment