Commit 3d6e5852 authored by Fabio Pitino's avatar Fabio Pitino

Add specs for job token scope blocking artifacts download

Ensure that job token scope, when enabled, blocks unauthorized
artifacts downloads.
parent f8382631
...@@ -209,6 +209,8 @@ RSpec.describe API::Ci::JobArtifacts do ...@@ -209,6 +209,8 @@ RSpec.describe API::Ci::JobArtifacts do
end end
it 'returns specific job artifacts' do it 'returns specific job artifacts' do
subject
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(response.headers.to_h).to include(download_headers) expect(response.headers.to_h).to include(download_headers)
expect(response.body).to match_file(job.artifacts_file.file.file) expect(response.body).to match_file(job.artifacts_file.file.file)
...@@ -220,18 +222,48 @@ RSpec.describe API::Ci::JobArtifacts do ...@@ -220,18 +222,48 @@ RSpec.describe API::Ci::JobArtifacts do
context 'when artifacts are stored locally' do context 'when artifacts are stored locally' do
let(:job) { create(:ci_build, :artifacts, pipeline: pipeline) } let(:job) { create(:ci_build, :artifacts, pipeline: pipeline) }
before do subject { get api("/projects/#{project.id}/jobs/#{job.id}/artifacts", api_user) }
get api("/projects/#{project.id}/jobs/#{job.id}/artifacts", api_user)
end
context 'authorized user' do context 'authorized user' do
it_behaves_like 'downloads artifact' it_behaves_like 'downloads artifact'
end end
context 'when job token is used' do
let(:other_job) { create(:ci_build, :running, user: user) }
subject { get api("/projects/#{project.id}/jobs/#{job.id}/artifacts", job_token: other_job.token) }
before do
stub_licensed_features(cross_project_pipelines: true)
end
it_behaves_like 'downloads artifact'
context 'when job token scope is enabled' do
before do
other_job.project.ci_cd_settings.update!(job_token_scope_enabled: true)
end
it 'does not allow downloading artifacts' do
subject
expect(response).to have_gitlab_http_status(:not_found)
end
context 'when project is added to the job token scope' do
let!(:link) { create(:ci_job_token_project_scope_link, source_project: other_job.project, target_project: job.project) }
it_behaves_like 'downloads artifact'
end
end
end
context 'unauthorized user' do context 'unauthorized user' do
let(:api_user) { nil } let(:api_user) { nil }
it 'does not return specific job artifacts' do it 'does not return specific job artifacts' do
subject
expect(response).to have_gitlab_http_status(:not_found) expect(response).to have_gitlab_http_status(:not_found)
end end
end end
......
...@@ -19,13 +19,15 @@ module ApiHelpers ...@@ -19,13 +19,15 @@ module ApiHelpers
# => "/api/v2/issues?foo=bar&private_token=..." # => "/api/v2/issues?foo=bar&private_token=..."
# #
# Returns the relative path to the requested API resource # Returns the relative path to the requested API resource
def api(path, user = nil, version: API::API.version, personal_access_token: nil, oauth_access_token: nil) def api(path, user = nil, version: API::API.version, personal_access_token: nil, oauth_access_token: nil, job_token: nil)
full_path = "/api/#{version}#{path}" full_path = "/api/#{version}#{path}"
if oauth_access_token if oauth_access_token
query_string = "access_token=#{oauth_access_token.token}" query_string = "access_token=#{oauth_access_token.token}"
elsif personal_access_token elsif personal_access_token
query_string = "private_token=#{personal_access_token.token}" query_string = "private_token=#{personal_access_token.token}"
elsif job_token
query_string = "job_token=#{job_token}"
elsif user elsif user
personal_access_token = create(:personal_access_token, user: user) personal_access_token = create(:personal_access_token, user: user)
query_string = "private_token=#{personal_access_token.token}" query_string = "private_token=#{personal_access_token.token}"
......
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