diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d0ff77b..9fffdcd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ['3.9', '3.10'] # TODO '3.11' + python-version: ['3.10', '3.11'] ckan-version: ["2.10", "2.11"] name: Python ${{ matrix.python-version }} CKAN ${{ matrix.ckan-version }} extension test diff --git a/ckanext/saml2auth/tests/test_blueprint_get_request.py b/ckanext/saml2auth/tests/test_blueprint_get_request.py index 10d7e59..5840975 100644 --- a/ckanext/saml2auth/tests/test_blueprint_get_request.py +++ b/ckanext/saml2auth/tests/test_blueprint_get_request.py @@ -227,35 +227,51 @@ def _load_base( } def _generate_cert(self): - from saml2.cert import OpenSSLWrapper - - cert_info_ca = { - "cn": "localhost.ca", - "country_code": "se", - "state": "ac", - "city": "umea", - "organization": "Test University", - "organization_unit": "Deca" - } - - osw = OpenSSLWrapper() - ca_cert, ca_key = osw.create_certificate( - cert_info_ca, - request=False, - write_to_file=False + # Mint a throwaway RSA keypair / self-signed certificate for the SP + # using the `cryptography` library directly. We deliberately avoid + # pysaml2's saml2.cert.OpenSSLWrapper, which relies on + # OpenSSL.crypto.X509Req -- deprecated in pyOpenSSL 24.2.0 and removed + # in 26.3.0 (which the fork's pyopenssl>=25.3.0 resolves to). The + # extension never generates certificates at runtime, so this keeps + # the test compatible with current pyOpenSSL / cryptography releases. + import datetime + from cryptography import x509 + from cryptography.x509.oid import NameOID + from cryptography.hazmat.primitives import hashes, serialization + from cryptography.hazmat.primitives.asymmetric import rsa + + key = rsa.generate_private_key(public_exponent=65537, key_size=2048) + + name = x509.Name([ + x509.NameAttribute(NameOID.COUNTRY_NAME, u"SE"), + x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"ac"), + x509.NameAttribute(NameOID.LOCALITY_NAME, u"umea"), + x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"Test University"), + x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u"Deca"), + x509.NameAttribute(NameOID.COMMON_NAME, u"localhost"), + ]) + + now = datetime.datetime.now(datetime.timezone.utc) + cert = ( + x509.CertificateBuilder() + .subject_name(name) + .issuer_name(name) + .public_key(key.public_key()) + .serial_number(x509.random_serial_number()) + .not_valid_before(now - datetime.timedelta(days=1)) + .not_valid_after(now + datetime.timedelta(days=3650)) + .sign(key, hashes.SHA256()) ) - cert_str, key_str = osw.create_certificate(cert_info_ca, request=True) - re_cert_str = osw.create_cert_signed_certificate( - ca_cert, - ca_key, - cert_str, - valid_from=0, - valid_to=1 + key_str = key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.TraditionalOpenSSL, + encryption_algorithm=serialization.NoEncryption(), ) + cert_str = cert.public_bytes(serialization.Encoding.PEM).decode('ascii') f = open(os.path.join(extras_folder, 'provider1', 'mycert.pem'), 'w') - f.write(re_cert_str) + f.write(cert_str) f.close() f = open(os.path.join(extras_folder, 'provider1', 'mykey.pem'), 'wb') @@ -263,7 +279,7 @@ def _generate_cert(self): f.close() self.key_str = key_str - self.cert_str = re_cert_str + self.cert_str = cert_str @pytest.mark.ckan_config(u'ckanext.saml2auth.entity_id', u'urn:gov:gsa:SAML:2.0.profiles:sp:sso:test:entity') @pytest.mark.ckan_config(u'ckanext.saml2auth.idp_metadata.location', u'local') diff --git a/dev-requirements.txt b/dev-requirements.txt index fcd5547..a59341a 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,3 +1,2 @@ flake8 # for the CI build -pysaml2 packaging>=22.0 diff --git a/setup.py b/setup.py index 904c33a..fde496b 100644 --- a/setup.py +++ b/setup.py @@ -78,9 +78,12 @@ packages=find_packages(exclude=['contrib', 'docs', 'tests*']), namespace_packages=['ckanext'], - # pysaml2 7.4 requires python 3.9 + # See pysaml2 dependency + # https://github.com/IdentityPython/pysaml2/pull/1021 + # https://github.com/IdentityPython/pysaml2/pull/1021#issuecomment-4075874429 install_requires=[ - 'pysaml2>=7.4', + 'pysaml2 @ git+https://github.com/peppelinux/pysaml2@pplnx-v7.5.4-1', + ], # If there are data files included in your packages that need to be