diff --git a/app/finders/group_members_finder.rb b/app/finders/group_members_finder.rb index ce0d52ad97a8b502fe7831e75a6f9a0deda0549f..09283f061c088a303e1506253935c18da7ef4862 100644 --- a/app/finders/group_members_finder.rb +++ b/app/finders/group_members_finder.rb @@ -17,9 +17,8 @@ def initialize(group, user = nil, params: {}) @params = params end - # rubocop: disable CodeReuse/ActiveRecord def execute(include_relations: [:inherited, :direct]) - group_members = group.members + group_members = group_members_list relations = [] return group_members if include_relations == [:direct] @@ -27,17 +26,13 @@ def execute(include_relations: [:inherited, :direct]) relations << group_members if include_relations.include?(:direct) if include_relations.include?(:inherited) && group.parent - parents_members = GroupMember.non_request.non_minimal_access - .where(source_id: group.ancestors.select(:id)) - .where.not(user_id: group.users.select(:id)) + parents_members = relation_group_members(group.ancestors) relations << parents_members end if include_relations.include?(:descendants) - descendant_members = GroupMember.non_request.non_minimal_access - .where(source_id: group.descendants.select(:id)) - .where.not(user_id: group.users.select(:id)) + descendant_members = relation_group_members(group.descendants) relations << descendant_members end @@ -47,7 +42,6 @@ def execute(include_relations: [:inherited, :direct]) members = find_union(relations, GroupMember) filter_members(members) end - # rubocop: enable CodeReuse/ActiveRecord private @@ -67,6 +61,22 @@ def filter_members(members) def can_manage_members Ability.allowed?(user, :admin_group_member, group) end + + def group_members_list + group.members + end + + def relation_group_members(relation) + all_group_members(relation).non_minimal_access + end + + # rubocop: disable CodeReuse/ActiveRecord + def all_group_members(relation) + GroupMember.non_request + .where(source_id: relation.select(:id)) + .where.not(user_id: group.users.select(:id)) + end + # rubocop: enable CodeReuse/ActiveRecord end GroupMembersFinder.prepend_if_ee('EE::GroupMembersFinder') diff --git a/app/helpers/groups/group_members_helper.rb b/app/helpers/groups/group_members_helper.rb index dcff2be34daca4903172e2f3b5f26de7c2324b99..64a91ef7dd0393939fceba23079cb4f2a3a13830 100644 --- a/app/helpers/groups/group_members_helper.rb +++ b/app/helpers/groups/group_members_helper.rb @@ -10,7 +10,7 @@ def group_member_select_options end def render_invite_member_for_group(group, default_access_level) - render 'shared/members/invite_member', submit_url: group_group_members_path(group), access_levels: GroupMember.access_level_roles, default_access_level: default_access_level + render 'shared/members/invite_member', submit_url: group_group_members_path(group), access_levels: group.access_level_roles, default_access_level: default_access_level end def linked_groups_data_json(group_links) diff --git a/app/models/group.rb b/app/models/group.rb index 01438ebb3a854b0056b3c66b7e447c3ce2d20303..ce4afcfbd06e47a8c5f30d33d1d8b5e2009ef15b 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -348,6 +348,7 @@ def members_with_parents end group_hierarchy_members = GroupMember.active_without_invites_and_requests + .non_minimal_access .where(source_id: source_ids) GroupMember.from_union([group_hierarchy_members, @@ -574,6 +575,14 @@ def default_owner owners.first || parent&.default_owner || owner end + def access_level_roles + GroupMember.access_level_roles + end + + def access_level_values + access_level_roles.values + end + private def update_two_factor_requirement diff --git a/app/models/user.rb b/app/models/user.rb index 9b8fe4881adf99fafb81e872fed7d7645d857936..c90743983c2f101a31a51dfd9fcf352b3e623962 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -134,6 +134,8 @@ def update_tracked_fields!(request) -> { where(members: { access_level: [Gitlab::Access::REPORTER, Gitlab::Access::DEVELOPER, Gitlab::Access::MAINTAINER, Gitlab::Access::OWNER] }) }, through: :group_members, source: :group + has_many :minimal_access_group_members, -> { where(access_level: [Gitlab::Access::MINIMAL_ACCESS]) }, source: 'GroupMember', class_name: 'GroupMember' + has_many :minimal_access_groups, through: :minimal_access_group_members, source: :group # Projects has_many :groups_projects, through: :groups, source: :projects diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml index 6c2c0b3a488feb596b2bdaba7ea713f13aa5b8f1..dc43b45195e97c5bea4793646feebf4bc7978612 100644 --- a/app/views/admin/groups/show.html.haml +++ b/app/views/admin/groups/show.html.haml @@ -113,7 +113,7 @@ %div = users_select_tag(:user_ids, multiple: true, email_user: true, skip_ldap: @group.ldap_synced?, scope: :all) .gl-mt-3 - = select_tag :access_level, options_for_select(GroupMember.access_level_roles), class: "project-access-select select2" + = select_tag :access_level, options_for_select(@group.access_level_roles), class: "project-access-select select2" %hr = button_tag _('Add users to group'), class: "btn btn-success" = render 'shared/members/requests', membership_source: @group, requesters: @requesters, force_mobile_view: true diff --git a/changelogs/unreleased/220203-gitlab-com-sso-create-no-access-role-fe-changes.yml b/changelogs/unreleased/220203-gitlab-com-sso-create-no-access-role-fe-changes.yml new file mode 100644 index 0000000000000000000000000000000000000000..d8b42d0bebc66fad6b61040d9b3de40a357263a6 --- /dev/null +++ b/changelogs/unreleased/220203-gitlab-com-sso-create-no-access-role-fe-changes.yml @@ -0,0 +1,5 @@ +--- +title: Add No Access Role for top group members +merge_request: 40942 +author: +type: added diff --git a/config/feature_flags/licensed/minimal_access_role.yml b/config/feature_flags/licensed/minimal_access_role.yml new file mode 100644 index 0000000000000000000000000000000000000000..ca27b86d35ffb3cfe4f6c94c8018e4450fce0300 --- /dev/null +++ b/config/feature_flags/licensed/minimal_access_role.yml @@ -0,0 +1,7 @@ +--- +name: minimal_access_role +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40942 +rollout_issue_url: +group: group::access +type: licensed +default_enabled: true diff --git a/ee/app/controllers/ee/admin/groups_controller.rb b/ee/app/controllers/ee/admin/groups_controller.rb index f49254d80384f4cf17766fb163c5a3f8b245eddb..ae80521e8006bf7ec769a2644b4eb77ade5799fc 100644 --- a/ee/app/controllers/ee/admin/groups_controller.rb +++ b/ee/app/controllers/ee/admin/groups_controller.rb @@ -4,6 +4,8 @@ module EE module Admin module GroupsController + extend ::Gitlab::Utils::Override + def reset_runners_minutes group @@ -25,6 +27,13 @@ def allowed_group_params ] end + override :group_members + def group_members + return @group.all_group_members if @group.minimal_access_role_allowed? + + @group.members + end + def groups super.with_deletion_schedule end diff --git a/ee/app/finders/ee/group_members_finder.rb b/ee/app/finders/ee/group_members_finder.rb index 951963a745404581c7946bbd5fa8049de29ef65a..43211cae9f15c5ec000f22b566e6d4bc91aae38d 100644 --- a/ee/app/finders/ee/group_members_finder.rb +++ b/ee/app/finders/ee/group_members_finder.rb @@ -2,6 +2,7 @@ module EE::GroupMembersFinder extend ActiveSupport::Concern + extend ::Gitlab::Utils::Override prepended do attr_reader :group @@ -12,4 +13,18 @@ def not_managed group.group_members.non_owners.joins(:user).merge(User.not_managed(group: group)) end # rubocop: enable CodeReuse/ActiveRecord + + override :group_members_list + def group_members_list + return group.all_group_members if group.minimal_access_role_allowed? + + super + end + + override :relation_group_members + def relation_group_members(relation) + return all_group_members(relation) if group.minimal_access_role_allowed? + + super + end end diff --git a/ee/app/models/ee/group.rb b/ee/app/models/ee/group.rb index 8d705e5abc23556ca50de5247a141d98885e158c..20ba5f21466593e674fb203893a687682717cb64 100644 --- a/ee/app/models/ee/group.rb +++ b/ee/app/models/ee/group.rb @@ -408,6 +408,21 @@ def minimal_member_access_level minimal_access_role_allowed? ? ::Gitlab::Access::MINIMAL_ACCESS : ::Gitlab::Access::GUEST end + override :access_level_roles + def access_level_roles + levels = ::GroupMember.access_level_roles + return levels unless minimal_access_role_allowed? + + levels.merge(::Gitlab::Access::MINIMAL_ACCESS_HASH) + end + + override :users_count + def users_count + return all_group_members.count unless minimal_access_role_allowed? + + members.count + end + private def custom_project_templates_group_allowed diff --git a/ee/app/models/ee/group_member.rb b/ee/app/models/ee/group_member.rb index b87296b9d1f2a53926378db290753f2ff4dd5294..956f14dcd6cc10ce4d1c3acd722c54e8229548da 100644 --- a/ee/app/models/ee/group_member.rb +++ b/ee/app/models/ee/group_member.rb @@ -3,9 +3,9 @@ module EE module GroupMember extend ActiveSupport::Concern + extend ::Gitlab::Utils::Override prepended do - extend ::Gitlab::Utils::Override include UsageStatistics validate :sso_enforcement, if: :group @@ -79,6 +79,14 @@ def group_saml_identity private + override :access_level_inclusion + def access_level_inclusion + levels = source.access_level_values + return if access_level.in?(levels) + + errors.add(:access_level, "is not included in the list") + end + def email_does_not_match_any_allowed_domains(email) _("email '%{email}' does not match the allowed domains of %{email_domains}" % { email: email, email_domains: ::Gitlab::Utils.to_exclusive_sentence(group_allowed_email_domains.map(&:domain)) }) diff --git a/ee/app/models/ee/user.rb b/ee/app/models/ee/user.rb index b1a78a9bd7aa751f9fec99e43cf1518def47a72d..77cb690a21a5f82d5bd5405d3543a629eb036b0e 100644 --- a/ee/app/models/ee/user.rb +++ b/ee/app/models/ee/user.rb @@ -44,6 +44,9 @@ module User has_many :approvals, dependent: :destroy # rubocop: disable Cop/ActiveRecordDependent has_many :approvers, dependent: :destroy # rubocop: disable Cop/ActiveRecordDependent + has_many :minimal_access_group_members, -> { where(access_level: [::Gitlab::Access::MINIMAL_ACCESS]) }, source: 'GroupMember', class_name: 'GroupMember' + has_many :minimal_access_groups, through: :minimal_access_group_members, source: :group + has_many :users_ops_dashboard_projects has_many :ops_dashboard_projects, through: :users_ops_dashboard_projects, source: :project has_many :users_security_dashboard_projects @@ -367,6 +370,18 @@ def owns_upgradeable_namespace? owns_paid_namespace?(plans: [::Plan::BRONZE, ::Plan::SILVER]) end + # Returns the groups a user has access to, either through a membership or a project authorization + override :authorized_groups + def authorized_groups + ::Group.unscoped do + ::Group.from_union([ + groups, + available_minimal_access_groups, + authorized_projects.joins(:namespace).select('namespaces.*') + ]) + end + end + protected override :password_required? @@ -397,5 +412,12 @@ def paid_in_current_license? highest_role > ::Gitlab::Access::GUEST end + + def available_minimal_access_groups + return ::Group.none unless License.feature_available?(:minimal_access_role) + return minimal_access_groups unless ::Gitlab::CurrentSettings.should_check_namespace_plan? + + minimal_access_groups.with_feature_available_in_plan(:minimal_access_role) + end end end diff --git a/ee/app/models/saml_provider.rb b/ee/app/models/saml_provider.rb index ee995c43cc7d2d9164653d922aa3f8fd4ee9b7aa..8b312a66d77804d7e250d186e08110084b5aeb32 100644 --- a/ee/app/models/saml_provider.rb +++ b/ee/app/models/saml_provider.rb @@ -9,7 +9,8 @@ class SamlProvider < ApplicationRecord validates :group, presence: true, top_level_group: true validates :sso_url, presence: true, addressable_url: { schemes: %w(https), ascii_only: true } validates :certificate_fingerprint, presence: true, certificate_fingerprint: true - validates :default_membership_role, presence: true, inclusion: { in: Gitlab::Access.values } + validates :default_membership_role, presence: true + validate :access_level_inclusion after_initialize :set_defaults, if: :new_record? @@ -82,6 +83,15 @@ def to_h private + def access_level_inclusion + return errors.add(:default_membership_role, "is dependent on a group") unless group + + levels = group.access_level_values + return if default_membership_role.in?(levels) + + errors.add(:default_membership_role, "is not included in the list") + end + def set_defaults self.enabled = true end diff --git a/ee/app/presenters/ee/group_member_presenter.rb b/ee/app/presenters/ee/group_member_presenter.rb index 3c8524691e0b1e99f222bfb0ac344c04ddbda5f5..668251451bad800cd7316f595f67aa955f93b2eb 100644 --- a/ee/app/presenters/ee/group_member_presenter.rb +++ b/ee/app/presenters/ee/group_member_presenter.rb @@ -2,6 +2,8 @@ module EE module GroupMemberPresenter + extend ::Gitlab::Utils::Override + def group_sso? member.user.group_sso?(source) end @@ -10,6 +12,11 @@ def group_managed_account? member.user.group_managed_account? end + override :access_level_roles + def access_level_roles + member.source.access_level_roles + end + private def override_member_permission diff --git a/ee/app/views/groups/saml_providers/_form.html.haml b/ee/app/views/groups/saml_providers/_form.html.haml index 44500796318631c1607cf6d07458a1133ec99fca..2bff553398df5d4571a7faedac2735628fa1b113 100644 --- a/ee/app/views/groups/saml_providers/_form.html.haml +++ b/ee/app/views/groups/saml_providers/_form.html.haml @@ -53,7 +53,7 @@ .well-segment.borderless.gl-mb-3.col-12.col-lg-9.gl-p-0 = f.label :default_membership_role, class: 'label-bold' do = s_('GroupSAML|Default membership role') - = f.select :default_membership_role, options_for_select(::Gitlab::Access.options, saml_provider.default_membership_role), {}, class: 'form-control', data: { qa_selector: 'default_membership_role_dropdown' } + = f.select :default_membership_role, options_for_select(group.access_level_roles, saml_provider.default_membership_role), {}, class: 'form-control', data: { qa_selector: 'default_membership_role_dropdown' } .form-text.text-muted = s_('GroupSAML|This will be set as the access level of users added to the group.') diff --git a/ee/lib/ee/gitlab/access.rb b/ee/lib/ee/gitlab/access.rb index d65f98921f8317ea6d09573ef13c7970380ebec5..2e48df1c5816a221e9bd057bb14293cf75617692 100644 --- a/ee/lib/ee/gitlab/access.rb +++ b/ee/lib/ee/gitlab/access.rb @@ -10,16 +10,26 @@ module Gitlab module Access extend ActiveSupport::Concern ADMIN = 60 + MINIMAL_ACCESS_HASH = { "Minimal Access" => ::Gitlab::Access::MINIMAL_ACCESS }.freeze class_methods do + extend ::Gitlab::Utils::Override + def vulnerability_access_levels @vulnerability_access_levels ||= options_with_owner.except('Guest') end def options_with_minimal_access - options_with_owner.merge( - "Minimal Access" => ::Gitlab::Access::MINIMAL_ACCESS - ) + options_with_owner.merge(MINIMAL_ACCESS_HASH) + end + + def values_with_minimal_access + options_with_minimal_access.values + end + + override :human_access + def human_access(access) + options_with_minimal_access.key(access) end end end diff --git a/ee/spec/finders/ee/group_members_finder_spec.rb b/ee/spec/finders/ee/group_members_finder_spec.rb index c388e4eafd4f8b43c7d607c892fafec4be82d668..7c87953582d4ddd83c7c1460889ae436b238775d 100644 --- a/ee/spec/finders/ee/group_members_finder_spec.rb +++ b/ee/spec/finders/ee/group_members_finder_spec.rb @@ -19,4 +19,35 @@ expect(finder.not_managed).to eq([group_member_membership]) end end + + describe '#execute' do + let_it_be(:group_minimal_access_membership) do + create(:group_member, :minimal_access, source: group, user: create(:user)) + end + + context 'when group does not allow minimal access members' do + before do + stub_licensed_features(minimal_access_role: false) + end + + it 'returns only members with full access' do + result = finder.execute(include_relations: [:direct, :descendants]) + + expect(result.to_a).to match_array([group_owner_membership, group_member_membership, dedicated_member_account_membership]) + end + end + + context 'when group allows minimal access members' do + before do + group.clear_memoization(:feature_available) + stub_licensed_features(minimal_access_role: true) + end + + it 'also returns members with minimal access' do + result = finder.execute(include_relations: [:direct, :descendants]) + + expect(result.to_a).to match_array([group_owner_membership, group_member_membership, dedicated_member_account_membership, group_minimal_access_membership]) + end + end + end end diff --git a/ee/spec/models/group_member_spec.rb b/ee/spec/models/group_member_spec.rb index 71413c82f21619c9b32894ef74e4c5a224f2baba..ce9a916f8ac0c562cc0e72afa16d075ef73512bc 100644 --- a/ee/spec/models/group_member_spec.rb +++ b/ee/spec/models/group_member_spec.rb @@ -107,6 +107,50 @@ end end end + + describe 'access level inclusion' do + let(:group) { create(:group) } + + context 'when minimal access user feature switched on' do + before do + stub_licensed_features(minimal_access_role: true) + end + + it 'users can have access levels from minimal access to owner' do + expect(build(:group_member, group: group, user: create(:user), access_level: ::Gitlab::Access::NO_ACCESS)).to be_invalid + expect(build(:group_member, group: group, user: create(:user), access_level: ::Gitlab::Access::MINIMAL_ACCESS)).to be_valid + expect(build(:group_member, group: group, user: create(:user), access_level: ::Gitlab::Access::GUEST)).to be_valid + expect(build(:group_member, group: group, user: create(:user), access_level: ::Gitlab::Access::REPORTER)).to be_valid + expect(build(:group_member, group: group, user: create(:user), access_level: ::Gitlab::Access::DEVELOPER)).to be_valid + expect(build(:group_member, group: group, user: create(:user), access_level: ::Gitlab::Access::MAINTAINER)).to be_valid + expect(build(:group_member, group: group, user: create(:user), access_level: ::Gitlab::Access::OWNER)).to be_valid + end + + context 'when group is a subgroup' do + let(:subgroup) { create(:group, parent: group) } + + it 'users cannot have minimal access level' do + expect(build(:group_member, group: subgroup, user: create(:user), access_level: ::Gitlab::Access::MINIMAL_ACCESS)).to be_invalid + end + end + end + + context 'when minimal access user feature switched off' do + before do + stub_licensed_features(minimal_access_role: false) + end + + it 'users can have access levels from guest to owner' do + expect(build(:group_member, group: group, user: create(:user), access_level: ::Gitlab::Access::NO_ACCESS)).to be_invalid + expect(build(:group_member, group: group, user: create(:user), access_level: ::Gitlab::Access::MINIMAL_ACCESS)).to be_invalid + expect(build(:group_member, group: group, user: create(:user), access_level: ::Gitlab::Access::GUEST)).to be_valid + expect(build(:group_member, group: group, user: create(:user), access_level: ::Gitlab::Access::REPORTER)).to be_valid + expect(build(:group_member, group: group, user: create(:user), access_level: ::Gitlab::Access::DEVELOPER)).to be_valid + expect(build(:group_member, group: group, user: create(:user), access_level: ::Gitlab::Access::MAINTAINER)).to be_valid + expect(build(:group_member, group: group, user: create(:user), access_level: ::Gitlab::Access::OWNER)).to be_valid + end + end + end end describe 'scopes' do diff --git a/ee/spec/models/group_spec.rb b/ee/spec/models/group_spec.rb index c3829d60947a1739b19380ceb92bad342047ce05..e727c481e9641f55b857ac9657ea4eb7e07a9246 100644 --- a/ee/spec/models/group_spec.rb +++ b/ee/spec/models/group_spec.rb @@ -705,7 +705,7 @@ context 'with `minimal_access_role` not licensed' do before do stub_licensed_features(minimal_access_role: false) - create(:group_member, :minimal_access, user: user, group: group) + create(:group_member, :minimal_access, user: user, source: group) end it { is_expected.to be_falsey } diff --git a/ee/spec/models/saml_provider_spec.rb b/ee/spec/models/saml_provider_spec.rb index a54db964030f19071e076c15af6e219a1b4341bf..a52adc30bfa9a268bf1d2039c9c53b7974c70ee8 100644 --- a/ee/spec/models/saml_provider_spec.rb +++ b/ee/spec/models/saml_provider_spec.rb @@ -62,6 +62,42 @@ expect(subject).to allow_value(group).for(:group) expect(subject).not_to allow_value(nested_group).for(:group) end + + describe 'access level inclusion' do + let(:group) { create(:group) } + + context 'when minimal access user feature is switched on' do + before do + stub_licensed_features(minimal_access_role: true) + end + + it 'default membership role can have access levels from minimal access to owner' do + expect(build(:saml_provider, group: group, default_membership_role: ::Gitlab::Access::NO_ACCESS)).to be_invalid + expect(build(:saml_provider, group: group, default_membership_role: ::Gitlab::Access::MINIMAL_ACCESS)).to be_valid + expect(build(:saml_provider, group: group, default_membership_role: ::Gitlab::Access::GUEST)).to be_valid + expect(build(:saml_provider, group: group, default_membership_role: ::Gitlab::Access::REPORTER)).to be_valid + expect(build(:saml_provider, group: group, default_membership_role: ::Gitlab::Access::DEVELOPER)).to be_valid + expect(build(:saml_provider, group: group, default_membership_role: ::Gitlab::Access::MAINTAINER)).to be_valid + expect(build(:saml_provider, group: group, default_membership_role: ::Gitlab::Access::OWNER)).to be_valid + end + end + + context 'when minimal access user feature switched off' do + before do + stub_licensed_features(minimal_access_role: false) + end + + it 'default membership role can have access levels from guest to owner' do + expect(build(:saml_provider, group: group, default_membership_role: ::Gitlab::Access::NO_ACCESS)).to be_invalid + expect(build(:saml_provider, group: group, default_membership_role: ::Gitlab::Access::MINIMAL_ACCESS)).to be_invalid + expect(build(:saml_provider, group: group, default_membership_role: ::Gitlab::Access::GUEST)).to be_valid + expect(build(:saml_provider, group: group, default_membership_role: ::Gitlab::Access::REPORTER)).to be_valid + expect(build(:saml_provider, group: group, default_membership_role: ::Gitlab::Access::DEVELOPER)).to be_valid + expect(build(:saml_provider, group: group, default_membership_role: ::Gitlab::Access::MAINTAINER)).to be_valid + expect(build(:saml_provider, group: group, default_membership_role: ::Gitlab::Access::OWNER)).to be_valid + end + end + end end describe 'Default values' do diff --git a/ee/spec/models/user_spec.rb b/ee/spec/models/user_spec.rb index 092d51541f03699c28958021e06158bf74c1ee45..1d84b09e6c4c1b019ef096d809b1a73f8197d9bb 100644 --- a/ee/spec/models/user_spec.rb +++ b/ee/spec/models/user_spec.rb @@ -1117,6 +1117,56 @@ end end + describe '#authorized_groups' do + let_it_be(:user) { create(:user) } + let_it_be(:private_group) { create(:group) } + let_it_be(:child_group) { create(:group, parent: private_group) } + let_it_be(:minimal_access_group) { create(:group) } + + let_it_be(:project_group) { create(:group) } + let_it_be(:project) { create(:project, group: project_group) } + + before do + private_group.add_user(user, Gitlab::Access::MAINTAINER) + project.add_maintainer(user) + create(:group_member, :minimal_access, user: user, source: minimal_access_group) + end + + subject { user.authorized_groups } + + context 'with minimal access role feature unavailable' do + it { is_expected.to contain_exactly private_group, project_group } + end + + context 'with minimal access feature available' do + before do + stub_licensed_features(minimal_access_role: true) + end + + context 'feature turned on for all groups' do + before do + allow(Gitlab::CurrentSettings) + .to receive(:should_check_namespace_plan?) + .and_return(false) + end + + it { is_expected.to contain_exactly private_group, project_group, minimal_access_group } + end + + context 'feature available for specific groups only' do + before do + allow(Gitlab::CurrentSettings) + .to receive(:should_check_namespace_plan?) + .and_return(true) + create(:gitlab_subscription, :gold, namespace: minimal_access_group) + create(:group_member, :minimal_access, user: user, source: create(:group)) + end + + it { is_expected.to contain_exactly private_group, project_group, minimal_access_group } + end + end + end + describe '#active_for_authentication?' do subject { user.active_for_authentication? } diff --git a/ee/spec/presenters/group_member_presenter_spec.rb b/ee/spec/presenters/group_member_presenter_spec.rb index 68b82be057e4e648f9a598f3084a9580a1f8a95b..891df9d445714d005d5f1c41a97ef680b90ef70e 100644 --- a/ee/spec/presenters/group_member_presenter_spec.rb +++ b/ee/spec/presenters/group_member_presenter_spec.rb @@ -60,4 +60,26 @@ it { expect(presenter.can_update?).to eq(false) } end end + + describe '#valid_level_roles?' do + context 'with minimal access role feature switched on' do + before do + allow(group_member).to receive(:highest_group_member) + allow(group_member).to receive_message_chain(:class, :access_level_roles).and_return(::Gitlab::Access.options_with_owner) + expect(group).to receive(:access_level_roles).and_return(::Gitlab::Access.options_with_minimal_access) + end + + it { expect(presenter.valid_level_roles).to eq(::Gitlab::Access.options_with_minimal_access) } + end + + context 'with minimal access role feature switched off' do + it_behaves_like '#valid_level_roles', :group do + let(:expected_roles) { { 'Developer' => 30, 'Maintainer' => 40, 'Owner' => 50, 'Reporter' => 20 } } + + before do + entity.parent = group + end + end + end + end end diff --git a/spec/support/shared_contexts/cache_allowed_users_in_namespace_shared_context.rb b/spec/support/shared_contexts/cache_allowed_users_in_namespace_shared_context.rb index e3c1d0afa535051f4ab013d3155bc8931326d282..bfb719fd8405936a772e4c85d4a7aaef2735e839 100644 --- a/spec/support/shared_contexts/cache_allowed_users_in_namespace_shared_context.rb +++ b/spec/support/shared_contexts/cache_allowed_users_in_namespace_shared_context.rb @@ -25,7 +25,7 @@ expect(described_class.l1_cache_backend).to receive(:fetch).and_call_original expect(described_class.l2_cache_backend).to receive(:fetch).and_call_original expect(subject).to be_truthy - end.not_to exceed_query_limit(2) + end.not_to exceed_query_limit(3) end end end