From 26efb2aee5b55dcb8d3480132ae8d39908b11837 Mon Sep 17 00:00:00 2001 From: Wassilios Lytras Date: Thu, 12 Jan 2023 02:13:25 +0100 Subject: [PATCH 1/4] Fix/build fix pyopenssl (#57) * Update PyOpenSSL --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 7bc4ff0..e5f350d 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ install_requires = [ "asn1crypto==1.5.1", "oscrypto==1.3.0", - "pyOpenSSL==21.0.0", + "pyOpenSSL==23.0.0", ] tests_require = [ From f15e8b90724069228ef6a5958b40113e388b6fea Mon Sep 17 00:00:00 2001 From: abhishekram Date: Wed, 25 Jan 2023 20:17:06 +0530 Subject: [PATCH 2/4] Bump version to 1.4.3 and update change log --- CHANGELOG.md | 4 ++++ pyas2lib/__init__.py | 2 +- setup.py | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 308eeab..356f159 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History +## 1.4.3 - 2023-01-25 + +* fix: update pyopenssl version to resovle pyca/cryptography#7959 + ## 1.4.2 - 2022-12-11 * fix: update the black version to fix github ci pipeline diff --git a/pyas2lib/__init__.py b/pyas2lib/__init__.py index 00d720f..aba789a 100644 --- a/pyas2lib/__init__.py +++ b/pyas2lib/__init__.py @@ -9,7 +9,7 @@ from pyas2lib.as2 import Organization from pyas2lib.as2 import Partner -__version__ = "1.4.1" +__version__ = "1.4.3" __all__ = [ diff --git a/setup.py b/setup.py index e5f350d..76edb93 100644 --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ long_description="Docs for this project are maintained at " "https://github.com/abhishek-ram/pyas2-lib/blob/" "master/README.md", - version="1.4.2", + version="1.4.3", author="Abhishek Ram", author_email="abhishek8816@gmail.com", packages=find_packages(where=".", exclude=("test*",)), From b9dc0a29e8b57c607805ff6677a8078a132b3f7f Mon Sep 17 00:00:00 2001 From: magicrobotmonkey Date: Sun, 20 Aug 2023 21:13:39 -0500 Subject: [PATCH 3/4] pyOpenSSL/cryptography upgrade (#61) bump pyOpenSSL version to 23.2.0, which bumps cryptography version to 41.0.x which fixes CVE-2023-2650 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 76edb93..e4d55b8 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ install_requires = [ "asn1crypto==1.5.1", "oscrypto==1.3.0", - "pyOpenSSL==23.0.0", + "pyOpenSSL==23.2.0", ] tests_require = [ From af63a9b6e39385f099ad3b9e94e5b730201ca293 Mon Sep 17 00:00:00 2001 From: Brandon Joyce Date: Wed, 29 Nov 2023 12:08:51 -0500 Subject: [PATCH 4/4] Add message_id parameter (#63) * Add message_id parameter * Validate length of message id when user provided * Formatting --- AUTHORS.md | 9 +++++---- pyas2lib/as2.py | 25 +++++++++++++++++++++---- pyas2lib/tests/test_basic.py | 24 ++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/AUTHORS.md b/AUTHORS.md index 3c75246..f8b47d9 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -1,4 +1,5 @@ -* Abhishek Ram @abhishek-ram -* Chad Gates @chadgates -* Bruno Ribeiro da Silva @loop0 -* Robin C Samuel @robincsamuel \ No newline at end of file +- Abhishek Ram @abhishek-ram +- Chad Gates @chadgates +- Bruno Ribeiro da Silva @loop0 +- Robin C Samuel @robincsamuel +- Brandon Joyce @brandonjoyce diff --git a/pyas2lib/as2.py b/pyas2lib/as2.py index cb058ad..12ebac7 100644 --- a/pyas2lib/as2.py +++ b/pyas2lib/as2.py @@ -330,6 +330,7 @@ def build( content_type="application/edi-consent", additional_headers=None, disposition_notification_to="no-reply@pyas2.com", + message_id=None, ): """Function builds the AS2 message. Compresses, signs and encrypts @@ -354,6 +355,10 @@ def build( :param disposition_notification_to: Email address for disposition-notification-to header entry. (default "no-reply@pyas2.com") + + :param message_id: + A value to be used for the left side of the message id. If not provided a + unique id is generated. (default None) """ # Validations @@ -372,10 +377,22 @@ def build( "Encryption of messages is enabled but encrypt key is not set for the receiver." ) - # Generate message id using UUID 1 as it uses both hostname and time - self.message_id = ( - email_utils.make_msgid(domain=self.sender.domain).lstrip("<").rstrip(">") - ) + if message_id: + self.message_id = f"{message_id}@{self.sender.domain}" + else: + self.message_id = ( + email_utils.make_msgid(domain=self.sender.domain) + .lstrip("<") + .rstrip(">") + ) + + # ensure the total length of the message id is no more than 255 characters + if len(self.message_id) > 255: + raise ValueError( + "Message ID must be no more than 255 characters for " + "compatibility with some AS2 servers. " + f"Current message ID length is {len(self.message_id)}." + ) # Set up the message headers as2_headers = { diff --git a/pyas2lib/tests/test_basic.py b/pyas2lib/tests/test_basic.py index 3eadbb8..fed94b9 100644 --- a/pyas2lib/tests/test_basic.py +++ b/pyas2lib/tests/test_basic.py @@ -1,4 +1,5 @@ """Module for testing the basic features of pyas2.""" +import pytest import socket from pyas2lib import as2 from . import Pyas2TestCase @@ -200,6 +201,29 @@ def test_plain_message_without_domain(self): out_message.build(self.test_data) self.assertEqual(out_message.message_id.split("@")[1], socket.getfqdn()) + def test_plain_message_with_custom_message_id(self): + """Test Message building with a custom message id""" + + # Build an As2 message to be transmitted to partner + self.org.domain = "example.com" + out_message = as2.Message(self.org, self.partner) + out_message.build(self.test_data, message_id="some_custom_id") + self.assertEqual(out_message.message_id, "some_custom_id@example.com") + + def test_invalid_message_id_length_raises_error(self): + """Test Message building with a custom message id that's invalid""" + + # Build an As2 message to be transmitted to partner + self.org.domain = "example.com" + out_message = as2.Message(self.org, self.partner) + very_long_message_id = "a" * 1000 + with pytest.raises(ValueError) as excinfo: + out_message.build(self.test_data, message_id=very_long_message_id) + assert ( + "Message ID must be no more than 255 characters for compatibility" + in str(excinfo.value) + ) + def find_org(self, as2_id): return self.org