No longer become member of a project's parent group
When a user is a member of a project, they are also a member of the project's parent group. This rule causes excessive computational overhead, is inconsistenly applied, and requires an inefficient recursive calculation to implement properly. Below I provide background on how this membership rule fits in to our overall group membership system, and why I believe we should remove the rule completely.
Very broadly, group membership involves the following factors:
- Direct group membership
- Inherited group membership
- Shared group membership
- Project membership parent group (The one this issue is about)
- Direct Project membership
- Inherited project memberships
- Shared group project membership
More specifically the group membership calculation works in this way:
- Group membership:
- Direct group memberships.
from members table where source_type = 'Group'
- Groups that parent projects from
2
below. - Groups shared into 1.1 and 1.2.
- Group descendants of 1.1, 1.2, and 1.3.
- Direct group memberships.
- Project membership (lib/gitlab/project_authorizations.rb):
- Direct project members.
from members table where source_type = 'Project'
- Projects that belong to Group membership (
1
). - Projects shared in to Group membership (
1
).from project_group_links
- Direct project members.
In flowchart form this looks like:
flowchart LR
subgraph 1[1 - Group Membership]
1.1[1.1 - Direct group membership]
1.2[1.2 - Project's parent group]
1.3[1.3 - Shared groups]
1.4[1.4 - Descendants]
1.1 --> 1.3
1.2 --> 1.3
1.1 --> 1.4
1.2 --> 1.4
1.3 --> 1.4
end
subgraph 2[2 - Project membership]
2.1[2.1 - Direct project membership]
2.2[2.2 - Group's projects]
2.3[2.3 - Group shared projects]
end
2 --> 1.2
1 --> 2.2
1 --> 2.3
Note the recursive relationship between Group Membership
and Project Membership
. In practice we don't honour this relationship. Instead we calculate Project Membership
first, and then calculate Group Membership
second. Therefore 2.2
and 2.3
of the Project Membership
calculation does not include 1.2
from Group Membership
. This looks more like:
flowchart LR
subgraph 2[2 - Project membership]
2.1[2.1 - Direct project membership]
2.2[2.2 - Group's projects]
2.3[2.3 - Group shared projects]
end
subgraph 1[1 - Group Membership]
subgraph 0[0 - Core group membership]
1.1[1.1 - Direct group membership]
1.3[1.3 - Shared groups]
1.4[1.4 - Descendants]
end
1.2[1.2 - Project's parent group]
1.1 --> 1.3
1.2 --> 1.3
1.1 --> 1.4
1.2 --> 1.4
1.3 --> 1.4
end
0 --> 2.2
0 --> 2.3
2 --> 1.2
There are a number of problems with these calculations. The most notable is the relationship between Group Membership
and Project Membership
.
- The relationship is recursive, but we only step through once. This results in inconsistent product rules.
- We make many redundant calculations because the project membership and group membership calculations overlap greatly.
I would like to propose that we remove the recursive relationship between project and group membership. To do so we remove the product rule where we are a member of a project's parent group if we're a member of that project. This rule does not make sense to me given existing rules, and I believe exists due to legacy reasons.
Removing this rule would simplify group membership greatly:
flowchart LR
subgraph 1[1 - Group Membership]
1.1[1.1 - Direct group membership]
1.3[1.3 - Shared groups]
1.4[1.4 - Descendants]
end
1.1 --> 1.3
1.1 --> 1.4
1.3 --> 1.4