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.
This commit is contained in:
Grzegorz Bizon 2017-03-30 15:24:46 +02:00
parent 236c9c1703
commit 7d3d1ec5a7
4 changed files with 70 additions and 5 deletions

View file

@ -60,6 +60,7 @@ class ContainerRepository < ActiveRecord::Base
end
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

View file

@ -74,9 +74,25 @@ module Auth
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 }
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)
return false unless requested_project.container_registry_enabled?

View file

@ -44,6 +44,10 @@ module ContainerRegistry
.where(name: repository_name).any?
end
def root_repository?
@path == repository_project.full_path
end
def repository_project
@project ||= Project.where_full_path_in(components.first(3))&.first
end

View file

@ -80,6 +80,19 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
it { is_expected.not_to include(:token) }
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
let(:project) { create(:empty_project) }
let(:token) { described_class.full_access_token(project.path_with_namespace) }
@ -89,6 +102,8 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
it_behaves_like 'an accessible' do
let(:actions) { ['*'] }
end
it_behaves_like 'not a container repository factory'
end
context 'user authorization' do
@ -109,16 +124,20 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
it_behaves_like 'a pushable'
it_behaves_like 'container repository factory'
end
context 'allow reporter to pull images' do
before { project.team << [current_user, :reporter] }
let(:current_params) do
{ scope: "repository:#{project.path_with_namespace}:pull" }
end
context 'when pulling from root level repository' do
let(:current_params) do
{ 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
context 'return a least of privileges' do
@ -129,6 +148,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
end
context 'disallow guest to pull or push images' do
@ -139,6 +159,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
end
end
@ -151,6 +172,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
end
context 'disallow anyone to push images' do
@ -159,6 +181,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
end
end
@ -172,6 +195,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
end
context 'disallow anyone to push images' do
@ -180,6 +204,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
end
end
@ -190,6 +215,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
end
end
end
@ -216,6 +242,10 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
it_behaves_like 'a pullable and pushable' do
let(:project) { current_project }
end
it_behaves_like 'container repository factory' do
let(:project) { current_project }
end
end
context 'for other projects' do
@ -228,11 +258,13 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
let(:project) { create(:empty_project, :public) }
it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
end
shared_examples 'pullable for being team member' do
context 'when you are not member' do
it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
end
context 'when you are member' do
@ -241,12 +273,14 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
end
context 'when you are owner' do
let(:project) { create(:empty_project, namespace: current_user.namespace) }
it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
end
end
@ -260,6 +294,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
context 'when you are not member' do
it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
end
context 'when you are member' do
@ -268,12 +303,14 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
end
context 'when you are owner' do
let(:project) { create(:empty_project, namespace: current_user.namespace) }
it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
end
end
end
@ -293,12 +330,14 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
end
context 'when you are owner' do
let(:project) { create(:empty_project, :public, namespace: current_user.namespace) }
it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
end
end
end
@ -315,6 +354,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
end
end
end
@ -322,6 +362,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
context 'unauthorized' do
context 'disallow to use scope-less authentication' do
it_behaves_like 'a forbidden'
it_behaves_like 'not a container repository factory'
end
context 'for invalid scope' do
@ -330,6 +371,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
it_behaves_like 'a forbidden'
it_behaves_like 'not a container repository factory'
end
context 'for private project' do
@ -351,6 +393,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
end
context 'when pushing' do
@ -359,6 +402,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
it_behaves_like 'a forbidden'
it_behaves_like 'not a container repository factory'
end
end
end