Commit 031122eb authored by Grzegorz Bizon's avatar Grzegorz Bizon

Add container repository create service with specs

parent 4407d3cf
...@@ -58,4 +58,8 @@ class ContainerRepository < ActiveRecord::Base ...@@ -58,4 +58,8 @@ class ContainerRepository < ActiveRecord::Base
client.delete_repository_tag(self.path, digest) client.delete_repository_tag(self.path, digest)
end end
end end
def self.create_from_path(path)
self.create(project: path.repository_project, name: path.repository_name)
end
end end
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
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
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