From 75415663f84ac006c5a4d5a6896ece50c299c03e Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Sat, 21 May 2016 09:40:08 -0700 Subject: Rename handlers and introduce Handler.for --- lib/gitlab/email/handler.rb | 57 ++++-------------------- lib/gitlab/email/handler/base_handler.rb | 57 ++++++++++++++++++++++++ lib/gitlab/email/handler/create_issue.rb | 50 --------------------- lib/gitlab/email/handler/create_issue_handler.rb | 50 +++++++++++++++++++++ lib/gitlab/email/handler/create_note.rb | 55 ----------------------- lib/gitlab/email/handler/create_note_handler.rb | 55 +++++++++++++++++++++++ lib/gitlab/email/receiver.rb | 12 +---- 7 files changed, 173 insertions(+), 163 deletions(-) create mode 100644 lib/gitlab/email/handler/base_handler.rb delete mode 100644 lib/gitlab/email/handler/create_issue.rb create mode 100644 lib/gitlab/email/handler/create_issue_handler.rb delete mode 100644 lib/gitlab/email/handler/create_note.rb create mode 100644 lib/gitlab/email/handler/create_note_handler.rb diff --git a/lib/gitlab/email/handler.rb b/lib/gitlab/email/handler.rb index 56d848cdd7b..b9221f1210c 100644 --- a/lib/gitlab/email/handler.rb +++ b/lib/gitlab/email/handler.rb @@ -1,54 +1,15 @@ +require 'gitlab/email/handler/create_note_handler' +require 'gitlab/email/handler/create_issue_handler' + module Gitlab module Email - class Handler - attr_reader :mail, :mail_key - - def initialize(mail, mail_key) - @mail = mail - @mail_key = mail_key - end - - def message - @message ||= process_message - end - - def author - raise NotImplementedError - end - - def project - raise NotImplementedError - end - - private - def validate_permission!(permission) - raise UserNotFoundError unless author - raise UserBlockedError if author.blocked? - raise ProjectNotFound unless author.can?(:read_project, project) - raise UserNotAuthorizedError unless author.can?(permission, project) - end - - def process_message - add_attachments(ReplyParser.new(mail).execute.strip) - end - - def add_attachments(reply) - attachments = Email::AttachmentUploader.new(mail).execute(project) - - reply + attachments.map do |link| - "\n\n#{link[:markdown]}" - end.join - end - - def verify_record(record, exception, error_title) - return if record.persisted? - - msg = error_title + record.errors.full_messages.map do |error| - "\n\n- #{error}" - end.join - - raise exception, msg + module Handler + def self.for(mail, mail_key) + [CreateNoteHandler, CreateIssueHandler].find do |klass| + handler = klass.new(mail, mail_key) + break handler if handler.can_handle? + end end end end diff --git a/lib/gitlab/email/handler/base_handler.rb b/lib/gitlab/email/handler/base_handler.rb new file mode 100644 index 00000000000..230d13feea9 --- /dev/null +++ b/lib/gitlab/email/handler/base_handler.rb @@ -0,0 +1,57 @@ + +module Gitlab + module Email + module Handler + class BaseHandler + attr_reader :mail, :mail_key + + def initialize(mail, mail_key) + @mail = mail + @mail_key = mail_key + end + + def message + @message ||= process_message + end + + def author + raise NotImplementedError + end + + def project + raise NotImplementedError + end + + private + def validate_permission!(permission) + raise UserNotFoundError unless author + raise UserBlockedError if author.blocked? + raise ProjectNotFound unless author.can?(:read_project, project) + raise UserNotAuthorizedError unless author.can?(permission, project) + end + + def process_message + add_attachments(ReplyParser.new(mail).execute.strip) + end + + def add_attachments(reply) + attachments = Email::AttachmentUploader.new(mail).execute(project) + + reply + attachments.map do |link| + "\n\n#{link[:markdown]}" + end.join + end + + def verify_record(record, exception, error_title) + return if record.persisted? + + msg = error_title + record.errors.full_messages.map do |error| + "\n\n- #{error}" + end.join + + raise exception, msg + end + end + end + end +end diff --git a/lib/gitlab/email/handler/create_issue.rb b/lib/gitlab/email/handler/create_issue.rb deleted file mode 100644 index 72d49ec6c96..00000000000 --- a/lib/gitlab/email/handler/create_issue.rb +++ /dev/null @@ -1,50 +0,0 @@ - -require 'gitlab/email/handler' - -module Gitlab - module Email - class Handler - class CreateIssue < Handler - def can_handle? - !!project - end - - def execute - validate_permission!(:create_issue) - - verify_record( - create_issue, - InvalidIssueError, - "The issue could not be created for the following reasons:" - ) - end - - def author - @author ||= User.find_by(authentication_token: authentication_token) - end - - def project - @project ||= Project.find_with_namespace(project_namespace) - end - - private - def authentication_token - mail_key[/[^\+]+$/] - end - - def project_namespace - mail_key[/^[^\+]+/] - end - - def create_issue - Issues::CreateService.new( - project, - author, - title: mail.subject, - description: message - ).execute - end - end - end - end -end diff --git a/lib/gitlab/email/handler/create_issue_handler.rb b/lib/gitlab/email/handler/create_issue_handler.rb new file mode 100644 index 00000000000..259d74a83bf --- /dev/null +++ b/lib/gitlab/email/handler/create_issue_handler.rb @@ -0,0 +1,50 @@ + +require 'gitlab/email/handler/base_handler' + +module Gitlab + module Email + module Handler + class CreateIssueHandler < BaseHandler + def can_handle? + !!project + end + + def execute + validate_permission!(:create_issue) + + verify_record( + create_issue, + InvalidIssueError, + "The issue could not be created for the following reasons:" + ) + end + + def author + @author ||= User.find_by(authentication_token: authentication_token) + end + + def project + @project ||= Project.find_with_namespace(project_namespace) + end + + private + def authentication_token + mail_key[/[^\+]+$/] + end + + def project_namespace + mail_key[/^[^\+]+/] + end + + def create_issue + Issues::CreateService.new( + project, + author, + title: mail.subject, + description: message + ).execute + end + end + end + end +end diff --git a/lib/gitlab/email/handler/create_note.rb b/lib/gitlab/email/handler/create_note.rb deleted file mode 100644 index 32deb5a311e..00000000000 --- a/lib/gitlab/email/handler/create_note.rb +++ /dev/null @@ -1,55 +0,0 @@ - -require 'gitlab/email/handler' - -module Gitlab - module Email - class Handler - class CreateNote < Handler - def can_handle? - !!sent_notification - end - - def execute - raise SentNotificationNotFoundError unless sent_notification - raise AutoGeneratedEmailError if mail.header.to_s =~ /auto-(generated|replied)/ - - validate_permission!(:create_note) - - raise NoteableNotFoundError unless sent_notification.noteable - raise EmptyEmailError if message.blank? - - verify_record( - create_note, - InvalidNoteError, - "The comment could not be created for the following reasons:" - ) - end - - def author - sent_notification.recipient - end - - def project - sent_notification.project - end - - def sent_notification - @sent_notification ||= SentNotification.for(mail_key) - end - - private - def create_note - Notes::CreateService.new( - project, - author, - note: message, - noteable_type: sent_notification.noteable_type, - noteable_id: sent_notification.noteable_id, - commit_id: sent_notification.commit_id, - line_code: sent_notification.line_code - ).execute - end - end - end - end -end diff --git a/lib/gitlab/email/handler/create_note_handler.rb b/lib/gitlab/email/handler/create_note_handler.rb new file mode 100644 index 00000000000..7252906fd48 --- /dev/null +++ b/lib/gitlab/email/handler/create_note_handler.rb @@ -0,0 +1,55 @@ + +require 'gitlab/email/handler/base_handler' + +module Gitlab + module Email + module Handler + class CreateNoteHandler < BaseHandler + def can_handle? + !!sent_notification + end + + def execute + raise SentNotificationNotFoundError unless sent_notification + raise AutoGeneratedEmailError if mail.header.to_s =~ /auto-(generated|replied)/ + + validate_permission!(:create_note) + + raise NoteableNotFoundError unless sent_notification.noteable + raise EmptyEmailError if message.blank? + + verify_record( + create_note, + InvalidNoteError, + "The comment could not be created for the following reasons:" + ) + end + + def author + sent_notification.recipient + end + + def project + sent_notification.project + end + + def sent_notification + @sent_notification ||= SentNotification.for(mail_key) + end + + private + def create_note + Notes::CreateService.new( + project, + author, + note: message, + noteable_type: sent_notification.noteable_type, + noteable_id: sent_notification.noteable_id, + commit_id: sent_notification.commit_id, + line_code: sent_notification.line_code + ).execute + end + end + end + end +end diff --git a/lib/gitlab/email/receiver.rb b/lib/gitlab/email/receiver.rb index da4299ebcb3..7038346192b 100644 --- a/lib/gitlab/email/receiver.rb +++ b/lib/gitlab/email/receiver.rb @@ -1,6 +1,5 @@ -require 'gitlab/email/handler/create_note' -require 'gitlab/email/handler/create_issue' +require 'gitlab/email/handler' # Inspired in great part by Discourse's Email::Receiver module Gitlab @@ -31,7 +30,7 @@ module Gitlab raise SentNotificationNotFoundError unless mail_key - if handler = find_handler(mail, mail_key) + if handler = Handler.for(mail, mail_key) handler.execute elsif mail_key =~ %r{/|\+} # Sent Notification mail_key would not have / or + @@ -65,13 +64,6 @@ module Gitlab break key if key end end - - def find_handler(mail, mail_key) - [Handler::CreateNote, Handler::CreateIssue].find do |klass| - handler = klass.new(mail, mail_key) - break handler if handler.can_handle? - end - end end end end -- cgit v1.2.1