diff options
-rw-r--r-- | changelogs/unreleased/fix_event_api_permissions.yml | 5 | ||||
-rw-r--r-- | doc/api/events.md | 12 | ||||
-rw-r--r-- | lib/api/events.rb | 5 | ||||
-rw-r--r-- | spec/requests/api/events_spec.rb | 48 |
4 files changed, 62 insertions, 8 deletions
diff --git a/changelogs/unreleased/fix_event_api_permissions.yml b/changelogs/unreleased/fix_event_api_permissions.yml new file mode 100644 index 00000000000..dee280e93ad --- /dev/null +++ b/changelogs/unreleased/fix_event_api_permissions.yml @@ -0,0 +1,5 @@ +--- +title: 'Events API now requires the read_user or api scope.' +merge_request: 20627 +author: Warren Parad +type: fixed diff --git a/doc/api/events.md b/doc/api/events.md index 1b6c4d437dd..fb5ebb71a86 100644 --- a/doc/api/events.md +++ b/doc/api/events.md @@ -48,9 +48,11 @@ GitLab removes events older than 1 year from the events table for performance re ## List currently authenticated user's events ->**Note:** This endpoint was introduced in GitLab 9.3. +>**Notes:** +> This endpoint was introduced in GitLab 9.3. +> `read_user` access was introduced in GitLab 11.3. -Get a list of events for the authenticated user. +Get a list of events for the authenticated user. Scope `read_user` or `api` is required. ``` GET /events @@ -119,9 +121,11 @@ Example response: ### Get user contribution events ->**Note:** Documentation was formerly located in the [Users API pages][users-api]. +>**Notes:** +> Documentation was formerly located in the [Users API pages][users-api]. +> `read_user` access was introduced in GitLab 11.3. -Get the contribution events for the specified user, sorted from newest to oldest. +Get the contribution events for the specified user, sorted from newest to oldest. Scope `read_user` or `api` is required. ``` GET /users/:id/events diff --git a/lib/api/events.rb b/lib/api/events.rb index fc4ba5a3188..a415508a632 100644 --- a/lib/api/events.rb +++ b/lib/api/events.rb @@ -1,6 +1,7 @@ module API class Events < Grape::API include PaginationParams + include APIGuard helpers do params :event_filter_params do @@ -24,6 +25,8 @@ module API end resource :events do + allow_access_with_scope :read_user, if: -> (request) { request.get? } + desc "List currently authenticated user's events" do detail 'This feature was introduced in GitLab 9.3.' success Entities::Event @@ -46,6 +49,8 @@ module API requires :id, type: String, desc: 'The ID or Username of the user' end resource :users do + allow_access_with_scope :read_user, if: -> (request) { request.get? } + desc 'Get the contribution events of a specified user' do detail 'This feature was introduced in GitLab 8.13.' success Entities::Event diff --git a/spec/requests/api/events_spec.rb b/spec/requests/api/events_spec.rb index e6a61fdcf39..573eebe314d 100644 --- a/spec/requests/api/events_spec.rb +++ b/spec/requests/api/events_spec.rb @@ -2,9 +2,9 @@ require 'spec_helper' describe API::Events do include ApiHelpers + let(:user) { create(:user) } let(:non_member) { create(:user) } - let(:other_user) { create(:user, username: 'otheruser') } let(:private_project) { create(:project, :private, creator_id: user.id, namespace: user.namespace) } let(:closed_issue) { create(:closed_issue, project: private_project, author: user) } let!(:closed_issue_event) { create(:event, project: private_project, author: user, target: closed_issue, action: Event::CLOSED, created_at: Date.new(2016, 12, 30)) } @@ -28,12 +28,52 @@ describe API::Events do expect(json_response.size).to eq(1) end end + + context 'when the requesting token has "read_user" scope' do + let(:token) { create(:personal_access_token, scopes: ['read_user'], user: user) } + + it 'returns users events' do + get api('/events?action=closed&target_type=issue&after=2016-12-1&before=2016-12-31', personal_access_token: token) + + expect(response).to have_gitlab_http_status(200) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + expect(json_response.size).to eq(1) + end + end + + context 'when the requesting token does not have "read_user" or "api" scope' do + let(:token_without_scopes) { create(:personal_access_token, scopes: ['read_repository'], user: user) } + + it 'returns a "403" response' do + get api('/events', personal_access_token: token_without_scopes) + + expect(response).to have_gitlab_http_status(403) + end + end end describe 'GET /users/:id/events' do - context "as a user that cannot see the event's project" do - it 'returns no events' do - get api("/users/#{user.id}/events", other_user) + context "as a user that cannot see another user" do + it 'returns a "404" response' do + allow(Ability).to receive(:allowed?).and_call_original + allow(Ability).to receive(:allowed?).with(non_member, :read_user, user).and_return(false) + + get api("/users/#{user.id}/events", non_member) + + expect(response).to have_gitlab_http_status(200) + expect(json_response).to be_empty + end + end + + context "as a user token that cannot see another user" do + let(:non_member_token) { create(:personal_access_token, scopes: ['read_user'], user: non_member) } + + it 'returns a "404" response' do + allow(Ability).to receive(:allowed?).and_call_original + allow(Ability).to receive(:allowed?).with(non_member, :read_user, user).and_return(false) + + get api("/users/#{user.id}/events", personal_access_token: non_member_token) expect(response).to have_gitlab_http_status(200) expect(json_response).to be_empty |