Exemple #1
0
def parse_attachment(message_part):
    content_disposition = message_part.get("Content-Disposition", None)
    if not content_disposition:
        return None
    dispo_type, dispo_dict = parse_dispositions(content_disposition)
    if not (dispo_type == "attachment" or
            (dispo_type == 'inline' and 'filename' in dispo_dict)):
        return None

    content_type = message_part.get("Content-Type", None)
    file_data = message_part.get_payload(decode=True)
    if file_data is None:
        payloads = message_part.get_payload()
        file_data = '\n\n'.join([p.as_string()
                                 for p in payloads]).encode('utf-8')
    attachment = BytesIO(file_data)
    attachment.content_type = message_part.get_content_type()
    attachment.size = len(file_data)
    attachment.name = None
    attachment.create_date = None
    attachment.mod_date = None
    attachment.read_date = None
    attachment.name = get_attachment_name(attachment,
                                          dispo_dict,
                                          content_type=content_type)

    if "create-date" in dispo_dict:
        attachment.create_date = dispo_dict['create-date']  # TODO: datetime
    if "modification-date" in dispo_dict:
        attachment.mod_date = dispo_dict['modification-date']  # TODO: datetime
    if "read-date" in dispo_dict:
        attachment.read_date = dispo_dict['read-date']  # TODO: datetime
    return attachment
Exemple #2
0
def parse_attachment(message_part):
    content_disposition = message_part.get("Content-Disposition", None)
    if not content_disposition:
        return None
    dispo_type, dispo_dict = parse_dispositions(content_disposition)
    if not (dispo_type == "attachment" or (dispo_type == 'inline' and
            'filename' in dispo_dict)):
        return None

    content_type = message_part.get("Content-Type", None)
    file_data = message_part.get_payload(decode=True)
    if file_data is None:
        payloads = message_part.get_payload()
        file_data = '\n\n'.join([p.as_string() for p in payloads]).encode('utf-8')
    attachment = BytesIO(file_data)
    attachment.content_type = message_part.get_content_type()
    attachment.size = len(file_data)
    attachment.name = None
    attachment.create_date = None
    attachment.mod_date = None
    attachment.read_date = None
    attachment.name = get_attachment_name(
        attachment, dispo_dict, content_type=content_type
    )

    if "create-date" in dispo_dict:
        attachment.create_date = dispo_dict['create-date']  # TODO: datetime
    if "modification-date" in dispo_dict:
        attachment.mod_date = dispo_dict['modification-date']  # TODO: datetime
    if "read-date" in dispo_dict:
        attachment.read_date = dispo_dict['read-date']  # TODO: datetime
    return attachment
Exemple #3
0
    def parse_postmark(self, obj):
        from_field = (obj['FromFull']['Name'], obj['FromFull']['Email'])
        tos = [(o['Name'], o['Email']) for o in obj['ToFull']]
        ccs = [(o['Name'], o['Email']) for o in obj['CcFull']]
        attachments = []
        for a in obj['Attachments']:
            attachment = BytesIO(base64.b64decode(a['Content']))
            attachment.content_type = a['ContentType']
            attachment.size = a['ContentLength']
            attachment.name = a['Name']
            attachment.create_date = None
            attachment.mod_date = None
            attachment.read_date = None
            attachments.append(attachment)

        return ParsedEmail(None, **{
            'postmark_msgobj': obj,
            'date': parse_date(obj['Date']),
            'subject': obj['Subject'],
            'body': obj['TextBody'],
            'html': obj['HtmlBody'],
            'from_': from_field,
            'to': tos,
            'cc': ccs,
            'resent_to': [],
            'resent_cc': [],
            'attachments': attachments
        })
Exemple #4
0
def _parse_attachment(message_part):
    content_disposition = message_part.get("Content-Disposition", None)
    if content_disposition:
        dispositions = content_disposition.strip().split(";")
        if content_disposition and dispositions[0].lower() == "attachment":
            file_data = message_part.get_payload(decode=True)
            attachment = BytesIO(file_data)
            attachment.content_type = message_part.get_content_type()
            attachment.size = len(file_data)
            attachment.name = None
            attachment.create_date = None
            attachment.mod_date = None
            attachment.read_date = None

            for param in dispositions[1:]:
                name, value = param.strip().split("=")
                name = name.lower()

                if name == "filename":
                    attachment.name = value
                elif name == "create-date":
                    attachment.create_date = value  # FIXME: datetime
                elif name == "modification-date":
                    attachment.mod_date = value  # FIXME: datetime
                elif name == "read-date":
                    attachment.read_date = value  # FIXME: datetime

            attachment.checksum = _md5(attachment)

            return attachment

    return None
Exemple #5
0
    def test_binary_gpg_data(self):
        url = reverse('account:register')
        client = Client()

        self.assertEqual(User.objects.count(), 0)

        get = client.get(url)
        self.assertEqual(get.status_code, 200)
        self.assertTrue(get.context['user'].is_anonymous)
        self.assertTrue('form' in get.context)

        with open(os.path.join(testdata_path, 'non_armored.gpg'),
                  'rb') as stream:
            data = stream.read()
        data = BytesIO(data)
        data.name = 'non_armored.gpg'
        data.content_type = 'application/pgp-encrypted'

        with self.mock_celery() as mock:
            response = client.post(url, {
                'username_0': NODE,
                'username_1': DOMAIN,
                'email': EMAIL,
                'gpg_key': data,
            },
                                   follow=True)
        self.assertEqual(User.objects.count(), 0)
        self.assertNoTasks(mock)
        self.assertFormError(response, 'form', 'gpg_key',
                             ['Please upload an ASCII armored GPG key.'])
Exemple #6
0
    def test_binary_gpg_data(self):
        url = reverse('account:register')
        client = Client()

        self.assertEqual(User.objects.count(), 0)

        get = client.get(url)
        self.assertEqual(get.status_code, 200)
        self.assertTrue(get.context['user'].is_anonymous)
        self.assertTrue('form' in get.context)

        with open(os.path.join(testdata_path, 'non_armored.gpg'), 'rb') as stream:
            data = stream.read()
        data = BytesIO(data)
        data.name = 'non_armored.gpg'
        data.content_type = 'application/pgp-encrypted'

        with self.mock_celery() as mock:
            response = client.post(url, {
                'username_0': NODE, 'username_1': DOMAIN, 'email': EMAIL,
                'gpg_key': data,
            }, follow=True)
        self.assertEqual(User.objects.count(), 0)
        self.assertNoTasks(mock)
        self.assertFormError(response, 'form', 'gpg_key', ['Please upload an ASCII armored GPG key.'])
Exemple #7
0
    def parse_postmark(self, obj):
        from_field = (obj['FromFull']['Name'], obj['FromFull']['Email'])
        tos = [(o['Name'], o['Email']) for o in obj['ToFull']]
        ccs = [(o['Name'], o['Email']) for o in obj['CcFull']]
        attachments = []
        for a in obj['Attachments']:
            attachment = BytesIO(base64.b64decode(a['Content']))
            attachment.content_type = a['ContentType']
            attachment.size = a['ContentLength']
            attachment.name = a['Name']
            attachment.create_date = None
            attachment.mod_date = None
            attachment.read_date = None
            attachments.append(attachment)

        return ParsedEmail(
            None, **{
                'postmark_msgobj': obj,
                'date': parse_date(obj['Date']),
                'subject': obj['Subject'],
                'body': obj['TextBody'],
                'html': obj['HtmlBody'],
                'from_': from_field,
                'to': tos,
                'cc': ccs,
                'resent_to': [],
                'resent_cc': [],
                'attachments': attachments
            })
Exemple #8
0
 def _build_file_upload(self, file_path):
     with open(file_path, "rb") as fp:
         upload = BytesIO(fp.read())
     upload.name = os.path.basename(file_path)  # get file name from path
     upload.content_type = (
         "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
     )
     return upload
Exemple #9
0
 def _run_upload(self, name):
     with factory.load_test_file(name) as fp:
         upload = BytesIO(fp.read())
     upload.name = name
     upload.content_type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
     response = self.client.post(
         reverse('main:describe', kwargs=self.target_kwargs),
         data={"file": upload},
     )
     return response
Exemple #10
0
 def test_invalid_filetype(self):
     upload = BytesIO(b"")
     upload.name = "testfile.docx"
     upload.content_type = "application/octet-stream"
     response = self.client.post(
         reverse("main:describe", kwargs=self.target_kwargs),
         data={"file": upload},
         # front-end returns one of: xlsx, csv, xml, txt; view requires xlsx
         HTTP_X_EDD_FILE_TYPE="txt",
         HTTP_X_FILE_NAME="testfile.docx",
     )
     self.assertEqual(response.status_code, codes.bad_request)
Exemple #11
0
    def test_validate_image_type(self):
        faker = Faker._get_faker()
        data = BytesIO(faker.binary(length=10))
        data.name = faker.file_name(category='image')

        class DummyField:
            pass  # noqa: E701

        test_content = DummyField()  # Mocking the Django's ImageField.

        with self.assertNotRaises(ValidationError):
            # A field with no underlying file is expected to pass the validation.
            validate_image(test_content)
            type(test_content).file = PropertyMock(
                side_effect=FileNotFoundError)
            validate_image(test_content)
            del type(test_content
                     ).file  # Clear the property mock for further testing.
            # A field with file of unknown content type is expected to pass the validation.
            test_content.file = data
            validate_image(test_content)
            # A field with file of content type 'image' is expected to pass the validation.
            data.content_type = faker.mime_type(category='image')
            validate_image(test_content)

        # A field with file of unsupported content type is expected to fail validation.
        for category in [
                'application', 'audio', 'message', 'model', 'multipart',
                'text', 'video'
        ]:
            data.content_type = faker.mime_type(category=category)
            with self.subTest(content_type=data.content_type):
                with self.assertRaises(ValidationError) as cm:
                    validate_image(test_content)
                with override_settings(LANGUAGE_CODE='en'):
                    self.assertEqual(next(iter(cm.exception)),
                                     "File type is not supported.")
                with override_settings(LANGUAGE_CODE='eo'):
                    self.assertEqual(next(iter(cm.exception)),
                                     "Dosiertipo ne akceptebla.")
Exemple #12
0
 def _attachment_upload(self, filename):
     with factory.load_test_file(filename) as fp:
         upload = BytesIO(fp.read())
     upload.name = filename
     upload.content_type = (
         "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
     )
     response = self.client.post(
         reverse("main:overview", kwargs=self.target_kwargs),
         data={"action": "attach", "file": upload, "description": "foobar"},
         follow=True,
     )
     return response
Exemple #13
0
def resize_image(image_object, max_dimension=2048):
    try:
        image = Image.open(image_object)
        if image.height > max_dimension or image.width > max_dimension:
            im = Image.open(image_object)
            im.thumbnail((max_dimension, max_dimension), Image.ANTIALIAS)
            outfile = BytesIO()
            im.save(outfile, image_object.content_type.split('/')[1])
            outfile.content_type = image_object.content_type
            return outfile
    except:
        pass
    return image_object
Exemple #14
0
 def test_comment_image_upload_invalid(self):
     """
     comment image upload, invalid image
     """
     utils.login(self)
     image = BytesIO('BAD\x02D\x01\x00;'.encode('utf-8'))
     image.name = 'image.gif'
     image.content_type = 'image/gif'
     files = {'image': SimpleUploadedFile(image.name, image.read()), }
     response = self.client.post(reverse('spirit:comment-image-upload-ajax'),
                                 HTTP_X_REQUESTED_WITH='XMLHttpRequest',
                                 data=files)
     res = json.loads(response.content.decode('utf-8'))
     self.assertIn('error', res.keys())
     self.assertIn('image', res['error'].keys())
Exemple #15
0
 def _create_workbook(self, parts):
     upload = BytesIO()
     wb = Workbook()
     ws = wb.active
     for i, title in enumerate(['Line Name', 'Part ID', 'Media'], 1):
         ws.cell(row=1, column=i).value = title
     for i, part in enumerate(parts, 2):
         ws.cell(row=i, column=1).value = part
         ws.cell(row=i, column=2).value = part
         ws.cell(row=i, column=3).value = 'M9'
     wb.save(upload)
     upload.name = 'description.xlsx'
     upload.content_type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
     upload.seek(0)
     return upload
Exemple #16
0
 def test_conversion_tool(self):
     response = self.client.get(reverse("edd_utils:proteomics_home"))
     self.assertEqual(response.status_code, codes.ok)
     fixture = (environ.Path(__file__) - 2)("fixtures", "misc_data",
                                            "skyline.csv")
     with open(fixture, "rb") as fp:
         upload = BytesIO(fp.read())
     upload.name = "skyline.csv"
     upload.content_type = "text/csv"
     response = self.client.post(reverse("edd_utils:parse_skyline"),
                                 data={"file": upload})
     self.assertEqual(response.status_code, codes.ok)
     message = response.json()
     self.assertEqual(message["n_proteins"], 4)
     self.assertEqual(message["n_samples"], 4)
     self.assertEqual(message["n_records"], 32)
Exemple #17
0
 def test_conversion_tool(self):
     response = self.client.get(reverse('edd_utils:proteomics_home'))
     self.assertEqual(response.status_code, codes.ok)
     fixture = (environ.Path(__file__) - 2)('fixtures', 'misc_data',
                                            'skyline.csv')
     with open(fixture, 'rb') as fp:
         upload = BytesIO(fp.read())
     upload.name = 'skyline.csv'
     upload.content_type = 'text/csv'
     response = self.client.post(
         reverse('edd_utils:parse_skyline'),
         data={'file': upload},
     )
     self.assertEqual(response.status_code, codes.ok)
     message = response.json()
     self.assertEqual(message['n_proteins'], 4)
     self.assertEqual(message['n_samples'], 4)
     self.assertEqual(message['n_records'], 32)
    def attempt_upload_file_and_verify_result(self, test_case, event_name, content=None):
        """
        Running on a test case, creating a temp file, uploading it by
        calling the corresponding ajax event, and verifying that upload
        happens or is rejected as expected.
        """
        if 'magic_number' in test_case:
            f_handler = BytesIO(codecs.decode(test_case['magic_number'], 'hex_codec'))
        elif content is not None:
            f_handler = BytesIO(
                json.dumps(content, sort_keys=True) if six.PY2 else json.dumps(content, sort_keys=True).encode('utf-8'))
        else:
            f_handler = BytesIO(b'')

        f_handler.content_type = test_case['mimetypes']
        f_handler.name = 'file' + test_case['suffixes']
        url = self.get_handler_url(event_name)
        resp = self.client.post(url, {'file': f_handler})
        self.assertEqual(resp.status_code, test_case['status'])
Exemple #19
0
    def test_attachments(self):
        att1 = BytesIO('test attachment'.encode('utf-8'))
        att1.name = 'test.txt'
        image_content = sample_image_content()
        att2 = BytesIO(image_content)
        att2.name = 'image.png'
        email_content = sample_email_content()
        att3 = BytesIO(email_content)
        att3.content_type = 'message/rfc822; charset="us-ascii"'
        raw_event = mailgun_sign_legacy_payload({
            'message-headers': '[]',
            'attachment-count': '3',
            'content-id-map': """{"<abc123>": "attachment-2"}""",
            'attachment-1': att1,
            'attachment-2': att2,  # inline
            'attachment-3': att3,
        })

        response = self.client.post('/anymail/mailgun/inbound/',
                                    data=raw_event)
        self.assertEqual(response.status_code, 200)
        kwargs = self.assert_handler_called_once_with(
            self.inbound_handler,
            sender=MailgunInboundWebhookView,
            event=ANY,
            esp_name='Mailgun')
        event = kwargs['event']
        message = event.message
        attachments = message.attachments  # AnymailInboundMessage convenience accessor
        self.assertEqual(len(attachments), 2)
        self.assertEqual(attachments[0].get_filename(), 'test.txt')
        self.assertEqual(attachments[0].get_content_type(), 'text/plain')
        self.assertEqual(attachments[0].get_content_text(), 'test attachment')
        self.assertEqual(attachments[1].get_content_type(), 'message/rfc822')
        self.assertEqualIgnoringHeaderFolding(
            attachments[1].get_content_bytes(), email_content)

        inlines = message.inline_attachments
        self.assertEqual(len(inlines), 1)
        inline = inlines['abc123']
        self.assertEqual(inline.get_filename(), 'image.png')
        self.assertEqual(inline.get_content_type(), 'image/png')
        self.assertEqual(inline.get_content_bytes(), image_content)
Exemple #20
0
 def create_file(self):
     attachment = BytesIO(self.data)
     attachment.content_type = self.content_type
     attachment.size = self.size
     attachment.name = "archivo.pdf"
     return attachment
Exemple #21
0
    def test_attachments(self):
        att1 = BytesIO('test attachment'.encode('utf-8'))
        att1.name = 'test.txt'
        image_content = sample_image_content()
        att2 = BytesIO(image_content)
        att2.name = 'image.png'
        email_content = sample_email_content()
        att3 = BytesIO(email_content)
        att3.content_type = 'message/rfc822; charset="us-ascii"'
        raw_event = {
            'headers':
            '',
            'attachments':
            '3',
            'attachment-info':
            json.dumps({
                "attachment3": {
                    "filename": "",
                    "name": "",
                    "charset": "US-ASCII",
                    "type": "message/rfc822"
                },
                "attachment2": {
                    "filename": "image.png",
                    "name": "image.png",
                    "type": "image/png",
                    "content-id": "abc123"
                },
                "attachment1": {
                    "filename": "test.txt",
                    "name": "test.txt",
                    "type": "text/plain"
                },
            }),
            'content-ids':
            '{"abc123": "attachment2"}',
            'attachment1':
            att1,
            'attachment2':
            att2,  # inline
            'attachment3':
            att3,
        }

        response = self.client.post('/anymail/sendgrid/inbound/',
                                    data=raw_event)
        self.assertEqual(response.status_code, 200)
        kwargs = self.assert_handler_called_once_with(
            self.inbound_handler,
            sender=SendGridInboundWebhookView,
            event=ANY,
            esp_name='SendGrid')
        event = kwargs['event']
        message = event.message
        attachments = message.attachments  # AnymailInboundMessage convenience accessor
        self.assertEqual(len(attachments), 2)
        self.assertEqual(attachments[0].get_filename(), 'test.txt')
        self.assertEqual(attachments[0].get_content_type(), 'text/plain')
        self.assertEqual(attachments[0].get_content_text(), 'test attachment')
        self.assertEqual(attachments[1].get_content_type(), 'message/rfc822')
        self.assertEqualIgnoringHeaderFolding(
            attachments[1].get_content_bytes(), email_content)

        inlines = message.inline_attachments
        self.assertEqual(len(inlines), 1)
        inline = inlines['abc123']
        self.assertEqual(inline.get_filename(), 'image.png')
        self.assertEqual(inline.get_content_type(), 'image/png')
        self.assertEqual(inline.get_content_bytes(), image_content)
Exemple #22
0
 def prep_data(length):
     data = BytesIO(faker.binary(length=length))
     data.name = faker.file_name(category='image')
     data.content_type = faker.mime_type(category='image')
     data.size = length
     return data