diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-07-14 15:09:05 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-07-14 15:09:05 +0000 |
commit | 66bd1f0fdcaf84fa3412c70d7962b49eb8a48fde (patch) | |
tree | 23f451b4e60a6e28bcc15043d7756bb27dcc2970 /lib | |
parent | 49089d4fb1f5c17328ac61c955d95a68c6d4d545 (diff) | |
download | gitlab-ce-66bd1f0fdcaf84fa3412c70d7962b49eb8a48fde.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib')
-rw-r--r-- | lib/event_filter.rb | 3 | ||||
-rw-r--r-- | lib/gitlab/ci/config/entry/environment.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/email/handler.rb | 5 | ||||
-rw-r--r-- | lib/gitlab/email/handler/reply_processing.rb | 15 | ||||
-rw-r--r-- | lib/gitlab/email/handler/service_desk_handler.rb | 152 | ||||
-rw-r--r-- | lib/gitlab/email/service_desk_receiver.rb | 23 |
6 files changed, 192 insertions, 8 deletions
diff --git a/lib/event_filter.rb b/lib/event_filter.rb index eab64d05114..73bdc8f0649 100644 --- a/lib/event_filter.rb +++ b/lib/event_filter.rb @@ -52,15 +52,12 @@ class EventFilter private def apply_feature_flags(events) - events = events.not_wiki_page unless Feature.enabled?(:wiki_events) events = events.not_design unless can_view_design_activity? events end def wiki_events(events) - return events unless Feature.enabled?(:wiki_events) - events.for_wiki_page end diff --git a/lib/gitlab/ci/config/entry/environment.rb b/lib/gitlab/ci/config/entry/environment.rb index fc62cca58ff..64e6d48133f 100644 --- a/lib/gitlab/ci/config/entry/environment.rb +++ b/lib/gitlab/ci/config/entry/environment.rb @@ -44,7 +44,7 @@ module Gitlab validates :action, type: String, - inclusion: { in: %w[start stop], message: 'should be start or stop' }, + inclusion: { in: %w[start stop prepare], message: 'should be start, stop or prepare' }, allow_nil: true validates :on_stop, type: String, allow_nil: true diff --git a/lib/gitlab/email/handler.rb b/lib/gitlab/email/handler.rb index 7f8dd815103..1b8421d34f3 100644 --- a/lib/gitlab/email/handler.rb +++ b/lib/gitlab/email/handler.rb @@ -12,7 +12,8 @@ module Gitlab CreateNoteHandler, CreateIssueHandler, UnsubscribeHandler, - CreateMergeRequestHandler + CreateMergeRequestHandler, + ServiceDeskHandler ] end @@ -25,5 +26,3 @@ module Gitlab end end end - -Gitlab::Email::Handler.prepend_if_ee('::EE::Gitlab::Email::Handler') diff --git a/lib/gitlab/email/handler/reply_processing.rb b/lib/gitlab/email/handler/reply_processing.rb index 312a9fdfbae..1beea4f9054 100644 --- a/lib/gitlab/email/handler/reply_processing.rb +++ b/lib/gitlab/email/handler/reply_processing.rb @@ -37,7 +37,11 @@ module Gitlab def process_message(**kwargs) message = ReplyParser.new(mail, **kwargs).execute.strip - add_attachments(message) + message_with_attachments = add_attachments(message) + + # Support bot is specifically forbidden + # from using slash commands. + strip_quick_actions(message_with_attachments) end def add_attachments(reply) @@ -82,6 +86,15 @@ module Gitlab def valid_project_slug?(found_project) project_slug == found_project.full_path_slug end + + def strip_quick_actions(content) + return content unless author.support_bot? + + command_definitions = ::QuickActions::InterpretService.command_definitions + extractor = ::Gitlab::QuickActions::Extractor.new(command_definitions) + + extractor.redact_commands(content) + end end end end diff --git a/lib/gitlab/email/handler/service_desk_handler.rb b/lib/gitlab/email/handler/service_desk_handler.rb new file mode 100644 index 00000000000..bcd8b98a06f --- /dev/null +++ b/lib/gitlab/email/handler/service_desk_handler.rb @@ -0,0 +1,152 @@ +# frozen_string_literal: true + +# handles service desk issue creation emails with these formats: +# incoming+gitlab-org-gitlab-ce-20-issue-@incoming.gitlab.com +# incoming+gitlab-org/gitlab-ce@incoming.gitlab.com (legacy) +module Gitlab + module Email + module Handler + class ServiceDeskHandler < BaseHandler + include ReplyProcessing + include Gitlab::Utils::StrongMemoize + + HANDLER_REGEX = /\A#{HANDLER_ACTION_BASE_REGEX}-issue-\z/.freeze + HANDLER_REGEX_LEGACY = /\A(?<project_path>[^\+]*)\z/.freeze + PROJECT_KEY_PATTERN = /\A(?<slug>.+)-(?<key>[a-z0-9_]+)\z/.freeze + + def initialize(mail, mail_key, service_desk_key: nil) + super(mail, mail_key) + + if service_desk_key.present? + @service_desk_key = service_desk_key + elsif !mail_key&.include?('/') && (matched = HANDLER_REGEX.match(mail_key.to_s)) + @project_slug = matched[:project_slug] + @project_id = matched[:project_id]&.to_i + elsif matched = HANDLER_REGEX_LEGACY.match(mail_key.to_s) + @project_path = matched[:project_path] + end + end + + def can_handle? + Gitlab::ServiceDesk.supported? && (project_id || can_handle_legacy_format? || service_desk_key) + end + + def execute + raise ProjectNotFound if project.nil? + + create_issue! + send_thank_you_email! if from_address + end + + def metrics_params + super.merge(project: project&.full_path) + end + + def metrics_event + :receive_email_service_desk + end + + private + + attr_reader :project_id, :project_path, :service_desk_key + + def project + strong_memoize(:project) do + @project = service_desk_key ? project_from_key : super + @project = nil unless @project&.service_desk_enabled? + @project + end + end + + def project_from_key + return unless match = service_desk_key.match(PROJECT_KEY_PATTERN) + + project = Project.find_by_service_desk_project_key(match[:key]) + return unless valid_project_key?(project, match[:slug]) + + project + end + + def valid_project_key?(project, slug) + project.present? && slug == project.full_path_slug && Feature.enabled?(:service_desk_custom_address, project) + end + + def create_issue! + @issue = Issues::CreateService.new( + project, + User.support_bot, + title: issue_title, + description: message_including_template, + confidential: true, + service_desk_reply_to: from_address + ).execute + + raise InvalidIssueError unless @issue.persisted? + + if service_desk_setting&.issue_template_missing? + create_template_not_found_note(@issue) + end + end + + def send_thank_you_email! + Notify.service_desk_thank_you_email(@issue.id).deliver_later! + end + + def message_including_template + description = message_including_reply + template_content = service_desk_setting&.issue_template_content + + if template_content.present? + description += " \n" + template_content + end + + description + end + + def service_desk_setting + strong_memoize(:service_desk_setting) do + project.service_desk_setting + end + end + + def create_template_not_found_note(issue) + issue_template_key = service_desk_setting&.issue_template_key + + warning_note = <<-MD.strip_heredoc + WARNING: The template file #{issue_template_key}.md used for service desk issues is empty or could not be found. + Please check service desk settings and update the file to be used. + MD + + note_params = { + noteable: issue, + note: warning_note + } + + ::Notes::CreateService.new( + project, + User.support_bot, + note_params + ).execute + end + + def from_address + (mail.reply_to || []).first || mail.from.first || mail.sender + end + + def issue_title + from = "(from #{from_address})" if from_address + + "Service Desk #{from}: #{mail.subject}" + end + + def can_handle_legacy_format? + project_path && project_path.include?('/') && !mail_key.include?('+') + end + + def author + User.support_bot + end + end + end + end +end diff --git a/lib/gitlab/email/service_desk_receiver.rb b/lib/gitlab/email/service_desk_receiver.rb new file mode 100644 index 00000000000..1ee5c10097b --- /dev/null +++ b/lib/gitlab/email/service_desk_receiver.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Gitlab + module Email + class ServiceDeskReceiver < Receiver + private + + def find_handler(mail) + key = service_desk_key(mail) + return unless key + + Gitlab::Email::Handler::ServiceDeskHandler.new(mail, nil, service_desk_key: key) + end + + def service_desk_key(mail) + mail.to.find do |address| + key = ::Gitlab::ServiceDeskEmail.key_from_address(address) + break key if key + end + end + end + end +end |