diff --git a/app/policies/ci/build_policy.rb b/app/policies/ci/build_policy.rb index 2232e231cf84f0b9c37505c3a522185db3a3040e..8b25332b73ceeeb2635ae78d1d0665b36dca8017 100644 --- a/app/policies/ci/build_policy.rb +++ b/app/policies/ci/build_policy.rb @@ -5,7 +5,7 @@ module Ci # If we can't read build we should also not have that # ability when looking at this in context of commit_status - %w(read create update admin).each do |rule| + %w[read create update admin].each do |rule| cannot! :"#{rule}_commit_status" unless can? :"#{rule}_build" end end diff --git a/app/policies/ci/pipeline_policy.rb b/app/policies/ci/pipeline_policy.rb new file mode 100644 index 0000000000000000000000000000000000000000..3d2eef1c50cf95b13a188870ec98a38355ceb1a3 --- /dev/null +++ b/app/policies/ci/pipeline_policy.rb @@ -0,0 +1,4 @@ +module Ci + class PipelinePolicy < BuildPolicy + end +end diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 2cc9a9fd7bf770dd0a90b84096b2723dc66b2bb0..f48255b2e6ce0c379bdb7db393de1d1cb0a9c853 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -489,9 +489,14 @@ class NotificationService end def reject_users_without_access(recipients, target) - return recipients unless target.is_a?(Issuable) - - ability = :"read_#{target.to_ability_name}" + ability = case target + when Issuable + :"read_#{target.to_ability_name}" + when Ci::Pipeline + :read_build # We have build trace in pipeline emails + end + + return recipients unless ability recipients.select do |user| user.can?(ability, target) diff --git a/spec/workers/pipeline_notification_worker_spec.rb b/spec/workers/pipeline_notification_worker_spec.rb index c334b2057a6ee90795fa73fed9390ea7ba6192a1..d487a7196800fc7298fb547fd03f6bd4a42aeb43 100644 --- a/spec/workers/pipeline_notification_worker_spec.rb +++ b/spec/workers/pipeline_notification_worker_spec.rb @@ -17,84 +17,114 @@ describe PipelineNotificationWorker do describe '#execute' do before do reset_delivered_emails! - pipeline.project.team << [watcher, Gitlab::Access::DEVELOPER] + pipeline.project.team << [pusher, Gitlab::Access::DEVELOPER] end - shared_examples 'sending emails' do - it 'sends emails' do - perform_enqueued_jobs do - subject.perform(pipeline.id) - end + context 'when watcher has developer access' do + before do + pipeline.project.team << [watcher, Gitlab::Access::DEVELOPER] + end - emails = ActionMailer::Base.deliveries - actual = emails.flat_map(&:bcc).sort - expected_receivers = [pusher, watcher].map(&:email).uniq.sort + shared_examples 'sending emails' do + it 'sends emails' do + perform_enqueued_jobs do + subject.perform(pipeline.id) + end - expect(actual).to eq(expected_receivers) - expect(emails.size).to eq(1) - expect(emails.last.subject).to include(email_subject) - end - end + emails = ActionMailer::Base.deliveries + actual = emails.flat_map(&:bcc).sort + expected_receivers = receivers.map(&:email).uniq.sort - context 'with success pipeline' do - let(:status) { 'success' } - let(:email_subject) { "Pipeline ##{pipeline.id} has succeeded" } + expect(actual).to eq(expected_receivers) + expect(emails.size).to eq(1) + expect(emails.last.subject).to include(email_subject) + end + end - it_behaves_like 'sending emails' + context 'with success pipeline' do + let(:status) { 'success' } + let(:email_subject) { "Pipeline ##{pipeline.id} has succeeded" } + let(:receivers) { [pusher, watcher] } - context 'with pipeline from someone else' do - let(:pusher) { create(:user) } + it_behaves_like 'sending emails' - context 'with success pipeline notification on' do + context 'with pipeline from someone else' do + let(:pusher) { create(:user) } let(:watcher) { user } - before do - watcher.global_notification_setting. - update(level: 'custom', success_pipeline: true) + context 'with success pipeline notification on' do + before do + watcher.global_notification_setting. + update(level: 'custom', success_pipeline: true) + end + + it_behaves_like 'sending emails' end - it_behaves_like 'sending emails' - end + context 'with success pipeline notification off' do + let(:receivers) { [pusher] } + + before do + watcher.global_notification_setting. + update(level: 'custom', success_pipeline: false) + end - context 'with success pipeline notification off' do - before do - watcher.global_notification_setting. - update(level: 'custom', success_pipeline: false) + it_behaves_like 'sending emails' end + end + + context 'with failed pipeline' do + let(:status) { 'failed' } + let(:email_subject) { "Pipeline ##{pipeline.id} has failed" } it_behaves_like 'sending emails' + + context 'with pipeline from someone else' do + let(:pusher) { create(:user) } + let(:watcher) { user } + + context 'with failed pipeline notification on' do + before do + watcher.global_notification_setting. + update(level: 'custom', failed_pipeline: true) + end + + it_behaves_like 'sending emails' + end + + context 'with failed pipeline notification off' do + let(:receivers) { [pusher] } + + before do + watcher.global_notification_setting. + update(level: 'custom', failed_pipeline: false) + end + + it_behaves_like 'sending emails' + end + end end end end - context 'with failed pipeline' do + context 'when watcher has no read_build access' do let(:status) { 'failed' } let(:email_subject) { "Pipeline ##{pipeline.id} has failed" } + let(:watcher) { create(:user) } - it_behaves_like 'sending emails' + before do + pipeline.project.team << [watcher, Gitlab::Access::GUEST] - context 'with pipeline from someone else' do - let(:pusher) { create(:user) } - - context 'with failed pipeline notification on' do - let(:watcher) { user } - - before do - watcher.global_notification_setting. - update(level: 'custom', failed_pipeline: true) - end + watcher.global_notification_setting. + update(level: 'custom', failed_pipeline: true) - it_behaves_like 'sending emails' + perform_enqueued_jobs do + subject.perform(pipeline.id) end + end - context 'with failed pipeline notification off' do - before do - watcher.global_notification_setting. - update(level: 'custom', failed_pipeline: false) - end - - it_behaves_like 'sending emails' - end + it 'does not send emails' do + should_only_email(pusher, kind: :bcc) end end end