Commit d4376e0c authored by Sean McGivern's avatar Sean McGivern Committed by Douglas Barbosa Alexandre

Merge branch '4269-public-files-api' into 'master'

Allow unauthenticated access to Repositories Files API GET endpoints

See merge request !8149
parent ef047d07
--- ---
title: Allow public access to some Project API endpoints title: Allow unauthenticated access to some Project API GET endpoints
merge_request: 7843 merge_request: 7843
author: author:
---
title: Allow unauthenticated access to Repositories Files API GET endpoints
merge_request:
author:
--- ---
title: Allow Repositories API GET endpoints to be requested anonymously title: Allow unauthenticated access to Repositories API GET endpoints
merge_request: 8148 merge_request: 8148
author: author:
...@@ -6,7 +6,9 @@ ...@@ -6,7 +6,9 @@
## Get file from repository ## Get file from repository
Allows you to receive information about file in repository like name, size, content. Note that file content is Base64 encoded. Allows you to receive information about file in repository like name, size,
content. Note that file content is Base64 encoded. This endpoint can be accessed
without authentication if the repository is publicly accessible.
``` ```
GET /projects/:id/repository/files GET /projects/:id/repository/files
......
module API module API
# Projects API # Projects API
class Files < Grape::API class Files < Grape::API
before { authenticate! }
helpers do helpers do
def commit_params(attrs) def commit_params(attrs)
{ {
......
...@@ -4,7 +4,14 @@ describe API::Files, api: true do ...@@ -4,7 +4,14 @@ describe API::Files, api: true do
include ApiHelpers include ApiHelpers
let(:user) { create(:user) } let(:user) { create(:user) }
let!(:project) { create(:project, namespace: user.namespace ) } let!(:project) { create(:project, namespace: user.namespace ) }
let(:guest) { create(:user).tap { |u| create(:project_member, :guest, user: u, project: project) } }
let(:file_path) { 'files/ruby/popen.rb' } let(:file_path) { 'files/ruby/popen.rb' }
let(:params) do
{
file_path: file_path,
ref: 'master'
}
end
let(:author_email) { FFaker::Internet.email } let(:author_email) { FFaker::Internet.email }
# I have to remove periods from the end of the name # I have to remove periods from the end of the name
...@@ -24,36 +31,72 @@ describe API::Files, api: true do ...@@ -24,36 +31,72 @@ describe API::Files, api: true do
before { project.team << [user, :developer] } before { project.team << [user, :developer] }
describe "GET /projects/:id/repository/files" do describe "GET /projects/:id/repository/files" do
it "returns file info" do let(:route) { "/projects/#{project.id}/repository/files" }
params = {
file_path: file_path,
ref: 'master',
}
get api("/projects/#{project.id}/repository/files", user), params shared_examples_for 'repository files' do
it "returns file info" do
get api(route, current_user), params
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(json_response['file_path']).to eq(file_path) expect(json_response['file_path']).to eq(file_path)
expect(json_response['file_name']).to eq('popen.rb') expect(json_response['file_name']).to eq('popen.rb')
expect(json_response['last_commit_id']).to eq('570e7b2abdd848b95f2f578043fc23bd6f6fd24d') expect(json_response['last_commit_id']).to eq('570e7b2abdd848b95f2f578043fc23bd6f6fd24d')
expect(Base64.decode64(json_response['content']).lines.first).to eq("require 'fileutils'\n") expect(Base64.decode64(json_response['content']).lines.first).to eq("require 'fileutils'\n")
end end
it "returns a 400 bad request if no params given" do context 'when no params are given' do
get api("/projects/#{project.id}/repository/files", user) it_behaves_like '400 response' do
let(:request) { get api(route, current_user) }
end
end
expect(response).to have_http_status(400) context 'when file_path does not exist' do
let(:params) do
{
file_path: 'app/models/application.rb',
ref: 'master',
}
end
it_behaves_like '404 response' do
let(:request) { get api(route, current_user), params }
let(:message) { '404 File Not Found' }
end
end
context 'when repository is disabled' do
include_context 'disabled repository'
it_behaves_like '403 response' do
let(:request) { get api(route, current_user), params }
end
end
end end
it "returns a 404 if such file does not exist" do context 'when unauthenticated', 'and project is public' do
params = { it_behaves_like 'repository files' do
file_path: 'app/models/application.rb', let(:project) { create(:project, :public) }
ref: 'master', let(:current_user) { nil }
} end
end
get api("/projects/#{project.id}/repository/files", user), params context 'when unauthenticated', 'and project is private' do
it_behaves_like '404 response' do
let(:request) { get api(route), params }
let(:message) { '404 Project Not Found' }
end
end
context 'when authenticated', 'as a developer' do
it_behaves_like 'repository files' do
let(:current_user) { user }
end
end
expect(response).to have_http_status(404) context 'when authenticated', 'as a guest' do
it_behaves_like '403 response' do
let(:request) { get api(route, guest), params }
end
end end
end end
......
...@@ -11,17 +11,6 @@ describe API::Repositories, api: true do ...@@ -11,17 +11,6 @@ describe API::Repositories, api: true do
let!(:project) { create(:project, creator_id: user.id) } let!(:project) { create(:project, creator_id: user.id) }
let!(:master) { create(:project_member, :master, user: user, project: project) } let!(:master) { create(:project_member, :master, user: user, project: project) }
shared_context 'disabled repository' do
before do
project.project_feature.update_attributes!(
repository_access_level: ProjectFeature::DISABLED,
merge_requests_access_level: ProjectFeature::DISABLED,
builds_access_level: ProjectFeature::DISABLED
)
expect(project.feature_available?(:repository, current_user)).to be false
end
end
describe "GET /projects/:id/repository/tree" do describe "GET /projects/:id/repository/tree" do
let(:route) { "/projects/#{project.id}/repository/tree" } let(:route) { "/projects/#{project.id}/repository/tree" }
......
shared_context 'disabled repository' do
before do
project.project_feature.update_attributes!(
repository_access_level: ProjectFeature::DISABLED,
merge_requests_access_level: ProjectFeature::DISABLED,
builds_access_level: ProjectFeature::DISABLED
)
expect(project.feature_available?(:repository, current_user)).to be false
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