Merge branch 'security-epic-notes-api-reveals-historical-info-ce-master' into 'master'
Filter out old system notes for epics in notes api endpoint response See merge request gitlab/gitlabhq!3224
This commit is contained in:
commit
5a008d1368
11 changed files with 42 additions and 23 deletions
|
@ -110,7 +110,7 @@ module IssuableActions
|
||||||
end
|
end
|
||||||
|
|
||||||
notes = prepare_notes_for_rendering(notes)
|
notes = prepare_notes_for_rendering(notes)
|
||||||
notes = notes.reject { |n| n.cross_reference_not_visible_for?(current_user) }
|
notes = notes.select { |n| n.visible_for?(current_user) }
|
||||||
|
|
||||||
discussions = Discussion.build_collection(notes, issuable)
|
discussions = Discussion.build_collection(notes, issuable)
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ module NotesActions
|
||||||
end
|
end
|
||||||
|
|
||||||
notes = prepare_notes_for_rendering(notes)
|
notes = prepare_notes_for_rendering(notes)
|
||||||
notes = notes.reject { |n| n.cross_reference_not_visible_for?(current_user) }
|
notes = notes.select { |n| n.visible_for?(current_user) }
|
||||||
|
|
||||||
notes_json[:notes] =
|
notes_json[:notes] =
|
||||||
if use_note_serializer?
|
if use_note_serializer?
|
||||||
|
|
|
@ -365,6 +365,8 @@ class Group < Namespace
|
||||||
end
|
end
|
||||||
|
|
||||||
def max_member_access_for_user(user)
|
def max_member_access_for_user(user)
|
||||||
|
return GroupMember::NO_ACCESS unless user
|
||||||
|
|
||||||
return GroupMember::OWNER if user.admin?
|
return GroupMember::OWNER if user.admin?
|
||||||
|
|
||||||
members_with_parents
|
members_with_parents
|
||||||
|
|
|
@ -332,6 +332,10 @@ class Note < ApplicationRecord
|
||||||
cross_reference? && !all_referenced_mentionables_allowed?(user)
|
cross_reference? && !all_referenced_mentionables_allowed?(user)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def visible_for?(user)
|
||||||
|
!cross_reference_not_visible_for?(user)
|
||||||
|
end
|
||||||
|
|
||||||
def award_emoji?
|
def award_emoji?
|
||||||
can_be_award_emoji? && contains_emoji_only?
|
can_be_award_emoji? && contains_emoji_only?
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Filter out old system notes for epics in notes api endpoint response
|
||||||
|
merge_request:
|
||||||
|
author:
|
||||||
|
type: security
|
|
@ -239,7 +239,7 @@ module API
|
||||||
# because notes are redacted if they point to projects that
|
# because notes are redacted if they point to projects that
|
||||||
# cannot be accessed by the user.
|
# cannot be accessed by the user.
|
||||||
notes = prepare_notes_for_rendering(notes)
|
notes = prepare_notes_for_rendering(notes)
|
||||||
notes.reject { |n| n.cross_reference_not_visible_for?(current_user) }
|
notes.select { |n| n.visible_for?(current_user) }
|
||||||
end
|
end
|
||||||
# rubocop: enable CodeReuse/ActiveRecord
|
# rubocop: enable CodeReuse/ActiveRecord
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,7 +12,7 @@ module API
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_note(noteable, note_id)
|
def update_note(noteable, note_id)
|
||||||
note = noteable.notes.find(params[:note_id])
|
note = noteable.notes.find(note_id)
|
||||||
|
|
||||||
authorize! :admin_note, note
|
authorize! :admin_note, note
|
||||||
|
|
||||||
|
@ -61,8 +61,8 @@ module API
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_note(noteable, note_id)
|
def get_note(noteable, note_id)
|
||||||
note = noteable.notes.with_metadata.find(params[:note_id])
|
note = noteable.notes.with_metadata.find(note_id)
|
||||||
can_read_note = !note.cross_reference_not_visible_for?(current_user)
|
can_read_note = note.visible_for?(current_user)
|
||||||
|
|
||||||
if can_read_note
|
if can_read_note
|
||||||
present note, with: Entities::Note
|
present note, with: Entities::Note
|
||||||
|
|
|
@ -42,7 +42,7 @@ module API
|
||||||
# array returned, but this is really a edge-case.
|
# array returned, but this is really a edge-case.
|
||||||
notes = paginate(raw_notes)
|
notes = paginate(raw_notes)
|
||||||
notes = prepare_notes_for_rendering(notes)
|
notes = prepare_notes_for_rendering(notes)
|
||||||
notes = notes.reject { |n| n.cross_reference_not_visible_for?(current_user) }
|
notes = notes.select { |note| note.visible_for?(current_user) }
|
||||||
present notes, with: Entities::Note
|
present notes, with: Entities::Note
|
||||||
end
|
end
|
||||||
# rubocop: enable CodeReuse/ActiveRecord
|
# rubocop: enable CodeReuse/ActiveRecord
|
||||||
|
|
|
@ -7,7 +7,7 @@ FactoryBot.define do
|
||||||
sequence(:email_alias) { |n| "user.alias#{n}@example.org" }
|
sequence(:email_alias) { |n| "user.alias#{n}@example.org" }
|
||||||
sequence(:title) { |n| "My title #{n}" }
|
sequence(:title) { |n| "My title #{n}" }
|
||||||
sequence(:filename) { |n| "filename-#{n}.rb" }
|
sequence(:filename) { |n| "filename-#{n}.rb" }
|
||||||
sequence(:url) { |n| "http://example#{n}.org" }
|
sequence(:url) { |n| "http://example#{n}.test" }
|
||||||
sequence(:label_title) { |n| "label#{n}" }
|
sequence(:label_title) { |n| "label#{n}" }
|
||||||
sequence(:branch) { |n| "my-branch-#{n}" }
|
sequence(:branch) { |n| "my-branch-#{n}" }
|
||||||
sequence(:past_time) { |n| 4.hours.ago + (2 * n).seconds }
|
sequence(:past_time) { |n| 4.hours.ago + (2 * n).seconds }
|
||||||
|
|
|
@ -4,6 +4,7 @@ require 'spec_helper'
|
||||||
|
|
||||||
describe Ci::Pipeline, :mailer do
|
describe Ci::Pipeline, :mailer do
|
||||||
include ProjectForksHelper
|
include ProjectForksHelper
|
||||||
|
include StubRequests
|
||||||
|
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
set(:project) { create(:project) }
|
set(:project) { create(:project) }
|
||||||
|
@ -2504,7 +2505,7 @@ describe Ci::Pipeline, :mailer do
|
||||||
let(:enabled) { true }
|
let(:enabled) { true }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
WebMock.stub_request(:post, hook.url)
|
stub_full_request(hook.url, method: :post)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with multiple builds' do
|
context 'with multiple builds' do
|
||||||
|
@ -2558,7 +2559,7 @@ describe Ci::Pipeline, :mailer do
|
||||||
end
|
end
|
||||||
|
|
||||||
def have_requested_pipeline_hook(status)
|
def have_requested_pipeline_hook(status)
|
||||||
have_requested(:post, hook.url).with do |req|
|
have_requested(:post, stubbed_hostname(hook.url)).with do |req|
|
||||||
json_body = JSON.parse(req.body)
|
json_body = JSON.parse(req.body)
|
||||||
json_body['object_attributes']['status'] == status &&
|
json_body['object_attributes']['status'] == status &&
|
||||||
json_body['builds'].length == 2
|
json_body['builds'].length == 2
|
||||||
|
|
|
@ -55,31 +55,38 @@ describe WebHookService do
|
||||||
describe '#execute' do
|
describe '#execute' do
|
||||||
before do
|
before do
|
||||||
project.hooks << [project_hook]
|
project.hooks << [project_hook]
|
||||||
|
|
||||||
WebMock.stub_request(:post, project_hook.url)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when token is defined' do
|
context 'when token is defined' do
|
||||||
let(:project_hook) { create(:project_hook, :token) }
|
let(:project_hook) { create(:project_hook, :token) }
|
||||||
|
|
||||||
it 'POSTs to the webhook URL' do
|
it 'POSTs to the webhook URL' do
|
||||||
|
stub_full_request(project_hook.url, method: :post)
|
||||||
|
|
||||||
service_instance.execute
|
service_instance.execute
|
||||||
expect(WebMock).to have_requested(:post, project_hook.url).with(
|
|
||||||
|
expect(WebMock).to have_requested(:post, stubbed_hostname(project_hook.url)).with(
|
||||||
headers: headers.merge({ 'X-Gitlab-Token' => project_hook.token })
|
headers: headers.merge({ 'X-Gitlab-Token' => project_hook.token })
|
||||||
).once
|
).once
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'POSTs to the webhook URL' do
|
it 'POSTs to the webhook URL' do
|
||||||
|
stub_full_request(project_hook.url, method: :post)
|
||||||
|
|
||||||
service_instance.execute
|
service_instance.execute
|
||||||
expect(WebMock).to have_requested(:post, project_hook.url).with(
|
|
||||||
|
expect(WebMock).to have_requested(:post, stubbed_hostname(project_hook.url)).with(
|
||||||
headers: headers
|
headers: headers
|
||||||
).once
|
).once
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'POSTs the data as JSON' do
|
it 'POSTs the data as JSON' do
|
||||||
|
stub_full_request(project_hook.url, method: :post)
|
||||||
|
|
||||||
service_instance.execute
|
service_instance.execute
|
||||||
expect(WebMock).to have_requested(:post, project_hook.url).with(
|
|
||||||
|
expect(WebMock).to have_requested(:post, stubbed_hostname(project_hook.url)).with(
|
||||||
headers: headers
|
headers: headers
|
||||||
).once
|
).once
|
||||||
end
|
end
|
||||||
|
@ -115,7 +122,7 @@ describe WebHookService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'catches exceptions' do
|
it 'catches exceptions' do
|
||||||
WebMock.stub_request(:post, project_hook.url).to_raise(StandardError.new('Some error'))
|
stub_full_request(project_hook.url, method: :post).to_raise(StandardError.new('Some error'))
|
||||||
|
|
||||||
expect { service_instance.execute }.to raise_error(StandardError)
|
expect { service_instance.execute }.to raise_error(StandardError)
|
||||||
end
|
end
|
||||||
|
@ -125,20 +132,20 @@ describe WebHookService do
|
||||||
exceptions.each do |exception_class|
|
exceptions.each do |exception_class|
|
||||||
exception = exception_class.new('Exception message')
|
exception = exception_class.new('Exception message')
|
||||||
|
|
||||||
WebMock.stub_request(:post, project_hook.url).to_raise(exception)
|
stub_full_request(project_hook.url, method: :post).to_raise(exception)
|
||||||
expect(service_instance.execute).to eq({ status: :error, message: exception.to_s })
|
expect(service_instance.execute).to eq({ status: :error, message: exception.to_s })
|
||||||
expect { service_instance.execute }.not_to raise_error
|
expect { service_instance.execute }.not_to raise_error
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'handles 200 status code' do
|
it 'handles 200 status code' do
|
||||||
WebMock.stub_request(:post, project_hook.url).to_return(status: 200, body: 'Success')
|
stub_full_request(project_hook.url, method: :post).to_return(status: 200, body: 'Success')
|
||||||
|
|
||||||
expect(service_instance.execute).to include({ status: :success, http_status: 200, message: 'Success' })
|
expect(service_instance.execute).to include({ status: :success, http_status: 200, message: 'Success' })
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'handles 2xx status codes' do
|
it 'handles 2xx status codes' do
|
||||||
WebMock.stub_request(:post, project_hook.url).to_return(status: 201, body: 'Success')
|
stub_full_request(project_hook.url, method: :post).to_return(status: 201, body: 'Success')
|
||||||
|
|
||||||
expect(service_instance.execute).to include({ status: :success, http_status: 201, message: 'Success' })
|
expect(service_instance.execute).to include({ status: :success, http_status: 201, message: 'Success' })
|
||||||
end
|
end
|
||||||
|
@ -148,7 +155,7 @@ describe WebHookService do
|
||||||
|
|
||||||
context 'with success' do
|
context 'with success' do
|
||||||
before do
|
before do
|
||||||
WebMock.stub_request(:post, project_hook.url).to_return(status: 200, body: 'Success')
|
stub_full_request(project_hook.url, method: :post).to_return(status: 200, body: 'Success')
|
||||||
service_instance.execute
|
service_instance.execute
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -165,7 +172,7 @@ describe WebHookService do
|
||||||
|
|
||||||
context 'with exception' do
|
context 'with exception' do
|
||||||
before do
|
before do
|
||||||
WebMock.stub_request(:post, project_hook.url).to_raise(SocketError.new('Some HTTP Post error'))
|
stub_full_request(project_hook.url, method: :post).to_raise(SocketError.new('Some HTTP Post error'))
|
||||||
service_instance.execute
|
service_instance.execute
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -182,7 +189,7 @@ describe WebHookService do
|
||||||
|
|
||||||
context 'with unsafe response body' do
|
context 'with unsafe response body' do
|
||||||
before do
|
before do
|
||||||
WebMock.stub_request(:post, project_hook.url).to_return(status: 200, body: "\xBB")
|
stub_full_request(project_hook.url, method: :post).to_return(status: 200, body: "\xBB")
|
||||||
service_instance.execute
|
service_instance.execute
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -202,7 +209,7 @@ describe WebHookService do
|
||||||
let(:service_instance) { described_class.new(service_hook, data, 'service_hook') }
|
let(:service_instance) { described_class.new(service_hook, data, 'service_hook') }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
WebMock.stub_request(:post, service_hook.url).to_return(status: 200, body: 'Success')
|
stub_full_request(service_hook.url, method: :post).to_return(status: 200, body: 'Success')
|
||||||
end
|
end
|
||||||
|
|
||||||
it { expect { service_instance.execute }.not_to change(WebHookLog, :count) }
|
it { expect { service_instance.execute }.not_to change(WebHookLog, :count) }
|
||||||
|
|
Loading…
Reference in a new issue