Commit 18524842 authored by Dmitriy Zaporozhets (DZ)'s avatar Dmitriy Zaporozhets (DZ) Committed by Etienne Baqué

Error tracking client keys api

parent b40f172e
...@@ -17,6 +17,6 @@ class ErrorTracking::ClientKey < ApplicationRecord ...@@ -17,6 +17,6 @@ class ErrorTracking::ClientKey < ApplicationRecord
private private
def generate_key def generate_key
self.public_key = "glet_#{SecureRandom.hex}" self.public_key ||= "glet_#{SecureRandom.hex}"
end end
end end
...@@ -68,3 +68,84 @@ Example response: ...@@ -68,3 +68,84 @@ Example response:
"integrated": false "integrated": false
} }
``` ```
## Error Tracking client keys
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68384) in GitLab 14.3.
For [integrated error tracking](https://gitlab.com/gitlab-org/gitlab/-/issues/329596) feature that is behind a disabled feature flag. Only for project maintainers.
### List project client keys
```plaintext
GET /projects/:id/error_tracking/client_keys
```
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/error_tracking/client_keys"
```
Example response:
```json
[
{
"id": 1,
"active": true,
"public_key": "glet_aa77551d849c083f76d0bc545ed053a3"
},
{
"id": 3,
"active": true,
"public_key": "glet_0ff98b1d849c083f76d0bc545ed053a3"
}
]
```
### Create a client key
Creates a new client key for a project. The public key attribute is generated automatically.
```plaintext
POST /projects/:id/error_tracking/client_keys
```
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --header "Content-Type: application/json" \
"https://gitlab.example.com/api/v4/projects/5/error_tracking/client_keys"
```
Example response:
```json
{
"id": 3,
"active": true,
"public_key": "glet_0ff98b1d849c083f76d0bc545ed053a3"
}
```
### Delete a client key
Removes a client key from the project.
```plaintext
DELETE /projects/:id/error_tracking/client_keys/:key_id
```
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
| `key_id` | integer | yes | The ID of the client key. |
```shell
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/error_tracking/client_keys/13"
```
...@@ -171,6 +171,7 @@ module API ...@@ -171,6 +171,7 @@ module API
mount ::API::Deployments mount ::API::Deployments
mount ::API::Environments mount ::API::Environments
mount ::API::ErrorTracking mount ::API::ErrorTracking
mount ::API::ErrorTrackingClientKeys
mount ::API::ErrorTrackingCollector mount ::API::ErrorTrackingCollector
mount ::API::Events mount ::API::Events
mount ::API::FeatureFlags mount ::API::FeatureFlags
......
...@@ -10,6 +10,12 @@ module API ...@@ -10,6 +10,12 @@ module API
expose :api_url expose :api_url
expose :integrated expose :integrated
end end
class ClientKey < Grape::Entity
expose :id
expose :active
expose :public_key
end
end end
end end
end end
...@@ -6,24 +6,30 @@ module API ...@@ -6,24 +6,30 @@ module API
feature_category :error_tracking feature_category :error_tracking
helpers do
def project_setting
@project_setting ||= user_project.error_tracking_setting
end
end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, type: String, desc: 'The ID of a project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
before do
authorize! :admin_operations, user_project
not_found!('Error Tracking Setting') unless project_setting
end
desc 'Get error tracking settings for the project' do desc 'Get error tracking settings for the project' do
detail 'This feature was introduced in GitLab 12.7.' detail 'This feature was introduced in GitLab 12.7.'
success Entities::ErrorTracking::ProjectSetting success Entities::ErrorTracking::ProjectSetting
end end
get ':id/error_tracking/settings' do get ':id/error_tracking/settings' do
authorize! :admin_operations, user_project present project_setting, with: Entities::ErrorTracking::ProjectSetting
setting = user_project.error_tracking_setting
not_found!('Error Tracking Setting') unless setting
present setting, with: Entities::ErrorTracking::ProjectSetting
end end
desc 'Enable or disable error tracking settings for the project' do desc 'Enable or disable error tracking settings for the project' do
...@@ -36,12 +42,6 @@ module API ...@@ -36,12 +42,6 @@ module API
end end
patch ':id/error_tracking/settings/' do patch ':id/error_tracking/settings/' do
authorize! :admin_operations, user_project
setting = user_project.error_tracking_setting
not_found!('Error Tracking Setting') unless setting
update_params = { update_params = {
error_tracking_setting_attributes: { enabled: params[:active] } error_tracking_setting_attributes: { enabled: params[:active] }
} }
...@@ -53,7 +53,7 @@ module API ...@@ -53,7 +53,7 @@ module API
result = ::Projects::Operations::UpdateService.new(user_project, current_user, update_params).execute result = ::Projects::Operations::UpdateService.new(user_project, current_user, update_params).execute
if result[:status] == :success if result[:status] == :success
present setting, with: Entities::ErrorTracking::ProjectSetting present project_setting, with: Entities::ErrorTracking::ProjectSetting
else else
result result
end end
......
# frozen_string_literal: true
module API
class ErrorTrackingClientKeys < ::API::Base
before { authenticate! }
feature_category :error_tracking
params do
requires :id, type: String, desc: 'The ID of a project'
end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
segment ':id/error_tracking' do
before do
authorize! :admin_operations, user_project
end
desc 'List all client keys' do
detail 'This feature was introduced in GitLab 14.3.'
success Entities::ErrorTracking::ClientKey
end
get '/client_keys' do
collection = user_project.error_tracking_client_keys
present paginate(collection), with: Entities::ErrorTracking::ClientKey
end
desc 'Create a client key' do
detail 'This feature was introduced in GitLab 14.3.'
success Entities::ErrorTracking::ClientKey
end
post '/client_keys' do
key = user_project.error_tracking_client_keys.create!
present key, with: Entities::ErrorTracking::ClientKey
end
desc 'Delete a client key' do
detail 'This feature was introduced in GitLab 14.3.'
success Entities::ErrorTracking::ClientKey
end
delete '/client_keys/:key_id' do
key = user_project.error_tracking_client_keys.find(params[:key_id])
key.destroy!
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe API::ErrorTrackingClientKeys do
let_it_be(:guest) { create(:user) }
let_it_be(:maintainer) { create(:user) }
let_it_be(:setting) { create(:project_error_tracking_setting) }
let_it_be(:project) { setting.project }
let!(:client_key) { create(:error_tracking_client_key, project: project) }
before do
project.add_guest(guest)
project.add_maintainer(maintainer)
end
shared_examples 'endpoint with authorization' do
context 'when unauthenticated' do
let(:user) { nil }
it { expect(response).to have_gitlab_http_status(:unauthorized) }
end
context 'when authenticated as non-maintainer' do
let(:user) { guest }
it { expect(response).to have_gitlab_http_status(:forbidden) }
end
end
describe "GET /projects/:id/error_tracking/client_keys" do
before do
get api("/projects/#{project.id}/error_tracking/client_keys", user)
end
it_behaves_like 'endpoint with authorization'
context 'when authenticated as maintainer' do
let(:user) { maintainer }
it 'returns client keys' do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response.size).to eq(1)
expect(json_response.first['id']).to eq(client_key.id)
end
end
end
describe "POST /projects/:id/error_tracking/client_keys" do
before do
post api("/projects/#{project.id}/error_tracking/client_keys", user)
end
it_behaves_like 'endpoint with authorization'
context 'when authenticated as maintainer' do
let(:user) { maintainer }
it 'returns a newly created client key' do
new_key = project.error_tracking_client_keys.last
expect(json_response['id']).to eq(new_key.id)
expect(json_response['public_key']).to eq(new_key.public_key)
end
end
end
describe "DELETE /projects/:id/error_tracking/client_keys/:key_id" do
before do
delete api("/projects/#{project.id}/error_tracking/client_keys/#{client_key.id}", user)
end
it_behaves_like 'endpoint with authorization'
context 'when authenticated as maintainer' do
let(:user) { maintainer }
it 'returns a correct status' do
expect(response).to have_gitlab_http_status(:ok)
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