Commit 7219ac55 authored by alinamihaila's avatar alinamihaila

Use authentication in UsageData API

  * USe authentication
  * Add string size limitation 36
  * Add array size limitation 10
parent ecbe1b30
...@@ -315,8 +315,11 @@ Implemented using Redis methods [PFADD](https://redis.io/commands/pfadd) and [PF ...@@ -315,8 +315,11 @@ Implemented using Redis methods [PFADD](https://redis.io/commands/pfadd) and [PF
1. Track event using `UsageData` API 1. Track event using `UsageData` API
Increment unique values count using Redis HLL, for given event name. Increment unique values count using Redis HLL, for given event name.
In order to be able to increment the values the related feature `usage_data<event_name>` should be enabled. In order to be able to increment the values the related feature `usage_data<event_name>` should be enabled.
It is allowed to send an array of maximum 10 strings of maximum size 36.
```plaintext ```plaintext
POST /usage_data/increment_unique_values POST /usage_data/increment_unique_values
``` ```
...@@ -324,14 +327,14 @@ Implemented using Redis methods [PFADD](https://redis.io/commands/pfadd) and [PF ...@@ -324,14 +327,14 @@ Implemented using Redis methods [PFADD](https://redis.io/commands/pfadd) and [PF
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| :-------- | :--- | :------- | :---------- | | :-------- | :--- | :------- | :---------- |
| `name` | string | yes | The event name it should be tracked | | `name` | string | yes | The event name it should be tracked |
| `values` | array | yes | The values counted | | `values` | array | yes | The values counted, maximum 10 string elements of size 36 |
Response Response
Return 200 if tracking failed for any reason. Return 200 if tracking failed for any reason.
- `403 Forbidden` if invalid CSRF token is provided - `401 Unauthorized` if user is not authenticated
- `400 Bad request` if name parameter is missing - `400 Bad request` if name parameter is missing, or validation errors
- `200` if event was tracked or any errors - `200` if event was tracked or any errors
1. Track event using base module `Gitlab::UsageDataCounters::HLLRedisCounter.track_event(entity_id, event_name)`. 1. Track event using base module `Gitlab::UsageDataCounters::HLLRedisCounter.track_event(entity_id, event_name)`.
......
...@@ -2,8 +2,15 @@ ...@@ -2,8 +2,15 @@
module API module API
class UsageData < Grape::API::Instance class UsageData < Grape::API::Instance
before do before { authenticate! }
forbidden!('Invalid CSRF token is provided') unless verified_request?
ALLOWED_ARRAY_SIZE = 10
ALLOWED_VALUE_SIZE = 36
helpers do
def valid_values(values)
values.size <= ALLOWED_ARRAY_SIZE && values.all? { |value| value.is_a?(String) && value.size <= ALLOWED_VALUE_SIZE }
end
end end
namespace 'usage_data' do namespace 'usage_data' do
...@@ -19,6 +26,10 @@ module API ...@@ -19,6 +26,10 @@ module API
event_name = params[:name] event_name = params[:name]
values = params[:values] values = params[:values]
unless valid_values(values)
render_api_error!('values needs to be an array of maxim 10 elements of strings of size maximum 36', 400)
end
increment_unique_values(event_name, values) increment_unique_values(event_name, values)
status :ok status :ok
......
...@@ -10,24 +10,18 @@ RSpec.describe API::UsageData do ...@@ -10,24 +10,18 @@ RSpec.describe API::UsageData do
let(:known_event) { 'g_compliance_dashboard' } let(:known_event) { 'g_compliance_dashboard' }
let(:unknown_event) { 'unknown' } let(:unknown_event) { 'unknown' }
context 'without CSRF token' do context 'without authentication' do
it 'returns 401 response' do it 'returns 401 response' do
allow(Gitlab::RequestForgeryProtection).to receive(:verified?).and_return(false)
post api(endpoint), params: { values: [user.id] } post api(endpoint), params: { values: [user.id] }
expect(response).to have_gitlab_http_status(:forbidden) expect(response).to have_gitlab_http_status(:unauthorized)
end
end end
context 'without CSRF token' do
before do
allow(Gitlab::RequestForgeryProtection).to receive(:verified?).and_return(true)
end end
context 'without authentication' do
context 'when name is missing from params' do context 'when name is missing from params' do
it 'returns bad request' do it 'returns bad request' do
post api(endpoint), params: { values: [user.id] } post api(endpoint, user), params: { values: [user.id] }
expect(response).to have_gitlab_http_status(:bad_request) expect(response).to have_gitlab_http_status(:bad_request)
end end
...@@ -35,7 +29,7 @@ RSpec.describe API::UsageData do ...@@ -35,7 +29,7 @@ RSpec.describe API::UsageData do
context 'with correct params' do context 'with correct params' do
it 'returns status ok' do it 'returns status ok' do
post api(endpoint), params: { name: known_event, values: [user.id] } post api(endpoint, user), params: { name: known_event, values: [user.id] }
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
end end
...@@ -43,11 +37,27 @@ RSpec.describe API::UsageData do ...@@ -43,11 +37,27 @@ RSpec.describe API::UsageData do
context 'with unknown event' do context 'with unknown event' do
it 'returns status ok' do it 'returns status ok' do
post api(endpoint), params: { name: unknown_event, values: [user.id] } post api(endpoint, user), params: { name: unknown_event, values: [user.id] }
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
end end
end end
context 'with 11 elements' do
it 'returns bad request' do
post api(endpoint, user), params: { name: known_event, values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] }
expect(response).to have_gitlab_http_status(:bad_request)
end
end
context 'with value of 37 chars' do
it 'returns bad request' do
post api(endpoint, user), params: { name: known_event, values: ['48ee87e2-7da5-4299-a56d-0424d5c5dab1e'] }
expect(response).to have_gitlab_http_status(:bad_request)
end
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