Commit ab94a5a5 authored by Alejandro Rodríguez's avatar Alejandro Rodríguez

Return max group access level in the projects API

Currently if a project is inside a nested group and a user doesn't have
specific permissions for that group but does have permissions on a
parent group the `GET /projects/:id` API call will return the following
permissions:

```json
permissions: { project_access: null, group_access: null }
```

It could also happen that the group specific permissions are of lower
level than the ones the user has in parent groups. This patch makes it
so that the permission returned for `group_access` is the highest from
amongst the hierarchy, which is (ostensibly) the information that the
API user is interested in for that field.
parent f821a53b
......@@ -382,6 +382,10 @@ class Group < Namespace
end
end
def highest_group_member(user)
GroupMember.where(source_id: self_and_ancestors_ids, user_id: user.id).order(:access_level).last
end
def hashed_storage?(_feature)
false
end
......
---
title: Return the maximum group access level in the projects API
merge_request: 24403
author:
type: changed
......@@ -961,7 +961,7 @@ module API
if options[:group_members]
options[:group_members].find { |member| member.source_id == project.namespace_id }
else
project.group.group_member(options[:current_user])
project.group.highest_group_member(options[:current_user])
end
end
end
......
......@@ -722,6 +722,42 @@ describe Group do
end
end
describe '#highest_group_member', :nested_groups do
let(:nested_group) { create(:group, parent: group) }
let(:nested_group_2) { create(:group, parent: nested_group) }
let(:user) { create(:user) }
subject(:highest_group_member) { nested_group_2.highest_group_member(user) }
context 'when the user is not a member of any group in the hierarchy' do
it 'returns nil' do
expect(highest_group_member).to be_nil
end
end
context 'when the user is only a member of one group in the hierarchy' do
before do
nested_group.add_developer(user)
end
it 'returns that group member' do
expect(highest_group_member.access_level).to eq(Gitlab::Access::DEVELOPER)
end
end
context 'when the user is a member of several groups in the hierarchy' do
before do
group.add_owner(user)
nested_group.add_developer(user)
nested_group_2.add_maintainer(user)
end
it 'returns the group member with the highest access level' do
expect(highest_group_member.access_level).to eq(Gitlab::Access::OWNER)
end
end
end
describe '#has_parent?' do
context 'when the group has a parent' do
it 'should be truthy' do
......
......@@ -1145,6 +1145,40 @@ describe API::Projects do
.to eq(Gitlab::Access::OWNER)
end
end
context 'nested group project', :nested_groups do
let(:group) { create(:group) }
let(:nested_group) { create(:group, parent: group) }
let(:project2) { create(:project, group: nested_group) }
before do
project2.group.parent.add_owner(user)
end
it 'sets group access and return 200' do
get api("/projects/#{project2.id}", user)
expect(response).to have_gitlab_http_status(200)
expect(json_response['permissions']['project_access']).to be_nil
expect(json_response['permissions']['group_access']['access_level'])
.to eq(Gitlab::Access::OWNER)
end
context 'with various access levels across nested groups' do
before do
project2.group.add_maintainer(user)
end
it 'sets the maximum group access and return 200' do
get api("/projects/#{project2.id}", user)
expect(response).to have_gitlab_http_status(200)
expect(json_response['permissions']['project_access']).to be_nil
expect(json_response['permissions']['group_access']['access_level'])
.to eq(Gitlab::Access::OWNER)
end
end
end
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment