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
# 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] = Encode.conv(mail.text_part.charset, data[:body])
data[:body] = data[:body].to_s.force_encoding('utf-8')
@ -170,7 +170,7 @@ class Channel::EmailParser
end
# any other attachments
if data[:body].empty?
if data[:body].blank?
data[:body] = 'no visible content'
data[:content_type] = 'text/plain'
end
@ -296,13 +296,13 @@ class Channel::EmailParser
def _get_attachment(file, attachments, mail)
# check if sub parts are available
if !file.parts.empty?
a = []
if file.parts.present?
list = []
file.parts.each do |p|
attachment = _get_attachment(p, attachments, mail)
a.concat(attachment)
list.concat(attachment)
end
return a
return list
end
# ignore text/plain attachments - already shown in view
@ -327,6 +327,12 @@ class Channel::EmailParser
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
filename = nil
@ -361,7 +367,38 @@ class Channel::EmailParser
# for some broken sm mail clients (X-MimeOLE: Produced By Microsoft Exchange V6.5)
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?
attachment_count = 0
(1..1000).each do |count|
@ -390,12 +427,6 @@ class Channel::EmailParser
headers_store.delete('Content-Transfer-Encoding')
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
# https://github.com/zammad/zammad/issues/928
filename = Mail::Encodings.value_decode(filename)
@ -667,7 +698,7 @@ returns
end
end
if data.empty? || data[:from_email].blank?
if data.blank? || data[:from_email].blank?
from.strip!
if from =~ /^(.+?)<(.+?)@(.+?)>$/
data[:from_email] = "#{$2}@#{$3}"

View file

@ -421,11 +421,11 @@ Managing Director: Martin Edenhofer
attachments: [
{
md5: '5536be23f647953dc39c1673205d6f5b',
filename: 'file-1',
filename: 'Neue Anfrage erstellt - 33284.eml',
},
{
md5: '4eeeae078b920f9d0708353ba0f6aa63',
filename: 'file-2',
filename: 'Call: HW-Anforderung; Best-nr.47524152.eml',
},
],
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."
},
},
{
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