From b86e18205be5425ccce60678b903864a8edd34ce Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Fri, 3 Feb 2017 16:44:55 +0100 Subject: [PATCH] Fixed issue #731 - Do not import own notification emails in Zammad. --- .../filter/own_notification_loop_detection.rb | 20 +++++++++++++ app/models/transaction/notification.rb | 1 + ...002_do_not_import_onw_notifications_731.rb | 18 ++++++++++++ db/seeds.rb | 9 ++++++ lib/notification_factory/mailer.rb | 8 ++++-- test/unit/email_process_test.rb | 28 +++++++++++++++++++ 6 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 app/models/channel/filter/own_notification_loop_detection.rb create mode 100644 db/migrate/20170203000002_do_not_import_onw_notifications_731.rb diff --git a/app/models/channel/filter/own_notification_loop_detection.rb b/app/models/channel/filter/own_notification_loop_detection.rb new file mode 100644 index 000000000..7f434a213 --- /dev/null +++ b/app/models/channel/filter/own_notification_loop_detection.rb @@ -0,0 +1,20 @@ +# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ + +module Channel::Filter::OwnNotificationLoopDetection + + def self.run(_channel, mail) + + message_id = mail['message-id'.to_sym] + return if !message_id + recedence = mail['precedence'.to_sym] + return if !recedence + return if recedence !~ /bulk/i + + fqdn = Setting.get('fqdn') + return if message_id !~ /@#{Regexp.quote(fqdn)}>/i + + mail[ 'x-zammad-ignore'.to_sym ] = true + Rails.logger.info "Detected onw sent notification mail and dropped it to prevent loops (message_id: #{message_id}, from: #{mail[:from]}, to: #{mail[:to]})" + + end +end diff --git a/app/models/transaction/notification.rb b/app/models/transaction/notification.rb index 81104332b..417e98fa9 100644 --- a/app/models/transaction/notification.rb +++ b/app/models/transaction/notification.rb @@ -206,6 +206,7 @@ class Transaction::Notification current_user: current_user, changes: changes, }, + message_id: "", references: ticket.get_references, main_object: ticket, attachments: attachments, diff --git a/db/migrate/20170203000002_do_not_import_onw_notifications_731.rb b/db/migrate/20170203000002_do_not_import_onw_notifications_731.rb new file mode 100644 index 000000000..e8a07064a --- /dev/null +++ b/db/migrate/20170203000002_do_not_import_onw_notifications_731.rb @@ -0,0 +1,18 @@ +class DoNotImportOnwNotifications731 < ActiveRecord::Migration + def up + + # return if it's a new setup + return if !Setting.find_by(name: 'system_init_done') + + Setting.create_if_not_exists( + title: 'Define postmaster filter.', + name: '0014_postmaster_filter_own_notification_loop_detection', + area: 'Postmaster::PreFilter', + description: 'Define postmaster filter to check if email is a own created notification email, then ignore it to prevent email loops.', + options: {}, + state: 'Channel::Filter::OwnNotificationLoopDetection', + frontend: false + ) + + end +end diff --git a/db/seeds.rb b/db/seeds.rb index 4977fc58e..1a70f96ec 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -2200,6 +2200,15 @@ Setting.create_if_not_exists( state: 'Channel::Filter::SenderIsSystemAddress', frontend: false ) +Setting.create_if_not_exists( + title: 'Define postmaster filter.', + name: '0014_postmaster_filter_own_notification_loop_detection', + area: 'Postmaster::PreFilter', + description: 'Define postmaster filter to check if email is a own created notification email, then ignore it to prevent email loops.', + options: {}, + state: 'Channel::Filter::OwnNotificationLoopDetection', + frontend: false +) Setting.create_if_not_exists( title: 'Define postmaster filter.', name: '0015_postmaster_filter_identify_sender', diff --git a/lib/notification_factory/mailer.rb b/lib/notification_factory/mailer.rb index 79895fb84..5142f1367 100644 --- a/lib/notification_factory/mailer.rb +++ b/lib/notification_factory/mailer.rb @@ -90,7 +90,8 @@ returns subject: 'sime subject', body: 'some body', content_type: '', # optional, e. g. 'text/html' - references: ['message-id123', 'message-id456'], + message_id: '', # optional + references: ['message-id123', 'message-id456'], # optional attachments: [attachments...], # optional ) @@ -113,6 +114,7 @@ returns from: sender, to: data[:recipient][:email], subject: data[:subject], + message_id: data[:message_id], references: data[:references], body: data[:body], content_type: content_type, @@ -131,7 +133,8 @@ returns recipient: User.find(2), }, main_object: ticket.find(123), # optional - references: ['message-id123', 'message-id456'], + message_id: '', # optional + references: ['message-id123', 'message-id456'], # optional standalone: true, # default: false - will send header & footer attachments: [attachments...], # optional ) @@ -158,6 +161,7 @@ returns subject: result[:subject], body: result[:body], content_type: 'text/html', + message_id: data[:message_id], references: data[:references], attachments: data[:attachments], ) diff --git a/test/unit/email_process_test.rb b/test/unit/email_process_test.rb index 8c0a25f2a..2b7c71655 100644 --- a/test/unit/email_process_test.rb +++ b/test/unit/email_process_test.rb @@ -18,6 +18,34 @@ Some Text', }, success: true, }, + { + data: "From: my_own_zammad@example.com +To: customer_which_is_routed_into_my_zammad@example.com +Subject: some subject +Message-ID: <1234@#{Setting.get('fqdn')}> + +Some Text", + channel: { + trusted: false, + }, + success: true, + }, + { + data: "From: my_own_zammad@example.com +To: customer_which_is_routed_into_my_zammad@example.com +Subject: some subject +Message-ID: <1234@#{Setting.get('fqdn')}> +X-Loop: yes +Precedence: bulk +Auto-Submitted: auto-generated +X-Auto-Response-Suppress: All + +Some Text", + channel: { + trusted: false, + }, + success: false, + }, { data: "From: me@example.com To: customer@example.com