Improved filename detection of incoming postmaster emails (use subject.eml and no file-1).

This commit is contained in:
Martin Edenhofer 2017-11-06 04:26:00 +01:00
parent 967f814ff3
commit 99af4f187a
2 changed files with 111 additions and 16 deletions

View file

@ -158,7 +158,7 @@ class Channel::EmailParser
end end
# text attachment/body exists # text attachment/body exists
if data[:body].empty? && mail.text_part if data[:body].blank? && mail.text_part
data[:body] = mail.text_part.body.decoded data[:body] = mail.text_part.body.decoded
data[:body] = Encode.conv(mail.text_part.charset, data[:body]) data[:body] = Encode.conv(mail.text_part.charset, data[:body])
data[:body] = data[:body].to_s.force_encoding('utf-8') data[:body] = data[:body].to_s.force_encoding('utf-8')
@ -170,7 +170,7 @@ class Channel::EmailParser
end end
# any other attachments # any other attachments
if data[:body].empty? if data[:body].blank?
data[:body] = 'no visible content' data[:body] = 'no visible content'
data[:content_type] = 'text/plain' data[:content_type] = 'text/plain'
end end
@ -296,13 +296,13 @@ class Channel::EmailParser
def _get_attachment(file, attachments, mail) def _get_attachment(file, attachments, mail)
# check if sub parts are available # check if sub parts are available
if !file.parts.empty? if file.parts.present?
a = [] list = []
file.parts.each do |p| file.parts.each do |p|
attachment = _get_attachment(p, attachments, mail) attachment = _get_attachment(p, attachments, mail)
a.concat(attachment) list.concat(attachment)
end end
return a return list
end end
# ignore text/plain attachments - already shown in view # ignore text/plain attachments - already shown in view
@ -327,6 +327,12 @@ class Channel::EmailParser
end end
end end
# cleanup content id, <> will be added automatically later
if headers_store['Content-ID']
headers_store['Content-ID'].gsub!(/^</, '')
headers_store['Content-ID'].gsub!(/>$/, '')
end
# get filename from content-disposition # get filename from content-disposition
filename = nil filename = nil
@ -361,7 +367,38 @@ class Channel::EmailParser
# for some broken sm mail clients (X-MimeOLE: Produced By Microsoft Exchange V6.5) # for some broken sm mail clients (X-MimeOLE: Produced By Microsoft Exchange V6.5)
filename ||= file.header[:content_location].to_s filename ||= file.header[:content_location].to_s
# generate file name # generate file name based on content-id
if filename.blank? && headers_store['Content-ID'].present?
if headers_store['Content-ID'] =~ /(.+?)@.+?/i
filename = $1
end
end
# generate file name based on content type
if filename.blank? && headers_store['Content-Type'].present?
if headers_store['Content-Type'] =~ %r{^message/delivery-status$}i
filename = if headers_store['Content-Description'].present?
"#{headers_store['Content-Description']}.txt"
else
'delivery-status.txt'
end
elsif headers_store['Content-Type'] =~ %r{^message/rfc822$}i
begin
parser = Channel::EmailParser.new
mail_local = parser.parse(file.body.to_s)
filename = if mail_local[:subject].present?
"#{mail_local[:subject]}.eml"
elsif headers_store['Content-Description'].present?
"#{headers_store['Content-Description']}.eml"
else
'Mail.eml'
end
rescue
filename = 'Mail.eml'
end
end
end
if filename.blank? if filename.blank?
attachment_count = 0 attachment_count = 0
(1..1000).each do |count| (1..1000).each do |count|
@ -390,12 +427,6 @@ class Channel::EmailParser
headers_store.delete('Content-Transfer-Encoding') headers_store.delete('Content-Transfer-Encoding')
headers_store.delete('Content-Disposition') headers_store.delete('Content-Disposition')
# cleanup content id, <> will be added automatically later
if headers_store['Content-ID']
headers_store['Content-ID'].gsub!(/^</, '')
headers_store['Content-ID'].gsub!(/>$/, '')
end
# workaround for mail gem # workaround for mail gem
# https://github.com/zammad/zammad/issues/928 # https://github.com/zammad/zammad/issues/928
filename = Mail::Encodings.value_decode(filename) filename = Mail::Encodings.value_decode(filename)
@ -667,7 +698,7 @@ returns
end end
end end
if data.empty? || data[:from_email].blank? if data.blank? || data[:from_email].blank?
from.strip! from.strip!
if from =~ /^(.+?)<(.+?)@(.+?)>$/ if from =~ /^(.+?)<(.+?)@(.+?)>$/
data[:from_email] = "#{$2}@#{$3}" data[:from_email] = "#{$2}@#{$3}"

View file

@ -421,11 +421,11 @@ Managing Director: Martin Edenhofer
attachments: [ attachments: [
{ {
md5: '5536be23f647953dc39c1673205d6f5b', md5: '5536be23f647953dc39c1673205d6f5b',
filename: 'file-1', filename: 'Neue Anfrage erstellt - 33284.eml',
}, },
{ {
md5: '4eeeae078b920f9d0708353ba0f6aa63', md5: '4eeeae078b920f9d0708353ba0f6aa63',
filename: 'file-2', filename: 'Call: HW-Anforderung; Best-nr.47524152.eml',
}, },
], ],
params: { params: {
@ -1191,6 +1191,70 @@ Old programmers never die. They just branch to a new address."
Old programmers never die. They just branch to a new address." Old programmers never die. They just branch to a new address."
}, },
}, },
{
data: IO.binread('test/fixtures/mail62.box'),
body_md5: '10e7158e65a12b5850163d4d4b8ca2f8',
attachments: [
{
md5: '2b615b93ed76877dddbb7d0e3855916b',
filename: 'message.html',
},
{
md5: 'a618d671348735744d4c9a4005b56799',
filename: 'image001.jpg',
cid: 'image001.jpg@01CDB132.D8A510F0',
},
{
md5: '2cca28177acb4190cbf79cf3624cddae',
filename: 'image000.jpg',
cid: 'image000.jpg@01CDB132.D8A510F0',
},
],
params: {
from: 'Smith Sepp <smith@example.com>',
from_email: 'smith@example.com',
from_display_name: 'Smith Sepp',
subject: 'Gruß aus Oberalteich',
content_type: 'text/html',
body: "<div>
<p>Herzliche Grüße aus Oberalteich sendet Herrn Smith</p><p>&nbsp;</p><p>Sepp Smith - Dipl.Ing. agr. (FH)</p><p>Geschäftsführer der example Straubing-Bogen</p><p>Klosterhof 1 | 94327 Bogen-Oberalteich</p><p>Tel: 09422-505601 | Fax: 09422-505620</p><p>Internet: <a href=\"http://example-straubing-bogen.de/\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">http://example-straubing-bogen.de</a></p><p>Facebook: <a href=\"http://facebook.de/examplesrbog\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">http://facebook.de/examplesrbog</a></p><p><b><img border=\"0\" src=\"cid:image001.jpg@01CDB132.D8A510F0\" alt=\"Beschreibung: Beschreibung: efqmLogo\" style=\"width:60px;height:19px;\"><img border=\"0\" src=\"cid:image000.jpg@01CDB132.D8A510F0\" alt=\"Beschreibung: Beschreibung: efqmLogo\" style=\"width:60px;height:19px;\"></b><b> - European Foundation für Quality Management</b></p><p>&nbsp;</p></div>",
},
},
{
data: IO.binread('test/fixtures/mail63.box'),
body_md5: 'dbed0b09656d17bf4e832b2c18381c24',
attachments: [
{
md5: 'b8be1b421733bf2fab2eb24e11d53139',
filename: 'Delivery report.txt',
},
{
md5: '47744d00358baaeff355ca91ede93859',
filename: 'hello 123 äöüß.eml',
},
],
params: {
from: 'MAILER-DAEMON@mx1.example.com (Mail Delivery System)',
from_email: 'MAILER-DAEMON@mx1.example.com',
from_display_name: 'Mail Delivery System',
subject: 'Undelivered Mail Returned to Sender',
content_type: 'text/plain',
body: "This is the mail system at host mx1.example.com.
I'm sorry to have to inform you that your message could not
be delivered to one or more recipients. It's attached below.
For further assistance, please send mail to postmaster.
If you do so, please include this problem report. You can
delete your own text from the attached returned message.
The mail system
<notextisting@example.com>: user unknown
",
},
},
] ]
count = 0 count = 0