summaryrefslogtreecommitdiff
path: root/lib/gitlab/email/handler
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/email/handler')
-rw-r--r--lib/gitlab/email/handler/base_handler.rb4
-rw-r--r--lib/gitlab/email/handler/create_issue_handler.rb28
-rw-r--r--lib/gitlab/email/handler/create_merge_request_handler.rb24
-rw-r--r--lib/gitlab/email/handler/create_note_handler.rb2
-rw-r--r--lib/gitlab/email/handler/reply_processing.rb19
-rw-r--r--lib/gitlab/email/handler/unsubscribe_handler.rb24
6 files changed, 76 insertions, 25 deletions
diff --git a/lib/gitlab/email/handler/base_handler.rb b/lib/gitlab/email/handler/base_handler.rb
index 35bb49ad19a..f89d1d15010 100644
--- a/lib/gitlab/email/handler/base_handler.rb
+++ b/lib/gitlab/email/handler/base_handler.rb
@@ -6,12 +6,14 @@ module Gitlab
class BaseHandler
attr_reader :mail, :mail_key
+ HANDLER_ACTION_BASE_REGEX ||= /(?<project_slug>.+)-(?<project_id>\d+)/.freeze
+
def initialize(mail, mail_key)
@mail = mail
@mail_key = mail_key
end
- def can_execute?
+ def can_handle?
raise NotImplementedError
end
diff --git a/lib/gitlab/email/handler/create_issue_handler.rb b/lib/gitlab/email/handler/create_issue_handler.rb
index 69982efbbe6..78a3a9489ac 100644
--- a/lib/gitlab/email/handler/create_issue_handler.rb
+++ b/lib/gitlab/email/handler/create_issue_handler.rb
@@ -2,21 +2,33 @@
require 'gitlab/email/handler/base_handler'
+# handles issue creation emails with these formats:
+# incoming+gitlab-org-gitlab-ce-20-Author_Token12345678-issue@incoming.gitlab.com
+# incoming+gitlab-org/gitlab-ce+Author_Token12345678@incoming.gitlab.com (legacy)
module Gitlab
module Email
module Handler
class CreateIssueHandler < BaseHandler
include ReplyProcessing
- attr_reader :project_path, :incoming_email_token
+
+ HANDLER_REGEX = /\A#{HANDLER_ACTION_BASE_REGEX}-(?<incoming_email_token>.+)-issue\z/.freeze
+ HANDLER_REGEX_LEGACY = /\A(?<project_path>[^\+]*)\+(?<incoming_email_token>.*)\z/.freeze
def initialize(mail, mail_key)
super(mail, mail_key)
- @project_path, @incoming_email_token =
- mail_key && mail_key.split('+', 2)
+
+ if !mail_key&.include?('/') && (matched = HANDLER_REGEX.match(mail_key.to_s))
+ @project_slug = matched[:project_slug]
+ @project_id = matched[:project_id]&.to_i
+ @incoming_email_token = matched[:incoming_email_token]
+ elsif matched = HANDLER_REGEX_LEGACY.match(mail_key.to_s)
+ @project_path = matched[:project_path]
+ @incoming_email_token = matched[:incoming_email_token]
+ end
end
def can_handle?
- !incoming_email_token.nil? && !incoming_email_token.include?("+") && !mail_key.include?(Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX)
+ incoming_email_token && (project_id || can_handle_legacy_format?)
end
def execute
@@ -36,10 +48,6 @@ module Gitlab
end
# rubocop: enable CodeReuse/ActiveRecord
- def project
- @project ||= Project.find_by_full_path(project_path)
- end
-
private
def create_issue
@@ -50,6 +58,10 @@ module Gitlab
description: message_including_reply
).execute
end
+
+ def can_handle_legacy_format?
+ project_path && !incoming_email_token.include?('+') && !mail_key.include?(Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX_LEGACY)
+ end
end
end
end
diff --git a/lib/gitlab/email/handler/create_merge_request_handler.rb b/lib/gitlab/email/handler/create_merge_request_handler.rb
index 5772727e855..b3b5063f2ca 100644
--- a/lib/gitlab/email/handler/create_merge_request_handler.rb
+++ b/lib/gitlab/email/handler/create_merge_request_handler.rb
@@ -3,23 +3,33 @@
require 'gitlab/email/handler/base_handler'
require 'gitlab/email/handler/reply_processing'
+# handles merge request creation emails with these formats:
+# incoming+gitlab-org-gitlab-ce-20-Author_Token12345678-merge-request@incoming.gitlab.com
+# incoming+gitlab-org/gitlab-ce+merge-request+Author_Token12345678@incoming.gitlab.com (legacy)
module Gitlab
module Email
module Handler
class CreateMergeRequestHandler < BaseHandler
include ReplyProcessing
- attr_reader :project_path, :incoming_email_token
+
+ HANDLER_REGEX = /\A#{HANDLER_ACTION_BASE_REGEX}-(?<incoming_email_token>.+)-merge-request\z/.freeze
+ HANDLER_REGEX_LEGACY = /\A(?<project_path>[^\+]*)\+merge-request\+(?<incoming_email_token>.*)/.freeze
def initialize(mail, mail_key)
super(mail, mail_key)
- if m = /\A([^\+]*)\+merge-request\+(.*)/.match(mail_key.to_s)
- @project_path, @incoming_email_token = m.captures
+ if !mail_key&.include?('/') && (matched = HANDLER_REGEX.match(mail_key.to_s))
+ @project_slug = matched[:project_slug]
+ @project_id = matched[:project_id]&.to_i
+ @incoming_email_token = matched[:incoming_email_token]
+ elsif matched = HANDLER_REGEX_LEGACY.match(mail_key.to_s)
+ @project_path = matched[:project_path]
+ @incoming_email_token = matched[:incoming_email_token]
end
end
def can_handle?
- @project_path && @incoming_email_token
+ incoming_email_token && (project_id || project_path)
end
def execute
@@ -40,10 +50,6 @@ module Gitlab
end
# rubocop: enable CodeReuse/ActiveRecord
- def project
- @project ||= Project.find_by_full_path(project_path)
- end
-
def metrics_params
super.merge(includes_patches: patch_attachments.any?)
end
@@ -97,7 +103,7 @@ module Gitlab
def remove_patch_attachments
patch_attachments.each { |patch| mail.parts.delete(patch) }
- # reset the message, so it needs to be reporocessed when the attachments
+ # reset the message, so it needs to be reprocessed when the attachments
# have been modified
@message = nil
end
diff --git a/lib/gitlab/email/handler/create_note_handler.rb b/lib/gitlab/email/handler/create_note_handler.rb
index c7c573595fa..b00af15364d 100644
--- a/lib/gitlab/email/handler/create_note_handler.rb
+++ b/lib/gitlab/email/handler/create_note_handler.rb
@@ -3,6 +3,8 @@
require 'gitlab/email/handler/base_handler'
require 'gitlab/email/handler/reply_processing'
+# handles note/reply creation emails with these formats:
+# incoming+1234567890abcdef1234567890abcdef@incoming.gitlab.com
module Gitlab
module Email
module Handler
diff --git a/lib/gitlab/email/handler/reply_processing.rb b/lib/gitlab/email/handler/reply_processing.rb
index ff6b2c729b2..ba9730d2685 100644
--- a/lib/gitlab/email/handler/reply_processing.rb
+++ b/lib/gitlab/email/handler/reply_processing.rb
@@ -6,13 +6,26 @@ module Gitlab
module ReplyProcessing
private
+ attr_reader :project_id, :project_slug, :project_path, :incoming_email_token
+
def author
raise NotImplementedError
end
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
def project
- raise NotImplementedError
+ return @project if instance_variable_defined?(:@project)
+
+ if project_id
+ @project = Project.find_by_id(project_id)
+ @project = nil unless valid_project_slug?(@project)
+ else
+ @project = Project.find_by_full_path(project_path)
+ end
+
+ @project
end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
def message
@message ||= process_message
@@ -58,6 +71,10 @@ module Gitlab
raise invalid_exception, msg
end
+
+ def valid_project_slug?(found_project)
+ project_slug == found_project.full_path_slug
+ end
end
end
end
diff --git a/lib/gitlab/email/handler/unsubscribe_handler.rb b/lib/gitlab/email/handler/unsubscribe_handler.rb
index d2f617b868a..20e4c125626 100644
--- a/lib/gitlab/email/handler/unsubscribe_handler.rb
+++ b/lib/gitlab/email/handler/unsubscribe_handler.rb
@@ -2,14 +2,28 @@
require 'gitlab/email/handler/base_handler'
+# handles unsubscribe emails with these formats:
+# incoming+1234567890abcdef1234567890abcdef-unsubscribe@incoming.gitlab.com
+# incoming+1234567890abcdef1234567890abcdef+unsubscribe@incoming.gitlab.com (legacy)
module Gitlab
module Email
module Handler
class UnsubscribeHandler < BaseHandler
delegate :project, to: :sent_notification, allow_nil: true
+ HANDLER_REGEX_FOR = -> (suffix) { /\A(?<reply_token>\w+)#{Regexp.escape(suffix)}\z/ }.freeze
+ HANDLER_REGEX = HANDLER_REGEX_FOR.call(Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX).freeze
+ HANDLER_REGEX_LEGACY = HANDLER_REGEX_FOR.call(Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX_LEGACY).freeze
+
+ def initialize(mail, mail_key)
+ super(mail, mail_key)
+
+ matched = HANDLER_REGEX.match(mail_key.to_s) || HANDLER_REGEX_LEGACY.match(mail_key.to_s)
+ @reply_token = matched[:reply_token] if matched
+ end
+
def can_handle?
- mail_key =~ /\A\w+#{Regexp.escape(Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX)}\z/
+ reply_token.present?
end
def execute
@@ -24,12 +38,10 @@ module Gitlab
private
- def sent_notification
- @sent_notification ||= SentNotification.for(reply_key)
- end
+ attr_reader :reply_token
- def reply_key
- mail_key.sub(Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX, '')
+ def sent_notification
+ @sent_notification ||= SentNotification.for(reply_token)
end
end
end