Fix api leaking notes when user is not authorized to read noteable
This commit is contained in:
parent
ae25c19ee5
commit
e56e3cdc62
|
|
@ -15,6 +15,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
|
||||||
|
|
|
||||||
|
|
@ -20,19 +20,24 @@ module API
|
||||||
# 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}").find(params[:"#{noteable_id_str}"])
|
||||||
|
read_ability_name = "read_#{@noteable.class.to_s.underscore.downcase}".to_sym
|
||||||
|
|
||||||
# We exclude notes that are cross-references and that cannot be viewed
|
if can?(current_user, read_ability_name, @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
|
||||||
|
render_api_error!("Not found.", 404)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get a single +noteable+ note
|
# Get a single +noteable+ note
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,15 @@ describe API::API, api: true do
|
||||||
expect(json_response).to be_empty
|
expect(json_response).to be_empty
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "and issue is confidential" do
|
||||||
|
before { ext_issue.update_attributes(confidential: true) }
|
||||||
|
|
||||||
|
it "returns 404" do
|
||||||
|
get api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes", user)
|
||||||
|
expect(response.status).to eq(404)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "and current user can view the note" do
|
context "and current user can view the note" do
|
||||||
it "should return an empty array" do
|
it "should return an empty array" do
|
||||||
get api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes", private_user)
|
get api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes", private_user)
|
||||||
|
|
@ -80,6 +89,11 @@ describe API::API, api: true do
|
||||||
get api("/projects/#{project.id}/snippets/42/notes", user)
|
get api("/projects/#{project.id}/snippets/42/notes", user)
|
||||||
expect(response.status).to eq(404)
|
expect(response.status).to eq(404)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "returns 404 when not authorized" do
|
||||||
|
get api("/projects/#{project.id}/snippets/#{snippet.id}/notes", private_user)
|
||||||
|
expect(response.status).to eq(404)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when noteable is a Merge Request" do
|
context "when noteable is a Merge Request" do
|
||||||
|
|
@ -94,6 +108,11 @@ describe API::API, api: true do
|
||||||
get api("/projects/#{project.id}/merge_requests/4444/notes", user)
|
get api("/projects/#{project.id}/merge_requests/4444/notes", user)
|
||||||
expect(response.status).to eq(404)
|
expect(response.status).to eq(404)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "returns 404 when not authorized" do
|
||||||
|
get api("/projects/#{project.id}/merge_requests/4444/notes", private_user)
|
||||||
|
expect(response.status).to eq(404)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue