Add container repository create service with specs
This commit is contained in:
parent
4407d3cf19
commit
031122eb54
3 changed files with 111 additions and 0 deletions
|
@ -58,4 +58,8 @@ class ContainerRepository < ActiveRecord::Base
|
|||
client.delete_repository_tag(self.path, digest)
|
||||
end
|
||||
end
|
||||
|
||||
def self.create_from_path(path)
|
||||
self.create(project: path.repository_project, name: path.repository_name)
|
||||
end
|
||||
end
|
||||
|
|
33
app/services/container_registry/create_repository_service.rb
Normal file
33
app/services/container_registry/create_repository_service.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
module ContainerRegistry
|
||||
##
|
||||
# Service for creating a container repository.
|
||||
#
|
||||
# It is usually executed before registry authenticator returns
|
||||
# a token for given request.
|
||||
#
|
||||
class CreateRepositoryService < BaseService
|
||||
def execute(path)
|
||||
@path = path
|
||||
|
||||
return if path.has_repository?
|
||||
|
||||
unless user_can_create? || legacy_trigger_can_create?
|
||||
raise Gitlab::Access::AccessDeniedError
|
||||
end
|
||||
|
||||
ContainerRepository.create_from_path(path)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user_can_create?
|
||||
can?(@current_user, :create_container_image, @path.repository_project)
|
||||
end
|
||||
|
||||
## TODO, remove it after removing legacy triggers.
|
||||
#
|
||||
def legacy_trigger_can_create?
|
||||
@current_user.nil? && @project == @path.repository_project
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,74 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe ContainerRegistry::CreateRepositoryService, '#execute' do
|
||||
let(:project) { create(:empty_project) }
|
||||
let(:user) { create(:user) }
|
||||
|
||||
let(:path) do
|
||||
ContainerRegistry::Path.new("#{project.full_path}/my/image")
|
||||
end
|
||||
|
||||
let(:service) { described_class.new(project, user) }
|
||||
|
||||
before do
|
||||
stub_container_registry_config(enabled: true)
|
||||
end
|
||||
|
||||
context 'when container repository already exists' do
|
||||
before do
|
||||
create(:container_repository, project: project, name: 'my/image')
|
||||
end
|
||||
|
||||
it 'does not create container repository again' do
|
||||
expect { service.execute(path) }
|
||||
.to raise_error(Gitlab::Access::AccessDeniedError)
|
||||
.and change { ContainerRepository.count }.by(0)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when repository is created by an user' do
|
||||
context 'when user has no ability to create a repository' do
|
||||
it 'does not create a new container repository' do
|
||||
expect { service.execute(path) }
|
||||
.to raise_error(Gitlab::Access::AccessDeniedError)
|
||||
.and change { ContainerRepository.count }.by(0)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user has ability do create a repository' do
|
||||
before do
|
||||
project.add_developer(user)
|
||||
end
|
||||
|
||||
it 'creates a new container repository' do
|
||||
expect { service.execute(path) }
|
||||
.to change { project.container_repositories.count }.by(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when repository is created by a legacy pipeline trigger' do
|
||||
let(:user) { nil }
|
||||
|
||||
context 'when repository path matches authenticated project' do
|
||||
it 'creates a new container repository' do
|
||||
expect { service.execute(path) }
|
||||
.to change { project.container_repositories.count }.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when repository path does not match authenticated project' do
|
||||
let(:private_project) { create(:empty_project, :private) }
|
||||
|
||||
let(:path) do
|
||||
ContainerRegistry::Path.new("#{private_project.full_path}/my/image")
|
||||
end
|
||||
|
||||
it 'does not create a new container repository' do
|
||||
expect { service.execute(path) }
|
||||
.to raise_error(Gitlab::Access::AccessDeniedError)
|
||||
.and change { ContainerRepository.count }.by(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue