From 5febcce20c00c916b3ebc29d399dff03be1339c2 Mon Sep 17 00:00:00 2001 From: "Dave St.Germain" <dstgermain@edx.org> Date: Mon, 19 Aug 2019 10:24:15 -0400 Subject: [PATCH] Fix python3 compatibility in SafeCookieData and elsewhere --- common/djangoapps/student/models.py | 4 ++-- lms/djangoapps/commerce/tests/test_signals.py | 9 +++++---- lms/djangoapps/course_goals/handlers.py | 1 + lms/djangoapps/verify_student/models.py | 4 ++-- .../verify_student/tests/test_fake_software_secure.py | 7 ++++--- openedx/core/djangoapps/safe_sessions/middleware.py | 9 ++++++--- 6 files changed, 20 insertions(+), 14 deletions(-) diff --git a/common/djangoapps/student/models.py b/common/djangoapps/student/models.py index a375daf2ac1..6725cdf0e7c 100644 --- a/common/djangoapps/student/models.py +++ b/common/djangoapps/student/models.py @@ -162,8 +162,8 @@ def anonymous_id_for_user(user, course_id, save=True): # include the secret key as a salt, and to make the ids unique across different LMS installs. hasher = hashlib.md5() - hasher.update(settings.SECRET_KEY) - hasher.update(text_type(user.id)) + hasher.update(settings.SECRET_KEY.encode('utf8')) + hasher.update(text_type(user.id).encode('utf8')) if course_id: hasher.update(text_type(course_id).encode('utf-8')) digest = hasher.hexdigest() diff --git a/lms/djangoapps/commerce/tests/test_signals.py b/lms/djangoapps/commerce/tests/test_signals.py index 95a8f21bc10..a2a5f7e240e 100644 --- a/lms/djangoapps/commerce/tests/test_signals.py +++ b/lms/djangoapps/commerce/tests/test_signals.py @@ -184,7 +184,7 @@ class TestRefundSignal(TestCase): self.assertFalse(mock_send_notification.called) last_request = httpretty.last_request() - self.assertDictEqual(json.loads(last_request.body), {'action': 'approve_payment_only'}) + self.assertDictEqual(json.loads(last_request.body.decode('utf8')), {'action': 'approve_payment_only'}) @mock.patch('lms.djangoapps.commerce.utils._send_refund_notification') def test_notification_no_refund(self, mock_send_notification): @@ -305,8 +305,9 @@ class TestRefundSignal(TestCase): # Verify the headers expected = { 'content-type': JSON, - 'Authorization': 'Basic ' + base64.b64encode( - '{user}/token:{pwd}'.format(user=ZENDESK_USER, pwd=ZENDESK_API_KEY)) + 'Authorization': 'Basic {}'.format(base64.b64encode( + '{user}/token:{pwd}'.format(user=ZENDESK_USER, pwd=ZENDESK_API_KEY).encode('utf8')).decode('utf8') + ) } self.assertDictContainsSubset(expected, last_request.headers) @@ -322,4 +323,4 @@ class TestRefundSignal(TestCase): 'tags': ['LMS'] + tags } } - self.assertDictEqual(json.loads(last_request.body), expected) + self.assertDictEqual(json.loads(last_request.body.decode('utf8')), expected) diff --git a/lms/djangoapps/course_goals/handlers.py b/lms/djangoapps/course_goals/handlers.py index ef4afb8c9f3..2992ba9a285 100644 --- a/lms/djangoapps/course_goals/handlers.py +++ b/lms/djangoapps/course_goals/handlers.py @@ -3,6 +3,7 @@ Signal handlers for course goals. """ from __future__ import absolute_import +import six from django.db import models from django.dispatch import receiver diff --git a/lms/djangoapps/verify_student/models.py b/lms/djangoapps/verify_student/models.py index e6aba8da2dc..ff03c1bd209 100644 --- a/lms/djangoapps/verify_student/models.py +++ b/lms/djangoapps/verify_student/models.py @@ -8,7 +8,7 @@ of a student over a period of time. Right now, the only models are the abstract `SoftwareSecurePhotoVerification`. The hope is to keep as much of the photo verification process as generic as possible. """ -from __future__ import absolute_import +from __future__ import absolute_import, unicode_literals import functools import json @@ -47,7 +47,7 @@ log = logging.getLogger(__name__) def generateUUID(): # pylint: disable=invalid-name """ Utility function; generates UUIDs """ - return str(uuid.uuid4()) + return six.text_type(uuid.uuid4()) class VerificationException(Exception): diff --git a/lms/djangoapps/verify_student/tests/test_fake_software_secure.py b/lms/djangoapps/verify_student/tests/test_fake_software_secure.py index 43a22bf7f45..6520952d8f1 100644 --- a/lms/djangoapps/verify_student/tests/test_fake_software_secure.py +++ b/lms/djangoapps/verify_student/tests/test_fake_software_secure.py @@ -2,7 +2,7 @@ Tests for the fake software secure response. """ -from __future__ import absolute_import +from __future__ import absolute_import, unicode_literals from django.test import TestCase from mock import patch @@ -79,5 +79,6 @@ class SoftwareSecureFakeViewEnabledTest(SoftwareSecureFakeViewTest): ) self.assertEqual(response.status_code, 200) - self.assertIn('EdX-ID', response.content) - self.assertIn('results_callback', response.content) + content = response.content.decode('utf8') + self.assertIn('EdX-ID', content) + self.assertIn('results_callback', content) diff --git a/openedx/core/djangoapps/safe_sessions/middleware.py b/openedx/core/djangoapps/safe_sessions/middleware.py index 5443bae9600..6591fe06568 100644 --- a/openedx/core/djangoapps/safe_sessions/middleware.py +++ b/openedx/core/djangoapps/safe_sessions/middleware.py @@ -55,7 +55,7 @@ SSL-protected channel. Otherwise, a session hijacker could copy the entire cookie and use it to impersonate the victim. """ -from __future__ import absolute_import +from __future__ import absolute_import, unicode_literals from base64 import b64encode from contextlib import contextmanager @@ -70,6 +70,8 @@ from django.contrib.sessions.middleware import SessionMiddleware from django.core import signing from django.http import HttpResponse from django.utils.crypto import get_random_string +from django.utils.encoding import python_2_unicode_compatible + from six import text_type # pylint: disable=ungrouped-imports from openedx.core.lib.mobile_utils import is_request_from_mobile_app @@ -145,7 +147,7 @@ class SafeCookieData(object): safe_cookie_string. """ try: - raw_cookie_components = safe_cookie_string.split(cls.SEPARATOR) + raw_cookie_components = six.text_type(safe_cookie_string).split(cls.SEPARATOR) safe_cookie_data = SafeCookieData(*raw_cookie_components) except TypeError: raise SafeCookieError( @@ -160,7 +162,8 @@ class SafeCookieData(object): )) return safe_cookie_data - def __unicode__(self): + @python_2_unicode_compatible + def __str__(self): """ Returns a string serialization of the safe cookie data. """ -- GitLab