add a blacklist for attachments (#15672)
This commit is contained in:
parent
ba26fd7726
commit
bd20f60fe1
|
@ -6,6 +6,7 @@ fi
|
||||||
|
|
||||||
export REDMINE_KEY=`cat /etc/redmine-key`
|
export REDMINE_KEY=`cat /etc/redmine-key`
|
||||||
export REDMINE_URL='https://dev.entrouvert.org'
|
export REDMINE_URL='https://dev.entrouvert.org'
|
||||||
|
export ATTACHMENTS_BLACKLIST=/etc/redmine.attachments.blacklist.json
|
||||||
|
|
||||||
export PROJECT=`echo $RECIPIENT | sed 's/support-\([a-z0-9-]*\)@.*/\1/'`
|
export PROJECT=`echo $RECIPIENT | sed 's/support-\([a-z0-9-]*\)@.*/\1/'`
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import email
|
import email
|
||||||
|
import hashlib
|
||||||
import tempfile
|
import tempfile
|
||||||
import uuid
|
import uuid
|
||||||
import smtplib
|
import smtplib
|
||||||
|
@ -18,6 +19,7 @@ TRACKER_ID = os.environ.get('REDMINE_TRACKER', '3')
|
||||||
PROJECT_ID = os.environ.get('PROJECT')
|
PROJECT_ID = os.environ.get('PROJECT')
|
||||||
TECH_MANAGER_ROLE_ID = os.environ.get('TECH_MANAGER_ROLE_ID', 10)
|
TECH_MANAGER_ROLE_ID = os.environ.get('TECH_MANAGER_ROLE_ID', 10)
|
||||||
FALLBACK_EMAIL = os.environ.get('FALLBACK_EMAIL', 'support@entrouvert.com')
|
FALLBACK_EMAIL = os.environ.get('FALLBACK_EMAIL', 'support@entrouvert.com')
|
||||||
|
ATTACHMENTS_BLACKLIST = os.environ.get('ATTACHMENTS_BLACKLIST', None)
|
||||||
|
|
||||||
|
|
||||||
class UnknownUser(Exception):
|
class UnknownUser(Exception):
|
||||||
|
@ -37,7 +39,7 @@ def parse_header(header_text):
|
||||||
return u' '.join(headers)
|
return u' '.join(headers)
|
||||||
|
|
||||||
|
|
||||||
def parse_attachment(data):
|
def parse_attachment(data, blacklist=None):
|
||||||
if data.get('Content-type', '').startswith('multipart/'):
|
if data.get('Content-type', '').startswith('multipart/'):
|
||||||
return None
|
return None
|
||||||
if data.get('Content-type', '').startswith('text/plain') and not (
|
if data.get('Content-type', '').startswith('text/plain') and not (
|
||||||
|
@ -46,6 +48,8 @@ def parse_attachment(data):
|
||||||
file_data = data.get_payload(decode=True)
|
file_data = data.get_payload(decode=True)
|
||||||
if not file_data:
|
if not file_data:
|
||||||
return None
|
return None
|
||||||
|
if blacklist and hashlib.sha1(file_data).hexdigest() in blacklist.get('sha1sums'):
|
||||||
|
return None
|
||||||
with tempfile.NamedTemporaryFile(delete=False) as attachment:
|
with tempfile.NamedTemporaryFile(delete=False) as attachment:
|
||||||
attachment.write(file_data)
|
attachment.write(file_data)
|
||||||
attachment.flush()
|
attachment.flush()
|
||||||
|
@ -74,13 +78,20 @@ def create_ticket(mail):
|
||||||
if not users:
|
if not users:
|
||||||
raise UnknownUser
|
raise UnknownUser
|
||||||
|
|
||||||
|
blacklist = {'sha1sums': []}
|
||||||
|
if ATTACHMENTS_BLACKLIST:
|
||||||
|
try:
|
||||||
|
blacklist = json.load(open(ATTACHMENTS_BLACKLIST))
|
||||||
|
except (IOError, ValueError):
|
||||||
|
pass
|
||||||
|
|
||||||
r = Redmine(REDMINE_URL, key=REDMINE_KEY, impersonate=users[0].login)
|
r = Redmine(REDMINE_URL, key=REDMINE_KEY, impersonate=users[0].login)
|
||||||
|
|
||||||
attachments = []
|
attachments = []
|
||||||
|
|
||||||
body = u''
|
body = u''
|
||||||
for data in mail.walk():
|
for data in mail.walk():
|
||||||
attachment = parse_attachment(data)
|
attachment = parse_attachment(data, blacklist)
|
||||||
if attachment:
|
if attachment:
|
||||||
attachments.append(attachment)
|
attachments.append(attachment)
|
||||||
elif data.get_content_type() == "text/plain":
|
elif data.get_content_type() == "text/plain":
|
||||||
|
|
|
@ -56,6 +56,23 @@ def test_mail_with_two_attachments(message):
|
||||||
attachments.append(attachment)
|
attachments.append(attachment)
|
||||||
assert len(attachments) == 2
|
assert len(attachments) == 2
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('message', ('mail_dumps/1461591292.25165_17.dor-lomin_2.mail',))
|
||||||
|
def test_mail_attachment_blacklist(message):
|
||||||
|
mail = mail2redmine.email.message_from_file(file(message))
|
||||||
|
attachments = []
|
||||||
|
blacklist = {'sha1sums': ['ab7c57983551204500d67f8ec3dd54a01e81d75d']}
|
||||||
|
for data in mail.walk():
|
||||||
|
attachment = mail2redmine.parse_attachment(data, blacklist=blacklist)
|
||||||
|
if attachment:
|
||||||
|
assert 'path' in attachment
|
||||||
|
assert 'content_type' in attachment
|
||||||
|
assert 'filename' in attachment
|
||||||
|
assert isinstance(attachment['filename'], unicode)
|
||||||
|
assert attachment['filename'] == u'201601-mise-a-jour-Publik.pdf'
|
||||||
|
attachments.append(attachment)
|
||||||
|
assert len(attachments) == 1
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('mail2redmine.Redmine')
|
@mock.patch('mail2redmine.Redmine')
|
||||||
def test_ticket_creation_by_unknown_user(mocked_redmine, dump):
|
def test_ticket_creation_by_unknown_user(mocked_redmine, dump):
|
||||||
user = mock.Mock()
|
user = mock.Mock()
|
||||||
|
|
Loading…
Reference in New Issue