diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/mailers/emails/issues.rb | 8 | ||||
-rw-r--r-- | app/mailers/emails/merge_requests.rb | 11 | ||||
-rw-r--r-- | app/mailers/emails/notes.rb | 6 | ||||
-rw-r--r-- | app/mailers/notify.rb | 54 | ||||
-rw-r--r-- | app/models/sent_notification.rb | 29 | ||||
-rw-r--r-- | app/workers/email_receiver_worker.rb | 22 |
6 files changed, 111 insertions, 19 deletions
diff --git a/app/mailers/emails/issues.rb b/app/mailers/emails/issues.rb index 687bac3aa31..c8b7775c328 100644 --- a/app/mailers/emails/issues.rb +++ b/app/mailers/emails/issues.rb @@ -8,6 +8,8 @@ module Emails from: sender(@issue.author_id), to: recipient(recipient_id), subject: subject("#{@issue.title} (##{@issue.iid})")) + + sent_notification!(@issue, recipient_id) end def reassigned_issue_email(recipient_id, issue_id, previous_assignee_id, updated_by_user_id) @@ -19,6 +21,8 @@ module Emails from: sender(updated_by_user_id), to: recipient(recipient_id), subject: subject("#{@issue.title} (##{@issue.iid})")) + + sent_notification!(@issue, recipient_id) end def closed_issue_email(recipient_id, issue_id, updated_by_user_id) @@ -30,6 +34,8 @@ module Emails from: sender(updated_by_user_id), to: recipient(recipient_id), subject: subject("#{@issue.title} (##{@issue.iid})")) + + sent_notification!(@issue, recipient_id) end def issue_status_changed_email(recipient_id, issue_id, status, updated_by_user_id) @@ -42,6 +48,8 @@ module Emails from: sender(updated_by_user_id), to: recipient(recipient_id), subject: subject("#{@issue.title} (##{@issue.iid})")) + + sent_notification!(@issue, recipient_id) end end end diff --git a/app/mailers/emails/merge_requests.rb b/app/mailers/emails/merge_requests.rb index 512a8f7ea6b..7a685c04ebc 100644 --- a/app/mailers/emails/merge_requests.rb +++ b/app/mailers/emails/merge_requests.rb @@ -10,6 +10,8 @@ module Emails from: sender(@merge_request.author_id), to: recipient(recipient_id), subject: subject("#{@merge_request.title} (##{@merge_request.iid})")) + + sent_notification!(@merge_request, recipient_id) end def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id, updated_by_user_id) @@ -23,6 +25,8 @@ module Emails from: sender(updated_by_user_id), to: recipient(recipient_id), subject: subject("#{@merge_request.title} (##{@merge_request.iid})")) + + sent_notification!(@merge_request, recipient_id) end def closed_merge_request_email(recipient_id, merge_request_id, updated_by_user_id) @@ -36,6 +40,8 @@ module Emails from: sender(updated_by_user_id), to: recipient(recipient_id), subject: subject("#{@merge_request.title} (##{@merge_request.iid})")) + + sent_notification!(@merge_request, recipient_id) end def merged_merge_request_email(recipient_id, merge_request_id, updated_by_user_id) @@ -48,6 +54,8 @@ module Emails from: sender(updated_by_user_id), to: recipient(recipient_id), subject: subject("#{@merge_request.title} (##{@merge_request.iid})")) + + sent_notification!(@merge_request, recipient_id) end def merge_request_status_email(recipient_id, merge_request_id, status, updated_by_user_id) @@ -58,11 +66,12 @@ module Emails @target_url = namespace_project_merge_request_url(@project.namespace, @project, @merge_request) - set_reference("merge_request_#{merge_request_id}") mail_answer_thread(@merge_request, from: sender(updated_by_user_id), to: recipient(recipient_id), subject: subject("#{@merge_request.title} (##{@merge_request.iid}) #{@mr_status}")) + + sent_notification!(@merge_request, recipient_id) end end diff --git a/app/mailers/emails/notes.rb b/app/mailers/emails/notes.rb index ff251209e01..2612074a5ff 100644 --- a/app/mailers/emails/notes.rb +++ b/app/mailers/emails/notes.rb @@ -11,6 +11,8 @@ module Emails from: sender(@note.author_id), to: recipient(recipient_id), subject: subject("#{@commit.title} (#{@commit.short_id})")) + + sent_notification!(@commit, recipient_id) end def note_issue_email(recipient_id, note_id) @@ -24,6 +26,8 @@ module Emails from: sender(@note.author_id), to: recipient(recipient_id), subject: subject("#{@issue.title} (##{@issue.iid})")) + + sent_notification!(@issue, recipient_id) end def note_merge_request_email(recipient_id, note_id) @@ -38,6 +42,8 @@ module Emails from: sender(@note.author_id), to: recipient(recipient_id), subject: subject("#{@merge_request.title} (##{@merge_request.iid})")) + + sent_notification!(@merge_request, recipient_id) end end end diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb index 79fb48b00d3..44df3d6407d 100644 --- a/app/mailers/notify.rb +++ b/app/mailers/notify.rb @@ -46,6 +46,17 @@ class Notify < ActionMailer::Base allowed_domains end + def sent_notification!(noteable, recipient_id) + return unless reply_key + + SentNotification.create( + project: noteable.project, + noteable: noteable, + recipient_id: recipient_id, + reply_key: reply_key + ) + end + private # The default email address to send emails from @@ -85,14 +96,6 @@ class Notify < ActionMailer::Base @current_user.notification_email end - # Set the References header field - # - # local_part - The local part of the referenced message ID - # - def set_reference(local_part) - headers["References"] = "<#{local_part}@#{Gitlab.config.gitlab.host}>" - end - # Formats arguments into a String suitable for use as an email subject # # extra - Extra Strings to be inserted into the subject @@ -130,10 +133,23 @@ class Notify < ActionMailer::Base # with headers suitable for grouping by thread in email clients. # # See: mail_answer_thread - def mail_new_thread(model, headers = {}, &block) + def mail_new_thread(model, headers = {}) + if @project + headers['X-GitLab-Project'] = @project.name + headers['X-GitLab-Project-Id'] = @project.id + headers['X-GitLab-Project-Path'] = @project.path_with_namespace + end + + headers["X-GitLab-#{model.class.name}-ID"] = model.id + headers['Message-ID'] = message_id(model) - headers['X-GitLab-Project'] = "#{@project.name} | " if @project - mail(headers, &block) + + if reply_key + headers['X-GitLab-Reply-Key'] = reply_key + headers['Reply-To'] = Gitlab.config.reply_by_email.address.gsub('%{reply_key}', reply_key) + end + + mail(headers) end # Send an email that responds to an existing conversation thread, @@ -144,19 +160,21 @@ class Notify < ActionMailer::Base # * have a subject that begin by 'Re: ' # * have a 'In-Reply-To' or 'References' header that references the original 'Message-ID' # - def mail_answer_thread(model, headers = {}, &block) + def mail_answer_thread(model, headers = {}) + headers['Message-ID'] = SecureRandom.hex headers['In-Reply-To'] = message_id(model) headers['References'] = message_id(model) - headers['X-GitLab-Project'] = "#{@project.name} | " if @project - if headers[:subject] - headers[:subject].prepend('Re: ') - end - - mail(headers, &block) + mail_new_thread(model, headers) end def can? Ability.abilities.allowed?(user, action, subject) end + + def reply_key + return nil unless Gitlab.config.reply_by_email.enabled + + @reply_key ||= SecureRandom.hex(16) + end end diff --git a/app/models/sent_notification.rb b/app/models/sent_notification.rb new file mode 100644 index 00000000000..a3d24669b52 --- /dev/null +++ b/app/models/sent_notification.rb @@ -0,0 +1,29 @@ +class SentNotification < ActiveRecord::Base + belongs_to :project + belongs_to :noteable, polymorphic: true + belongs_to :recipient, class_name: "User" + + validate :project, :recipient, :reply_key, presence: true + validate :reply_key, uniqueness: true + + validates :noteable_id, presence: true, if: ->(n) { n.noteable_type.present? && n.noteable_type != 'Commit' } + validates :commit_id, presence: true, if: ->(n) { n.noteable_type == 'Commit' } + + def self.for(reply_key) + find_by(reply_key: reply_key) + end + + def for_commit? + noteable_type == "Commit" + end + + def noteable + if for_commit? + project.commit(commit_id) + else + super + end + rescue + nil + end +end diff --git a/app/workers/email_receiver_worker.rb b/app/workers/email_receiver_worker.rb new file mode 100644 index 00000000000..e44a430f6bc --- /dev/null +++ b/app/workers/email_receiver_worker.rb @@ -0,0 +1,22 @@ +class EmailReceiverWorker + include Sidekiq::Worker + + sidekiq_options queue: :incoming_email + + def perform(raw) + return unless Gitlab.config.reply_by_email.enabled + + # begin + Gitlab::EmailReceiver.new(raw).process + # rescue => e + # handle_failure(raw, e) + # end + end + + private + + def handle_failure(raw, e) + # TODO: Handle better. + Rails.logger.warn("Email can not be processed: #{e}\n\n#{raw}") + end +end |