diff options
Diffstat (limited to 'spec/lib/gitlab/project_authorizations_spec.rb')
-rw-r--r-- | spec/lib/gitlab/project_authorizations_spec.rb | 599 |
1 files changed, 271 insertions, 328 deletions
diff --git a/spec/lib/gitlab/project_authorizations_spec.rb b/spec/lib/gitlab/project_authorizations_spec.rb index f3dcdfe2a9d..c4cb88cf3f2 100644 --- a/spec/lib/gitlab/project_authorizations_spec.rb +++ b/spec/lib/gitlab/project_authorizations_spec.rb @@ -15,465 +15,408 @@ RSpec.describe Gitlab::ProjectAuthorizations, feature_category: :system_access d service.calculate end - # 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 } + 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) - end + 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 - 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 - end + it 'does not create authorization' do + expect(mapping[group_project.id]).to be_nil 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 - end + it 'does not create authorization' do + expect(mapping[sub_group_project.id]).to be_nil 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 - end + it 'does not create authorization' do + expect(mapping[group_project.id]).to be_nil 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 - end + it 'does not create authorization' do + expect(mapping[shared_group_project.id]).to be_nil 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 - end + it 'does not create authorization' do + expect(mapping[shared_project.id]).to be_nil end end + end - 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) } + context 'user with minimal access to group' do + let_it_be(:group) { create(:group) } + let_it_be(:user) { create(:user) } - context 'group membership' do - let!(:group_project) { create(:project, namespace: group) } + subject(:mapping) { map_access_levels(authorizations) } - before do - create(:group_member, :minimal_access, user: user, source: group) - end + context 'group membership' do + let!(:group_project) { create(:project, namespace: group) } - it 'does not create authorization' do - expect(mapping[group_project.id]).to be_nil - end + before do + create(:group_member, :minimal_access, user: user, source: group) end - 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 - - it 'does not create authorization' do - expect(mapping[sub_group_project.id]).to be_nil - end + it 'does not create authorization' do + expect(mapping[group_project.id]).to be_nil end + end - context 'shared group' do - let!(:shared_group) { create(:group) } - let!(:shared_group_project) { create(:project, namespace: shared_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_group_link, shared_group: shared_group, shared_with_group: group) - 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[shared_group_project.id]).to be_nil - end + it 'does not create authorization' do + expect(mapping[sub_group_project.id]).to be_nil end + end - context 'shared project' do - let!(:another_group) { create(:group) } - let!(:shared_project) { create(:project, namespace: another_group) } + context 'shared group' do + let!(:shared_group) { create(:group) } + let!(:shared_group_project) { create(:project, namespace: shared_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(: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_project.id]).to be_nil - end + it 'does not create authorization' do + expect(mapping[shared_group_project.id]).to be_nil 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 'shared project' do + let!(:another_group) { create(:group) } + let!(:shared_project) { create(:project, namespace: another_group) } before do - group.add_developer(user) + create(:project_group_link, group: group, project: shared_project) + create(:group_member, :minimal_access, user: user, source: group) end - it 'includes nested groups' do - expect(authorizations.pluck(:project_id)).to include(nested_project.id) + it 'does not create authorization' do + expect(mapping[shared_project.id]).to be_nil end + end + end - it 'inherits access levels when the user is not a member of a nested group' do - mapping = map_access_levels(authorizations) + 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) } - expect(mapping[nested_project.id]).to eq(Gitlab::Access::DEVELOPER) - end + before do + group.add_developer(user) + end - it 'uses the greatest access level when a user is a member of a nested group' do - nested_group.add_maintainer(user) + it 'includes nested groups' do + expect(authorizations.pluck(:project_id)).to include(nested_project.id) + end - 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::MAINTAINER) - 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) + + mapping = map_access_levels(authorizations) + + expect(mapping[nested_project.id]).to eq(Gitlab::Access::MAINTAINER) 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 - create(:project_group_link, :developer, project: project, group: shared_with_group) - shared_with_group.add_maintainer(user) + 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 - 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 + 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 - 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 + it 'does not create authorizations' do + expect(mapping[project.id]).to be_nil 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) - end + 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 - 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) - end + 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 - 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 - end + 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 - 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 - end + 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 - 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 - end + 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 - 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 - end + 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 'with pending memberships' do - let_it_be(:group) { create(:group) } - let_it_be(:user) { create(:user) } - - subject(:mapping) { map_access_levels(authorizations) } + context 'with pending memberships' do + let_it_be(:group) { create(:group) } + let_it_be(:user) { create(:user) } - context 'group membership' do - let!(:group_project) { create(:project, namespace: group) } + subject(:mapping) { map_access_levels(authorizations) } - before do - create(:group_member, :developer, :awaiting, user: user, group: group) - end + context 'group membership' do + let!(:group_project) { create(:project, namespace: group) } - it 'does not create authorization' do - expect(mapping[group_project.id]).to be_nil - end + before do + create(:group_member, :developer, :awaiting, user: user, group: group) end - 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 - - it 'does not create authorization' do - expect(mapping[sub_group_project.id]).to be_nil - end + it 'does not create authorization' do + expect(mapping[group_project.id]).to be_nil end + end - context 'project membership' do - let!(:group_project) { create(:project, namespace: group) } - - before do - create(:project_member, :developer, :awaiting, user: user, project: group_project) - end + context 'inherited group membership' do + let!(:sub_group) { create(:group, parent: group) } + let!(:sub_group_project) { create(:project, namespace: sub_group) } - it 'does not create authorization' do - expect(mapping[group_project.id]).to be_nil - end + before do + create(:group_member, :developer, :awaiting, user: user, group: group) end - 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 - - it 'does not create authorization' do - expect(mapping[shared_group_project.id]).to be_nil - end + it 'does not create authorization' do + expect(mapping[sub_group_project.id]).to be_nil end + end - 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 + context 'project membership' do + let!(:group_project) { create(:project, namespace: group) } - it 'does not create authorization' do - expect(mapping[shared_project.id]).to be_nil - end + before do + create(:project_member, :developer, :awaiting, user: user, project: group_project) end - end - end - - context 'it compares values for correctness' do - let_it_be(:user) { create(:user) } - context 'when values returned by the queries are the same' do - it 'logs a message indicating that the values are the same' do - expect(Gitlab::AppJsonLogger).to receive(:info).with(event: 'linear_authorized_projects_check', - user_id: user.id, - matching_results: true) - service.calculate + it 'does not create authorization' do + expect(mapping[group_project.id]).to be_nil end end - context 'when values returned by queries are diffrent' do + context 'shared group' do + let!(:shared_group) { create(:group) } + let!(:shared_group_project) { create(:project, namespace: shared_group) } + before do - create(:project_authorization) - allow(service).to receive(:calculate_with_linear_query).and_return(ProjectAuthorization.all) + create(:group_group_link, shared_group: shared_group, shared_with_group: group) + create(:group_member, :developer, :awaiting, user: user, group: group) end - it 'logs a message indicating that the values are different' do - expect(Gitlab::AppJsonLogger).to receive(:warn).with(event: 'linear_authorized_projects_check', - user_id: user.id, - matching_results: false) - service.calculate + it 'does not create authorization' do + expect(mapping[shared_group_project.id]).to be_nil 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 - context 'when feature_flag compare_project_authorization_linear_cte is disabled' do - before do - stub_feature_flags(compare_project_authorization_linear_cte: false) - end + context 'shared project' do + let!(:another_group) { create(:group) } + let!(:shared_project) { create(:project, namespace: another_group) } - it_behaves_like 'project authorizations' - end + before do + create(:project_group_link, group: group, project: shared_project) + create(:group_member, :developer, :awaiting, user: user, group: group) + end - context 'when feature_flag linear_project_authorization and compare_project_authorization_linear_cte are disabled' do - before do - stub_feature_flags(linear_project_authorization: false) - stub_feature_flags(compare_project_authorization_linear_cte: false) + it 'does not create authorization' do + expect(mapping[shared_project.id]).to be_nil + end end - - it_behaves_like 'project authorizations' end - - it_behaves_like 'project authorizations' end |