1# frozen_string_literal: true 2 3require 'gitlab/email/handler/base_handler' 4 5# handles issue creation emails with these formats: 6# incoming+gitlab-org-gitlab-ce-20-Author_Token12345678-issue@incoming.gitlab.com 7# incoming+gitlab-org/gitlab-ce+Author_Token12345678@incoming.gitlab.com (legacy) 8module Gitlab 9 module Email 10 module Handler 11 class CreateIssueHandler < BaseHandler 12 include ReplyProcessing 13 14 HANDLER_REGEX = /\A#{HANDLER_ACTION_BASE_REGEX}-(?<incoming_email_token>.+)-issue\z/.freeze 15 HANDLER_REGEX_LEGACY = /\A(?<project_path>[^\+]*)\+(?<incoming_email_token>.*)\z/.freeze 16 17 def initialize(mail, mail_key) 18 super(mail, mail_key) 19 20 if !mail_key&.include?('/') && (matched = HANDLER_REGEX.match(mail_key.to_s)) 21 @project_slug = matched[:project_slug] 22 @project_id = matched[:project_id]&.to_i 23 @incoming_email_token = matched[:incoming_email_token] 24 elsif matched = HANDLER_REGEX_LEGACY.match(mail_key.to_s) 25 @project_path = matched[:project_path] 26 @incoming_email_token = matched[:incoming_email_token] 27 end 28 end 29 30 def can_handle? 31 incoming_email_token && (project_id || can_handle_legacy_format?) 32 end 33 34 def execute 35 raise ProjectNotFound unless project 36 37 validate_permission!(:create_issue) 38 39 verify_record!( 40 record: create_issue, 41 invalid_exception: InvalidIssueError, 42 record_name: 'issue') 43 end 44 45 # rubocop: disable CodeReuse/ActiveRecord 46 def author 47 @author ||= User.find_by(incoming_email_token: incoming_email_token) 48 end 49 # rubocop: enable CodeReuse/ActiveRecord 50 51 def metrics_event 52 :receive_email_create_issue 53 end 54 55 private 56 57 def create_issue 58 ::Issues::CreateService.new( 59 project: project, 60 current_user: author, 61 params: { 62 title: mail.subject, 63 description: message_including_reply_or_only_quotes 64 }, 65 spam_params: nil 66 ).execute 67 end 68 69 def can_handle_legacy_format? 70 project_path && !incoming_email_token.include?('+') && !mail_key.include?(Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX_LEGACY) 71 end 72 end 73 end 74 end 75end 76