Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/requests/api/maven_packages_spec.rb')
-rw-r--r--spec/requests/api/maven_packages_spec.rb246
1 files changed, 193 insertions, 53 deletions
diff --git a/spec/requests/api/maven_packages_spec.rb b/spec/requests/api/maven_packages_spec.rb
index 20aa660d95b..60e91973b5d 100644
--- a/spec/requests/api/maven_packages_spec.rb
+++ b/spec/requests/api/maven_packages_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe API::MavenPackages, feature_category: :package_registry do
using RSpec::Parameterized::TableSyntax
include WorkhorseHelpers
+ include HttpBasicAuthHelpers
include_context 'workhorse headers'
@@ -22,7 +23,7 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
let_it_be(:deploy_token_for_group) { create(:deploy_token, :group, read_package_registry: true, write_package_registry: true) }
let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: deploy_token_for_group, group: group) }
- let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace, property: 'i_package_maven_user' } }
+ let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace, user: user, property: 'i_package_maven_user' } }
let(:package_name) { 'com/example/my-app' }
let(:headers) { workhorse_headers }
@@ -159,56 +160,149 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
end
end
- shared_examples 'downloads with a deploy token' do
- context 'successful download' do
+ shared_examples 'allowing the download' do
+ it 'allows download' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.media_type).to eq('application/octet-stream')
+ end
+ end
+
+ shared_examples 'not allowing the download with' do |not_found_response|
+ it 'does not allow the download' do
+ subject
+
+ expect(response).to have_gitlab_http_status(not_found_response)
+ end
+ end
+
+ shared_examples 'downloads with a personal access token' do |not_found_response|
+ where(:valid, :sent_using) do
+ true | :custom_header
+ false | :custom_header
+ true | :basic_auth
+ false | :basic_auth
+ end
+
+ with_them do
+ let(:token) { valid ? personal_access_token.token : 'not_valid' }
+ let(:headers) do
+ case sent_using
+ when :custom_header
+ { 'Private-Token' => token }
+ when :basic_auth
+ basic_auth_header(user.username, token)
+ end
+ end
+
subject do
download_file(
file_name: package_file.file_name,
- request_headers: { Gitlab::Auth::AuthFinders::DEPLOY_TOKEN_HEADER => deploy_token.token }
+ request_headers: headers
)
end
- it 'allows download with deploy token' do
- subject
+ if params[:valid]
+ it_behaves_like 'allowing the download'
+ else
+ expected_status_code = not_found_response
+ # invalid PAT values sent through headers are validated.
+ # Invalid values will trigger an :unauthorized response (and not set current_user to nil)
+ expected_status_code = :unauthorized if params[:sent_using] == :custom_header && !params[:valid]
+ it_behaves_like 'not allowing the download with', expected_status_code
+ end
+ end
+ end
- expect(response).to have_gitlab_http_status(:ok)
- expect(response.media_type).to eq('application/octet-stream')
+ shared_examples 'downloads with a deploy token' do |not_found_response|
+ where(:valid, :sent_using) do
+ true | :custom_header
+ false | :custom_header
+ true | :basic_auth
+ false | :basic_auth
+ end
+
+ with_them do
+ let(:token) { valid ? deploy_token.token : 'not_valid' }
+ let(:headers) do
+ case sent_using
+ when :custom_header
+ { Gitlab::Auth::AuthFinders::DEPLOY_TOKEN_HEADER => token }
+ when :basic_auth
+ basic_auth_header(deploy_token.username, token)
+ end
end
- it 'allows download with deploy token with only write_package_registry scope' do
- deploy_token.update!(read_package_registry: false)
+ subject do
+ download_file(
+ file_name: package_file.file_name,
+ request_headers: headers
+ )
+ end
- subject
+ if params[:valid]
+ it_behaves_like 'allowing the download'
- expect(response).to have_gitlab_http_status(:ok)
- expect(response.media_type).to eq('application/octet-stream')
+ context 'with only write_package_registry scope' do
+ it_behaves_like 'allowing the download' do
+ before do
+ deploy_token.update!(read_package_registry: false)
+ end
+ end
+ end
+ else
+ it_behaves_like 'not allowing the download with', not_found_response
end
end
end
shared_examples 'downloads with a job token' do
- context 'with a running job' do
- it 'allows download with job token' do
- download_file(file_name: package_file.file_name, params: { job_token: job.token })
+ where(:valid, :sent_using) do
+ true | :custom_params
+ false | :custom_params
+ true | :basic_auth
+ false | :basic_auth
+ end
- expect(response).to have_gitlab_http_status(:ok)
- expect(response.media_type).to eq('application/octet-stream')
+ with_them do
+ let(:token) { valid ? job.token : 'not_valid' }
+ let(:headers) { basic_auth_header(::Gitlab::Auth::CI_JOB_USER, token) }
+ let(:params) { { job_token: token } }
+
+ subject do
+ case sent_using
+ when :custom_params
+ download_file(file_name: package_file.file_name, params: params)
+ when :basic_auth
+ download_file(file_name: package_file.file_name, request_headers: headers)
+ end
end
- end
- context 'with a finished job' do
- before do
- job.update!(status: :failed)
+ context 'with a running job' do
+ if params[:valid]
+ it_behaves_like 'allowing the download'
+ else
+ it_behaves_like 'not allowing the download with', :unauthorized
+ end
end
- it 'returns unauthorized error' do
- download_file(file_name: package_file.file_name, params: { job_token: job.token })
+ context 'with a finished job' do
+ before do
+ job.update!(status: :failed)
+ end
- expect(response).to have_gitlab_http_status(:unauthorized)
+ it_behaves_like 'not allowing the download with', :unauthorized
end
end
end
+ shared_examples 'downloads with different tokens' do |not_found_response|
+ it_behaves_like 'downloads with a personal access token', not_found_response
+ it_behaves_like 'downloads with a deploy token', not_found_response
+ it_behaves_like 'downloads with a job token'
+ end
+
shared_examples 'successfully returning the file' do
it 'returns the file', :aggregate_failures do
subject
@@ -285,6 +379,8 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
describe 'GET /api/v4/packages/maven/*path/:file_name' do
context 'a public project' do
+ let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace, property: 'i_package_maven_user' } }
+
subject { download_file(file_name: package_file.file_name) }
shared_examples 'getting a file' do
@@ -336,11 +432,10 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
it 'denies download when no private token' do
download_file(file_name: package_file.file_name)
- expect(response).to have_gitlab_http_status(:forbidden)
+ expect(response).to have_gitlab_http_status(:unauthorized)
end
- it_behaves_like 'downloads with a job token'
- it_behaves_like 'downloads with a deploy token'
+ it_behaves_like 'downloads with different tokens', :unauthorized
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') }
@@ -377,11 +472,10 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
it 'denies download when no private token' do
download_file(file_name: package_file.file_name)
- expect(response).to have_gitlab_http_status(:forbidden)
+ expect(response).to have_gitlab_http_status(:unauthorized)
end
- it_behaves_like 'downloads with a job token'
- it_behaves_like 'downloads with a deploy token'
+ it_behaves_like 'downloads with different tokens', :unauthorized
it 'does not allow download by a unauthorized deploy token with same id as a user with access' do
unauthorized_deploy_token = create(:deploy_token, read_package_registry: true, write_package_registry: true)
@@ -411,12 +505,8 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
end
context 'project name is different from a package name' do
- before do
- maven_metadatum.update!(path: "wrong_name/#{package.version}")
- end
-
it 'rejects request' do
- download_file(file_name: package_file.file_name)
+ download_file(file_name: package_file.file_name, path: "wrong_name/#{package.version}")
expect(response).to have_gitlab_http_status(:forbidden)
end
@@ -451,6 +541,8 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
it_behaves_like 'forwarding package requests'
context 'a public project' do
+ let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace, property: 'i_package_maven_user' } }
+
subject { download_file(file_name: package_file.file_name) }
shared_examples 'getting a file for a group' do
@@ -496,8 +588,7 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
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'
+ it_behaves_like 'downloads with different tokens', not_found_response
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') }
@@ -506,7 +597,7 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
end
end
- it_behaves_like 'handling groups and subgroups for', 'getting a file for a group', visibilities: { internal: :not_found, public: :redirect }
+ it_behaves_like 'handling groups and subgroups for', 'getting a file for a group', visibilities: { internal: :unauthorized, public: :redirect }
end
context 'private project' do
@@ -535,8 +626,7 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
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'
+ it_behaves_like 'downloads with different tokens', not_found_response
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') }
@@ -566,7 +656,7 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
end
end
- it_behaves_like 'handling groups and subgroups for', 'getting a file for a group', visibilities: { private: :not_found, internal: :not_found, public: :redirect }
+ it_behaves_like 'handling groups and subgroups for', 'getting a file for a group', visibilities: { private: :unauthorized, internal: :unauthorized, public: :redirect }
context 'with a reporter from a subgroup accessing the root group' do
let_it_be(:root_group) { create(:group, :private) }
@@ -660,6 +750,8 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
describe 'GET /api/v4/projects/:id/packages/maven/*path/:file_name' do
context 'a public project' do
+ let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace, property: 'i_package_maven_user' } }
+
subject { download_file(file_name: package_file.file_name) }
it_behaves_like 'tracking the file download event'
@@ -718,7 +810,7 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
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(:unauthorized)
end
context 'with access to package registry for everyone' do
@@ -731,8 +823,7 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
it_behaves_like 'successfully returning the file'
end
- it_behaves_like 'downloads with a job token'
- it_behaves_like 'downloads with a deploy token'
+ it_behaves_like 'downloads with different tokens', :unauthorized
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') }
@@ -901,8 +992,6 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
it_behaves_like 'package workhorse uploads'
context 'event tracking' do
- let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace, user: user, property: 'i_package_maven_user' } }
-
it_behaves_like 'a package tracking event', described_class.name, 'push_package'
context 'when the package file fails to be created' do
@@ -917,6 +1006,8 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
end
it 'creates package and stores package file' do
+ expect_use_primary
+
expect { upload_file_with_token(params: params) }.to change { project.packages.count }.by(1)
.and change { Packages::Maven::Metadatum.count }.by(1)
.and change { Packages::PackageFile.count }.by(1)
@@ -962,6 +1053,17 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
expect(response).to have_gitlab_http_status(:forbidden)
end
+ context 'file name is too long' do
+ let(:file_name) { 'a' * (Packages::Maven::FindOrCreatePackageService::MAX_FILE_NAME_LENGTH + 1) }
+
+ it 'rejects request' do
+ expect { upload_file_with_token(params: params, file_name: file_name) }.not_to change { project.packages.count }
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response['message']).to include('File name is too long')
+ end
+ end
+
context 'version is not correct' do
let(:version) { '$%123' }
@@ -981,9 +1083,9 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
package_settings.update!(maven_duplicates_allowed: false)
end
- shared_examples 'storing the package file' do
+ shared_examples 'storing the package file' do |file_name: 'my-app-1.0-20180724.124855-1'|
it 'stores the file', :aggregate_failures do
- expect { upload_file_with_token(params: params) }.to change { package.package_files.count }.by(1)
+ expect { upload_file_with_token(params: params, file_name: file_name) }.to change { package.package_files.count }.by(1)
expect(response).to have_gitlab_http_status(:ok)
expect(jar_file.file_name).to eq(file_upload.original_filename)
@@ -1023,6 +1125,10 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
it_behaves_like 'storing the package file'
end
+
+ context 'when uploading a similar package file name with a classifier' do
+ it_behaves_like 'storing the package file', file_name: 'my-app-1.0-20180724.124855-1-javadoc'
+ end
end
context 'for sha1 file' do
@@ -1043,6 +1149,8 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
end
it 'returns no content' do
+ expect_use_primary
+
upload
expect(response).to have_gitlab_http_status(:no_content)
@@ -1072,6 +1180,8 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
subject { upload_file_with_token(params: params, file_extension: 'jar.md5') }
it 'returns an empty body' do
+ expect_use_primary
+
subject
expect(response.body).to eq('')
@@ -1086,10 +1196,40 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
end
end
end
+
+ context 'reading fingerprints from UploadedFile instance' do
+ let(:file) { Packages::Package.last.package_files.with_format('%.jar').last }
+
+ subject { upload_file_with_token(params: params) }
+
+ before do
+ allow_next_instance_of(UploadedFile) do |uploaded_file|
+ allow(uploaded_file).to receive(:size).and_return(123)
+ allow(uploaded_file).to receive(:sha1).and_return('sha1')
+ allow(uploaded_file).to receive(:md5).and_return('md5')
+ end
+ end
+
+ it 'reads size, sha1 and md5 fingerprints from uploaded_file instance' do
+ subject
+
+ expect(file.size).to eq(123)
+ expect(file.file_sha1).to eq('sha1')
+ expect(file.file_md5).to eq('md5')
+ end
+ end
+
+ def expect_use_primary
+ lb_session = ::Gitlab::Database::LoadBalancing::Session.current
+
+ expect(lb_session).to receive(:use_primary).and_call_original
+
+ allow(::Gitlab::Database::LoadBalancing::Session).to receive(:current).and_return(lb_session)
+ end
end
- def upload_file(params: {}, request_headers: headers, file_extension: 'jar')
- url = "/projects/#{project.id}/packages/maven/#{param_path}/my-app-1.0-20180724.124855-1.#{file_extension}"
+ def upload_file(params: {}, request_headers: headers, file_extension: 'jar', file_name: 'my-app-1.0-20180724.124855-1')
+ url = "/projects/#{project.id}/packages/maven/#{param_path}/#{file_name}.#{file_extension}"
workhorse_finalize(
api(url),
method: :put,
@@ -1100,8 +1240,8 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
)
end
- def upload_file_with_token(params: {}, request_headers: headers_with_token, file_extension: 'jar')
- upload_file(params: params, request_headers: request_headers, file_extension: file_extension)
+ def upload_file_with_token(params: {}, request_headers: headers_with_token, file_extension: 'jar', file_name: 'my-app-1.0-20180724.124855-1')
+ upload_file(params: params, request_headers: request_headers, file_name: file_name, file_extension: file_extension)
end
end