Commit 043c6649 authored by Steve Abrams's avatar Steve Abrams

Verify workhorse request for uploads

Verify PUT requests come from workhorse for
package upload and artifact endpoints using workhorse uploads.
parent e3bee019
---
title: Add workhorse request verification to package upload endpoints
merge_request:
author:
type: security
...@@ -179,10 +179,7 @@ module API ...@@ -179,10 +179,7 @@ module API
end end
route_setting :authentication, job_token_allowed: true route_setting :authentication, job_token_allowed: true
put ':id/packages/maven/*path/:file_name/authorize', requirements: MAVEN_ENDPOINT_REQUIREMENTS do put ':id/packages/maven/*path/:file_name/authorize', requirements: MAVEN_ENDPOINT_REQUIREMENTS do
authorize_create_package!(user_project) authorize_upload!
require_gitlab_workhorse!
Gitlab::Workhorse.verify_api_request!(headers)
status 200 status 200
content_type Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE content_type Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE
...@@ -205,8 +202,7 @@ module API ...@@ -205,8 +202,7 @@ module API
end end
route_setting :authentication, job_token_allowed: true route_setting :authentication, job_token_allowed: true
put ':id/packages/maven/*path/:file_name', requirements: MAVEN_ENDPOINT_REQUIREMENTS do put ':id/packages/maven/*path/:file_name', requirements: MAVEN_ENDPOINT_REQUIREMENTS do
authorize_create_package!(user_project) authorize_upload!
require_gitlab_workhorse!
file_name, format = extract_format(params[:file_name]) file_name, format = extract_format(params[:file_name])
......
...@@ -586,6 +586,8 @@ describe API::ConanPackages do ...@@ -586,6 +586,8 @@ describe API::ConanPackages do
context 'without a file from workhorse' do context 'without a file from workhorse' do
let(:params) { { file: nil } } let(:params) { { file: nil } }
it_behaves_like 'package workhorse uploads'
it 'rejects the request' do it 'rejects the request' do
subject subject
...@@ -710,7 +712,7 @@ describe API::ConanPackages do ...@@ -710,7 +712,7 @@ describe API::ConanPackages do
subject subject
expect(response).to have_gitlab_http_status(:error) expect(response).to have_gitlab_http_status(:forbidden)
end end
context 'when using remote storage' do context 'when using remote storage' do
......
...@@ -10,8 +10,8 @@ describe API::MavenPackages do ...@@ -10,8 +10,8 @@ describe API::MavenPackages do
let(:package_file) { package.package_files.where('file_name like ?', '%.xml').first } let(:package_file) { package.package_files.where('file_name like ?', '%.xml').first }
let(:jar_file) { package.package_files.where('file_name like ?', '%.jar').first } let(:jar_file) { package.package_files.where('file_name like ?', '%.jar').first }
let(:personal_access_token) { create(:personal_access_token, user: user) } let(:personal_access_token) { create(:personal_access_token, user: user) }
let(:jwt_token) { JWT.encode({ 'iss' => 'gitlab-workhorse' }, Gitlab::Workhorse.secret, 'HS256') } let(:workhorse_token) { JWT.encode({ 'iss' => 'gitlab-workhorse' }, Gitlab::Workhorse.secret, 'HS256') }
let(:headers) { { 'GitLab-Workhorse' => '1.0', Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER => jwt_token } } let(:headers) { { 'GitLab-Workhorse' => '1.0', Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER => workhorse_token } }
let(:headers_with_token) { headers.merge('Private-Token' => personal_access_token.token) } let(:headers_with_token) { headers.merge('Private-Token' => personal_access_token.token) }
let(:job) { create(:ci_build, user: user) } let(:job) { create(:ci_build, user: user) }
let(:version) { '1.0-SNAPSHOT' } let(:version) { '1.0-SNAPSHOT' }
...@@ -40,14 +40,14 @@ describe API::MavenPackages do ...@@ -40,14 +40,14 @@ describe API::MavenPackages do
it 'returns the file' do it 'returns the file' do
subject subject
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq('application/octet-stream') expect(response.content_type.to_s).to eq('application/octet-stream')
end end
it 'returns sha1 of the file' do it 'returns sha1 of the file' do
download_file(package_file.file_name + '.sha1') download_file(package_file.file_name + '.sha1')
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq('text/plain') expect(response.content_type.to_s).to eq('text/plain')
expect(response.body).to eq(package_file.file_sha1) expect(response.body).to eq(package_file.file_sha1)
end end
...@@ -66,20 +66,20 @@ describe API::MavenPackages do ...@@ -66,20 +66,20 @@ describe API::MavenPackages do
it 'returns the file' do it 'returns the file' do
subject subject
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq('application/octet-stream') expect(response.content_type.to_s).to eq('application/octet-stream')
end end
it 'denies download when no private token' do it 'denies download when no private token' do
download_file(package_file.file_name) download_file(package_file.file_name)
expect(response).to have_gitlab_http_status(403) expect(response).to have_gitlab_http_status(:forbidden)
end end
it 'allows download with job token' do it 'allows download with job token' do
download_file(package_file.file_name, job_token: job.token) download_file(package_file.file_name, job_token: job.token)
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq('application/octet-stream') expect(response.content_type.to_s).to eq('application/octet-stream')
end end
end end
...@@ -96,7 +96,7 @@ describe API::MavenPackages do ...@@ -96,7 +96,7 @@ describe API::MavenPackages do
it 'returns the file' do it 'returns the file' do
subject subject
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq('application/octet-stream') expect(response.content_type.to_s).to eq('application/octet-stream')
end end
...@@ -105,19 +105,19 @@ describe API::MavenPackages do ...@@ -105,19 +105,19 @@ describe API::MavenPackages do
subject subject
expect(response).to have_gitlab_http_status(403) expect(response).to have_gitlab_http_status(:forbidden)
end end
it 'denies download when no private token' do it 'denies download when no private token' do
download_file(package_file.file_name) download_file(package_file.file_name)
expect(response).to have_gitlab_http_status(403) expect(response).to have_gitlab_http_status(:forbidden)
end end
it 'allows download with job token' do it 'allows download with job token' do
download_file(package_file.file_name, job_token: job.token) download_file(package_file.file_name, job_token: job.token)
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq('application/octet-stream') expect(response.content_type.to_s).to eq('application/octet-stream')
end end
end end
...@@ -127,7 +127,7 @@ describe API::MavenPackages do ...@@ -127,7 +127,7 @@ describe API::MavenPackages do
download_file(package_file.file_name) download_file(package_file.file_name)
expect(response).to have_gitlab_http_status(403) expect(response).to have_gitlab_http_status(:forbidden)
end end
context 'project name is different from a package name' do context 'project name is different from a package name' do
...@@ -136,7 +136,7 @@ describe API::MavenPackages do ...@@ -136,7 +136,7 @@ describe API::MavenPackages do
it 'rejects request' do it 'rejects request' do
download_file(package_file.file_name) download_file(package_file.file_name)
expect(response).to have_gitlab_http_status(403) expect(response).to have_gitlab_http_status(:forbidden)
end end
end end
...@@ -163,14 +163,14 @@ describe API::MavenPackages do ...@@ -163,14 +163,14 @@ describe API::MavenPackages do
it 'returns the file' do it 'returns the file' do
subject subject
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq('application/octet-stream') expect(response.content_type.to_s).to eq('application/octet-stream')
end end
it 'returns sha1 of the file' do it 'returns sha1 of the file' do
download_file(package_file.file_name + '.sha1') download_file(package_file.file_name + '.sha1')
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq('text/plain') expect(response.content_type.to_s).to eq('text/plain')
expect(response.body).to eq(package_file.file_sha1) expect(response.body).to eq(package_file.file_sha1)
end end
...@@ -189,20 +189,20 @@ describe API::MavenPackages do ...@@ -189,20 +189,20 @@ describe API::MavenPackages do
it 'returns the file' do it 'returns the file' do
subject subject
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq('application/octet-stream') expect(response.content_type.to_s).to eq('application/octet-stream')
end end
it 'denies download when no private token' do it 'denies download when no private token' do
download_file(package_file.file_name) download_file(package_file.file_name)
expect(response).to have_gitlab_http_status(404) expect(response).to have_gitlab_http_status(:not_found)
end end
it 'allows download with job token' do it 'allows download with job token' do
download_file(package_file.file_name, job_token: job.token) download_file(package_file.file_name, job_token: job.token)
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq('application/octet-stream') expect(response.content_type.to_s).to eq('application/octet-stream')
end end
end end
...@@ -219,7 +219,7 @@ describe API::MavenPackages do ...@@ -219,7 +219,7 @@ describe API::MavenPackages do
it 'returns the file' do it 'returns the file' do
subject subject
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq('application/octet-stream') expect(response.content_type.to_s).to eq('application/octet-stream')
end end
...@@ -228,19 +228,19 @@ describe API::MavenPackages do ...@@ -228,19 +228,19 @@ describe API::MavenPackages do
subject subject
expect(response).to have_gitlab_http_status(403) expect(response).to have_gitlab_http_status(:forbidden)
end end
it 'denies download when no private token' do it 'denies download when no private token' do
download_file(package_file.file_name) download_file(package_file.file_name)
expect(response).to have_gitlab_http_status(404) expect(response).to have_gitlab_http_status(:not_found)
end end
it 'allows download with job token' do it 'allows download with job token' do
download_file(package_file.file_name, job_token: job.token) download_file(package_file.file_name, job_token: job.token)
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq('application/octet-stream') expect(response.content_type.to_s).to eq('application/octet-stream')
end end
end end
...@@ -250,7 +250,7 @@ describe API::MavenPackages do ...@@ -250,7 +250,7 @@ describe API::MavenPackages do
download_file(package_file.file_name) download_file(package_file.file_name)
expect(response).to have_gitlab_http_status(403) expect(response).to have_gitlab_http_status(:forbidden)
end end
def download_file(file_name, params = {}, request_headers = headers) def download_file(file_name, params = {}, request_headers = headers)
...@@ -271,14 +271,14 @@ describe API::MavenPackages do ...@@ -271,14 +271,14 @@ describe API::MavenPackages do
it 'returns the file' do it 'returns the file' do
subject subject
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq('application/octet-stream') expect(response.content_type.to_s).to eq('application/octet-stream')
end end
it 'returns sha1 of the file' do it 'returns sha1 of the file' do
download_file(package_file.file_name + '.sha1') download_file(package_file.file_name + '.sha1')
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq('text/plain') expect(response.content_type.to_s).to eq('text/plain')
expect(response.body).to eq(package_file.file_sha1) expect(response.body).to eq(package_file.file_sha1)
end end
...@@ -296,7 +296,7 @@ describe API::MavenPackages do ...@@ -296,7 +296,7 @@ describe API::MavenPackages do
it 'returns the file' do it 'returns the file' do
subject subject
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq('application/octet-stream') expect(response.content_type.to_s).to eq('application/octet-stream')
end end
...@@ -305,19 +305,19 @@ describe API::MavenPackages do ...@@ -305,19 +305,19 @@ describe API::MavenPackages do
subject subject
expect(response).to have_gitlab_http_status(403) expect(response).to have_gitlab_http_status(:forbidden)
end end
it 'denies download when no private token' do it 'denies download when no private token' do
download_file(package_file.file_name) download_file(package_file.file_name)
expect(response).to have_gitlab_http_status(404) expect(response).to have_gitlab_http_status(:not_found)
end end
it 'allows download with job token' do it 'allows download with job token' do
download_file(package_file.file_name, job_token: job.token) download_file(package_file.file_name, job_token: job.token)
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq('application/octet-stream') expect(response.content_type.to_s).to eq('application/octet-stream')
end end
end end
...@@ -327,7 +327,7 @@ describe API::MavenPackages do ...@@ -327,7 +327,7 @@ describe API::MavenPackages do
download_file(package_file.file_name) download_file(package_file.file_name)
expect(response).to have_gitlab_http_status(403) expect(response).to have_gitlab_http_status(:forbidden)
end end
def download_file(file_name, params = {}, request_headers = headers) def download_file(file_name, params = {}, request_headers = headers)
...@@ -344,13 +344,13 @@ describe API::MavenPackages do ...@@ -344,13 +344,13 @@ describe API::MavenPackages do
it 'rejects a malicious request' do it 'rejects a malicious request' do
put api("/projects/#{project.id}/packages/maven/com/example/my-app/#{version}/%2e%2e%2F.ssh%2Fauthorized_keys/authorize"), params: {}, headers: headers_with_token put api("/projects/#{project.id}/packages/maven/com/example/my-app/#{version}/%2e%2e%2F.ssh%2Fauthorized_keys/authorize"), params: {}, headers: headers_with_token
expect(response).to have_gitlab_http_status(400) expect(response).to have_gitlab_http_status(:bad_request)
end end
it 'authorizes posting package with a valid token' do it 'authorizes posting package with a valid token' do
authorize_upload_with_token authorize_upload_with_token
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE) expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
expect(json_response['TempPath']).not_to be_nil expect(json_response['TempPath']).not_to be_nil
end end
...@@ -360,7 +360,7 @@ describe API::MavenPackages do ...@@ -360,7 +360,7 @@ describe API::MavenPackages do
authorize_upload_with_token authorize_upload_with_token
expect(response).to have_gitlab_http_status(401) expect(response).to have_gitlab_http_status(:unauthorized)
end end
it 'rejects request without a valid permission' do it 'rejects request without a valid permission' do
...@@ -368,7 +368,7 @@ describe API::MavenPackages do ...@@ -368,7 +368,7 @@ describe API::MavenPackages do
authorize_upload_with_token authorize_upload_with_token
expect(response).to have_gitlab_http_status(403) expect(response).to have_gitlab_http_status(:forbidden)
end end
it 'rejects requests that did not go through gitlab-workhorse' do it 'rejects requests that did not go through gitlab-workhorse' do
...@@ -376,13 +376,13 @@ describe API::MavenPackages do ...@@ -376,13 +376,13 @@ describe API::MavenPackages do
authorize_upload_with_token authorize_upload_with_token
expect(response).to have_gitlab_http_status(500) expect(response).to have_gitlab_http_status(:forbidden)
end end
it 'authorizes upload with job token' do it 'authorizes upload with job token' do
authorize_upload(job_token: job.token) authorize_upload(job_token: job.token)
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
end end
def authorize_upload(params = {}, request_headers = headers) def authorize_upload(params = {}, request_headers = headers)
...@@ -405,13 +405,13 @@ describe API::MavenPackages do ...@@ -405,13 +405,13 @@ describe API::MavenPackages do
it 'rejects requests without a file from workhorse' do it 'rejects requests without a file from workhorse' do
upload_file_with_token upload_file_with_token
expect(response).to have_gitlab_http_status(400) expect(response).to have_gitlab_http_status(:bad_request)
end end
it 'rejects request without a token' do it 'rejects request without a token' do
upload_file upload_file
expect(response).to have_gitlab_http_status(401) expect(response).to have_gitlab_http_status(:unauthorized)
end end
it 'rejects request if feature is not in the license' do it 'rejects request if feature is not in the license' do
...@@ -419,7 +419,7 @@ describe API::MavenPackages do ...@@ -419,7 +419,7 @@ describe API::MavenPackages do
upload_file_with_token upload_file_with_token
expect(response).to have_gitlab_http_status(403) expect(response).to have_gitlab_http_status(:forbidden)
end end
context 'when params from workhorse are correct' do context 'when params from workhorse are correct' do
...@@ -435,7 +435,13 @@ describe API::MavenPackages do ...@@ -435,7 +435,13 @@ describe API::MavenPackages do
it 'rejects a malicious request' do it 'rejects a malicious request' do
put api("/projects/#{project.id}/packages/maven/com/example/my-app/#{version}/%2e%2e%2f.ssh%2fauthorized_keys"), params: params, headers: headers_with_token put api("/projects/#{project.id}/packages/maven/com/example/my-app/#{version}/%2e%2e%2f.ssh%2fauthorized_keys"), params: params, headers: headers_with_token
expect(response).to have_gitlab_http_status(400) expect(response).to have_gitlab_http_status(:bad_request)
end
context 'without workhorse header' do
subject { upload_file_with_token(params) }
it_behaves_like 'package workhorse uploads'
end end
context 'event tracking' do context 'event tracking' do
...@@ -451,14 +457,14 @@ describe API::MavenPackages do ...@@ -451,14 +457,14 @@ describe API::MavenPackages do
.and change { Packages::MavenMetadatum.count }.by(1) .and change { Packages::MavenMetadatum.count }.by(1)
.and change { Packages::PackageFile.count }.by(1) .and change { Packages::PackageFile.count }.by(1)
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(package_file.file_name).to eq(file_upload.original_filename) expect(package_file.file_name).to eq(file_upload.original_filename)
end end
it 'allows upload with job token' do it 'allows upload with job token' do
upload_file(params.merge(job_token: job.token)) upload_file(params.merge(job_token: job.token))
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:ok)
expect(package.build_info.pipeline).to eq job.pipeline expect(package.build_info.pipeline).to eq job.pipeline
end end
...@@ -468,7 +474,7 @@ describe API::MavenPackages do ...@@ -468,7 +474,7 @@ describe API::MavenPackages do
it 'rejects request' do it 'rejects request' do
expect { upload_file_with_token(params) }.not_to change { project.packages.count } expect { upload_file_with_token(params) }.not_to change { project.packages.count }
expect(response).to have_gitlab_http_status(400) expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']).to include('Validation failed') expect(json_response['message']).to include('Validation failed')
end end
end end
......
...@@ -172,8 +172,8 @@ describe API::NugetPackages do ...@@ -172,8 +172,8 @@ describe API::NugetPackages do
end end
describe 'PUT /api/v4/projects/:id/packages/nuget' do describe 'PUT /api/v4/projects/:id/packages/nuget' do
let_it_be(:workhorse_token) { JWT.encode({ 'iss' => 'gitlab-workhorse' }, Gitlab::Workhorse.secret, 'HS256') } let(:workhorse_token) { JWT.encode({ 'iss' => 'gitlab-workhorse' }, Gitlab::Workhorse.secret, 'HS256') }
let_it_be(:workhorse_header) { { 'GitLab-Workhorse' => '1.0', Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER => workhorse_token } } let(:workhorse_header) { { 'GitLab-Workhorse' => '1.0', Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER => workhorse_token } }
let_it_be(:file_name) { 'package.nupkg' } let_it_be(:file_name) { 'package.nupkg' }
let(:url) { "/projects/#{project.id}/packages/nuget" } let(:url) { "/projects/#{project.id}/packages/nuget" }
let(:headers) { {} } let(:headers) { {} }
......
...@@ -72,7 +72,7 @@ RSpec.shared_examples 'process nuget workhorse authorization' do |user_type, sta ...@@ -72,7 +72,7 @@ RSpec.shared_examples 'process nuget workhorse authorization' do |user_type, sta
project.add_maintainer(user) project.add_maintainer(user)
end end
it_behaves_like 'returning response status', :error it_behaves_like 'returning response status', :forbidden
end end
end end
end end
...@@ -104,6 +104,7 @@ RSpec.shared_examples 'process nuget upload' do |user_type, status, add_member = ...@@ -104,6 +104,7 @@ RSpec.shared_examples 'process nuget upload' do |user_type, status, add_member =
end end
context 'with correct params' do context 'with correct params' do
it_behaves_like 'package workhorse uploads'
it_behaves_like 'creates nuget package files' it_behaves_like 'creates nuget package files'
it_behaves_like 'a gitlab tracking event', described_class.name, 'push_package' it_behaves_like 'a gitlab tracking event', described_class.name, 'push_package'
end end
......
...@@ -115,3 +115,17 @@ RSpec.shared_examples 'background upload schedules a file migration' do ...@@ -115,3 +115,17 @@ RSpec.shared_examples 'background upload schedules a file migration' do
end end
end end
end end
shared_examples 'package workhorse uploads' do
context 'without a workhorse header' do
let(:workhorse_token) { JWT.encode({ 'iss' => 'invalid header' }, Gitlab::Workhorse.secret, 'HS256') }
it_behaves_like 'returning response status', :forbidden
it 'logs an error' do
expect(Gitlab::ErrorTracking).to receive(:track_exception).once
subject
end
end
end
...@@ -258,11 +258,21 @@ module API ...@@ -258,11 +258,21 @@ module API
end end
def require_gitlab_workhorse! def require_gitlab_workhorse!
verify_workhorse_api!
unless env['HTTP_GITLAB_WORKHORSE'].present? unless env['HTTP_GITLAB_WORKHORSE'].present?
forbidden!('Request should be executed via GitLab Workhorse') forbidden!('Request should be executed via GitLab Workhorse')
end end
end end
def verify_workhorse_api!
Gitlab::Workhorse.verify_api_request!(request.headers)
rescue => e
Gitlab::ErrorTracking.track_exception(e)
forbidden!
end
def require_pages_enabled! def require_pages_enabled!
not_found! unless user_project.pages_available? not_found! unless user_project.pages_available?
end end
......
...@@ -1545,7 +1545,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do ...@@ -1545,7 +1545,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
authorize_artifacts authorize_artifacts
expect(response).to have_gitlab_http_status(500) expect(response).to have_gitlab_http_status(:forbidden)
end end
context 'authorization token is invalid' do context 'authorization token is invalid' do
...@@ -1675,6 +1675,18 @@ describe API::Runner, :clean_gitlab_redis_shared_state do ...@@ -1675,6 +1675,18 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
end end
end end
context 'Is missing GitLab Workhorse token headers' do
let(:jwt_token) { JWT.encode({ 'iss' => 'invalid-header' }, Gitlab::Workhorse.secret, 'HS256') }
it 'fails to post artifacts without GitLab-Workhorse' do
expect(Gitlab::ErrorTracking).to receive(:track_exception).once
upload_artifacts(file_upload, headers_with_token)
expect(response).to have_gitlab_http_status(:forbidden)
end
end
context 'when setting an expire date' do context 'when setting an expire date' do
let(:default_artifacts_expire_in) {} let(:default_artifacts_expire_in) {}
let(:post_data) do let(:post_data) do
......
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