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_levelbut not the realaccess_levelthat the user has on theproject/group. In fact the real permission is the one set inside theprojects_authorizations.access_leveltable. Is that alright? Shall we consider to useprojects_authorizations.access_levelrather 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
subin theparentnamespace - in the
subnamespace create a projectsub_p - in the group
subadd a member with an access_level of20(Reporter) - in the group
parentadd a member with an access_level of30(Developer) - if you check the project
sub_pmembers UI you'll see that the user has an access_level of20(Reporter) whilst if you check theprojects_authorizationtable (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)