From 9bf8735e0e675f3db97873afa9bb3237fa6a03b9 Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Sun, 3 Dec 2017 00:10:38 +0000 Subject: [PATCH] Make generate_signature return a string, so we can pass it to reverse() again --- docs/releases/2.0.rst | 6 ++++++ wagtail/images/tests/test_admin_views.py | 2 +- wagtail/images/tests/tests.py | 8 ++++---- wagtail/images/views/serve.py | 5 +++-- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/docs/releases/2.0.rst b/docs/releases/2.0.rst index d18dce3642..b6238816c2 100644 --- a/docs/releases/2.0.rst +++ b/docs/releases/2.0.rst @@ -126,3 +126,9 @@ Removed support for Elasticsearch 1.x ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Elasticsearch 1.x is no longer supported in this release. Please upgrade to a 2.x or 5.x release of Elasticsearch before upgrading to Wagtail 2.0. + + +``wagtail.images.views.serve.generate_signature`` now returns a string +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``generate_signature`` function in ``wagtail.images.views.serve``, used to build URLs for the :ref:`dynamic image serve view `, now returns a string rather than a binary string. This ensures that any existing user code that builds up the final image URL with ``reverse`` will continue to work on Django 2.0 (which no longer allows binary strings to be passed to ``reverse``). Any code that expects a binary string as the return value of ``generate_string`` - for example, calling ``decode()`` on the result - will need to be updated. (Apps that need to preserve compatibility with earlier versions of Wagtail can call ``django.utils.encoding.force_text`` instead of ``decode``.) diff --git a/wagtail/images/tests/test_admin_views.py b/wagtail/images/tests/test_admin_views.py index 16499e2c1f..11b765b942 100644 --- a/wagtail/images/tests/test_admin_views.py +++ b/wagtail/images/tests/test_admin_views.py @@ -1065,7 +1065,7 @@ class TestGenerateURLView(TestCase, WagtailTestUtils): self.assertEqual(set(content_json.keys()), set(['url', 'preview_url'])) expected_url = 'http://localhost/images/%(signature)s/%(image_id)d/fill-800x600/' % { - 'signature': urlquote(generate_signature(self.image.id, 'fill-800x600').decode(), safe=urlquote_safechars), + 'signature': urlquote(generate_signature(self.image.id, 'fill-800x600'), safe=urlquote_safechars), 'image_id': self.image.id, } self.assertEqual(content_json['url'], expected_url) diff --git a/wagtail/images/tests/tests.py b/wagtail/images/tests/tests.py index d4a6f4794c..297c68d646 100644 --- a/wagtail/images/tests/tests.py +++ b/wagtail/images/tests/tests.py @@ -225,16 +225,16 @@ class TestFormat(TestCase): class TestSignatureGeneration(TestCase): def test_signature_generation(self): - self.assertEqual(generate_signature(100, 'fill-800x600'), b'xnZOzQyUg6pkfciqcfRJRosOrGg=') + self.assertEqual(generate_signature(100, 'fill-800x600'), 'xnZOzQyUg6pkfciqcfRJRosOrGg=') def test_signature_verification(self): - self.assertTrue(verify_signature(b'xnZOzQyUg6pkfciqcfRJRosOrGg=', 100, 'fill-800x600')) + self.assertTrue(verify_signature('xnZOzQyUg6pkfciqcfRJRosOrGg=', 100, 'fill-800x600')) def test_signature_changes_on_image_id(self): - self.assertFalse(verify_signature(b'xnZOzQyUg6pkfciqcfRJRosOrGg=', 200, 'fill-800x600')) + self.assertFalse(verify_signature('xnZOzQyUg6pkfciqcfRJRosOrGg=', 200, 'fill-800x600')) def test_signature_changes_on_filter_spec(self): - self.assertFalse(verify_signature(b'xnZOzQyUg6pkfciqcfRJRosOrGg=', 100, 'fill-800x700')) + self.assertFalse(verify_signature('xnZOzQyUg6pkfciqcfRJRosOrGg=', 100, 'fill-800x700')) class TestFrontendServeView(TestCase): diff --git a/wagtail/images/views/serve.py b/wagtail/images/views/serve.py index 49fd877f6e..390a128346 100644 --- a/wagtail/images/views/serve.py +++ b/wagtail/images/views/serve.py @@ -9,6 +9,7 @@ from django.core.exceptions import ImproperlyConfigured, PermissionDenied from django.http import HttpResponse, HttpResponsePermanentRedirect, StreamingHttpResponse from django.shortcuts import get_object_or_404 from django.utils.decorators import classonlymethod +from django.utils.encoding import force_text from django.views.generic import View from wagtail.utils.sendfile import sendfile @@ -28,11 +29,11 @@ def generate_signature(image_id, filter_spec, key=None): # Based on libthumbor hmac generation # https://github.com/thumbor/libthumbor/blob/b19dc58cf84787e08c8e397ab322e86268bb4345/libthumbor/crypto.py#L50 url = '{}/{}/'.format(image_id, filter_spec) - return base64.urlsafe_b64encode(hmac.new(key, url.encode(), hashlib.sha1).digest()) + return force_text(base64.urlsafe_b64encode(hmac.new(key, url.encode(), hashlib.sha1).digest())) def verify_signature(signature, image_id, filter_spec, key=None): - return signature == generate_signature(image_id, filter_spec, key=key) + return force_text(signature) == generate_signature(image_id, filter_spec, key=key) class ServeView(View):