From c9be74e24797c1dab5b443728349bb0c5ce969c3 Mon Sep 17 00:00:00 2001
From: Felipe Artur <felipefac@gmail.com>
Date: Mon, 16 May 2016 16:43:19 -0300
Subject: [PATCH] Fix single note api request

---
 lib/api/helpers.rb              |  4 ++++
 lib/api/notes.rb                | 10 +++++-----
 spec/requests/api/notes_spec.rb | 17 ++++++++++++++---
 3 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index 40c967453fb..1003b596aec 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -397,5 +397,9 @@ module API
       error!(errors[:access_level], 422) if errors[:access_level].any?
       not_found!(errors)
     end
+
+    def noteable_ability_name(noteable)
+      "read_#{noteable.class.to_s.underscore.downcase}".to_sym
+    end
   end
 end
diff --git a/lib/api/notes.rb b/lib/api/notes.rb
index f0116acd90f..c49b107d1d9 100644
--- a/lib/api/notes.rb
+++ b/lib/api/notes.rb
@@ -20,9 +20,8 @@ module API
         #   GET /projects/:id/snippets/:noteable_id/notes
         get ":id/#{noteables_str}/:#{noteable_id_str}/notes" do
           @noteable = user_project.send(noteables_str.to_sym).find(params[noteable_id_str.to_sym])
-          read_ability_name = "read_#{@noteable.class.to_s.underscore.downcase}".to_sym
 
-          if can?(current_user, read_ability_name, @noteable)
+          if can?(current_user, noteable_ability_name(@noteable), @noteable)
             # We exclude notes that are cross-references and that cannot be viewed
             # by the current user. By doing this exclusion at this level and not
             # at the DB query level (which we cannot in that case), the current
@@ -52,11 +51,12 @@ module API
         get ":id/#{noteables_str}/:#{noteable_id_str}/notes/:note_id" do
           @noteable = user_project.send(noteables_str.to_sym).find(params[noteable_id_str.to_sym])
           @note = @noteable.notes.find(params[:note_id])
+          can_read_note = can?(current_user, noteable_ability_name(@noteable), @noteable) && !@note.cross_reference_not_visible_for?(current_user)
 
-          if @note.cross_reference_not_visible_for?(current_user)
-            not_found!("Note")
-          else
+          if can_read_note
             present @note, with: Entities::Note
+          else
+            not_found!("Note")
           end
         end
 
diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb
index f9bfee94424..ed1ed5aeb95 100644
--- a/spec/requests/api/notes_spec.rb
+++ b/spec/requests/api/notes_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
 describe API::API, api: true  do
   include ApiHelpers
   let(:user) { create(:user) }
-  let!(:project) { create(:project, namespace: user.namespace) }
+  let!(:project) { create(:project, :public, namespace: user.namespace) }
   let!(:issue) { create(:issue, project: project, author: user) }
   let!(:merge_request) { create(:merge_request, source_project: project, target_project: project, author: user) }
   let!(:snippet) { create(:project_snippet, project: project, author: user) }
@@ -51,7 +51,7 @@ describe API::API, api: true  do
         expect(response.status).to eq(404)
       end
 
-      context "that references a private issue" do
+      context "and current user cannot view the notes" do
         it "should return an empty array" do
           get api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes", user)
 
@@ -142,13 +142,24 @@ describe API::API, api: true  do
         expect(response.status).to eq(404)
       end
 
-      context "that references a private issue" do
+      context "and current user cannot view the note" do
         it "should return a 404 error" do
           get api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes/#{cross_reference_note.id}", user)
 
           expect(response.status).to eq(404)
         end
 
+        context "when issue is confidential" do
+          before { issue.update_attributes(confidential: true) }
+
+          it "returns 404" do
+            get api("/projects/#{project.id}/issues/#{issue.id}/notes/#{issue_note.id}", private_user)
+
+            expect(response.status).to eq(404)
+          end
+        end
+
+
         context "and current user can view the note" do
           it "should return an issue note by id" do
             get api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes/#{cross_reference_note.id}", private_user)
-- 
GitLab