54 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			54 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
# frozen_string_literal: true
 | 
						|
 | 
						|
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?
 | 
						|
          reply_token.present?
 | 
						|
        end
 | 
						|
 | 
						|
        def execute
 | 
						|
          raise SentNotificationNotFoundError unless sent_notification
 | 
						|
          return unless sent_notification.unsubscribable?
 | 
						|
 | 
						|
          noteable = sent_notification.noteable
 | 
						|
          raise NoteableNotFoundError unless noteable
 | 
						|
 | 
						|
          noteable.unsubscribe(sent_notification.recipient)
 | 
						|
        end
 | 
						|
 | 
						|
        def metrics_event
 | 
						|
          :receive_email_unsubscribe
 | 
						|
        end
 | 
						|
 | 
						|
        private
 | 
						|
 | 
						|
        attr_reader :reply_token
 | 
						|
 | 
						|
        def sent_notification
 | 
						|
          @sent_notification ||= SentNotification.for(reply_token)
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 |