Пример #1
0
    def as2message(self):
        """ Returns an object of pyas2lib's Message class"""
        if self.direction == 'IN':
            as2m = As2Message(sender=self.partner.as2partner, receiver=self.organization.as2org)
        else:
            as2m = As2Message(sender=self.organization.as2org, receiver=self.partner.as2partner)

        as2m.message_id = self.message_id
        as2m.mic = self.mic

        return as2m
Пример #2
0
    def form_valid(self, form):
        # Send the file to the partner
        payload = form.cleaned_data['file'].read()
        as2message = As2Message(
            sender=form.cleaned_data['organization'].as2org,
            receiver=form.cleaned_data['partner'].as2partner
        )
        logger.debug(f'Building message from {form.cleaned_data["file"].name} to send to partner '
                     f'{as2message.receiver.as2_name} from org {as2message.sender.as2_name}.')
        as2message.build(
            payload,
            filename=form.cleaned_data['file'].name,
            subject=form.cleaned_data['partner'].subject,
            content_type=form.cleaned_data['partner'].content_type
        )

        message, _ = Message.objects.create_from_as2message(
            as2message=as2message,
            payload=payload,
            filename=form.cleaned_data['file'].name,
            direction='OUT',
            status='P'
        )
        message.send_message(as2message.headers, as2message.content)
        if message.status in ['S', 'P']:
            messages.success(
                self.request, 'Message has been successfully send to Partner.')
        else:
            messages.error(
                self.request, 'Message transmission failed, check Messages tab for details.')
        return super(SendAs2Message, self).form_valid(form)
Пример #3
0
    def test_manageserver_command(self):
        """ Test the command for managing the as2 server """
        settings.MAX_ARCH_DAYS = -1
        # Create a message
        as2message = As2Message(
            sender=self.organization.as2org,
            receiver=self.partner.as2partner)
        as2message.build(
            self.payload,
            filename='testmessage.edi',
            subject=self.partner.subject,
            content_type=self.partner.content_type
        )
        out_message, _ = Message.objects.create_from_as2message(
            as2message=as2message,
            payload=self.payload,
            direction='OUT',
            status='P'
        )
        out_message.send_message(as2message.headers, as2message.content)

        # Test the retry command
        out_message.refresh_from_db()
        self.assertEqual(out_message.status, 'R')
        management.call_command('manageas2server', retry=True)
        out_message.refresh_from_db()
        self.assertEqual(out_message.retries, 1)

        # Test max retry setting
        settings.MAX_RETRIES = 1
        management.call_command('manageas2server', retry=True)
        out_message.refresh_from_db()
        self.assertEqual(out_message.retries, 2)
        self.assertEqual(out_message.status, 'E')

        # Test the async mdn command for outbound messages
        out_message.status = 'P'
        out_message.save()
        settings.ASYNC_MDN_WAIT = 0
        management.call_command('manageas2server', async_mdns=True)
        out_message.refresh_from_db()
        self.assertEqual(out_message.status, 'E')

        # Test the clean command
        management.call_command('manageas2server', clean=True)
        self.assertEqual(
            Message.objects.filter(
                message_id=out_message.message_id).count(), 0)
Пример #4
0
    def test_duplicate_error(self, mock_request):
        partner = Partner.objects.create(
            name='AS2 Server', as2_name='as2server',
            target_url='http://localhost:8080/pyas2/as2receive',
            signature='sha1',
            signature_cert=self.server_crt,
            encryption='tripledes_192_cbc',
            encryption_cert=self.server_crt,
            mdn=True,
            mdn_mode='SYNC',
            mdn_sign='sha1',
        )

        # Send the message once
        as2message = As2Message(
            sender=self.organization.as2org,
            receiver=partner.as2partner)
        as2message.build(
            self.payload,
            filename='testmessage.edi',
            subject=partner.subject,
            content_type=partner.content_type
        )
        in_message, _ = Message.objects.create_from_as2message(
            as2message=as2message,
            payload=self.payload,
            direction='OUT',
            status='P'
        )

        mock_request.side_effect = SendMessageMock(self.client)
        in_message.send_message(as2message.headers, as2message.content)

        # Check the status of the message
        self.assertEqual(in_message.status, 'S')
        out_message = Message.objects.get(
            message_id=in_message.message_id, direction='IN')
        self.assertEqual(out_message.status, 'S')

        # send it again to cause duplicate error
        in_message.send_message(as2message.headers, as2message.content)

        # Make sure out message was created
        self.assertEqual(in_message.status, 'E')
        out_message = Message.objects.get(
            message_id=in_message.message_id + '_duplicate', direction='IN')
        self.assertEqual(out_message.status, 'E')
Пример #5
0
    def test_duplicate_error(self, mock_request):
        partner = Partner.objects.create(
            name="AS2 Server",
            as2_name="as2server",
            target_url="http://localhost:8080/pyas2/as2receive",
            signature="sha1",
            signature_cert=self.server_crt,
            encryption="tripledes_192_cbc",
            encryption_cert=self.server_crt,
            mdn=True,
            mdn_mode="SYNC",
            mdn_sign="sha1",
        )

        # Send the message once
        as2message = As2Message(sender=self.organization.as2org,
                                receiver=partner.as2partner)
        as2message.build(
            self.payload,
            filename="testmessage.edi",
            subject=partner.subject,
            content_type=partner.content_type,
        )
        in_message, _ = Message.objects.create_from_as2message(
            as2message=as2message,
            payload=self.payload,
            direction="OUT",
            status="P")

        mock_request.side_effect = SendMessageMock(self.client)
        in_message.send_message(as2message.headers, as2message.content)

        # Check the status of the message
        self.assertEqual(in_message.status, "S")
        out_message = Message.objects.get(message_id=in_message.message_id,
                                          direction="IN")
        self.assertEqual(out_message.status, "S")

        # send it again to cause duplicate error
        in_message.send_message(as2message.headers, as2message.content)

        # Make sure out message was created
        self.assertEqual(in_message.status, "E")
        out_message = Message.objects.get(message_id=in_message.message_id +
                                          "_duplicate",
                                          direction="IN")
        self.assertEqual(out_message.status, "E")
Пример #6
0
    def build_and_send(self, partner, mock_request, smudge=False):
        # Build and send the message to server
        as2message = As2Message(sender=self.organization.as2org,
                                receiver=partner.as2partner)
        as2message.build(self.payload,
                         filename='testmessage.edi',
                         subject=partner.subject,
                         content_type=partner.content_type)
        out_message, _ = Message.objects.create_from_as2message(
            as2message=as2message,
            payload=self.payload,
            direction='OUT',
            status='P')
        mock_request.side_effect = SendMessageMock(self.client)
        out_message.send_message(
            as2message.headers,
            b'xxxx' + as2message.content if smudge else as2message.content)

        return out_message
Пример #7
0
    def form_valid(self, form):
        # Send the file to the partner
        payload = form.cleaned_data["file"].read()
        as2message = As2Message(
            sender=form.cleaned_data["organization"].as2org,
            receiver=form.cleaned_data["partner"].as2partner,
        )
        logger.debug(
            f'Building message from {form.cleaned_data["file"].name} to send to partner '
            f"{as2message.receiver.as2_name} from org {as2message.sender.as2_name}."
        )
        as2message.build(
            payload,
            filename=form.cleaned_data["file"].name,
            subject=form.cleaned_data["partner"].subject,
            content_type=form.cleaned_data["partner"].content_type,
            disposition_notification_to=form.cleaned_data["organization"].email_address
            or "*****@*****.**",
        )

        message, _ = Message.objects.create_from_as2message(
            as2message=as2message,
            payload=payload,
            filename=form.cleaned_data["file"].name,
            direction="OUT",
            status="P",
        )
        message.send_message(as2message.headers, as2message.content)
        if message.status in ["S", "P"]:
            messages.success(
                self.request, "Message has been successfully send to Partner."
            )
        else:
            messages.error(
                self.request,
                "Message transmission failed, check Messages tab for details.",
            )
        return super().form_valid(form)
Пример #8
0
    def post(self, request, *args, **kwargs):

        # extract the  headers from the http request
        as2headers = ""
        for key in request.META:
            if key.startswith("HTTP") or key.startswith("CONTENT"):
                as2headers += (
                    f'{key.replace("HTTP_", "").replace("_", "-").lower()}: '
                    f"{request.META[key]}\n")

        # build the body along with the headers
        request_body = as2headers.encode() + b"\r\n" + request.body
        logger.debug(
            f'Received an HTTP POST from {request.META["REMOTE_ADDR"]} '
            f"with payload :\n{request_body}")

        # First try to see if this is an MDN
        logger.debug("Check to see if payload is an Asynchronous MDN.")
        as2mdn = As2Mdn()

        # Parse the mdn and get the message status
        status, detailed_status = as2mdn.parse(request_body, self.find_message)

        if not detailed_status == "mdn-not-found":
            message = Message.objects.get(message_id=as2mdn.orig_message_id,
                                          direction="OUT")
            logger.info(
                f"Asynchronous MDN received for AS2 message {as2mdn.message_id} to organization "
                f"{message.organization.as2_name} from partner {message.partner.as2_name}"
            )

            # Update the message status and return the response
            if status == "processed":
                message.status = "S"
                run_post_send(message)
            else:
                message.status = "E"
                message.detailed_status = (
                    f"Partner failed to process message: {detailed_status}")
            # Save the message and create the mdn
            message.save()
            Mdn.objects.create_from_as2mdn(as2mdn=as2mdn,
                                           message=message,
                                           status="R")

            return HttpResponse(_("AS2 ASYNC MDN has been received"))

        else:
            logger.debug("Payload is not an MDN parse it as an AS2 Message")
            as2message = As2Message()
            status, exception, as2mdn = as2message.parse(
                request_body,
                self.find_organization,
                self.find_partner,
                self.check_message_exists,
            )

            logger.info(
                f'Received an AS2 message with id {as2message.headers.get("message-id")} for '
                f'organization {as2message.headers.get("as2-to")} from '
                f'partner {as2message.headers.get("as2-from")}.')

            # In case of duplicates update message id
            if isinstance(exception[0], DuplicateDocument):
                as2message.message_id += "_duplicate"

            # Create the Message and MDN objects
            message, full_fn = Message.objects.create_from_as2message(
                as2message=as2message,
                filename=as2message.payload.get_filename(),
                payload=as2message.content,
                direction="IN",
                status="S" if status == "processed" else "E",
                detailed_status=exception[1],
            )

            # run post receive command on success
            if status == "processed":
                run_post_receive(message, full_fn)

            # Return the mdn in case of sync else return text message
            if as2mdn and as2mdn.mdn_mode == "SYNC":
                message.mdn = Mdn.objects.create_from_as2mdn(as2mdn=as2mdn,
                                                             message=message,
                                                             status="S")
                response = HttpResponse(as2mdn.content)
                for key, value in as2mdn.headers.items():
                    response[key] = value
                return response

            elif as2mdn and as2mdn.mdn_mode == "ASYNC":
                Mdn.objects.create_from_as2mdn(
                    as2mdn=as2mdn,
                    message=message,
                    status="P",
                    return_url=as2mdn.mdn_url,
                )
            return HttpResponse(_("AS2 message has been received"))
Пример #9
0
    def post(self, request, *args, **kwargs):

        # extract the  headers from the http request
        as2headers = ''
        for key in request.META:
            if key.startswith('HTTP') or key.startswith('CONTENT'):
                as2headers += f'{key.replace("HTTP_", "").replace("_", "-").lower()}: ' \
                              f'{request.META[key]}\n'

        # build the body along with the headers
        request_body = as2headers.encode() + b'\r\n' + request.body
        logger.debug(
            f'Received an HTTP POST from {request.META["REMOTE_ADDR"]} '
            f'with payload :\n{request_body}'
        )

        # First try to see if this is an MDN
        logger.debug('Check to see if payload is an Asynchronous MDN.')
        as2mdn = As2Mdn()

        # Parse the mdn and get the message status
        status, detailed_status = as2mdn.parse(request_body, self.find_message)

        if not detailed_status == 'mdn-not-found':
            message = Message.objects.get(message_id=as2mdn.orig_message_id, direction='OUT')
            logger.info(
                f'Asynchronous MDN received for AS2 message {as2mdn.message_id} to organization '
                f'{message.organization.as2_name} from partner {message.partner.as2_name}')

            # Update the message status and return the response
            if status == 'processed':
                message.status = 'S'
                run_post_send(message)
            else:
                message.status = 'E'
                message.detailed_status = f'Partner failed to process message: {detailed_status}'
                run_post_failure(message)
            # Save the message and create the mdn
            message.save()
            Mdn.objects.create_from_as2mdn(as2mdn=as2mdn, message=message, status='R')

            return HttpResponse(_('AS2 ASYNC MDN has been received'))

        else:
            logger.debug('Payload is not an MDN parse it as an AS2 Message')
            as2message = As2Message()
            status, exception, as2mdn = as2message.parse(
                request_body, self.find_organization, self.find_partner, self.check_message_exists)

            logger.info(
                f'Received an AS2 message with id {as2message.headers.get("message-id")} for '
                f'organization {as2message.headers.get("as2-to")} from '
                f'partner {as2message.headers.get("as2-from")}.'
            )

            # In case of duplicates update message id
            if isinstance(exception[0], DuplicateDocument):
                as2message.message_id += '_duplicate'

            # Create the Message and MDN objects
            message, full_fn = Message.objects.create_from_as2message(
                as2message=as2message,
                filename=as2message.payload.get_filename(),
                payload=as2message.content,
                direction='IN',
                status='S' if status == 'processed' else 'E',
                detailed_status=exception[1]
            )

            # run post receive command on success
            if status == 'processed':
                run_post_receive(message, full_fn)

            # Return the mdn in case of sync else return text message
            if as2mdn and as2mdn.mdn_mode == 'SYNC':
                message.mdn = Mdn.objects.create_from_as2mdn(
                    as2mdn=as2mdn, message=message, status='S')
                response = HttpResponse(as2mdn.content)
                for key, value in as2mdn.headers.items():
                    response[key] = value
                return response

            elif as2mdn and as2mdn.mdn_mode == 'ASYNC':
                Mdn.objects.create_from_as2mdn(
                    as2mdn=as2mdn, message=message, status='P', return_url=as2mdn.mdn_url)
            return HttpResponse(_('AS2 message has been received'))