Просмотр исходного кода

Fixes #4452 - Mail processing not possible if reply-to header is faulty.

Co-authored-by: Dominik Klein <dk@zammad.com>
Co-authored-by: Florian Liebe <fl@zammad.com>
Dominik Klein 1 год назад
Родитель
Сommit
78ec876878

+ 12 - 0
app/models/channel/filter/reply_to_based_sender.rb

@@ -9,6 +9,9 @@ module Channel::Filter::ReplyToBasedSender
     reply_to = mail[:'reply-to'].gsub('<>', '').strip
     return if reply_to.blank?
 
+    # Check if the reply-to address can be parsed and otherwise skip the filter.
+    return if !valid_address?(reply_to)
+
     setting = Setting.get('postmaster_sender_based_on_reply_to')
     return if setting.blank?
 
@@ -49,4 +52,13 @@ module Channel::Filter::ReplyToBasedSender
     Rails.logger.error "Invalid setting value for 'postmaster_sender_based_on_reply_to' -> #{setting.inspect}"
   end
 
+  def self.valid_address?(address)
+    begin
+      Mail::AddressList.new(address)&.addresses&.first&.address
+
+      true
+    rescue
+      false
+    end
+  end
 end

+ 33 - 1
spec/models/channel/email_parser_spec.rb

@@ -285,6 +285,38 @@ RSpec.describe Channel::EmailParser, type: :model do
           end
         end
 
+        context 'when reply-to is taken as sender/from of email' do
+          let(:reply_to) { 'jane.doe@example.corp' }
+          let(:raw_mail) { <<~RAW.chomp }
+            From: foo@bar.com
+            To: baz@qux.net
+            Reply-To: #{reply_to}
+            Subject: Foo
+
+            Lorem ipsum dolor
+          RAW
+
+          before do
+            Setting.set('postmaster_sender_based_on_reply_to', 'as_sender_of_email')
+          end
+
+          it 'sets reply-to as from value' do
+            described_class.new.process({}, raw_mail)
+
+            expect(Ticket.last.articles.first.from).to eq('jane.doe@example.corp')
+          end
+
+          context 'with broken reply-to value' do
+            let(:reply_to) { '<Jane Doe>' }
+
+            it 'ignores reply-to and keeps from' do
+              described_class.new.process({}, raw_mail)
+
+              expect(Ticket.last.articles.first.from).to eq('foo@bar.com')
+            end
+          end
+        end
+
         context 'when from address matches an existing customer' do
           let!(:customer) { create(:customer, email: 'foo@bar.com') }
 
@@ -348,7 +380,7 @@ RSpec.describe Channel::EmailParser, type: :model do
       end
 
       context 'Mentions:' do
-        let(:agent) { create(:agent) }
+        let(:agent)    { create(:agent) }
         let(:raw_mail) { <<~RAW.chomp }
           From: foo@bar.com
           To: baz@qux.net

+ 9 - 0
spec/models/channel/filter/reply_to_based_sender_spec.rb

@@ -35,6 +35,15 @@ RSpec.describe Channel::Filter::ReplyToBasedSender, type: :channel_filter do
       end
     end
 
+    context 'when invalid reply-to content' do
+      let(:reply_to) { 'Jane Doe' }
+
+      it 'keeps from' do
+        expect { filter(mail_hash) }
+          .not_to change { mail_hash[:from] }
+      end
+    end
+
     context 'when valid reply-to address' do
       let(:reply_to) { '<bugs.bunny@acme.corp>' }