diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 37c8345e51ee08eee90dc0269213a40cec0b7e47..4c543cc4f2afbf6f16ef644dafaa1133691dd72a 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -8,6 +8,9 @@ class NotificationService # Always notify user about ssh key added # only if ssh key is not deploy key + # + # This is security email so it will be sent + # even if user disabled notifications def new_key(key) if key.user Notify.delay.new_ssh_key_email(key.id) @@ -21,10 +24,10 @@ class NotificationService # * project team members with notification level higher then Participating # def close_issue(issue, current_user) - recipients = [issue.author, issue.assignee].compact.uniq + recipients = reject_muted_users([issue.author, issue.assignee]) # Dont send email to me when I close an issue - recipients.reject! { |u| u == current_user } + recipients.delete(current_user) recipients.each do |recipient| Notify.delay.issue_status_changed_email(recipient.id, issue.id, issue.state, current_user.id) @@ -37,14 +40,7 @@ class NotificationService # * issue new assignee if his notification level is not Disabled # def reassigned_issue(issue, current_user) - recipient_ids = [issue.assignee_id, issue.assignee_id_was].compact.uniq - - # Reject me from recipients if I reassign an issue - recipient_ids.reject! { |id| id == current_user.id } - - recipient_ids.each do |recipient_id| - Notify.delay.reassigned_issue_email(recipient_id, issue.id, issue.assignee_id_was) - end + reassign_email(merge_request, current_user, 'reassigned_issue_email') end # When create an issue we should send next emails: @@ -52,7 +48,11 @@ class NotificationService # * issue assignee if his notification level is not Disabled # def new_issue(issue, current_user) + if issue.assignee && issue.assignee != current_user + # skip if assignee notification disabled + return true if issue.assignee.notification.disabled? + Notify.delay.new_issue_email(issue.id) end end @@ -63,6 +63,9 @@ class NotificationService # def new_merge_request(merge_request, current_user) if merge_request.assignee && merge_request.assignee != current_user + # skip if assignee notification disabled + return true if merge_request.assignee.notification.disabled? + Notify.delay.new_merge_request_email(merge_request.id) end end @@ -73,12 +76,7 @@ class NotificationService # * merge_request assignee if his notification level is not Disabled # def reassigned_merge_request(merge_request, current_user) - recipients_ids = merge_request.assignee_id_was, merge_request.assignee_id - recipients_ids.delete current_user.id - - recipients_ids.each do |recipient_id| - Notify.delay.reassigned_merge_request_email(recipient_id, merge_request.id, merge_request.assignee_id_was) - end + reassign_email(merge_request, current_user, 'reassigned_merge_request_email') end # Notify new user with email after creation @@ -93,15 +91,17 @@ class NotificationService # def new_note(note) if note.notify - users = note.project.users.reject { |u| u.id == note.author.id } + users = note.project.users + users = reject_muted_users(users) + users.delete(note.author) # Note: wall posts are not "attached" to anything, so fall back to "Wall" noteable_type = note.noteable_type.presence || "Wall" notify_method = "note_#{noteable_type.underscore}_email".to_sym if Notify.respond_to? notify_method - team_without_note_author(note).map do |u| - Notify.delay.send(notify_method, u.id, note.id) + users.each do |user| + Notify.delay.send(notify_method, user.id, note.id) end end elsif note.notify_author && note.commit_author @@ -116,4 +116,28 @@ class NotificationService def update_team_member(users_project) Notify.delay.project_access_granted_email(users_project.id) end + + protected + + # Remove users with disabled notifications from array + # Also remove duplications and nil recipients + def reject_muted_users(users) + users.compact.uniq.reject do |user| + user.notification.disabled? + end + end + + def reassign_email(target, current_user, entity_sym) + recipients = User.where(id: [target.assignee_id, target.assignee_id_was]) + + # reject users with disabled notifications + recipients = reject_muted_users(recipients) + + # Reject me from recipients if I reassign an item + recipients.delete(current_user) + + recipients.each do |recipient_id| + Notify.delay.send(method, recipient.id, target.id, target.assignee_id_was) + end + end end