Comment 97 for bug 1640978

Revision history for this message
Michael Casadevall (mcasadevall) wrote :

This is the backported patch to python-acme, as stated before, this is a direct backport from upstream to handle compat issues, and extends the unittests to cover the new backworks compatibility area.

mcasadevall@lighthouse:~/src/le/sru/python-acme-0.22.2/debian/patches$ cat fix-jose-import
Description: Allow josepy to be imported via acme.jose
 This is a backwards compatibility fixed taken from upstream
 from the following commits:
 https://github.com/certbot/certbot/commit/e3cb782e5992ba306de59ba96dfb6f125720cd06.patch
 https://github.com/certbot/certbot/commit/ec297ccf72e95961586ec2382c3e3225ce578aa4.patch
 .
 python-acme (0.22.2-1ubuntu0.16.04.1~ppa4) xenial; urgency=medium
 .
   * Backport to Xenial for LE change (LP: #1640978)
Author: Michael Casadevall <email address hidden>
Bug-Ubuntu: https://bugs.launchpad.net/bugs/1640978

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: upstream
Bug: https://github.com/certbot/certbot/pull/6592
Forwarded: not-needed
Reviewed-By: Michael Casadevall <email address hidden>
Last-Update: 2019-01-11

--- python-acme-0.22.2.orig/acme/__init__.py
+++ python-acme-0.22.2/acme/__init__.py
@@ -10,3 +10,18 @@ supported version: `draft-ietf-acme-01`_
   https://github.com/ietf-wg-acme/acme/tree/draft-ietf-acme-acme-01

 """
+import sys
+
+# This code exists to keep backwards compatibility with people using acme.jose
+# before it became the standalone josepy package.
+#
+# It is based on
+# https://github.com/requests/requests/blob/1278ecdf71a312dc2268f3bfc0aabfab3c006dcf/requests/packages.py
+
+import josepy as jose
+
+for mod in list(sys.modules):
+ # This traversal is apparently necessary such that the identities are
+ # preserved (acme.jose.* is josepy.*)
+ if mod == 'josepy' or mod.startswith('josepy.'):
+ sys.modules['acme.' + mod.replace('josepy', 'jose', 1)] = sys.modules[mod]
--- /dev/null
+++ python-acme-0.22.2/acme/jose_test.py
@@ -0,0 +1,53 @@
+"""Tests for acme.jose shim."""
+import importlib
+import unittest
+
+class JoseTest(unittest.TestCase):
+ """Tests for acme.jose shim."""
+
+ def _test_it(self, submodule, attribute):
+ if submodule:
+ acme_jose_path = 'acme.jose.' + submodule
+ josepy_path = 'josepy.' + submodule
+ else:
+ acme_jose_path = 'acme.jose'
+ josepy_path = 'josepy'
+ acme_jose_mod = importlib.import_module(acme_jose_path)
+ josepy_mod = importlib.import_module(josepy_path)
+
+ self.assertIs(acme_jose_mod, josepy_mod)
+ self.assertIs(getattr(acme_jose_mod, attribute), getattr(josepy_mod, attribute))
+
+ # We use the imports below with eval, but pylint doesn't
+ # understand that.
+ # pylint: disable=eval-used,unused-variable
+ import acme
+ import josepy
+ acme_jose_mod = eval(acme_jose_path)
+ josepy_mod = eval(josepy_path)
+ self.assertIs(acme_jose_mod, josepy_mod)
+ self.assertIs(getattr(acme_jose_mod, attribute), getattr(josepy_mod, attribute))
+
+ def test_top_level(self):
+ self._test_it('', 'RS512')
+
+ def test_submodules(self):
+ # This test ensures that the modules in josepy that were
+ # available at the time it was moved into its own package are
+ # available under acme.jose. Backwards compatibility with new
+ # modules or testing code is not maintained.
+ mods_and_attrs = [('b64', 'b64decode',),
+ ('errors', 'Error',),
+ ('interfaces', 'JSONDeSerializable',),
+ ('json_util', 'Field',),
+ ('jwa', 'HS256',),
+ ('jwk', 'JWK',),
+ ('jws', 'JWS',),
+ ('util', 'ImmutableMap',),]
+
+ for mod, attr in mods_and_attrs:
+ self._test_it(mod, attr)
+
+
+if __name__ == '__main__':
+ unittest.main() # pragma: no cover