Commit b99ebc5d authored by Vasilii Iakliushin's avatar Vasilii Iakliushin

Merge branch 'read-project-bot-names' into 'master'

Users who can read project should be able to read project bot name

See merge request gitlab-org/gitlab!78319
parents 9391ddd8 933798cc
...@@ -31,7 +31,7 @@ module Types ...@@ -31,7 +31,7 @@ module Types
null: false, null: false,
resolver_method: :redacted_name, resolver_method: :redacted_name,
description: 'Human-readable name of the user. ' \ description: 'Human-readable name of the user. ' \
'Will return `****` if the user is a project bot and the requester does not have permission to read resource access tokens.' 'Returns `****` if the user is a project bot and the requester does not have permission to view the project.'
field :state, field :state,
type: Types::UserStateEnum, type: Types::UserStateEnum,
...@@ -127,7 +127,7 @@ module Types ...@@ -127,7 +127,7 @@ module Types
def redacted_name def redacted_name
return object.name unless object.project_bot? return object.name unless object.project_bot?
return object.name if context[:current_user]&.can?(:read_resource_access_tokens, object.projects.first) return object.name if context[:current_user]&.can?(:read_project, object.projects.first)
# If the requester does not have permission to read the project bot name, # If the requester does not have permission to read the project bot name,
# the API returns an arbitrary string. UI changes will be addressed in a follow up issue: # the API returns an arbitrary string. UI changes will be addressed in a follow up issue:
......
...@@ -12025,7 +12025,7 @@ A user assigned to a merge request. ...@@ -12025,7 +12025,7 @@ A user assigned to a merge request.
| <a id="mergerequestassigneeid"></a>`id` | [`ID!`](#id) | ID of the user. | | <a id="mergerequestassigneeid"></a>`id` | [`ID!`](#id) | ID of the user. |
| <a id="mergerequestassigneelocation"></a>`location` | [`String`](#string) | Location of the user. | | <a id="mergerequestassigneelocation"></a>`location` | [`String`](#string) | Location of the user. |
| <a id="mergerequestassigneemergerequestinteraction"></a>`mergeRequestInteraction` | [`UserMergeRequestInteraction`](#usermergerequestinteraction) | Details of this user's interactions with the merge request. | | <a id="mergerequestassigneemergerequestinteraction"></a>`mergeRequestInteraction` | [`UserMergeRequestInteraction`](#usermergerequestinteraction) | Details of this user's interactions with the merge request. |
| <a id="mergerequestassigneename"></a>`name` | [`String!`](#string) | Human-readable name of the user. Will return `****` if the user is a project bot and the requester does not have permission to read resource access tokens. | | <a id="mergerequestassigneename"></a>`name` | [`String!`](#string) | Human-readable name of the user. Returns `****` if the user is a project bot and the requester does not have permission to view the project. |
| <a id="mergerequestassigneenamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. | | <a id="mergerequestassigneenamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. |
| <a id="mergerequestassigneeprojectmemberships"></a>`projectMemberships` | [`ProjectMemberConnection`](#projectmemberconnection) | Project memberships of the user. (see [Connections](#connections)) | | <a id="mergerequestassigneeprojectmemberships"></a>`projectMemberships` | [`ProjectMemberConnection`](#projectmemberconnection) | Project memberships of the user. (see [Connections](#connections)) |
| <a id="mergerequestassigneepublicemail"></a>`publicEmail` | [`String`](#string) | User's public email. | | <a id="mergerequestassigneepublicemail"></a>`publicEmail` | [`String`](#string) | User's public email. |
...@@ -12280,7 +12280,7 @@ A user assigned to a merge request as a reviewer. ...@@ -12280,7 +12280,7 @@ A user assigned to a merge request as a reviewer.
| <a id="mergerequestreviewerid"></a>`id` | [`ID!`](#id) | ID of the user. | | <a id="mergerequestreviewerid"></a>`id` | [`ID!`](#id) | ID of the user. |
| <a id="mergerequestreviewerlocation"></a>`location` | [`String`](#string) | Location of the user. | | <a id="mergerequestreviewerlocation"></a>`location` | [`String`](#string) | Location of the user. |
| <a id="mergerequestreviewermergerequestinteraction"></a>`mergeRequestInteraction` | [`UserMergeRequestInteraction`](#usermergerequestinteraction) | Details of this user's interactions with the merge request. | | <a id="mergerequestreviewermergerequestinteraction"></a>`mergeRequestInteraction` | [`UserMergeRequestInteraction`](#usermergerequestinteraction) | Details of this user's interactions with the merge request. |
| <a id="mergerequestreviewername"></a>`name` | [`String!`](#string) | Human-readable name of the user. Will return `****` if the user is a project bot and the requester does not have permission to read resource access tokens. | | <a id="mergerequestreviewername"></a>`name` | [`String!`](#string) | Human-readable name of the user. Returns `****` if the user is a project bot and the requester does not have permission to view the project. |
| <a id="mergerequestreviewernamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. | | <a id="mergerequestreviewernamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. |
| <a id="mergerequestreviewerprojectmemberships"></a>`projectMemberships` | [`ProjectMemberConnection`](#projectmemberconnection) | Project memberships of the user. (see [Connections](#connections)) | | <a id="mergerequestreviewerprojectmemberships"></a>`projectMemberships` | [`ProjectMemberConnection`](#projectmemberconnection) | Project memberships of the user. (see [Connections](#connections)) |
| <a id="mergerequestreviewerpublicemail"></a>`publicEmail` | [`String`](#string) | User's public email. | | <a id="mergerequestreviewerpublicemail"></a>`publicEmail` | [`String`](#string) | User's public email. |
...@@ -15501,7 +15501,7 @@ Core represention of a GitLab user. ...@@ -15501,7 +15501,7 @@ Core represention of a GitLab user.
| <a id="usercoregroupmemberships"></a>`groupMemberships` | [`GroupMemberConnection`](#groupmemberconnection) | Group memberships of the user. (see [Connections](#connections)) | | <a id="usercoregroupmemberships"></a>`groupMemberships` | [`GroupMemberConnection`](#groupmemberconnection) | Group memberships of the user. (see [Connections](#connections)) |
| <a id="usercoreid"></a>`id` | [`ID!`](#id) | ID of the user. | | <a id="usercoreid"></a>`id` | [`ID!`](#id) | ID of the user. |
| <a id="usercorelocation"></a>`location` | [`String`](#string) | Location of the user. | | <a id="usercorelocation"></a>`location` | [`String`](#string) | Location of the user. |
| <a id="usercorename"></a>`name` | [`String!`](#string) | Human-readable name of the user. Will return `****` if the user is a project bot and the requester does not have permission to read resource access tokens. | | <a id="usercorename"></a>`name` | [`String!`](#string) | Human-readable name of the user. Returns `****` if the user is a project bot and the requester does not have permission to view the project. |
| <a id="usercorenamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. | | <a id="usercorenamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. |
| <a id="usercoreprojectmemberships"></a>`projectMemberships` | [`ProjectMemberConnection`](#projectmemberconnection) | Project memberships of the user. (see [Connections](#connections)) | | <a id="usercoreprojectmemberships"></a>`projectMemberships` | [`ProjectMemberConnection`](#projectmemberconnection) | Project memberships of the user. (see [Connections](#connections)) |
| <a id="usercorepublicemail"></a>`publicEmail` | [`String`](#string) | User's public email. | | <a id="usercorepublicemail"></a>`publicEmail` | [`String`](#string) | User's public email. |
...@@ -18736,7 +18736,7 @@ Implementations: ...@@ -18736,7 +18736,7 @@ Implementations:
| <a id="usergroupmemberships"></a>`groupMemberships` | [`GroupMemberConnection`](#groupmemberconnection) | Group memberships of the user. (see [Connections](#connections)) | | <a id="usergroupmemberships"></a>`groupMemberships` | [`GroupMemberConnection`](#groupmemberconnection) | Group memberships of the user. (see [Connections](#connections)) |
| <a id="userid"></a>`id` | [`ID!`](#id) | ID of the user. | | <a id="userid"></a>`id` | [`ID!`](#id) | ID of the user. |
| <a id="userlocation"></a>`location` | [`String`](#string) | Location of the user. | | <a id="userlocation"></a>`location` | [`String`](#string) | Location of the user. |
| <a id="username"></a>`name` | [`String!`](#string) | Human-readable name of the user. Will return `****` if the user is a project bot and the requester does not have permission to read resource access tokens. | | <a id="username"></a>`name` | [`String!`](#string) | Human-readable name of the user. Returns `****` if the user is a project bot and the requester does not have permission to view the project. |
| <a id="usernamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. | | <a id="usernamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. |
| <a id="userprojectmemberships"></a>`projectMemberships` | [`ProjectMemberConnection`](#projectmemberconnection) | Project memberships of the user. (see [Connections](#connections)) | | <a id="userprojectmemberships"></a>`projectMemberships` | [`ProjectMemberConnection`](#projectmemberconnection) | Project memberships of the user. (see [Connections](#connections)) |
| <a id="userpublicemail"></a>`publicEmail` | [`String`](#string) | User's public email. | | <a id="userpublicemail"></a>`publicEmail` | [`String`](#string) | User's public email. |
...@@ -42,7 +42,7 @@ To create a project access token: ...@@ -42,7 +42,7 @@ To create a project access token:
1. On the top bar, select **Menu > Projects** and find your project. 1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Access Tokens**. 1. On the left sidebar, select **Settings > Access Tokens**.
1. Enter a name. 1. Enter a name. The token name is visible to any user with permissions to view the project.
1. Optional. Enter an expiry date for the token. The token will expire on that date at midnight UTC. 1. Optional. Enter an expiry date for the token. The token will expire on that date at midnight UTC.
1. Select a role for the token. 1. Select a role for the token.
1. Select the [desired scopes](#scopes-for-a-project-access-token). 1. Select the [desired scopes](#scopes-for-a-project-access-token).
......
...@@ -7,7 +7,7 @@ module API ...@@ -7,7 +7,7 @@ module API
expose :name do |user| expose :name do |user|
next user.name unless user.project_bot? next user.name unless user.project_bot?
next user.name if options[:current_user]&.can?(:read_resource_access_tokens, user.projects.first) next user.name if options[:current_user]&.can?(:read_project, user.projects.first)
# If the requester does not have permission to read the project bot name, # If the requester does not have permission to read the project bot name,
# the API returns an arbitrary string. UI changes will be addressed in a follow up issue: # the API returns an arbitrary string. UI changes will be addressed in a follow up issue:
......
...@@ -67,14 +67,14 @@ RSpec.describe GitlabSchema.types['User'] do ...@@ -67,14 +67,14 @@ RSpec.describe GitlabSchema.types['User'] do
) )
end end
subject { GitlabSchema.execute(query, context: { current_user: current_user }).as_json.dig('data', 'user', 'name') } subject(:user_name) { GitlabSchema.execute(query, context: { current_user: current_user }).as_json.dig('data', 'user', 'name') }
context 'user requests' do context 'user requests' do
let(:current_user) { user } let(:current_user) { user }
context 'a user' do context 'a user' do
it 'returns name' do it 'returns name' do
expect(subject).to eq('John Smith') expect(user_name).to eq('John Smith')
end end
end end
...@@ -85,21 +85,39 @@ RSpec.describe GitlabSchema.types['User'] do ...@@ -85,21 +85,39 @@ RSpec.describe GitlabSchema.types['User'] do
let(:current_user) { nil } let(:current_user) { nil }
it 'returns `****`' do it 'returns `****`' do
expect(subject).to eq('****') expect(user_name).to eq('****')
end end
end end
it 'returns `****` for a regular user' do context 'when the requester is not a project member' do
expect(subject).to eq('****') it 'returns `Project bot` for a non project member in a public project' do
expect(user_name).to eq('Project bot')
end
context 'in a private project' do
let(:project) { create(:project, :private) }
it 'returns `****` for a non project member in a private project' do
expect(user_name).to eq('****')
end
end
end end
context 'when requester is a project maintainer' do context 'with a project member' do
before do before do
project.add_maintainer(user) project.add_guest(user)
end
it 'returns `Project bot` for a project member' do
expect(user_name).to eq('Project bot')
end end
it 'returns name' do context 'in a private project' do
expect(subject).to eq('Project bot') let(:project) { create(:project, :private) }
it 'returns `Project bot` for a project member in a private project' do
expect(user_name).to eq('Project bot')
end
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