Follow-up from "Resolve "API to get all project/group members returns duplicates""
The following discussion from !24005 (merged) should be addressed:
-
@jamedjo started a discussion: (+14 comments) I've noted that both in members API and in the members UI we return the
members.access_level
but not the realaccess_level
that the user has on theproject/group
. In fact the real permission is the one set inside theprojects_authorizations.access_level
table. Is that alright? Shall we consider to useprojects_authorizations.access_level
rather thanmembers.access_level
?Do we still have bugs relating to these permissions? I vaguely remember the projects page not always showing the correct members and another bug where the correct permissions didn't always apply.
My hunch is that using the actual access levels would have been safer, but I guess we should be fine as long as those differences have been fixed. I guess it is probably fine to match the UI in the API, as we'll eventually fix the UI's finder to match reality.
When a user is a member of the project/group and of one or more ancestor groups the user is returned only once with the project access_level (if exists)
or the access_level for the user in the first group which he belongs to in the project groups ancestors chain. The highest access_level
for the user on the project should be returned instead. For invited groups the access_level
should be no higher than the invited group access level.
Development info
If you check https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/project_authorizations/with_nested_groups.rb#L32-52 and https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/project_authorizations/with_nested_groups.rb#L76-81 looks like when an user is a member of a group and of a parent group the permission associated to the user is the MAX(access_level) for all the groups user memberships. Here we just obtain the first GroupMember
(if there is no ProjectMember
) thus if the user has higher access_level
in a parent group and a lower access_level
in a subgroup the lowest access level is returned, which is wrong.
A solution to handle this should be to always rely on projects_authorization.access_level
instead.
How to reproduce the issue
- create a group
parent
- create a group
sub
in theparent
namespace - in the
sub
namespace create a projectsub_p
- in the group
sub
add a member with an access_level of20
(Reporter) - in the group
parent
add a member with an access_level of30
(Developer) - if you check the project
sub_p
members UI you'll see that the user has an access_level of20
(Reporter) whilst if you check theprojects_authorization
table (the real data used in ourpolicy
) you'll find that the user has an access_level of30
Note that 4.
and 5.
steps could not be swapped because this would show a validation error.
A similar issue occurs for project_invited_groups_members
.
this would also fix https://gitlab.com/gitlab-org/gitlab-ce/issues/62988 (duplicate)