Commit da8ac163 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'issue_17302' into 'master'

Fix api leaking notes when user is not authorized to read noteable

fixes #17302

See merge request !4102
parents 98d88e81 5bf49bb6
...@@ -21,6 +21,7 @@ v 8.8.0 (unreleased) ...@@ -21,6 +21,7 @@ v 8.8.0 (unreleased)
- Bump mail_room to 0.7.0 to fix stuck IDLE connections - Bump mail_room to 0.7.0 to fix stuck IDLE connections
- Remove future dates from contribution calendar graph. - Remove future dates from contribution calendar graph.
- Support e-mail notifications for comments on project snippets - Support e-mail notifications for comments on project snippets
- Fix API leak of notes of unauthorized issues, snippets and merge requests
- Use ActionDispatch Remote IP for Akismet checking - Use ActionDispatch Remote IP for Akismet checking
- Fix error when visiting commit builds page before build was updated - Fix error when visiting commit builds page before build was updated
- Add 'l' shortcut to open Label dropdown on issuables and 'i' to create new issue on a project - Add 'l' shortcut to open Label dropdown on issuables and 'i' to create new issue on a project
......
...@@ -19,20 +19,24 @@ module API ...@@ -19,20 +19,24 @@ module API
# GET /projects/:id/issues/:noteable_id/notes # GET /projects/:id/issues/:noteable_id/notes
# GET /projects/:id/snippets/:noteable_id/notes # GET /projects/:id/snippets/:noteable_id/notes
get ":id/#{noteables_str}/:#{noteable_id_str}/notes" do get ":id/#{noteables_str}/:#{noteable_id_str}/notes" do
@noteable = user_project.send(:"#{noteables_str}").find(params[:"#{noteable_id_str}"]) @noteable = user_project.send(noteables_str.to_sym).find(params[noteable_id_str.to_sym])
# We exclude notes that are cross-references and that cannot be viewed if can?(current_user, noteable_read_ability_name(@noteable), @noteable)
# by the current user. By doing this exclusion at this level and not # We exclude notes that are cross-references and that cannot be viewed
# at the DB query level (which we cannot in that case), the current # by the current user. By doing this exclusion at this level and not
# page can have less elements than :per_page even if # at the DB query level (which we cannot in that case), the current
# there's more than one page. # page can have less elements than :per_page even if
notes = # there's more than one page.
# paginate() only works with a relation. This could lead to a notes =
# mismatch between the pagination headers info and the actual notes # paginate() only works with a relation. This could lead to a
# array returned, but this is really a edge-case. # mismatch between the pagination headers info and the actual notes
paginate(@noteable.notes). # array returned, but this is really a edge-case.
reject { |n| n.cross_reference_not_visible_for?(current_user) } paginate(@noteable.notes).
present notes, with: Entities::Note reject { |n| n.cross_reference_not_visible_for?(current_user) }
present notes, with: Entities::Note
else
not_found!("Notes")
end
end end
# Get a single +noteable+ note # Get a single +noteable+ note
...@@ -45,13 +49,14 @@ module API ...@@ -45,13 +49,14 @@ module API
# GET /projects/:id/issues/:noteable_id/notes/:note_id # GET /projects/:id/issues/:noteable_id/notes/:note_id
# GET /projects/:id/snippets/:noteable_id/notes/:note_id # GET /projects/:id/snippets/:noteable_id/notes/:note_id
get ":id/#{noteables_str}/:#{noteable_id_str}/notes/:note_id" do get ":id/#{noteables_str}/:#{noteable_id_str}/notes/:note_id" do
@noteable = user_project.send(:"#{noteables_str}").find(params[:"#{noteable_id_str}"]) @noteable = user_project.send(noteables_str.to_sym).find(params[noteable_id_str.to_sym])
@note = @noteable.notes.find(params[:note_id]) @note = @noteable.notes.find(params[:note_id])
can_read_note = can?(current_user, noteable_read_ability_name(@noteable), @noteable) && !@note.cross_reference_not_visible_for?(current_user)
if @note.cross_reference_not_visible_for?(current_user) if can_read_note
not_found!("Note")
else
present @note, with: Entities::Note present @note, with: Entities::Note
else
not_found!("Note")
end end
end end
...@@ -136,5 +141,11 @@ module API ...@@ -136,5 +141,11 @@ module API
end end
end end
end end
helpers do
def noteable_read_ability_name(noteable)
"read_#{noteable.class.to_s.underscore.downcase}".to_sym
end
end
end end
end end
This diff is collapsed.
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