diff options
Diffstat (limited to 'spec/lib/gitlab/project_authorizations_spec.rb')
-rw-r--r-- | spec/lib/gitlab/project_authorizations_spec.rb | 567 |
1 files changed, 290 insertions, 277 deletions
diff --git a/spec/lib/gitlab/project_authorizations_spec.rb b/spec/lib/gitlab/project_authorizations_spec.rb index 640cf9be453..b076bb65fb5 100644 --- a/spec/lib/gitlab/project_authorizations_spec.rb +++ b/spec/lib/gitlab/project_authorizations_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::ProjectAuthorizations do +RSpec.describe Gitlab::ProjectAuthorizations, feature_category: :system_access do def map_access_levels(rows) rows.each_with_object({}) do |row, hash| hash[row.project_id] = row.access_level @@ -13,408 +13,421 @@ RSpec.describe Gitlab::ProjectAuthorizations do described_class.new(user).calculate end - context 'user added to group and project' do - let(:group) { create(:group) } - let!(:other_project) { create(:project) } - let!(:group_project) { create(:project, namespace: group) } - let!(:owned_project) { create(:project) } - let(:user) { owned_project.namespace.owner } + # Inline this shared example while cleaning up feature flag linear_project_authorization + RSpec.shared_examples 'project authorizations' do + context 'user added to group and project' do + let(:group) { create(:group) } + let!(:other_project) { create(:project) } + let!(:group_project) { create(:project, namespace: group) } + let!(:owned_project) { create(:project) } + let(:user) { owned_project.namespace.owner } - before do - other_project.add_reporter(user) - group.add_developer(user) - end + before do + other_project.add_reporter(user) + group.add_developer(user) + end - it 'returns the correct number of authorizations' do - expect(authorizations.length).to eq(3) - end + it 'returns the correct number of authorizations' do + expect(authorizations.length).to eq(3) + end - it 'includes the correct projects' do - expect(authorizations.pluck(:project_id)) - .to include(owned_project.id, other_project.id, group_project.id) - end + it 'includes the correct projects' do + expect(authorizations.pluck(:project_id)) + .to include(owned_project.id, other_project.id, group_project.id) + end - it 'includes the correct access levels' do - mapping = map_access_levels(authorizations) + it 'includes the correct access levels' do + mapping = map_access_levels(authorizations) - expect(mapping[owned_project.id]).to eq(Gitlab::Access::OWNER) - expect(mapping[other_project.id]).to eq(Gitlab::Access::REPORTER) - expect(mapping[group_project.id]).to eq(Gitlab::Access::DEVELOPER) + expect(mapping[owned_project.id]).to eq(Gitlab::Access::OWNER) + expect(mapping[other_project.id]).to eq(Gitlab::Access::REPORTER) + expect(mapping[group_project.id]).to eq(Gitlab::Access::DEVELOPER) + end end - end - context 'unapproved access request' do - let_it_be(:group) { create(:group) } - let_it_be(:user) { create(:user) } + context 'unapproved access request' do + let_it_be(:group) { create(:group) } + let_it_be(:user) { create(:user) } - subject(:mapping) { map_access_levels(authorizations) } + subject(:mapping) { map_access_levels(authorizations) } - context 'group membership' do - let!(:group_project) { create(:project, namespace: group) } + context 'group membership' do + let!(:group_project) { create(:project, namespace: group) } - before do - create(:group_member, :developer, :access_request, user: user, group: group) - end + before do + create(:group_member, :developer, :access_request, user: user, group: group) + end - it 'does not create authorization' do - expect(mapping[group_project.id]).to be_nil + it 'does not create authorization' do + expect(mapping[group_project.id]).to be_nil + end end - end - context 'inherited group membership' do - let!(:sub_group) { create(:group, parent: group) } - let!(:sub_group_project) { create(:project, namespace: sub_group) } + context 'inherited group membership' do + let!(:sub_group) { create(:group, parent: group) } + let!(:sub_group_project) { create(:project, namespace: sub_group) } - before do - create(:group_member, :developer, :access_request, user: user, group: group) - end + before do + create(:group_member, :developer, :access_request, user: user, group: group) + end - it 'does not create authorization' do - expect(mapping[sub_group_project.id]).to be_nil + it 'does not create authorization' do + expect(mapping[sub_group_project.id]).to be_nil + end end - end - context 'project membership' do - let!(:group_project) { create(:project, namespace: group) } + context 'project membership' do + let!(:group_project) { create(:project, namespace: group) } - before do - create(:project_member, :developer, :access_request, user: user, project: group_project) - end + before do + create(:project_member, :developer, :access_request, user: user, project: group_project) + end - it 'does not create authorization' do - expect(mapping[group_project.id]).to be_nil + it 'does not create authorization' do + expect(mapping[group_project.id]).to be_nil + end end - end - context 'shared group' do - let!(:shared_group) { create(:group) } - let!(:shared_group_project) { create(:project, namespace: shared_group) } + context 'shared group' do + let!(:shared_group) { create(:group) } + let!(:shared_group_project) { create(:project, namespace: shared_group) } - before do - create(:group_group_link, shared_group: shared_group, shared_with_group: group) - create(:group_member, :developer, :access_request, user: user, group: group) - end + before do + create(:group_group_link, shared_group: shared_group, shared_with_group: group) + create(:group_member, :developer, :access_request, user: user, group: group) + end - it 'does not create authorization' do - expect(mapping[shared_group_project.id]).to be_nil + it 'does not create authorization' do + expect(mapping[shared_group_project.id]).to be_nil + end end - end - context 'shared project' do - let!(:another_group) { create(:group) } - let!(:shared_project) { create(:project, namespace: another_group) } + context 'shared project' do + let!(:another_group) { create(:group) } + let!(:shared_project) { create(:project, namespace: another_group) } - before do - create(:project_group_link, group: group, project: shared_project) - create(:group_member, :developer, :access_request, user: user, group: group) - end + before do + create(:project_group_link, group: group, project: shared_project) + create(:group_member, :developer, :access_request, user: user, group: group) + end - it 'does not create authorization' do - expect(mapping[shared_project.id]).to be_nil + it 'does not create authorization' do + expect(mapping[shared_project.id]).to be_nil + end end end - end - context 'user with minimal access to group' do - let_it_be(:group) { create(:group) } - let_it_be(:user) { create(:user) } + context 'user with minimal access to group' do + let_it_be(:group) { create(:group) } + let_it_be(:user) { create(:user) } - subject(:mapping) { map_access_levels(authorizations) } + subject(:mapping) { map_access_levels(authorizations) } - context 'group membership' do - let!(:group_project) { create(:project, namespace: group) } + context 'group membership' do + let!(:group_project) { create(:project, namespace: group) } - before do - create(:group_member, :minimal_access, user: user, source: group) - end + before do + create(:group_member, :minimal_access, user: user, source: group) + end - it 'does not create authorization' do - expect(mapping[group_project.id]).to be_nil + it 'does not create authorization' do + expect(mapping[group_project.id]).to be_nil + end end - end - context 'inherited group membership' do - let!(:sub_group) { create(:group, parent: group) } - let!(:sub_group_project) { create(:project, namespace: sub_group) } + context 'inherited group membership' do + let!(:sub_group) { create(:group, parent: group) } + let!(:sub_group_project) { create(:project, namespace: sub_group) } - before do - create(:group_member, :minimal_access, user: user, source: group) - end + before do + create(:group_member, :minimal_access, user: user, source: group) + end - it 'does not create authorization' do - expect(mapping[sub_group_project.id]).to be_nil + it 'does not create authorization' do + expect(mapping[sub_group_project.id]).to be_nil + end end - end - context 'shared group' do - let!(:shared_group) { create(:group) } - let!(:shared_group_project) { create(:project, namespace: shared_group) } + context 'shared group' do + let!(:shared_group) { create(:group) } + let!(:shared_group_project) { create(:project, namespace: shared_group) } - before do - create(:group_group_link, shared_group: shared_group, shared_with_group: group) - create(:group_member, :minimal_access, user: user, source: group) - end + before do + create(:group_group_link, shared_group: shared_group, shared_with_group: group) + create(:group_member, :minimal_access, user: user, source: group) + end - it 'does not create authorization' do - expect(mapping[shared_group_project.id]).to be_nil + it 'does not create authorization' do + expect(mapping[shared_group_project.id]).to be_nil + end end - end - context 'shared project' do - let!(:another_group) { create(:group) } - let!(:shared_project) { create(:project, namespace: another_group) } + context 'shared project' do + let!(:another_group) { create(:group) } + let!(:shared_project) { create(:project, namespace: another_group) } - before do - create(:project_group_link, group: group, project: shared_project) - create(:group_member, :minimal_access, user: user, source: group) - end + before do + create(:project_group_link, group: group, project: shared_project) + create(:group_member, :minimal_access, user: user, source: group) + end - it 'does not create authorization' do - expect(mapping[shared_project.id]).to be_nil + it 'does not create authorization' do + expect(mapping[shared_project.id]).to be_nil + end end end - end - context 'with nested groups' do - let(:group) { create(:group) } - let!(:nested_group) { create(:group, parent: group) } - let!(:nested_project) { create(:project, namespace: nested_group) } - let(:user) { create(:user) } + context 'with nested groups' do + let(:group) { create(:group) } + let!(:nested_group) { create(:group, parent: group) } + let!(:nested_project) { create(:project, namespace: nested_group) } + let(:user) { create(:user) } - before do - group.add_developer(user) - end + before do + group.add_developer(user) + end - it 'includes nested groups' do - expect(authorizations.pluck(:project_id)).to include(nested_project.id) - end + it 'includes nested groups' do + expect(authorizations.pluck(:project_id)).to include(nested_project.id) + end - it 'inherits access levels when the user is not a member of a nested group' do - mapping = map_access_levels(authorizations) + it 'inherits access levels when the user is not a member of a nested group' do + mapping = map_access_levels(authorizations) - expect(mapping[nested_project.id]).to eq(Gitlab::Access::DEVELOPER) - end + expect(mapping[nested_project.id]).to eq(Gitlab::Access::DEVELOPER) + end - it 'uses the greatest access level when a user is a member of a nested group' do - nested_group.add_maintainer(user) + it 'uses the greatest access level when a user is a member of a nested group' do + nested_group.add_maintainer(user) - mapping = map_access_levels(authorizations) + mapping = map_access_levels(authorizations) - expect(mapping[nested_project.id]).to eq(Gitlab::Access::MAINTAINER) + expect(mapping[nested_project.id]).to eq(Gitlab::Access::MAINTAINER) + end end - end - context 'with shared projects' do - let_it_be(:shared_with_group) { create(:group) } - let_it_be(:user) { create(:user) } - let_it_be(:project) { create(:project, group: create(:group)) } + context 'with shared projects' do + let_it_be(:shared_with_group) { create(:group) } + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project, group: create(:group)) } - let(:mapping) { map_access_levels(authorizations) } + let(:mapping) { map_access_levels(authorizations) } - before do - create(:project_group_link, :developer, project: project, group: shared_with_group) - shared_with_group.add_maintainer(user) - end - - it 'creates proper authorizations' do - expect(mapping[project.id]).to eq(Gitlab::Access::DEVELOPER) - end - - context 'even when the `lock_memberships_to_ldap` setting has been turned ON' do before do - stub_application_setting(lock_memberships_to_ldap: true) + create(:project_group_link, :developer, project: project, group: shared_with_group) + shared_with_group.add_maintainer(user) end it 'creates proper authorizations' do expect(mapping[project.id]).to eq(Gitlab::Access::DEVELOPER) end - end - context 'when the group containing the project has forbidden group shares for any of its projects' do - before do - project.namespace.update!(share_with_group_lock: true) + context 'even when the `lock_memberships_to_ldap` setting has been turned ON' do + before do + stub_application_setting(lock_memberships_to_ldap: true) + end + + it 'creates proper authorizations' do + expect(mapping[project.id]).to eq(Gitlab::Access::DEVELOPER) + end end - it 'does not create authorizations' do - expect(mapping[project.id]).to be_nil + context 'when the group containing the project has forbidden group shares for any of its projects' do + before do + project.namespace.update!(share_with_group_lock: true) + end + + it 'does not create authorizations' do + expect(mapping[project.id]).to be_nil + end end end - end - context 'with shared groups' do - let(:parent_group_user) { create(:user) } - let(:group_user) { create(:user) } - let(:child_group_user) { create(:user) } + context 'with shared groups' do + let(:parent_group_user) { create(:user) } + let(:group_user) { create(:user) } + let(:child_group_user) { create(:user) } - let_it_be(:group_parent) { create(:group, :private) } - let_it_be(:group) { create(:group, :private, parent: group_parent) } - let_it_be(:group_child) { create(:group, :private, parent: group) } + let_it_be(:group_parent) { create(:group, :private) } + let_it_be(:group) { create(:group, :private, parent: group_parent) } + let_it_be(:group_child) { create(:group, :private, parent: group) } - let_it_be(:shared_group_parent) { create(:group, :private) } - let_it_be(:shared_group) { create(:group, :private, parent: shared_group_parent) } - let_it_be(:shared_group_child) { create(:group, :private, parent: shared_group) } + let_it_be(:shared_group_parent) { create(:group, :private) } + let_it_be(:shared_group) { create(:group, :private, parent: shared_group_parent) } + let_it_be(:shared_group_child) { create(:group, :private, parent: shared_group) } - let_it_be(:project_parent) { create(:project, group: shared_group_parent) } - let_it_be(:project) { create(:project, group: shared_group) } - let_it_be(:project_child) { create(:project, group: shared_group_child) } + let_it_be(:project_parent) { create(:project, group: shared_group_parent) } + let_it_be(:project) { create(:project, group: shared_group) } + let_it_be(:project_child) { create(:project, group: shared_group_child) } - before do - group_parent.add_owner(parent_group_user) - group.add_owner(group_user) - group_child.add_owner(child_group_user) + before do + group_parent.add_owner(parent_group_user) + group.add_owner(group_user) + group_child.add_owner(child_group_user) - create(:group_group_link, shared_group: shared_group, shared_with_group: group) - end + create(:group_group_link, shared_group: shared_group, shared_with_group: group) + end - context 'group user' do - let(:user) { group_user } + context 'group user' do + let(:user) { group_user } - it 'creates proper authorizations' do - mapping = map_access_levels(authorizations) + it 'creates proper authorizations' do + mapping = map_access_levels(authorizations) - expect(mapping[project_parent.id]).to be_nil - expect(mapping[project.id]).to eq(Gitlab::Access::DEVELOPER) - expect(mapping[project_child.id]).to eq(Gitlab::Access::DEVELOPER) + expect(mapping[project_parent.id]).to be_nil + expect(mapping[project.id]).to eq(Gitlab::Access::DEVELOPER) + expect(mapping[project_child.id]).to eq(Gitlab::Access::DEVELOPER) + end end - end - context 'with lower group access level than max access level for share' do - let(:user) { create(:user) } + context 'with lower group access level than max access level for share' do + let(:user) { create(:user) } - it 'creates proper authorizations' do - group.add_reporter(user) + it 'creates proper authorizations' do + group.add_reporter(user) - mapping = map_access_levels(authorizations) + mapping = map_access_levels(authorizations) - expect(mapping[project_parent.id]).to be_nil - expect(mapping[project.id]).to eq(Gitlab::Access::REPORTER) - expect(mapping[project_child.id]).to eq(Gitlab::Access::REPORTER) + expect(mapping[project_parent.id]).to be_nil + expect(mapping[project.id]).to eq(Gitlab::Access::REPORTER) + expect(mapping[project_child.id]).to eq(Gitlab::Access::REPORTER) + end end - end - context 'parent group user' do - let(:user) { parent_group_user } + context 'parent group user' do + let(:user) { parent_group_user } - it 'creates proper authorizations' do - mapping = map_access_levels(authorizations) + it 'creates proper authorizations' do + mapping = map_access_levels(authorizations) - expect(mapping[project_parent.id]).to be_nil - expect(mapping[project.id]).to be_nil - expect(mapping[project_child.id]).to be_nil + expect(mapping[project_parent.id]).to be_nil + expect(mapping[project.id]).to be_nil + expect(mapping[project_child.id]).to be_nil + end end - end - context 'child group user' do - let(:user) { child_group_user } + context 'child group user' do + let(:user) { child_group_user } - it 'creates proper authorizations' do - mapping = map_access_levels(authorizations) + it 'creates proper authorizations' do + mapping = map_access_levels(authorizations) - expect(mapping[project_parent.id]).to be_nil - expect(mapping[project.id]).to be_nil - expect(mapping[project_child.id]).to be_nil + expect(mapping[project_parent.id]).to be_nil + expect(mapping[project.id]).to be_nil + expect(mapping[project_child.id]).to be_nil + end end - end - context 'user without accepted access request' do - let!(:user) { create(:user) } + context 'user without accepted access request' do + let!(:user) { create(:user) } - it 'does not have access to group and its projects' do - create(:group_member, :developer, :access_request, user: user, group: group) + it 'does not have access to group and its projects' do + create(:group_member, :developer, :access_request, user: user, group: group) - mapping = map_access_levels(authorizations) + mapping = map_access_levels(authorizations) - expect(mapping[project_parent.id]).to be_nil - expect(mapping[project.id]).to be_nil - expect(mapping[project_child.id]).to be_nil + expect(mapping[project_parent.id]).to be_nil + expect(mapping[project.id]).to be_nil + expect(mapping[project_child.id]).to be_nil + end end - end - context 'unrelated project owner' do - let(:common_id) { non_existing_record_id } - let!(:group) { create(:group, id: common_id) } - let!(:unrelated_project) { create(:project, id: common_id) } - let(:user) { unrelated_project.first_owner } + context 'unrelated project owner' do + let(:common_id) { non_existing_record_id } + let!(:group) { create(:group, id: common_id) } + let!(:unrelated_project) { create(:project, id: common_id) } + let(:user) { unrelated_project.first_owner } - it 'does not have access to group and its projects' do - mapping = map_access_levels(authorizations) + it 'does not have access to group and its projects' do + mapping = map_access_levels(authorizations) - expect(mapping[project_parent.id]).to be_nil - expect(mapping[project.id]).to be_nil - expect(mapping[project_child.id]).to be_nil + expect(mapping[project_parent.id]).to be_nil + expect(mapping[project.id]).to be_nil + expect(mapping[project_child.id]).to be_nil + end end end - end - context 'with pending memberships' do - let_it_be(:group) { create(:group) } - let_it_be(:user) { create(:user) } + context 'with pending memberships' do + let_it_be(:group) { create(:group) } + let_it_be(:user) { create(:user) } - subject(:mapping) { map_access_levels(authorizations) } + subject(:mapping) { map_access_levels(authorizations) } - context 'group membership' do - let!(:group_project) { create(:project, namespace: group) } + context 'group membership' do + let!(:group_project) { create(:project, namespace: group) } - before do - create(:group_member, :developer, :awaiting, user: user, group: group) - end + before do + create(:group_member, :developer, :awaiting, user: user, group: group) + end - it 'does not create authorization' do - expect(mapping[group_project.id]).to be_nil + it 'does not create authorization' do + expect(mapping[group_project.id]).to be_nil + end end - end - context 'inherited group membership' do - let!(:sub_group) { create(:group, parent: group) } - let!(:sub_group_project) { create(:project, namespace: sub_group) } + context 'inherited group membership' do + let!(:sub_group) { create(:group, parent: group) } + let!(:sub_group_project) { create(:project, namespace: sub_group) } - before do - create(:group_member, :developer, :awaiting, user: user, group: group) - end + before do + create(:group_member, :developer, :awaiting, user: user, group: group) + end - it 'does not create authorization' do - expect(mapping[sub_group_project.id]).to be_nil + it 'does not create authorization' do + expect(mapping[sub_group_project.id]).to be_nil + end end - end - context 'project membership' do - let!(:group_project) { create(:project, namespace: group) } + context 'project membership' do + let!(:group_project) { create(:project, namespace: group) } - before do - create(:project_member, :developer, :awaiting, user: user, project: group_project) - end + before do + create(:project_member, :developer, :awaiting, user: user, project: group_project) + end - it 'does not create authorization' do - expect(mapping[group_project.id]).to be_nil + it 'does not create authorization' do + expect(mapping[group_project.id]).to be_nil + end end - end - context 'shared group' do - let!(:shared_group) { create(:group) } - let!(:shared_group_project) { create(:project, namespace: shared_group) } + context 'shared group' do + let!(:shared_group) { create(:group) } + let!(:shared_group_project) { create(:project, namespace: shared_group) } - before do - create(:group_group_link, shared_group: shared_group, shared_with_group: group) - create(:group_member, :developer, :awaiting, user: user, group: group) - end + before do + create(:group_group_link, shared_group: shared_group, shared_with_group: group) + create(:group_member, :developer, :awaiting, user: user, group: group) + end - it 'does not create authorization' do - expect(mapping[shared_group_project.id]).to be_nil + it 'does not create authorization' do + expect(mapping[shared_group_project.id]).to be_nil + end end - end - context 'shared project' do - let!(:another_group) { create(:group) } - let!(:shared_project) { create(:project, namespace: another_group) } + context 'shared project' do + let!(:another_group) { create(:group) } + let!(:shared_project) { create(:project, namespace: another_group) } - before do - create(:project_group_link, group: group, project: shared_project) - create(:group_member, :developer, :awaiting, user: user, group: group) - end + before do + create(:project_group_link, group: group, project: shared_project) + create(:group_member, :developer, :awaiting, user: user, group: group) + end - it 'does not create authorization' do - expect(mapping[shared_project.id]).to be_nil + it 'does not create authorization' do + expect(mapping[shared_project.id]).to be_nil + end end end end + + context 'when feature_flag linear_project_authorization_is disabled' do + before do + stub_feature_flags(linear_project_authorization: false) + end + + it_behaves_like 'project authorizations' + end + + it_behaves_like 'project authorizations' end |