Hello community,

here is the log from the commit of package python-acme for openSUSE:Factory 
checked in at 2020-07-15 15:01:22
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-acme (Old)
 and      /work/SRC/openSUSE:Factory/.python-acme.new.3060 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-acme"

Wed Jul 15 15:01:22 2020 rev:45 rq:820645 version:1.6.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-acme/python-acme.changes  2020-06-11 
15:15:27.678955627 +0200
+++ /work/SRC/openSUSE:Factory/.python-acme.new.3060/python-acme.changes        
2020-07-15 15:01:41.151214944 +0200
@@ -1,0 +2,9 @@
+Mon Jul 13 08:27:35 UTC 2020 - Marketa Calabkova <[email protected]>
+
+- update to version 1.6.0
+  * Support for alternative certificate chains in the acme module.
+  * Added --preferred-chain <issuer CN>. If a CA offers multiple 
+    certificate chains, it may be used to indicate to Certbot which 
+    chain should be preferred. 
+
+-------------------------------------------------------------------

Old:
----
  acme-1.5.0.tar.gz
  acme-1.5.0.tar.gz.asc

New:
----
  acme-1.6.0.tar.gz
  acme-1.6.0.tar.gz.asc

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-acme.spec ++++++
--- /var/tmp/diff_new_pack.wHBi9c/_old  2020-07-15 15:01:42.887216638 +0200
+++ /var/tmp/diff_new_pack.wHBi9c/_new  2020-07-15 15:01:42.891216641 +0200
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define libname acme
 Name:           python-%{libname}
-Version:        1.5.0
+Version:        1.6.0
 Release:        0
 Summary:        Python library for the ACME protocol
 License:        Apache-2.0
@@ -30,7 +30,7 @@
 BuildRequires:  %{python_module cryptography >= 1.2.3}
 BuildRequires:  %{python_module josepy >= 1.1.0}
 BuildRequires:  %{python_module mock}
-BuildRequires:  %{python_module pyOpenSSL >= 0.13.1}
+BuildRequires:  %{python_module pyOpenSSL >= 0.15.1}
 BuildRequires:  %{python_module pyRFC3339}
 BuildRequires:  %{python_module pytest}
 BuildRequires:  %{python_module pytz}
@@ -43,7 +43,7 @@
 BuildRequires:  python-rpm-macros
 Requires:       python-cryptography >= 1.2.3
 Requires:       python-josepy >= 1.1.0
-Requires:       python-pyOpenSSL >= 0.13.1
+Requires:       python-pyOpenSSL >= 0.15.1
 Requires:       python-pyRFC3339
 Requires:       python-pytz
 Requires:       python-requests >= 2.6.0

++++++ acme-1.5.0.tar.gz -> acme-1.6.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/acme-1.5.0/PKG-INFO new/acme-1.6.0/PKG-INFO
--- old/acme-1.5.0/PKG-INFO     2020-06-02 19:12:54.000000000 +0200
+++ new/acme-1.6.0/PKG-INFO     2020-07-07 19:13:32.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: acme
-Version: 1.5.0
+Version: 1.6.0
 Summary: ACME protocol implementation in Python
 Home-page: https://github.com/letsencrypt/letsencrypt
 Author: Certbot Project
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/acme-1.5.0/acme/client.py 
new/acme-1.6.0/acme/client.py
--- old/acme-1.5.0/acme/client.py       2020-06-02 19:12:31.000000000 +0200
+++ new/acme-1.6.0/acme/client.py       2020-07-07 19:13:19.000000000 +0200
@@ -13,6 +13,7 @@
 import OpenSSL
 import requests
 from requests.adapters import HTTPAdapter
+from requests.utils import parse_header_links
 from requests_toolbelt.adapters.source import SourceAddressAdapter
 import six
 from six.moves import http_client
@@ -733,11 +734,13 @@
             raise errors.ValidationError(failed)
         return orderr.update(authorizations=responses)
 
-    def finalize_order(self, orderr, deadline):
+    def finalize_order(self, orderr, deadline, fetch_alternative_chains=False):
         """Finalize an order and obtain a certificate.
 
         :param messages.OrderResource orderr: order to finalize
         :param datetime.datetime deadline: when to stop polling and timeout
+        :param bool fetch_alternative_chains: whether to also fetch alternative
+            certificate chains
 
         :returns: finalized order
         :rtype: messages.OrderResource
@@ -754,8 +757,13 @@
             if body.error is not None:
                 raise errors.IssuanceError(body.error)
             if body.certificate is not None:
-                certificate_response = self._post_as_get(body.certificate).text
-                return orderr.update(body=body, 
fullchain_pem=certificate_response)
+                certificate_response = self._post_as_get(body.certificate)
+                orderr = orderr.update(body=body, 
fullchain_pem=certificate_response.text)
+                if fetch_alternative_chains:
+                    alt_chains_urls = self._get_links(certificate_response, 
'alternate')
+                    alt_chains = [self._post_as_get(url).text for url in 
alt_chains_urls]
+                    orderr = 
orderr.update(alternative_fullchains_pem=alt_chains)
+                return orderr
         raise errors.TimeoutError()
 
     def revoke(self, cert, rsn):
@@ -785,6 +793,20 @@
         new_args = args[:1] + (None,) + args[1:]
         return self._post(*new_args, **kwargs)
 
+    def _get_links(self, response, relation_type):
+        """
+        Retrieves all Link URIs of relation_type from the response.
+        :param requests.Response response: The requests HTTP response.
+        :param str relation_type: The relation type to filter by.
+        """
+        # Can't use response.links directly because it drops multiple links
+        # of the same relation type, which is possible in RFC8555 responses.
+        if not 'Link' in response.headers:
+            return []
+        links = parse_header_links(response.headers['Link'])
+        return [l['url'] for l in links
+                if 'rel' in l and 'url' in l and l['rel'] == relation_type]
+
 
 class BackwardsCompatibleClientV2(object):
     """ACME client wrapper that tends towards V2-style calls, but
@@ -863,11 +885,13 @@
             return messages.OrderResource(authorizations=authorizations, 
csr_pem=csr_pem)
         return self.client.new_order(csr_pem)
 
-    def finalize_order(self, orderr, deadline):
+    def finalize_order(self, orderr, deadline, fetch_alternative_chains=False):
         """Finalize an order and obtain a certificate.
 
         :param messages.OrderResource orderr: order to finalize
         :param datetime.datetime deadline: when to stop polling and timeout
+        :param bool fetch_alternative_chains: whether to also fetch alternative
+            certificate chains
 
         :returns: finalized order
         :rtype: messages.OrderResource
@@ -898,7 +922,7 @@
             chain = crypto_util.dump_pyopenssl_chain(chain).decode()
 
             return orderr.update(fullchain_pem=(cert + chain))
-        return self.client.finalize_order(orderr, deadline)
+        return self.client.finalize_order(orderr, deadline, 
fetch_alternative_chains)
 
     def revoke(self, cert, rsn):
         """Revoke certificate.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/acme-1.5.0/acme/messages.py 
new/acme-1.6.0/acme/messages.py
--- old/acme-1.5.0/acme/messages.py     2020-06-02 19:12:31.000000000 +0200
+++ new/acme-1.6.0/acme/messages.py     2020-07-07 19:13:19.000000000 +0200
@@ -566,9 +566,11 @@
 class Order(ResourceBody):
     """Order Resource Body.
 
-    :ivar list of .Identifier: List of identifiers for the certificate.
+    :ivar identifiers: List of identifiers for the certificate.
+    :vartype identifiers: `list` of `.Identifier`
     :ivar acme.messages.Status status:
-    :ivar list of str authorizations: URLs of authorizations.
+    :ivar authorizations: URLs of authorizations.
+    :vartype authorizations: `list` of `str`
     :ivar str certificate: URL to download certificate as a fullchain PEM.
     :ivar str finalize: URL to POST to to request issuance once all
         authorizations have "valid" status.
@@ -593,15 +595,20 @@
 
     :ivar acme.messages.Order body:
     :ivar str csr_pem: The CSR this Order will be finalized with.
-    :ivar list of acme.messages.AuthorizationResource authorizations:
-        Fully-fetched AuthorizationResource objects.
+    :ivar authorizations: Fully-fetched AuthorizationResource objects.
+    :vartype authorizations: `list` of `acme.messages.AuthorizationResource`
     :ivar str fullchain_pem: The fetched contents of the certificate URL
         produced once the order was finalized, if it's present.
+    :ivar alternative_fullchains_pem: The fetched contents of alternative 
certificate
+        chain URLs produced once the order was finalized, if present and 
requested during
+        finalization.
+    :vartype alternative_fullchains_pem: `list` of `str`
     """
     body = jose.Field('body', decoder=Order.from_json)
     csr_pem = jose.Field('csr_pem', omitempty=True)
     authorizations = jose.Field('authorizations')
     fullchain_pem = jose.Field('fullchain_pem', omitempty=True)
+    alternative_fullchains_pem = jose.Field('alternative_fullchains_pem', 
omitempty=True)
 
 @Directory.register
 class NewOrder(Order):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/acme-1.5.0/acme.egg-info/PKG-INFO 
new/acme-1.6.0/acme.egg-info/PKG-INFO
--- old/acme-1.5.0/acme.egg-info/PKG-INFO       2020-06-02 19:12:54.000000000 
+0200
+++ new/acme-1.6.0/acme.egg-info/PKG-INFO       2020-07-07 19:13:32.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: acme
-Version: 1.5.0
+Version: 1.6.0
 Summary: ACME protocol implementation in Python
 Home-page: https://github.com/letsencrypt/letsencrypt
 Author: Certbot Project
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/acme-1.5.0/acme.egg-info/requires.txt 
new/acme-1.6.0/acme.egg-info/requires.txt
--- old/acme-1.5.0/acme.egg-info/requires.txt   2020-06-02 19:12:54.000000000 
+0200
+++ new/acme-1.6.0/acme.egg-info/requires.txt   2020-07-07 19:13:32.000000000 
+0200
@@ -1,6 +1,6 @@
 cryptography>=1.2.3
 josepy>=1.1.0
-PyOpenSSL>=0.13.1
+PyOpenSSL>=0.15.1
 pyrfc3339
 pytz
 requests[security]>=2.6.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/acme-1.5.0/setup.py new/acme-1.6.0/setup.py
--- old/acme-1.5.0/setup.py     2020-06-02 19:12:35.000000000 +0200
+++ new/acme-1.6.0/setup.py     2020-07-07 19:13:23.000000000 +0200
@@ -1,4 +1,4 @@
-from distutils.version import StrictVersion
+from distutils.version import LooseVersion
 import sys
 
 from setuptools import __version__ as setuptools_version
@@ -6,7 +6,7 @@
 from setuptools import setup
 from setuptools.command.test import test as TestCommand
 
-version = '1.5.0'
+version = '1.6.0'
 
 # Please update tox.ini when modifying dependency version requirements
 install_requires = [
@@ -17,8 +17,8 @@
     # 1.1.0+ is required to avoid the warnings described at
     # https://github.com/certbot/josepy/issues/13.
     'josepy>=1.1.0',
-    # Connection.set_tlsext_host_name (>=0.13)
-    'PyOpenSSL>=0.13.1',
+    # Connection.set_tlsext_host_name (>=0.13) + matching Xenial requirements 
(>=0.15.1)
+    'PyOpenSSL>=0.15.1',
     'pyrfc3339',
     'pytz',
     'requests[security]>=2.6.0',  # security extras added in 2.4.1
@@ -27,7 +27,7 @@
     'six>=1.9.0',  # needed for python_2_unicode_compatible
 ]
 
-setuptools_known_environment_markers = (StrictVersion(setuptools_version) >= 
StrictVersion('36.2'))
+setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= 
LooseVersion('36.2'))
 if setuptools_known_environment_markers:
     install_requires.append('mock ; python_version < "3.3"')
 elif 'bdist_wheel' in sys.argv[1:]:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/acme-1.5.0/tests/client_test.py 
new/acme-1.6.0/tests/client_test.py
--- old/acme-1.5.0/tests/client_test.py 2020-06-02 19:12:31.000000000 +0200
+++ new/acme-1.6.0/tests/client_test.py 2020-07-07 19:13:19.000000000 +0200
@@ -263,7 +263,7 @@
         with mock.patch('acme.client.ClientV2') as mock_client:
             client = self._init()
             client.finalize_order(mock_orderr, mock_deadline)
-            mock_client().finalize_order.assert_called_once_with(mock_orderr, 
mock_deadline)
+            mock_client().finalize_order.assert_called_once_with(mock_orderr, 
mock_deadline, False)
 
     def test_revoke(self):
         self.response.json.return_value = DIRECTORY_V1.to_json()
@@ -842,6 +842,32 @@
         deadline = datetime.datetime.now() - datetime.timedelta(seconds=60)
         self.assertRaises(errors.TimeoutError, self.client.finalize_order, 
self.orderr, deadline)
 
+    def test_finalize_order_alt_chains(self):
+        updated_order = self.order.update(
+            certificate='https://www.letsencrypt-demo.org/acme/cert/',
+        )
+        updated_orderr = self.orderr.update(body=updated_order,
+                                            fullchain_pem=CERT_SAN_PEM,
+                                            
alternative_fullchains_pem=[CERT_SAN_PEM,
+                                                                        
CERT_SAN_PEM])
+        self.response.json.return_value = updated_order.to_json()
+        self.response.text = CERT_SAN_PEM
+        self.response.headers['Link'] 
='<https://example.com/acme/cert/1>;rel="alternate", ' + \
+            '<https://exaple.com/dir>;rel="index", ' + \
+            '<https://example.com/acme/cert/2>;title="foo";rel="alternate"'
+
+        deadline = datetime.datetime(9999, 9, 9)
+        resp = self.client.finalize_order(self.orderr, deadline, 
fetch_alternative_chains=True)
+        self.net.post.assert_any_call('https://example.com/acme/cert/1',
+                                      mock.ANY, acme_version=2, 
new_nonce_url=mock.ANY)
+        self.net.post.assert_any_call('https://example.com/acme/cert/2',
+                                      mock.ANY, acme_version=2, 
new_nonce_url=mock.ANY)
+        self.assertEqual(resp, updated_orderr)
+
+        del self.response.headers['Link']
+        resp = self.client.finalize_order(self.orderr, deadline, 
fetch_alternative_chains=True)
+        self.assertEqual(resp, 
updated_orderr.update(alternative_fullchains_pem=[]))
+
     def test_revoke(self):
         self.client.revoke(messages_test.CERT, self.rsn)
         self.net.post.assert_called_once_with(



Reply via email to