diff options
-rw-r--r-- | changelogs/unreleased/public-tags-api.yml | 4 | ||||
-rw-r--r-- | doc/api/tags.md | 7 | ||||
-rw-r--r-- | lib/api/tags.rb | 1 | ||||
-rw-r--r-- | spec/requests/api/tags_spec.rb | 55 |
4 files changed, 57 insertions, 10 deletions
diff --git a/changelogs/unreleased/public-tags-api.yml b/changelogs/unreleased/public-tags-api.yml new file mode 100644 index 00000000000..f5e844470b2 --- /dev/null +++ b/changelogs/unreleased/public-tags-api.yml @@ -0,0 +1,4 @@ +--- +title: Allow public access to some Tag API endpoints +merge_request: +author: diff --git a/doc/api/tags.md b/doc/api/tags.md index 14573d48fe4..7f78ffc2390 100644 --- a/doc/api/tags.md +++ b/doc/api/tags.md @@ -2,7 +2,9 @@ ## List project repository tags -Get a list of repository tags from a project, sorted by name in reverse alphabetical order. +Get a list of repository tags from a project, sorted by name in reverse +alphabetical order. This endpoint can be accessed without authentication if the +repository is publicly accessible. ``` GET /projects/:id/repository/tags @@ -40,7 +42,8 @@ Parameters: ## Get a single repository tag -Get a specific repository tag determined by its name. +Get a specific repository tag determined by its name. This endpoint can be +accessed without authentication if the repository is publicly accessible. ``` GET /projects/:id/repository/tags/:tag_name diff --git a/lib/api/tags.rb b/lib/api/tags.rb index cd33f9a9903..5b345db3a41 100644 --- a/lib/api/tags.rb +++ b/lib/api/tags.rb @@ -1,7 +1,6 @@ module API # Git Tags API class Tags < Grape::API - before { authenticate! } before { authorize! :download_code, user_project } params do diff --git a/spec/requests/api/tags_spec.rb b/spec/requests/api/tags_spec.rb index 06fa94fae87..a1c32ae65ba 100644 --- a/spec/requests/api/tags_spec.rb +++ b/spec/requests/api/tags_spec.rb @@ -15,6 +15,31 @@ describe API::Tags, api: true do let(:tag_name) { project.repository.tag_names.sort.reverse.first } let(:description) { 'Awesome release!' } + shared_examples_for 'repository tags' do + it 'returns the repository tags' do + get api("/projects/#{project.id}/repository/tags", current_user) + + expect(response).to have_http_status(200) + + first_tag = json_response.first + + expect(first_tag['name']).to eq(tag_name) + end + end + + context 'when unauthenticated' do + it_behaves_like 'repository tags' do + let(:project) { create(:project, :public) } + let(:current_user) { nil } + end + end + + context 'when authenticated' do + it_behaves_like 'repository tags' do + let(:current_user) { user } + end + end + context 'without releases' do it "returns an array of project tags" do get api("/projects/#{project.id}/repository/tags", user) @@ -45,17 +70,33 @@ describe API::Tags, api: true do describe 'GET /projects/:id/repository/tags/:tag_name' do let(:tag_name) { project.repository.tag_names.sort.reverse.first } - it 'returns a specific tag' do - get api("/projects/#{project.id}/repository/tags/#{tag_name}", user) + shared_examples_for 'repository tag' do + it 'returns the repository tag' do + get api("/projects/#{project.id}/repository/tags/#{tag_name}", current_user) + + expect(response).to have_http_status(200) + + expect(json_response['name']).to eq(tag_name) + end + + it 'returns 404 for an invalid tag name' do + get api("/projects/#{project.id}/repository/tags/foobar", current_user) - expect(response).to have_http_status(200) - expect(json_response['name']).to eq(tag_name) + expect(response).to have_http_status(404) + end end - it 'returns 404 for an invalid tag name' do - get api("/projects/#{project.id}/repository/tags/foobar", user) + context 'when unauthenticated' do + it_behaves_like 'repository tag' do + let(:project) { create(:project, :public) } + let(:current_user) { nil } + end + end - expect(response).to have_http_status(404) + context 'when authenticated' do + it_behaves_like 'repository tag' do + let(:current_user) { user } + end end end |