Skip to content
Snippets Groups Projects
Commit 4eeb6b0d authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 8cc5f279
No related branches found
No related tags found
No related merge requests found
Showing
with 113 additions and 23 deletions
Loading
Loading
@@ -144,4 +144,15 @@ module MembershipActions
end
end
end
def requested_relations
case params[:with_inherited_permissions].presence
when 'exclude'
[:direct]
when 'only'
[:inherited]
else
[:inherited, :direct]
end
end
end
Loading
Loading
@@ -24,8 +24,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
 
@sort = params[:sort].presence || sort_value_name
@project = @group.projects.find(params[:project_id]) if params[:project_id]
@members = GroupMembersFinder.new(@group).execute
@members = find_members
 
if can_manage_members
@invited_members = @members.invite
Loading
Loading
@@ -52,6 +51,12 @@ class Groups::GroupMembersController < Groups::ApplicationController
 
# MembershipActions concern
alias_method :membershipable, :group
private
def find_members
GroupMembersFinder.new(@group).execute(include_relations: requested_relations)
end
end
 
Groups::GroupMembersController.prepend_if_ee('EE::Groups::GroupMembersController')
Loading
Loading
@@ -17,7 +17,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController
@skip_groups << @project.namespace_id unless @project.personal?
@skip_groups += @project.group.ancestors.pluck(:id) if @project.group
 
@project_members = MembersFinder.new(@project, current_user).execute
@project_members = MembersFinder.new(@project, current_user).execute(include_relations: requested_relations)
 
if params[:search].present?
@project_members = @project_members.joins(:user).merge(User.search(params[:search]))
Loading
Loading
Loading
Loading
@@ -6,15 +6,15 @@ class GroupMembersFinder < UnionFinder
end
 
# rubocop: disable CodeReuse/ActiveRecord
def execute(include_descendants: false)
def execute(include_relations: [:inherited, :direct])
group_members = @group.members
relations = []
 
return group_members unless @group.parent || include_descendants
return group_members if include_relations == [:direct]
 
relations << group_members
relations << group_members if include_relations.include?(:direct)
 
if @group.parent
if include_relations.include?(:inherited) && @group.parent
parents_members = GroupMember.non_request
.where(source_id: @group.ancestors.select(:id))
.where.not(user_id: @group.users.select(:id))
Loading
Loading
@@ -22,7 +22,7 @@ class GroupMembersFinder < UnionFinder
relations << parents_members
end
 
if include_descendants
if include_relations.include?(:descendants)
descendant_members = GroupMember.non_request
.where(source_id: @group.descendants.select(:id))
.where.not(user_id: @group.users.select(:id))
Loading
Loading
Loading
Loading
@@ -9,14 +9,18 @@ class MembersFinder
@group = project.group
end
 
def execute(include_descendants: false, include_invited_groups_members: false)
def execute(include_relations: [:inherited, :direct])
project_members = project.project_members
project_members = project_members.non_invite unless can?(current_user, :admin_project, project)
 
union_members = group_union_members(include_descendants, include_invited_groups_members)
return project_members if include_relations == [:direct]
union_members = group_union_members(include_relations)
union_members << project_members if include_relations.include?(:direct)
 
if union_members.any?
distinct_union_of_members(union_members << project_members)
distinct_union_of_members(union_members)
else
project_members
end
Loading
Loading
@@ -28,15 +32,17 @@ class MembersFinder
 
private
 
def group_union_members(include_descendants, include_invited_groups_members)
def group_union_members(include_relations)
[].tap do |members|
members << direct_group_members(include_descendants) if group
members << project_invited_groups_members if include_invited_groups_members
members << direct_group_members(include_relations.include?(:descendants)) if group
members << project_invited_groups_members if include_relations.include?(:invited_groups_members)
end
end
 
def direct_group_members(include_descendants)
GroupMembersFinder.new(group).execute(include_descendants: include_descendants).non_invite # rubocop: disable CodeReuse/Finder
requested_relations = [:inherited, :direct]
requested_relations << :descendants if include_descendants
GroupMembersFinder.new(group).execute(include_relations: requested_relations).non_invite # rubocop: disable CodeReuse/Finder
end
 
def project_invited_groups_members
Loading
Loading
Loading
Loading
@@ -8,3 +8,13 @@
%li
= link_to filter_group_project_member_path(sort: value), class: ("is-active" if @sort == value) do
= title
%li.divider
%li{ data: { 'qa-selector': 'filter-members-with-inherited-permissions' } }
= link_to filter_group_project_member_path(with_inherited_permissions: nil), class: ("is-active" unless params[:with_inherited_permissions].present?) do
= _("Show all members")
%li{ data: { 'qa-selector': 'filter-members-with-inherited-permissions' } }
= link_to filter_group_project_member_path(with_inherited_permissions: 'exclude'), class: ("is-active" if params[:with_inherited_permissions] == 'exclude') do
= _("Show only direct members")
%li{ data: { 'qa-selector': 'filter-members-with-inherited-permissions' } }
= link_to filter_group_project_member_path(with_inherited_permissions: 'only'), class: ("is-active" if params[:with_inherited_permissions] == 'only') do
= _("Show only inherited members")
---
title: Added filtering of inherited members for subgroups
merge_request: 18842
author:
type: added
doc/ci/img/collapsible_log.png

272 KiB

doc/ci/img/collapsible_log_v12_6.png

94.3 KiB

Loading
Loading
@@ -157,7 +157,7 @@ In the following example:
- Two sections are collapsed and can be expanded.
- Three sections are expanded and can be collapsed.
 
![Collapsible sections](img/collapsible_log.png)
![Collapsible sections](img/collapsible_log_v12_6.png)
 
## Configuring pipelines
 
Loading
Loading
Loading
Loading
@@ -16,10 +16,15 @@ migrations automatically reschedule themselves for a later point in time.
> the migrations.
 
In the vast majority of cases you will want to use a regular Rails migration
instead. Background migrations should _only_ be used when migrating _data_ in
instead. Background migrations should be used when migrating _data_ in
tables that have so many rows this process would take hours when performed in a
regular Rails migration.
 
Background migrations _may_ also be used when executing numerous single-row queries
for every item on a large dataset. Typically, for single-record patterns, runtime is
largely dependent on the size of the dataset, hence it should be split accordingly
and put into background migrations.
Background migrations _may not_ be used to perform schema migrations, they
should only be used for data migrations.
 
Loading
Loading
Loading
Loading
@@ -103,10 +103,13 @@ and details for a database reviewer:
need to fit comfortably within `15s` - preferably much less than that - on GitLab.com.
- For column removals, make sure the column has been [ignored in a previous release](what_requires_downtime.md#dropping-columns)
- Check [background migrations](background_migrations.md):
- Establish a time estimate for execution on GitLab.com.
- They should only be used when migrating data in larger tables.
- If a single `update` is below than `1s` the query can be placed
- Establish a time estimate for execution on GitLab.com. For historical purposes,
it's highly recommended to include this estimation on the merge request description.
- If a single `update` is below than `1s` the query can be placed
directly in a regular migration (inside `db/migrate`).
- Background migrations are normally used, but not limited to:
- Migrating data in larger tables.
- Making numerous SQL queries per record in a dataset.
- Review queries (for example, make sure batch sizes are fine)
- Because execution time can be longer than for a regular migration,
it's suggested to treat background migrations as post migrations:
Loading
Loading
doc/user/group/subgroups/img/group_members_filter_v12_6.png

19.4 KiB

Loading
Loading
@@ -4,7 +4,7 @@ type: reference, howto, concepts
 
# Subgroups
 
>[Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/2772) in GitLab 9.0.
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/2772) in GitLab 9.0.
 
Subgroups, also known as nested groups or hierarchical groups, allow you to have up to 20
levels of groups.
Loading
Loading
@@ -142,6 +142,16 @@ From the image above, we can deduce the following things:
- Administrator is the Owner and member of **all** subgroups and for that reason,
as with User3, there is no indication of an ancestor group.
 
[From](https://gitlab.com/gitlab-org/gitlab/issues/21727) GitLab 12.6, you can filter
this list using dropdown on the right side:
![Group members filter](img/group_members_filter_v12_6.png)
- **Show only direct members** displays only Administrator and User3, since these are
the only users that belong to group `four`, which is the one we're inspecting.
- **Show only inherited members** displays User0, User1 and User2, no matter which group
above the hierarchy is the source of inherited permissions.
### Overriding the ancestor group membership
 
NOTE: **Note:**
Loading
Loading
@@ -186,7 +196,7 @@ Here's a list of what you can't do with subgroups:
 
[ce-2772]: https://gitlab.com/gitlab-org/gitlab-foss/issues/2772
[permissions]: ../../permissions.md#group-members-permissions
[reserved]: ../../reserved_names.md
[reserved]: ../../reserved_names.md
[issue]: https://gitlab.com/gitlab-org/gitlab-foss/issues/30472#note_27747600
 
<!-- ## Troubleshooting
Loading
Loading
doc/user/project/members/img/project_members.png

106 KiB

doc/user/project/members/img/project_members_filter_v12_6.png

19.4 KiB

Loading
Loading
@@ -10,6 +10,31 @@ or import a new user to your project.
To view, edit, add, and remove project's members, go to your
project's **Settings > Members**.
 
## Inherited membership
When your project belongs to the group, group members inherit the membership and permission
level for the project from the group.
![Project members page](img/project_members.png)
From the image above, we can deduce the following things:
- There are 3 members that have access to the project.
- User0 is a Reporter and has inherited their permissions from group `demo`
which contains current project.
- For User1 there is no indication of a group, therefore they belong directly
to the project we're inspecting.
- Administrator is the Owner and member of **all** groups and for that reason,
there is an indication of an ancestor group and inherited Owner permissions.
[From](https://gitlab.com/gitlab-org/gitlab/issues/21727), you can filter this list
using dropdown on the right side:
![Project members filter](img/project_members_filter_v12_6.png)
- **Show only direct members** displays only User1.
- **Show only inherited members** displays User0 and Administrator.
## Add a user
 
Right next to **People**, start typing the name or username of the user you
Loading
Loading
Loading
Loading
@@ -29,7 +29,7 @@ module API
end
 
def find_all_members_for_project(project)
MembersFinder.new(project, current_user).execute(include_invited_groups_members: true)
MembersFinder.new(project, current_user).execute(include_relations: [:inherited, :direct, :invited_groups_members])
end
 
def find_all_members_for_group(group)
Loading
Loading
Loading
Loading
@@ -16189,6 +16189,9 @@ msgstr ""
msgid "Show all activity"
msgstr ""
 
msgid "Show all members"
msgstr ""
msgid "Show archived projects"
msgstr ""
 
Loading
Loading
@@ -16216,6 +16219,12 @@ msgstr ""
msgid "Show latest version"
msgstr ""
 
msgid "Show only direct members"
msgstr ""
msgid "Show only inherited members"
msgstr ""
msgid "Show parent pages"
msgstr ""
 
Loading
Loading
Loading
Loading
@@ -36,6 +36,7 @@ module QA
autoload :GPG, 'qa/runtime/gpg'
autoload :MailHog, 'qa/runtime/mail_hog'
autoload :IPAddress, 'qa/runtime/ip_address'
autoload :Search, 'qa/runtime/search'
 
module API
autoload :Client, 'qa/runtime/api/client'
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment