diff options
author | Tomasz Maczukin <tomasz@maczukin.pl> | 2017-11-23 14:32:16 +0100 |
---|---|---|
committer | Tomasz Maczukin <tomasz@maczukin.pl> | 2017-11-23 17:44:05 +0100 |
commit | dfbfd3c7d7d4677ac99a7f8147a673911e8d4e98 (patch) | |
tree | 7dfb3b813f9820fa539eb908dd1ca06719a63348 | |
parent | 5c2578e68177e0b5ba48f9d2931602747ad58c91 (diff) | |
download | gitlab-ce-dfbfd3c7d7d4677ac99a7f8147a673911e8d4e98.tar.gz |
Allow request namespace by ID or path
-rw-r--r-- | doc/api/namespaces.md | 22 | ||||
-rw-r--r-- | lib/api/helpers.rb | 22 | ||||
-rw-r--r-- | lib/api/namespaces.rb | 18 | ||||
-rw-r--r-- | spec/requests/api/namespaces_spec.rb | 38 |
4 files changed, 72 insertions, 28 deletions
diff --git a/doc/api/namespaces.md b/doc/api/namespaces.md index d06b0d31c67..25cae5ce1f9 100644 --- a/doc/api/namespaces.md +++ b/doc/api/namespaces.md @@ -100,7 +100,7 @@ GET /namespaces/:id | Attribute | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `id` | integer | yes | ID of the namespace | +| `id` | integer/string | yes | ID or path of the namespace | Example request: @@ -121,3 +121,23 @@ Example response: "members_count_with_descendants": 2 } ``` + +Example request: + +```bash +curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/namespaces/group1 +``` + +Example response: + +```json +{ + "id": 2, + "name": "group1", + "path": "group1", + "kind": "group", + "full_path": "group1", + "parent_id": "null", + "members_count_with_descendants": 2 +} +``` diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index b26c61ab8da..52ac416f9ad 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -50,6 +50,10 @@ module API initial_current_user != current_user end + def user_namespace + @user_namespace ||= find_namespace!(params[:id]) + end + def user_group @group ||= find_group!(params[:id]) end @@ -112,6 +116,24 @@ module API end end + def find_namespace(id) + if id.to_s =~ /^\d+$/ + Namespace.find_by(id: id) + else + Namespace.find_by_full_path(id) + end + end + + def find_namespace!(id) + namespace = find_namespace(id) + + if can?(current_user, :admin_namespace, namespace) + namespace + else + not_found!('Namespace') + end + end + def find_project_label(id) label = available_labels.find_by_id(id) || available_labels.find_by_title(id) label || not_found!('Label') diff --git a/lib/api/namespaces.rb b/lib/api/namespaces.rb index 21dc5009d0e..32b77aedba8 100644 --- a/lib/api/namespaces.rb +++ b/lib/api/namespaces.rb @@ -24,24 +24,10 @@ module API success Entities::Namespace end params do - requires :id, type: Integer, desc: "Namespace's ID" + requires :id, type: String, desc: "Namespace's ID or path" end get ':id' do - namespace = Namespace.find(params[:id]) - authenticate_get_namespace!(namespace) - - present namespace, with: Entities::Namespace, current_user: current_user - end - end - - helpers do - def authenticate_get_namespace!(namespace) - return if current_user.admin? - forbidden!('No access granted') unless user_can_access_namespace?(namespace) - end - - def user_can_access_namespace?(namespace) - namespace.has_owner?(current_user) + present user_namespace, with: Entities::Namespace, current_user: current_user end end end diff --git a/spec/requests/api/namespaces_spec.rb b/spec/requests/api/namespaces_spec.rb index 80698e1ff74..900d7e059b8 100644 --- a/spec/requests/api/namespaces_spec.rb +++ b/spec/requests/api/namespaces_spec.rb @@ -95,19 +95,36 @@ describe API::Namespaces do describe 'GET /namespaces/:id' do let(:owned_group) { group1 } + shared_examples 'can access namespace' do + it 'returns namespace details' do + get api("/namespaces/#{namespace_id}", request_actor) + + expect(response).to have_gitlab_http_status(200) + + expect(json_response['id']).to eq(requested_namespace.id) + expect(json_response['path']).to eq(requested_namespace.path) + expect(json_response['name']).to eq(requested_namespace.name) + end + end + shared_examples 'namespace reader' do + let(:requested_namespace) { owned_group } + before do owned_group.add_owner(request_actor) end context 'when namespace exists' do - it 'returns namespace details' do - get api("/namespaces/#{owned_group.id}", request_actor) + context 'when requested by ID' do + let(:namespace_id) { owned_group.id } - expect(response).to have_gitlab_http_status(200) + it_behaves_like 'can access namespace' + end + + context 'when requested by path' do + let(:namespace_id) { owned_group.path } - expect(json_response['id']).to eq(owned_group.id) - expect(json_response['name']).to eq(owned_group.name) + it_behaves_like 'can access namespace' end end @@ -132,10 +149,10 @@ describe API::Namespaces do let(:request_actor) { user } context 'when requested namespace is not owned by user' do - it 'returns authentication error' do + it 'returns not-found' do get api("/namespaces/#{group2.id}", request_actor) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(404) end end @@ -148,11 +165,10 @@ describe API::Namespaces do let(:request_actor) { admin } context 'when requested namespace is not owned by user' do - it 'returns authentication error' do - get api("/namespaces/#{group2.id}", request_actor) + let(:namespace_id) { group2.id } + let(:requested_namespace) { group2 } - expect(response).to have_gitlab_http_status(200) - end + it_behaves_like 'can access namespace' end context 'when requested namespace is owned by user' do |