From 5652da8bb4ea26acd35a241683e242439fefdd33 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9my=20Coutable?= <remy@rymai.me>
Date: Fri, 16 Dec 2016 18:58:24 +0100
Subject: [PATCH] Allow unauthenticated access to Repositories Files API GET
 endpoints
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Rémy Coutable <remy@rymai.me>
---
 changelogs/unreleased/4269-public-api.yml     |  2 +-
 .../unreleased/4269-public-files-api.yml      |  4 ++
 .../4269-public-repositories-api.yml          |  2 +-
 doc/api/repository_files.md                   |  4 +-
 lib/api/files.rb                              |  2 -
 spec/requests/api/files_spec.rb               | 37 +++++++++++++------
 6 files changed, 35 insertions(+), 16 deletions(-)
 create mode 100644 changelogs/unreleased/4269-public-files-api.yml

diff --git a/changelogs/unreleased/4269-public-api.yml b/changelogs/unreleased/4269-public-api.yml
index 560bc6a4f13..9de739d0cad 100644
--- a/changelogs/unreleased/4269-public-api.yml
+++ b/changelogs/unreleased/4269-public-api.yml
@@ -1,4 +1,4 @@
 ---
-title: Allow public access to some Project API endpoints
+title: Allow unauthenticated access to some Project API GET endpoints
 merge_request: 7843
 author:
diff --git a/changelogs/unreleased/4269-public-files-api.yml b/changelogs/unreleased/4269-public-files-api.yml
new file mode 100644
index 00000000000..e8f9e9b5ed3
--- /dev/null
+++ b/changelogs/unreleased/4269-public-files-api.yml
@@ -0,0 +1,4 @@
+---
+title: Allow unauthenticated access to Repositories Files API GET endpoints
+merge_request:
+author:
diff --git a/changelogs/unreleased/4269-public-repositories-api.yml b/changelogs/unreleased/4269-public-repositories-api.yml
index 861307a022b..38984eed904 100644
--- a/changelogs/unreleased/4269-public-repositories-api.yml
+++ b/changelogs/unreleased/4269-public-repositories-api.yml
@@ -1,4 +1,4 @@
 ---
-title: Allow Repositories API GET endpoints to be requested anonymously
+title: Allow unauthenticated access to Repositories API GET endpoints
 merge_request: 8148
 author:
diff --git a/doc/api/repository_files.md b/doc/api/repository_files.md
index b8c9eb2c9a8..8a6baed5987 100644
--- a/doc/api/repository_files.md
+++ b/doc/api/repository_files.md
@@ -6,7 +6,9 @@
 
 ## 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
diff --git a/lib/api/files.rb b/lib/api/files.rb
index 28f306e45f3..532a317c89e 100644
--- a/lib/api/files.rb
+++ b/lib/api/files.rb
@@ -1,8 +1,6 @@
 module API
   # Projects API
   class Files < Grape::API
-    before { authenticate! }
-
     helpers do
       def commit_params(attrs)
         {
diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb
index 2081f80ccc1..4dd312e2852 100644
--- a/spec/requests/api/files_spec.rb
+++ b/spec/requests/api/files_spec.rb
@@ -24,19 +24,34 @@ describe API::Files, api: true  do
   before { project.team << [user, :developer] }
 
   describe "GET /projects/:id/repository/files" do
-    it "returns file info" do
-      params = {
-        file_path: file_path,
-        ref: 'master',
-      }
+    shared_examples_for 'repository files' do
+      it "returns file info" do
+        params = {
+          file_path: file_path,
+          ref: 'master',
+        }
 
-      get api("/projects/#{project.id}/repository/files", user), params
+        get api("/projects/#{project.id}/repository/files", current_user), params
 
-      expect(response).to have_http_status(200)
-      expect(json_response['file_path']).to eq(file_path)
-      expect(json_response['file_name']).to eq('popen.rb')
-      expect(json_response['last_commit_id']).to eq('570e7b2abdd848b95f2f578043fc23bd6f6fd24d')
-      expect(Base64.decode64(json_response['content']).lines.first).to eq("require 'fileutils'\n")
+        expect(response).to have_http_status(200)
+        expect(json_response['file_path']).to eq(file_path)
+        expect(json_response['file_name']).to eq('popen.rb')
+        expect(json_response['last_commit_id']).to eq('570e7b2abdd848b95f2f578043fc23bd6f6fd24d')
+        expect(Base64.decode64(json_response['content']).lines.first).to eq("require 'fileutils'\n")
+      end
+    end
+
+    context 'when unauthenticated' do
+      it_behaves_like 'repository files' do
+        let(:project) { create(:project, :public) }
+        let(:current_user) { nil }
+      end
+    end
+
+    context 'when authenticated' do
+      it_behaves_like 'repository files' do
+        let(:current_user) { user }
+      end
     end
 
     it "returns a 400 bad request if no params given" do
-- 
GitLab