Skip to content
Snippets Groups Projects
Commit 7d3d1ec5 authored by Grzegorz Bizon's avatar Grzegorz Bizon
Browse files

Create container repository on successful push auth

Because we do not have yet two way communication between container
registry and GitLab, we need to eagerly create a new container
repository objects in database. We now do that after user/build
successfully authenticates a push action using auth service.
parent 236c9c17
No related branches found
No related tags found
1 merge request!10109Multi-level container registry images
Pipeline #
Loading
@@ -60,6 +60,7 @@ class ContainerRepository < ActiveRecord::Base
Loading
@@ -60,6 +60,7 @@ class ContainerRepository < ActiveRecord::Base
end end
   
def self.create_from_path(path) def self.create_from_path(path)
self.create(project: path.repository_project, name: path.repository_name) self.create(project: path.repository_project,
name: path.repository_name)
end end
end end
Loading
@@ -74,9 +74,25 @@ module Auth
Loading
@@ -74,9 +74,25 @@ module Auth
   
return unless actions.present? return unless actions.present?
   
# At this point user/build is already authenticated.
#
ensure_container_repository!(path, actions)
{ type: type, name: path.to_s, actions: actions } { type: type, name: path.to_s, actions: actions }
end end
   
##
# Because we do not have two way communication with registry yet,
# we create a container repository image resource when push to the
# registry is successfuly authorized.
#
def ensure_container_repository!(path, actions)
return if path.has_repository?
return unless actions.include?('push')
ContainerRepository.create_from_path(path)
end
def can_access?(requested_project, requested_action) def can_access?(requested_project, requested_action)
return false unless requested_project.container_registry_enabled? return false unless requested_project.container_registry_enabled?
   
Loading
Loading
Loading
@@ -44,6 +44,10 @@ module ContainerRegistry
Loading
@@ -44,6 +44,10 @@ module ContainerRegistry
.where(name: repository_name).any? .where(name: repository_name).any?
end end
   
def root_repository?
@path == repository_project.full_path
end
def repository_project def repository_project
@project ||= Project.where_full_path_in(components.first(3))&.first @project ||= Project.where_full_path_in(components.first(3))&.first
end end
Loading
Loading
Loading
@@ -80,6 +80,19 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -80,6 +80,19 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
it { is_expected.not_to include(:token) } it { is_expected.not_to include(:token) }
end end
   
shared_examples 'container repository factory' do
it 'creates a new containe repository resource' do
expect { subject }
.to change { project.container_repositories.count }.by(1)
end
end
shared_examples 'container repository factory' do
it 'does not create a new container repository resource' do
expect { subject }.not_to change { ContainerRepository.count }
end
end
describe '#full_access_token' do describe '#full_access_token' do
let(:project) { create(:empty_project) } let(:project) { create(:empty_project) }
let(:token) { described_class.full_access_token(project.path_with_namespace) } let(:token) { described_class.full_access_token(project.path_with_namespace) }
Loading
@@ -89,6 +102,8 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -89,6 +102,8 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
it_behaves_like 'an accessible' do it_behaves_like 'an accessible' do
let(:actions) { ['*'] } let(:actions) { ['*'] }
end end
it_behaves_like 'not a container repository factory'
end end
   
context 'user authorization' do context 'user authorization' do
Loading
@@ -109,16 +124,20 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -109,16 +124,20 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end end
   
it_behaves_like 'a pushable' it_behaves_like 'a pushable'
it_behaves_like 'container repository factory'
end end
   
context 'allow reporter to pull images' do context 'allow reporter to pull images' do
before { project.team << [current_user, :reporter] } before { project.team << [current_user, :reporter] }
   
let(:current_params) do context 'when pulling from root level repository' do
{ scope: "repository:#{project.path_with_namespace}:pull" } let(:current_params) do
end { scope: "repository:#{project.path_with_namespace}:pull" }
end
   
it_behaves_like 'a pullable' it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
end
end end
   
context 'return a least of privileges' do context 'return a least of privileges' do
Loading
@@ -129,6 +148,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -129,6 +148,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end end
   
it_behaves_like 'a pullable' it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
end end
   
context 'disallow guest to pull or push images' do context 'disallow guest to pull or push images' do
Loading
@@ -139,6 +159,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -139,6 +159,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end end
   
it_behaves_like 'an inaccessible' it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
end end
end end
   
Loading
@@ -151,6 +172,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -151,6 +172,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end end
   
it_behaves_like 'a pullable' it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
end end
   
context 'disallow anyone to push images' do context 'disallow anyone to push images' do
Loading
@@ -159,6 +181,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -159,6 +181,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end end
   
it_behaves_like 'an inaccessible' it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
end end
end end
   
Loading
@@ -172,6 +195,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -172,6 +195,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end end
   
it_behaves_like 'a pullable' it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
end end
   
context 'disallow anyone to push images' do context 'disallow anyone to push images' do
Loading
@@ -180,6 +204,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -180,6 +204,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end end
   
it_behaves_like 'an inaccessible' it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
end end
end end
   
Loading
@@ -190,6 +215,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -190,6 +215,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end end
   
it_behaves_like 'an inaccessible' it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
end end
end end
end end
Loading
@@ -216,6 +242,10 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -216,6 +242,10 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
it_behaves_like 'a pullable and pushable' do it_behaves_like 'a pullable and pushable' do
let(:project) { current_project } let(:project) { current_project }
end end
it_behaves_like 'container repository factory' do
let(:project) { current_project }
end
end end
   
context 'for other projects' do context 'for other projects' do
Loading
@@ -228,11 +258,13 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -228,11 +258,13 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
let(:project) { create(:empty_project, :public) } let(:project) { create(:empty_project, :public) }
   
it_behaves_like 'a pullable' it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
end end
   
shared_examples 'pullable for being team member' do shared_examples 'pullable for being team member' do
context 'when you are not member' do context 'when you are not member' do
it_behaves_like 'an inaccessible' it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
end end
   
context 'when you are member' do context 'when you are member' do
Loading
@@ -241,12 +273,14 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -241,12 +273,14 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end end
   
it_behaves_like 'a pullable' it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
end end
   
context 'when you are owner' do context 'when you are owner' do
let(:project) { create(:empty_project, namespace: current_user.namespace) } let(:project) { create(:empty_project, namespace: current_user.namespace) }
   
it_behaves_like 'a pullable' it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
end end
end end
   
Loading
@@ -260,6 +294,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -260,6 +294,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
   
context 'when you are not member' do context 'when you are not member' do
it_behaves_like 'an inaccessible' it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
end end
   
context 'when you are member' do context 'when you are member' do
Loading
@@ -268,12 +303,14 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -268,12 +303,14 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end end
   
it_behaves_like 'a pullable' it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
end end
   
context 'when you are owner' do context 'when you are owner' do
let(:project) { create(:empty_project, namespace: current_user.namespace) } let(:project) { create(:empty_project, namespace: current_user.namespace) }
   
it_behaves_like 'a pullable' it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
end end
end end
end end
Loading
@@ -293,12 +330,14 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -293,12 +330,14 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end end
   
it_behaves_like 'an inaccessible' it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
end end
   
context 'when you are owner' do context 'when you are owner' do
let(:project) { create(:empty_project, :public, namespace: current_user.namespace) } let(:project) { create(:empty_project, :public, namespace: current_user.namespace) }
   
it_behaves_like 'an inaccessible' it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
end end
end end
end end
Loading
@@ -315,6 +354,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -315,6 +354,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end end
   
it_behaves_like 'an inaccessible' it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
end end
end end
end end
Loading
@@ -322,6 +362,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -322,6 +362,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
context 'unauthorized' do context 'unauthorized' do
context 'disallow to use scope-less authentication' do context 'disallow to use scope-less authentication' do
it_behaves_like 'a forbidden' it_behaves_like 'a forbidden'
it_behaves_like 'not a container repository factory'
end end
   
context 'for invalid scope' do context 'for invalid scope' do
Loading
@@ -330,6 +371,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -330,6 +371,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end end
   
it_behaves_like 'a forbidden' it_behaves_like 'a forbidden'
it_behaves_like 'not a container repository factory'
end end
   
context 'for private project' do context 'for private project' do
Loading
@@ -351,6 +393,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -351,6 +393,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end end
   
it_behaves_like 'a pullable' it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
end end
   
context 'when pushing' do context 'when pushing' do
Loading
@@ -359,6 +402,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
Loading
@@ -359,6 +402,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end end
   
it_behaves_like 'a forbidden' it_behaves_like 'a forbidden'
it_behaves_like 'not a container repository factory'
end end
end end
end end
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment