Prepare ForkService to support forking projects to given namespaces
Remove overload of BaseService.initialize, so initialize gains params, which is used to pass the namespace (like e.g. in TransferService). The namespace is checked for permission to create projects in it.
This commit is contained in:
parent
f74dba8c42
commit
c44764f523
|
@ -9,6 +9,7 @@ v 7.4.0
|
||||||
- Do not delete tmp/repositories itself during clean-up, only its contents
|
- Do not delete tmp/repositories itself during clean-up, only its contents
|
||||||
- Support for backup uploads to remote storage
|
- Support for backup uploads to remote storage
|
||||||
- Prevent notes polling when there are not notes
|
- Prevent notes polling when there are not notes
|
||||||
|
- Internal ForkService: Prepare support for fork to a given namespace
|
||||||
- API: Add support for forking a project via the API (Bernhard Kaindl)
|
- API: Add support for forking a project via the API (Bernhard Kaindl)
|
||||||
- API: filter project issues by milestone (Julien Bianchi)
|
- API: filter project issues by milestone (Julien Bianchi)
|
||||||
- Fail harder in the backup script
|
- Fail harder in the backup script
|
||||||
|
|
|
@ -2,11 +2,9 @@ module Projects
|
||||||
class ForkService < BaseService
|
class ForkService < BaseService
|
||||||
include Gitlab::ShellAdapter
|
include Gitlab::ShellAdapter
|
||||||
|
|
||||||
def initialize(project, user)
|
|
||||||
@from_project, @current_user = project, user
|
|
||||||
end
|
|
||||||
|
|
||||||
def execute
|
def execute
|
||||||
|
@from_project = @project
|
||||||
|
|
||||||
project_params = {
|
project_params = {
|
||||||
visibility_level: @from_project.visibility_level,
|
visibility_level: @from_project.visibility_level,
|
||||||
description: @from_project.description,
|
description: @from_project.description,
|
||||||
|
@ -15,8 +13,15 @@ module Projects
|
||||||
project = Project.new(project_params)
|
project = Project.new(project_params)
|
||||||
project.name = @from_project.name
|
project.name = @from_project.name
|
||||||
project.path = @from_project.path
|
project.path = @from_project.path
|
||||||
project.namespace = current_user.namespace
|
project.namespace = @current_user.namespace
|
||||||
project.creator = current_user
|
if namespace = @params[:namespace]
|
||||||
|
project.namespace = namespace
|
||||||
|
end
|
||||||
|
project.creator = @current_user
|
||||||
|
unless @current_user.can?(:create_projects, project.namespace)
|
||||||
|
project.errors.add(:namespace, 'insufficient access rights')
|
||||||
|
return project
|
||||||
|
end
|
||||||
|
|
||||||
# If the project cannot save, we do not want to trigger the project destroy
|
# If the project cannot save, we do not want to trigger the project destroy
|
||||||
# as this can have the side effect of deleting a repo attached to an existing
|
# as this can have the side effect of deleting a repo attached to an existing
|
||||||
|
@ -27,7 +32,7 @@ module Projects
|
||||||
#First save the DB entries as they can be rolled back if the repo fork fails
|
#First save the DB entries as they can be rolled back if the repo fork fails
|
||||||
project.build_forked_project_link(forked_to_project_id: project.id, forked_from_project_id: @from_project.id)
|
project.build_forked_project_link(forked_to_project_id: project.id, forked_from_project_id: @from_project.id)
|
||||||
if project.save
|
if project.save
|
||||||
project.team << [current_user, :master]
|
project.team << [@current_user, :master]
|
||||||
end
|
end
|
||||||
#Now fork the repo
|
#Now fork the repo
|
||||||
unless gitlab_shell.fork_repository(@from_project.path_with_namespace, project.namespace.path)
|
unless gitlab_shell.fork_repository(@from_project.path_with_namespace, project.namespace.path)
|
||||||
|
|
|
@ -42,10 +42,54 @@ describe Projects::ForkService do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def fork_project(from_project, user, fork_success = true)
|
describe :fork_to_namespace do
|
||||||
context = Projects::ForkService.new(from_project, user)
|
before do
|
||||||
shell = double("gitlab_shell")
|
@group_owner = create(:user)
|
||||||
shell.stub(fork_repository: fork_success)
|
@developer = create(:user)
|
||||||
|
@project = create(:project, creator_id: @group_owner.id,
|
||||||
|
star_count: 777,
|
||||||
|
description: 'Wow, such a cool project!')
|
||||||
|
@group = create(:group)
|
||||||
|
@group.add_user(@group_owner, GroupMember::OWNER)
|
||||||
|
@group.add_user(@developer, GroupMember::DEVELOPER)
|
||||||
|
@opts = { namespace: @group }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'fork project for group' do
|
||||||
|
it 'group owner successfully forks project into the group' do
|
||||||
|
to_project = fork_project(@project, @group_owner, true, @opts)
|
||||||
|
to_project.owner.should == @group
|
||||||
|
to_project.namespace.should == @group
|
||||||
|
to_project.name.should == @project.name
|
||||||
|
to_project.path.should == @project.path
|
||||||
|
to_project.description.should == @project.description
|
||||||
|
to_project.star_count.should be_zero
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'fork project for group when user not owner' do
|
||||||
|
it 'group developer should fail to fork project into the group' do
|
||||||
|
to_project = fork_project(@project, @developer, true, @opts)
|
||||||
|
to_project.errors[:namespace].should == ['insufficient access rights']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'project already exists in group' do
|
||||||
|
it 'should fail due to validation, not transaction failure' do
|
||||||
|
existing_project = create(:project, name: @project.name,
|
||||||
|
namespace: @group)
|
||||||
|
to_project = fork_project(@project, @group_owner, true, @opts)
|
||||||
|
existing_project.persisted?.should be_true
|
||||||
|
to_project.errors[:base].should == ['Invalid fork destination']
|
||||||
|
to_project.errors[:name].should == ['has already been taken']
|
||||||
|
to_project.errors[:path].should == ['has already been taken']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def fork_project(from_project, user, fork_success = true, params = {})
|
||||||
|
context = Projects::ForkService.new(from_project, user, params)
|
||||||
|
shell = double('gitlab_shell').stub(fork_repository: fork_success)
|
||||||
context.stub(gitlab_shell: shell)
|
context.stub(gitlab_shell: shell)
|
||||||
context.execute
|
context.execute
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue