Commit de66a69b authored by Stan Hu's avatar Stan Hu

Merge branch '12420-prevent-projects-from-being-shared-outside-a-gma-group-forking' into 'master'

Resolve "Prevent projects from being shared outside a GMA group" - forking case

Closes #12420

See merge request gitlab-org/gitlab!26456
parents da5370ee 57636695
...@@ -8,7 +8,7 @@ module EE ...@@ -8,7 +8,7 @@ module EE
override :execute override :execute
def execute(group) def execute(group)
return error(error_message, 409) unless group_allowed_to_be_shared_with?(group) return error(error_message, 409) unless allowed_to_be_shared_with?(group)
result = super result = super
...@@ -18,10 +18,17 @@ module EE ...@@ -18,10 +18,17 @@ module EE
private private
def group_allowed_to_be_shared_with?(group) def allowed_to_be_shared_with?(group)
return true unless project.root_ancestor.kind == 'group' && project.root_ancestor.enforced_sso? project_can_be_shared_with_group = project_can_be_shared_with_group?(group, project)
source_project_can_be_shared_with_group = project.forked? ? project_can_be_shared_with_group?(group, project.forked_from_project) : true
group.root_ancestor == project.root_ancestor project_can_be_shared_with_group && source_project_can_be_shared_with_group
end
def project_can_be_shared_with_group?(group, given_project)
return true unless given_project.root_ancestor.kind == 'group' && given_project.root_ancestor.enforced_sso?
group.root_ancestor == given_project.root_ancestor
end end
def error_message def error_message
......
---
title: Restrict inviting outside group to a project forked from a group with enforced SSO
merge_request: 26456
author:
type: changed
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
require 'spec_helper' require 'spec_helper'
describe Projects::GroupLinks::CreateService, '#execute' do describe Projects::GroupLinks::CreateService, '#execute' do
include ProjectForksHelper
let(:user) { create :user } let(:user) { create :user }
let(:project) { create :project } let(:project) { create :project }
let(:group) { create(:group, visibility_level: 0) } let(:group) { create(:group, visibility_level: 0) }
...@@ -40,6 +42,8 @@ describe Projects::GroupLinks::CreateService, '#execute' do ...@@ -40,6 +42,8 @@ describe Projects::GroupLinks::CreateService, '#execute' do
context 'when project is in sso enforced group' do context 'when project is in sso enforced group' do
let(:saml_provider) { create(:saml_provider, enforced_sso: true) } let(:saml_provider) { create(:saml_provider, enforced_sso: true) }
let(:root_group) { saml_provider.group } let(:root_group) { saml_provider.group }
let(:identity) { create(:group_saml_identity, saml_provider: saml_provider) }
let(:user) { identity.user }
let(:project) { create(:project, :private, group: root_group) } let(:project) { create(:project, :private, group: root_group) }
let(:subject) { described_class.new(project, user, opts) } let(:subject) { described_class.new(project, user, opts) }
...@@ -82,6 +86,75 @@ describe Projects::GroupLinks::CreateService, '#execute' do ...@@ -82,6 +86,75 @@ describe Projects::GroupLinks::CreateService, '#execute' do
end end
end end
end end
context 'when project is forked from group with enforced SSO' do
let(:forked_project) { create(:project) }
before do
root_group.add_developer(user)
fork_project(project, user, target_project: forked_project)
end
context 'when invited group is outside top group' do
let(:group_to_invite) { create(:group) }
it 'does not add group to project' do
expect { described_class.new(forked_project, user, opts).execute(group_to_invite) }.not_to change { forked_project.project_group_links.count }
end
it 'returns error status and message' do
result = described_class.new(forked_project, user, opts).execute(group_to_invite)
expect(result[:message]).to eq('This group cannot be invited to a project inside a group with enforced SSO')
expect(result[:status]).to eq(:error)
end
end
context 'when invited group is in the top group' do
let(:group_to_invite) { create(:group, parent: root_group) }
it 'adds group to project' do
expect { described_class.new(forked_project, user, opts).execute(group_to_invite) }.to change { forked_project.project_group_links.count }.from(0).to(1)
group_link = forked_project.project_group_links.first
expect(group_link.group_id).to eq(group_to_invite.id)
expect(group_link.project_id).to eq(forked_project.id)
end
end
end
context 'when project is forked to group with enforced sso' do
let(:source_project) { create(:project) }
before do
source_project.add_developer(user)
fork_project(source_project, user, target_project: project)
end
context 'when invited group is outside top group' do
let(:group_to_invite) { create(:group) }
it 'does not add group to project' do
expect { subject.execute(group_to_invite) }.not_to change { project.project_group_links.count }
end
end
context 'when invited group is in the top group' do
let(:group_to_invite) { create(:group, parent: root_group) }
it 'adds group to project' do
expect { subject.execute(group_to_invite) }.to change { project.project_group_links.count }.from(0).to(1)
group_link = project.project_group_links.first
expect(group_link.group_id).to eq(group_to_invite.id)
expect(group_link.project_id).to eq(project.id)
end
end
end
end end
def create_group_link(user, project, group, opts) def create_group_link(user, project, group, opts)
......
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