Commit 118d0949 authored by Fabio Pitino's avatar Fabio Pitino

Merge branch '213723-ci-job-token-public-package-access' into 'master'

Give CI_JOB_TOKEN permission to access public packages

See merge request gitlab-org/gitlab!57265
parents 59dd8a69 f641c086
...@@ -293,7 +293,7 @@ module EE ...@@ -293,7 +293,7 @@ module EE
rule { ~commit_committer_check_available }.prevent :change_commit_committer_check rule { ~commit_committer_check_available }.prevent :change_commit_committer_check
rule { owner | reporter }.enable :build_read_project rule { owner | reporter | public_project }.enable :build_read_project
rule { ~admin & owner & owner_cannot_destroy_project }.prevent :remove_project rule { ~admin & owner & owner_cannot_destroy_project }.prevent :remove_project
......
---
title: Give CI_JOB_TOKEN read access to public projects so public packages can be
consumed
merge_request: 57265
author:
type: fixed
...@@ -123,4 +123,45 @@ RSpec.describe EE::API::Helpers do ...@@ -123,4 +123,45 @@ RSpec.describe EE::API::Helpers do
end end
end end
end end
describe '#find_project!' do
let_it_be(:project) { create(:project, :public) }
let_it_be(:job) { create(:ci_build, :running) }
let(:helper) do
Class.new do
include API::Helpers
include API::APIGuard::HelperMethods
include EE::API::Helpers
end
end
subject { helper.new }
context 'when current_user is from a job' do
before do
subject.instance_variable_set(:@current_authenticated_job, job)
subject.instance_variable_set(:@initial_current_user, job.user)
subject.instance_variable_set(:@current_user, job.user)
end
context 'public project' do
it 'returns requested project' do
expect(subject.find_project!(project.id)).to eq(project)
end
end
context 'private project without access' do
before do
project.update_column(:visibility_level, Gitlab::VisibilityLevel.level_value('private'))
end
it 'returns not found' do
expect(subject).to receive(:not_found!)
subject.find_project!(project.id)
end
end
end
end
end end
...@@ -1658,4 +1658,35 @@ RSpec.describe ProjectPolicy do ...@@ -1658,4 +1658,35 @@ RSpec.describe ProjectPolicy do
end end
end end
end end
describe ':build_read_project' do
using RSpec::Parameterized::TableSyntax
let(:policy) { :build_read_project }
where(:role, :project_visibility, :allowed) do
:guest | 'public' | true
:reporter | 'public' | true
:developer | 'public' | true
:maintainer | 'public' | true
:owner | 'public' | true
:admin | 'public' | true
:guest | 'private' | false
:reporter | 'private' | true
:developer | 'private' | true
:maintainer | 'private' | true
:owner | 'private' | true
:admin | 'private' | false
end
with_them do
let(:current_user) { public_send(role) }
before do
project.update_column(:visibility_level, Gitlab::VisibilityLevel.level_value(project_visibility))
end
it { is_expected.to(allowed ? be_allowed(policy) : be_disallowed(policy)) }
end
end
end end
...@@ -47,6 +47,58 @@ RSpec.describe API::Helpers do ...@@ -47,6 +47,58 @@ RSpec.describe API::Helpers do
end end
end end
describe '#find_project!' do
let_it_be(:project) { create(:project, :public) }
let_it_be(:user) { create(:user) }
shared_examples 'private project without access' do
before do
project.update_column(:visibility_level, Gitlab::VisibilityLevel.level_value('private'))
allow(subject).to receive(:authenticate_non_public?).and_return(false)
end
it 'returns not found' do
expect(subject).to receive(:not_found!)
subject.find_project!(project.id)
end
end
context 'when user is authenticated' do
before do
subject.instance_variable_set(:@current_user, user)
subject.instance_variable_set(:@initial_current_user, user)
end
context 'public project' do
it 'returns requested project' do
expect(subject.find_project!(project.id)).to eq(project)
end
end
context 'private project' do
it_behaves_like 'private project without access'
end
end
context 'when user is not authenticated' do
before do
subject.instance_variable_set(:@current_user, nil)
subject.instance_variable_set(:@initial_current_user, nil)
end
context 'public project' do
it 'returns requested project' do
expect(subject.find_project!(project.id)).to eq(project)
end
end
context 'private project' do
it_behaves_like 'private project without access'
end
end
end
describe '#find_namespace' do describe '#find_namespace' do
let(:namespace) { create(:namespace) } let(:namespace) { create(:namespace) }
......
...@@ -41,6 +41,15 @@ RSpec.describe API::NpmProjectPackages do ...@@ -41,6 +41,15 @@ RSpec.describe API::NpmProjectPackages do
project.add_developer(user) project.add_developer(user)
end end
shared_examples 'successfully downloads the file' do
it 'returns the file' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(response.media_type).to eq('application/octet-stream')
end
end
shared_examples 'a package file that requires auth' do shared_examples 'a package file that requires auth' do
it 'denies download with no token' do it 'denies download with no token' do
subject subject
...@@ -51,35 +60,28 @@ RSpec.describe API::NpmProjectPackages do ...@@ -51,35 +60,28 @@ RSpec.describe API::NpmProjectPackages do
context 'with access token' do context 'with access token' do
let(:headers) { build_token_auth_header(token.token) } let(:headers) { build_token_auth_header(token.token) }
it 'returns the file' do it_behaves_like 'successfully downloads the file'
subject
expect(response).to have_gitlab_http_status(:ok)
expect(response.media_type).to eq('application/octet-stream')
end
end end
context 'with job token' do context 'with job token' do
let(:headers) { build_token_auth_header(job.token) } let(:headers) { build_token_auth_header(job.token) }
it 'returns the file' do it_behaves_like 'successfully downloads the file'
subject
expect(response).to have_gitlab_http_status(:ok)
expect(response.media_type).to eq('application/octet-stream')
end
end end
end end
context 'a public project' do context 'a public project' do
it 'returns the file with no token needed' do it_behaves_like 'successfully downloads the file'
subject it_behaves_like 'a package tracking event', 'API::NpmPackages', 'pull_package'
expect(response).to have_gitlab_http_status(:ok) context 'with a job token for a different user' do
expect(response.media_type).to eq('application/octet-stream') let_it_be(:other_user) { create(:user) }
end let_it_be_with_reload(:other_job) { create(:ci_build, :running, user: other_user) }
it_behaves_like 'a package tracking event', 'API::NpmPackages', 'pull_package' let(:headers) { build_token_auth_header(other_job.token) }
it_behaves_like 'successfully downloads the file'
end
end end
context 'private project' do context 'private project' 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