Hello community, here is the log from the commit of package python-acme for openSUSE:Factory checked in at 2018-07-18 22:55:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-acme (Old) and /work/SRC/openSUSE:Factory/.python-acme.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-acme" Wed Jul 18 22:55:02 2018 rev:20 rq:623161 version:0.26.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-acme/python-acme.changes 2018-07-06 10:41:50.795265381 +0200 +++ /work/SRC/openSUSE:Factory/.python-acme.new/python-acme.changes 2018-07-18 22:55:49.514585767 +0200 @@ -2 +2,7 @@ -Wed Jul 4 11:20:45 UTC 2018 - [email protected] +Mon Jul 16 14:37:48 UTC 2018 - [email protected] + +- update to 0.26.0 + - No changelog from upstream + +------------------------------------------------------------------- +Wed Jul 4 11:20:45 UTC 2018 - [email protected] Old: ---- acme-0.25.1.tar.gz acme-0.25.1.tar.gz.asc New: ---- acme-0.26.0.tar.gz acme-0.26.0.tar.gz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-acme.spec ++++++ --- /var/tmp/diff_new_pack.WXwcF6/_old 2018-07-18 22:55:50.106583804 +0200 +++ /var/tmp/diff_new_pack.WXwcF6/_new 2018-07-18 22:55:50.110583791 +0200 @@ -21,7 +21,7 @@ %define libname acme Name: python-%{libname} -Version: 0.25.1 +Version: 0.26.0 Release: 0 Summary: Python library for the ACME protocol License: Apache-2.0 @@ -35,8 +35,6 @@ BuildRequires: %{python_module cryptography >= 0.8} BuildRequires: %{python_module devel >= 2.7} BuildRequires: %{python_module dnspython >= 1.12} -BuildRequires: %{python_module idna < 2.7} -BuildRequires: %{python_module idna >= 2.5} BuildRequires: %{python_module josepy >= 1.0.0} BuildRequires: %{python_module mock} BuildRequires: %{python_module ndg-httpsclient} @@ -67,8 +65,8 @@ Requires: python-pyasn1 Requires: python-pytz Requires: python-requests >= 2.10 -Requires: python-six >= 1.5.2 Requires: python-requests-toolbelt >= 0.3.0 +Requires: python-six >= 1.5.2 BuildArch: noarch %python_subpackages ++++++ acme-0.25.1.tar.gz -> acme-0.26.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-0.25.1/PKG-INFO new/acme-0.26.0/PKG-INFO --- old/acme-0.25.1/PKG-INFO 2018-06-13 03:20:35.000000000 +0200 +++ new/acme-0.26.0/PKG-INFO 2018-07-11 23:10:12.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: acme -Version: 0.25.1 +Version: 0.26.0 Summary: ACME protocol implementation in Python Home-page: https://github.com/letsencrypt/letsencrypt Author: Certbot Project @@ -8,7 +8,7 @@ License: Apache License 2.0 Description: UNKNOWN Platform: UNKNOWN -Classifier: Development Status :: 3 - Alpha +Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: Apache Software License Classifier: Programming Language :: Python @@ -18,6 +18,7 @@ Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Security Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-0.25.1/acme/challenges.py new/acme-0.26.0/acme/challenges.py --- old/acme-0.25.1/acme/challenges.py 2018-06-13 03:20:14.000000000 +0200 +++ new/acme-0.26.0/acme/challenges.py 2018-07-11 23:09:09.000000000 +0200 @@ -508,6 +508,21 @@ @Challenge.register # pylint: disable=too-many-ancestors +class TLSALPN01(KeyAuthorizationChallenge): + """ACME tls-alpn-01 challenge. + + This class simply allows parsing the TLS-ALPN-01 challenge returned from + the CA. Full TLS-ALPN-01 support is not currently provided. + + """ + typ = "tls-alpn-01" + + def validation(self, account_key, **kwargs): + """Generate validation for the challenge.""" + raise NotImplementedError() + + [email protected] # pylint: disable=too-many-ancestors class DNS(_TokenChallenge): """ACME "dns" challenge.""" typ = "dns" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-0.25.1/acme/challenges_test.py new/acme-0.26.0/acme/challenges_test.py --- old/acme-0.25.1/acme/challenges_test.py 2018-06-13 03:20:14.000000000 +0200 +++ new/acme-0.26.0/acme/challenges_test.py 2018-07-11 23:09:09.000000000 +0200 @@ -393,6 +393,38 @@ mock_gen_cert.assert_called_once_with(key=mock.sentinel.cert_key) +class TLSALPN01Test(unittest.TestCase): + + def setUp(self): + from acme.challenges import TLSALPN01 + self.msg = TLSALPN01( + token=jose.b64decode('a82d5ff8ef740d12881f6d3c2277ab2e')) + self.jmsg = { + 'type': 'tls-alpn-01', + 'token': 'a82d5ff8ef740d12881f6d3c2277ab2e', + } + + def test_to_partial_json(self): + self.assertEqual(self.jmsg, self.msg.to_partial_json()) + + def test_from_json(self): + from acme.challenges import TLSALPN01 + self.assertEqual(self.msg, TLSALPN01.from_json(self.jmsg)) + + def test_from_json_hashable(self): + from acme.challenges import TLSALPN01 + hash(TLSALPN01.from_json(self.jmsg)) + + def test_from_json_invalid_token_length(self): + from acme.challenges import TLSALPN01 + self.jmsg['token'] = jose.encode_b64jose(b'abcd') + self.assertRaises( + jose.DeserializationError, TLSALPN01.from_json, self.jmsg) + + def test_validation(self): + self.assertRaises(NotImplementedError, self.msg.validation, KEY) + + class DNSTest(unittest.TestCase): def setUp(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-0.25.1/acme/client.py new/acme-0.26.0/acme/client.py --- old/acme-0.25.1/acme/client.py 2018-06-13 03:20:14.000000000 +0200 +++ new/acme-0.26.0/acme/client.py 2018-07-11 23:09:09.000000000 +0200 @@ -50,7 +50,6 @@ :ivar .ClientNetwork net: Client network. :ivar int acme_version: ACME protocol version. 1 or 2. """ - def __init__(self, directory, net, acme_version): """Initialize. @@ -588,6 +587,30 @@ self.net.account = regr return regr + def update_registration(self, regr, update=None): + """Update registration. + + :param messages.RegistrationResource regr: Registration Resource. + :param messages.Registration update: Updated body of the + resource. If not provided, body will be taken from `regr`. + + :returns: Updated Registration Resource. + :rtype: `.RegistrationResource` + + """ + # https://github.com/certbot/certbot/issues/6155 + new_regr = self._get_v2_account(regr) + return super(ClientV2, self).update_registration(new_regr, update) + + def _get_v2_account(self, regr): + self.net.account = None + only_existing_reg = regr.body.update(only_return_existing=True) + response = self._post(self.directory['newAccount'], only_existing_reg) + updated_uri = response.headers['Location'] + new_regr = regr.update(uri=updated_uri) + self.net.account = new_regr + return new_regr + def new_order(self, csr_pem): """Request a new Order object from the server. @@ -910,6 +933,7 @@ if acme_version == 2: kwargs["url"] = url # newAccount and revokeCert work without the kid + # newAccount must not have kid if self.account is not None: kwargs["kid"] = self.account["uri"] kwargs["key"] = self.key diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-0.25.1/acme/client_test.py new/acme-0.26.0/acme/client_test.py --- old/acme-0.25.1/acme/client_test.py 2018-06-13 03:20:14.000000000 +0200 +++ new/acme-0.26.0/acme/client_test.py 2018-07-11 23:09:09.000000000 +0200 @@ -139,7 +139,7 @@ client = self._init() self.assertEqual(client.directory, client.client.directory) self.assertEqual(client.key, KEY) - self.assertEqual(client.update_registration, client.client.update_registration) + self.assertEqual(client.deactivate_registration, client.client.deactivate_registration) self.assertRaises(AttributeError, client.__getattr__, 'nonexistent') self.assertRaises(AttributeError, client.__getattr__, 'new_account_and_tos') self.assertRaises(AttributeError, client.__getattr__, 'new_account') @@ -270,6 +270,13 @@ client.revoke(messages_test.CERT, self.rsn) mock_client().revoke.assert_called_once_with(messages_test.CERT, self.rsn) + def test_update_registration(self): + self.response.json.return_value = DIRECTORY_V1.to_json() + with mock.patch('acme.client.Client') as mock_client: + client = self._init() + client.update_registration(mock.sentinel.regr, None) + mock_client().update_registration.assert_called_once_with(mock.sentinel.regr, None) + class ClientTest(ClientTestBase): """Tests for acme.client.Client.""" @@ -789,6 +796,19 @@ self.net.post.assert_called_once_with( self.directory["revokeCert"], mock.ANY, acme_version=2) + def test_update_registration(self): + # "Instance of 'Field' has no to_json/update member" bug: + # pylint: disable=no-member + self.response.headers['Location'] = self.regr.uri + self.response.json.return_value = self.regr.body.to_json() + self.assertEqual(self.regr, self.client.update_registration(self.regr)) + self.assertNotEqual(self.client.net.account, None) + self.assertEqual(self.client.net.post.call_count, 2) + self.assertTrue(DIRECTORY_V2.newAccount in self.net.post.call_args_list[0][0]) + + self.response.json.return_value = self.regr.body.update( + contact=()).to_json() + class MockJSONDeSerializable(jose.JSONDeSerializable): # pylint: disable=missing-docstring diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-0.25.1/acme/crypto_util_test.py new/acme-0.26.0/acme/crypto_util_test.py --- old/acme-0.25.1/acme/crypto_util_test.py 2018-06-13 03:20:14.000000000 +0200 +++ new/acme-0.26.0/acme/crypto_util_test.py 2018-07-11 23:09:09.000000000 +0200 @@ -42,28 +42,38 @@ self.server_thread = threading.Thread( # pylint: disable=no-member target=self.server.handle_request) - self.server_thread.start() - time.sleep(1) # TODO: avoid race conditions in other way def tearDown(self): - self.server_thread.join() + if self.server_thread.is_alive(): + # The thread may have already terminated. + self.server_thread.join() # pragma: no cover def _probe(self, name): from acme.crypto_util import probe_sni return jose.ComparableX509(probe_sni( name, host='127.0.0.1', port=self.port)) + def _start_server(self): + self.server_thread.start() + time.sleep(1) # TODO: avoid race conditions in other way + def test_probe_ok(self): + self._start_server() self.assertEqual(self.cert, self._probe(b'foo')) def test_probe_not_recognized_name(self): + self._start_server() self.assertRaises(errors.Error, self._probe, b'bar') - # TODO: py33/py34 tox hangs forever on do_handshake in second probe - #def probe_connection_error(self): - # self._probe(b'foo') - # #time.sleep(1) # TODO: avoid race conditions in other way - # self.assertRaises(errors.Error, self._probe, b'bar') + def test_probe_connection_error(self): + # pylint has a hard time with six + self.server.server_close() # pylint: disable=no-member + original_timeout = socket.getdefaulttimeout() + try: + socket.setdefaulttimeout(1) + self.assertRaises(errors.Error, self._probe, b'bar') + finally: + socket.setdefaulttimeout(original_timeout) class PyOpenSSLCertOrReqAllNamesTest(unittest.TestCase): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-0.25.1/acme/messages.py new/acme-0.26.0/acme/messages.py --- old/acme-0.25.1/acme/messages.py 2018-06-13 03:20:14.000000000 +0200 +++ new/acme-0.26.0/acme/messages.py 2018-07-11 23:09:09.000000000 +0200 @@ -274,6 +274,7 @@ agreement = jose.Field('agreement', omitempty=True) status = jose.Field('status', omitempty=True) terms_of_service_agreed = jose.Field('termsOfServiceAgreed', omitempty=True) + only_return_existing = jose.Field('onlyReturnExisting', omitempty=True) phone_prefix = 'tel:' email_prefix = 'mailto:' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-0.25.1/acme/standalone_test.py new/acme-0.26.0/acme/standalone_test.py --- old/acme-0.25.1/acme/standalone_test.py 2018-06-13 03:20:14.000000000 +0200 +++ new/acme-0.26.0/acme/standalone_test.py 2018-07-11 23:09:09.000000000 +0200 @@ -4,10 +4,10 @@ import socket import threading import tempfile -import time import unittest from six.moves import http_client # pylint: disable=import-error +from six.moves import queue # pylint: disable=import-error from six.moves import socketserver # type: ignore # pylint: disable=import-error import josepy as jose @@ -16,7 +16,6 @@ from acme import challenges from acme import crypto_util -from acme import errors from acme import test_util from acme.magic_typing import Set # pylint: disable=unused-import, no-name-in-module @@ -261,10 +260,9 @@ os.path.join(localhost_dir, 'key.pem')) from acme.standalone import simple_tls_sni_01_server - self.port = 1234 self.thread = threading.Thread( target=simple_tls_sni_01_server, kwargs={ - 'cli_args': ('xxx', '--port', str(self.port)), + 'cli_args': ('filename',), 'forever': False, }, ) @@ -276,25 +274,20 @@ self.thread.join() shutil.rmtree(self.test_cwd) - def test_it(self): - max_attempts = 5 - for attempt in range(max_attempts): - try: - cert = crypto_util.probe_sni( - b'localhost', b'0.0.0.0', self.port) - except errors.Error: - self.assertTrue(attempt + 1 < max_attempts, "Timeout!") - time.sleep(1) # wait until thread starts - else: - self.assertEqual(jose.ComparableX509(cert), - test_util.load_comparable_cert( - 'rsa2048_cert.pem')) - break - - if attempt == 0: - # the first attempt is always meant to fail, so we can test - # the socket failure code-path for probe_sni, as well - self.thread.start() + @mock.patch('acme.standalone.logger') + def test_it(self, mock_logger): + # Use a Queue because mock objects aren't thread safe. + q = queue.Queue() # type: queue.Queue[int] + # Add port number to the queue. + mock_logger.info.side_effect = lambda *args: q.put(args[-1]) + self.thread.start() + + # After the timeout, an exception is raised if the queue is empty. + port = q.get(timeout=5) + cert = crypto_util.probe_sni(b'localhost', b'0.0.0.0', port) + self.assertEqual(jose.ComparableX509(cert), + test_util.load_comparable_cert( + 'rsa2048_cert.pem')) if __name__ == "__main__": diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-0.25.1/acme.egg-info/PKG-INFO new/acme-0.26.0/acme.egg-info/PKG-INFO --- old/acme-0.25.1/acme.egg-info/PKG-INFO 2018-06-13 03:20:35.000000000 +0200 +++ new/acme-0.26.0/acme.egg-info/PKG-INFO 2018-07-11 23:10:12.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: acme -Version: 0.25.1 +Version: 0.26.0 Summary: ACME protocol implementation in Python Home-page: https://github.com/letsencrypt/letsencrypt Author: Certbot Project @@ -8,7 +8,7 @@ License: Apache License 2.0 Description: UNKNOWN Platform: UNKNOWN -Classifier: Development Status :: 3 - Alpha +Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: Apache Software License Classifier: Programming Language :: Python @@ -18,6 +18,7 @@ Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Security Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/acme-0.25.1/setup.py new/acme-0.26.0/setup.py --- old/acme-0.25.1/setup.py 2018-06-13 03:20:15.000000000 +0200 +++ new/acme-0.26.0/setup.py 2018-07-11 23:09:10.000000000 +0200 @@ -3,7 +3,7 @@ from setuptools.command.test import test as TestCommand import sys -version = '0.25.1' +version = '0.26.0' # Please update tox.ini when modifying dependency version requirements install_requires = [ @@ -58,7 +58,7 @@ license='Apache License 2.0', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', classifiers=[ - 'Development Status :: 3 - Alpha', + 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'License :: OSI Approved :: Apache Software License', 'Programming Language :: Python', @@ -68,6 +68,7 @@ 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', 'Topic :: Internet :: WWW/HTTP', 'Topic :: Security', ],
