diff options
Diffstat (limited to 'spec/requests/api/maven_packages_spec.rb')
-rw-r--r-- | spec/requests/api/maven_packages_spec.rb | 160 |
1 files changed, 108 insertions, 52 deletions
diff --git a/spec/requests/api/maven_packages_spec.rb b/spec/requests/api/maven_packages_spec.rb index 1b378788b6a..d7cc6991ef4 100644 --- a/spec/requests/api/maven_packages_spec.rb +++ b/spec/requests/api/maven_packages_spec.rb @@ -2,6 +2,7 @@ require 'spec_helper' RSpec.describe API::MavenPackages do + using RSpec::Parameterized::TableSyntax include WorkhorseHelpers include_context 'workhorse headers' @@ -40,15 +41,15 @@ RSpec.describe API::MavenPackages do project.add_developer(user) end - shared_examples 'handling groups and subgroups for' do |shared_example_name, visibilities: %i[public]| + shared_examples 'handling groups and subgroups for' do |shared_example_name, visibilities: { public: :redirect }| context 'within a group' do - visibilities.each do |visibility| + visibilities.each do |visibility, not_found_response| context "that is #{visibility}" do before do group.update!(visibility_level: Gitlab::VisibilityLevel.level_value(visibility.to_s)) end - it_behaves_like shared_example_name + it_behaves_like shared_example_name, not_found_response end end end @@ -60,20 +61,20 @@ RSpec.describe API::MavenPackages do move_project_to_namespace(subgroup) end - visibilities.each do |visibility| + visibilities.each do |visibility, not_found_response| context "that is #{visibility}" do before do subgroup.update!(visibility_level: Gitlab::VisibilityLevel.level_value(visibility.to_s)) group.update!(visibility_level: Gitlab::VisibilityLevel.level_value(visibility.to_s)) end - it_behaves_like shared_example_name + it_behaves_like shared_example_name, not_found_response end end end end - shared_examples 'handling groups, subgroups and user namespaces for' do |shared_example_name, visibilities: %i[public]| + shared_examples 'handling groups, subgroups and user namespaces for' do |shared_example_name, visibilities: { public: :redirect }| it_behaves_like 'handling groups and subgroups for', shared_example_name, visibilities: visibilities context 'within a user namespace' do @@ -103,16 +104,6 @@ RSpec.describe API::MavenPackages do end end - shared_examples 'rejecting the request for non existing maven path' do |expected_status: :not_found| - it 'rejects the request' do - expect(::Packages::Maven::PackageFinder).not_to receive(:new) - - subject - - expect(response).to have_gitlab_http_status(expected_status) - end - end - shared_examples 'processing HEAD requests' do |instance_level: false| subject { head api(url) } @@ -162,7 +153,7 @@ RSpec.describe API::MavenPackages do context 'with a non existing maven path' do let(:path) { 'foo/bar/1.2.3' } - it_behaves_like 'rejecting the request for non existing maven path', expected_status: instance_level ? :forbidden : :not_found + it_behaves_like 'returning response status', instance_level ? :forbidden : :redirect end end end @@ -238,12 +229,66 @@ RSpec.describe API::MavenPackages do end end + shared_examples 'forwarding package requests' do + context 'request forwarding' do + include_context 'dependency proxy helpers context' + + subject { download_file(file_name: package_name) } + + shared_examples 'redirecting the request' do + it_behaves_like 'returning response status', :redirect + end + + shared_examples 'package not found' do + it_behaves_like 'returning response status', :not_found + end + + where(:forward, :package_in_project, :shared_examples_name) do + true | true | 'successfully returning the file' + true | false | 'redirecting the request' + false | true | 'successfully returning the file' + false | false | 'package not found' + end + + with_them do + let(:package_name) { package_in_project ? package_file.file_name : 'foo' } + + before do + allow_fetch_application_setting(attribute: 'maven_package_requests_forwarding', return_value: forward) + end + + it_behaves_like params[:shared_examples_name] + end + + context 'with maven_central_request_forwarding disabled' do + where(:forward, :package_in_project, :shared_examples_name) do + true | true | 'successfully returning the file' + true | false | 'package not found' + false | true | 'successfully returning the file' + false | false | 'package not found' + end + + with_them do + let(:package_name) { package_in_project ? package_file.file_name : 'foo' } + + before do + stub_feature_flags(maven_central_request_forwarding: false) + allow_fetch_application_setting(attribute: 'maven_package_requests_forwarding', return_value: forward) + end + + it_behaves_like params[:shared_examples_name] + end + end + end + end + describe 'GET /api/v4/packages/maven/*path/:file_name' do context 'a public project' do subject { download_file(file_name: package_file.file_name) } shared_examples 'getting a file' do it_behaves_like 'tracking the file download event' + it_behaves_like 'bumping the package last downloaded at field' it_behaves_like 'successfully returning the file' it_behaves_like 'file download in FIPS mode' @@ -258,7 +303,16 @@ RSpec.describe API::MavenPackages do context 'with a non existing maven path' do subject { download_file(file_name: package_file.file_name, path: 'foo/bar/1.2.3') } - it_behaves_like 'rejecting the request for non existing maven path', expected_status: :forbidden + it_behaves_like 'returning response status', :forbidden + end + + it 'returns not found when a package is not found' do + finder = double('finder', execute: nil) + expect(::Packages::Maven::PackageFinder).to receive(:new).and_return(finder) + + subject + + expect(response).to have_gitlab_http_status(:not_found) end end @@ -275,7 +329,7 @@ RSpec.describe API::MavenPackages do shared_examples 'getting a file' do it_behaves_like 'tracking the file download event' - + it_behaves_like 'bumping the package last downloaded at field' it_behaves_like 'successfully returning the file' it 'denies download when no private token' do @@ -285,17 +339,16 @@ RSpec.describe API::MavenPackages do end it_behaves_like 'downloads with a job token' - it_behaves_like 'downloads with a deploy token' context 'with a non existing maven path' do subject { download_file_with_token(file_name: package_file.file_name, path: 'foo/bar/1.2.3') } - it_behaves_like 'rejecting the request for non existing maven path', expected_status: :forbidden + it_behaves_like 'returning response status', :forbidden end end - it_behaves_like 'handling groups, subgroups and user namespaces for', 'getting a file', visibilities: %i[public internal] + it_behaves_like 'handling groups, subgroups and user namespaces for', 'getting a file', visibilities: { public: :redirect, internal: :not_found } end context 'private project' do @@ -307,7 +360,7 @@ RSpec.describe API::MavenPackages do shared_examples 'getting a file' do it_behaves_like 'tracking the file download event' - + it_behaves_like 'bumping the package last downloaded at field' it_behaves_like 'successfully returning the file' it 'denies download when not enough permissions' do @@ -327,7 +380,6 @@ RSpec.describe API::MavenPackages do end it_behaves_like 'downloads with a job token' - it_behaves_like 'downloads with a deploy token' it 'does not allow download by a unauthorized deploy token with same id as a user with access' do @@ -350,11 +402,11 @@ RSpec.describe API::MavenPackages do context 'with a non existing maven path' do subject { download_file_with_token(file_name: package_file.file_name, path: 'foo/bar/1.2.3') } - it_behaves_like 'rejecting the request for non existing maven path', expected_status: :forbidden + it_behaves_like 'returning response status', :forbidden end end - it_behaves_like 'handling groups, subgroups and user namespaces for', 'getting a file', visibilities: %i[public internal private] + it_behaves_like 'handling groups, subgroups and user namespaces for', 'getting a file', visibilities: { public: :redirect, internal: :not_found, private: :not_found } end context 'project name is different from a package name' do @@ -409,11 +461,14 @@ RSpec.describe API::MavenPackages do group.add_developer(user) end + it_behaves_like 'forwarding package requests' + context 'a public project' do subject { download_file(file_name: package_file.file_name) } shared_examples 'getting a file for a group' do it_behaves_like 'tracking the file download event' + it_behaves_like 'bumping the package last downloaded at field' it_behaves_like 'successfully returning the file' it_behaves_like 'file download in FIPS mode' @@ -428,7 +483,7 @@ RSpec.describe API::MavenPackages do context 'with a non existing maven path' do subject { download_file(file_name: package_file.file_name, path: 'foo/bar/1.2.3') } - it_behaves_like 'rejecting the request for non existing maven path' + it_behaves_like 'returning response status', :redirect end end @@ -443,29 +498,28 @@ RSpec.describe API::MavenPackages do subject { download_file_with_token(file_name: package_file.file_name) } - shared_examples 'getting a file for a group' do + shared_examples 'getting a file for a group' do |not_found_response| it_behaves_like 'tracking the file download event' - + it_behaves_like 'bumping the package last downloaded at field' it_behaves_like 'successfully returning the file' - it 'denies download when no private token' do + it 'forwards download when no private token' do download_file(file_name: package_file.file_name) - expect(response).to have_gitlab_http_status(:not_found) + expect(response).to have_gitlab_http_status(not_found_response) end it_behaves_like 'downloads with a job token' - it_behaves_like 'downloads with a deploy token' context 'with a non existing maven path' do subject { download_file_with_token(file_name: package_file.file_name, path: 'foo/bar/1.2.3') } - it_behaves_like 'rejecting the request for non existing maven path' + it_behaves_like 'returning response status', :redirect end end - it_behaves_like 'handling groups and subgroups for', 'getting a file for a group', visibilities: %i[internal public] + it_behaves_like 'handling groups and subgroups for', 'getting a file for a group', visibilities: { internal: :not_found, public: :redirect } end context 'private project' do @@ -475,9 +529,9 @@ RSpec.describe API::MavenPackages do subject { download_file_with_token(file_name: package_file.file_name) } - shared_examples 'getting a file for a group' do + shared_examples 'getting a file for a group' do |not_found_response| it_behaves_like 'tracking the file download event' - + it_behaves_like 'bumping the package last downloaded at field' it_behaves_like 'successfully returning the file' it 'denies download when not enough permissions' do @@ -485,23 +539,22 @@ RSpec.describe API::MavenPackages do subject - expect(response).to have_gitlab_http_status(:not_found) + expect(response).to have_gitlab_http_status(:redirect) end it 'denies download when no private token' do download_file(file_name: package_file.file_name) - expect(response).to have_gitlab_http_status(:not_found) + expect(response).to have_gitlab_http_status(not_found_response) end it_behaves_like 'downloads with a job token' - it_behaves_like 'downloads with a deploy token' context 'with a non existing maven path' do subject { download_file_with_token(file_name: package_file.file_name, path: 'foo/bar/1.2.3') } - it_behaves_like 'rejecting the request for non existing maven path' + it_behaves_like 'returning response status', :redirect end context 'with group deploy token' do @@ -521,12 +574,12 @@ RSpec.describe API::MavenPackages do context 'with a non existing maven path' do subject { download_file_with_token(file_name: package_file.file_name, path: 'foo/bar/1.2.3', request_headers: group_deploy_token_headers) } - it_behaves_like 'rejecting the request for non existing maven path' + it_behaves_like 'returning response status', :redirect end end end - it_behaves_like 'handling groups and subgroups for', 'getting a file for a group', visibilities: %i[private internal public] + it_behaves_like 'handling groups and subgroups for', 'getting a file for a group', visibilities: { private: :not_found, internal: :not_found, public: :redirect } context 'with a reporter from a subgroup accessing the root group' do let_it_be(:root_group) { create(:group, :private) } @@ -544,7 +597,7 @@ RSpec.describe API::MavenPackages do context 'with a non existing maven path' do subject { download_file_with_token(file_name: package_file.file_name, path: 'foo/bar/1.2.3', request_headers: headers_with_token, group_id: root_group.id) } - it_behaves_like 'rejecting the request for non existing maven path' + it_behaves_like 'returning response status', :redirect end end end @@ -640,12 +693,14 @@ RSpec.describe API::MavenPackages do it_behaves_like 'successfully returning the file' it_behaves_like 'file download in FIPS mode' - it 'returns sha1 of the file' do - download_file(file_name: package_file.file_name + '.sha1') + %w[sha1 md5].each do |format| + it "returns #{format} of the file" do + download_file(file_name: package_file.file_name + ".#{format}") - expect(response).to have_gitlab_http_status(:ok) - expect(response.media_type).to eq('text/plain') - expect(response.body).to eq(package_file.file_sha1) + expect(response).to have_gitlab_http_status(:ok) + expect(response.media_type).to eq('text/plain') + expect(response.body).to eq(package_file.send("file_#{format}".to_sym)) + end end context 'when the repository is disabled' do @@ -664,7 +719,7 @@ RSpec.describe API::MavenPackages do context 'with a non existing maven path' do subject { download_file(file_name: package_file.file_name, path: 'foo/bar/1.2.3') } - it_behaves_like 'rejecting the request for non existing maven path' + it_behaves_like 'returning response status', :redirect end end @@ -676,7 +731,7 @@ RSpec.describe API::MavenPackages do subject { download_file_with_token(file_name: package_file.file_name) } it_behaves_like 'tracking the file download event' - + it_behaves_like 'bumping the package last downloaded at field' it_behaves_like 'successfully returning the file' it 'denies download when not enough permissions' do @@ -694,16 +749,17 @@ RSpec.describe API::MavenPackages do end it_behaves_like 'downloads with a job token' - it_behaves_like 'downloads with a deploy token' context 'with a non existing maven path' do subject { download_file_with_token(file_name: package_file.file_name, path: 'foo/bar/1.2.3') } - it_behaves_like 'rejecting the request for non existing maven path' + it_behaves_like 'returning response status', :redirect end end + it_behaves_like 'forwarding package requests' + def download_file(file_name:, params: {}, request_headers: headers, path: maven_metadatum.path) get api("/projects/#{project.id}/packages/maven/" \ "#{path}/#{file_name}"), params: params, headers: request_headers |