From aea7fcee452bc06ec8ba2ec882ecf064f891a69e Mon Sep 17 00:00:00 2001 From: Muhammad Anas Date: Fri, 19 Apr 2024 07:22:14 +0000 Subject: [PATCH] feat: added feature flag to enable blake2b hashing --- cms/envs/common.py | 3 ++ common/djangoapps/util/memcache.py | 10 ++++-- common/djangoapps/util/tests/test_memcache.py | 35 ++++++++++++++++++- lms/envs/common.py | 12 +++++++ 4 files changed, 56 insertions(+), 4 deletions(-) diff --git a/cms/envs/common.py b/cms/envs/common.py index 9c9d900a1af9..eada49c53e45 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -579,6 +579,9 @@ # .. toggle_creation_date: 2024-03-22 # .. toggle_tickets: https://github.com/openedx/edx-platform/pull/33911 'ENABLE_GRADING_METHOD_IN_PROBLEMS': False, + + # See annotations in lms/envs/common.py for details. + 'ENABLE_BLAKE2B_HASHiNG': False, } # .. toggle_name: ENABLE_COPPA_COMPLIANCE diff --git a/common/djangoapps/util/memcache.py b/common/djangoapps/util/memcache.py index 2f439245ac14..2f7e6dc623a0 100644 --- a/common/djangoapps/util/memcache.py +++ b/common/djangoapps/util/memcache.py @@ -7,6 +7,7 @@ import hashlib from urllib.parse import quote_plus +from django.conf import settings from django.utils.encoding import smart_str @@ -14,9 +15,12 @@ def fasthash(string): """ Hashes `string` into a string representation of a 128-bit digest. """ - md4 = hashlib.new("md4") - md4.update(string.encode('utf-8')) - return md4.hexdigest() + if settings.FEATURES.get("ENABLE_BLAKE2B_HASHING", False): + hash_obj = hashlib.new("blake2b", digest_size=16) + else: + hash_obj = hashlib.new("md4") + hash_obj.update(string.encode('utf-8')) + return hash_obj.hexdigest() def cleaned_string(val): diff --git a/common/djangoapps/util/tests/test_memcache.py b/common/djangoapps/util/tests/test_memcache.py index 8854d6b8c590..13f67f386a00 100644 --- a/common/djangoapps/util/tests/test_memcache.py +++ b/common/djangoapps/util/tests/test_memcache.py @@ -3,11 +3,15 @@ """ +from django.conf import settings from django.core.cache import caches -from django.test import TestCase +from django.test import TestCase, override_settings from common.djangoapps.util.memcache import safe_key +BLAKE2B_ENABLED_FEATURES = settings.FEATURES.copy() +BLAKE2B_ENABLED_FEATURES["ENABLE_BLAKE2B_HASHING"] = True + class MemcacheTest(TestCase): """ @@ -51,6 +55,20 @@ def test_safe_key_long(self): # The key should now be valid assert self._is_valid_key(key), f'Failed for key length {length}' + @override_settings(FEATURES=BLAKE2B_ENABLED_FEATURES) + def test_safe_key_long_with_blake2b_enabled(self): + # Choose lengths close to memcached's cutoff (250) + for length in [248, 249, 250, 251, 252]: + + # Generate a key of that length + key = 'a' * length + + # Make the key safe + key = safe_key(key, '', '') + + # The key should now be valid + assert self._is_valid_key(key), f'Failed for key length {length}' + def test_long_key_prefix_version(self): # Long key @@ -65,6 +83,21 @@ def test_long_key_prefix_version(self): key = safe_key('key', 'prefix', 'a' * 300) assert self._is_valid_key(key) + @override_settings(FEATURES=BLAKE2B_ENABLED_FEATURES) + def test_long_key_prefix_version_with_blake2b_enabled(self): + + # Long key + key = safe_key('a' * 300, 'prefix', 'version') + assert self._is_valid_key(key) + + # Long prefix + key = safe_key('key', 'a' * 300, 'version') + assert self._is_valid_key(key) + + # Long version + key = safe_key('key', 'prefix', 'a' * 300) + assert self._is_valid_key(key) + def test_safe_key_unicode(self): for unicode_char in self.UNICODE_CHAR_CODES: diff --git a/lms/envs/common.py b/lms/envs/common.py index 4fd9ba08ada5..e14d0b3311c3 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -1059,6 +1059,18 @@ # .. toggle_creation_date: 2024-03-22 # .. toggle_tickets: https://github.com/openedx/edx-platform/pull/33911 'ENABLE_GRADING_METHOD_IN_PROBLEMS': False, + + # .. toggle_name: FEATURES['ENABLE_BLAKE2B_HASHING'] + # .. toggle_implementation: DjangoSetting + # .. toggle_default: False + # .. toggle_description: Enables the memcache to use the blake2b hash algorithm instead of depreciated md4 for keys + # exceeding 250 characters + # .. toggle_use_cases: open_edx + # .. toggle_creation_date: 2024-04-02 + # .. toggle_target_removal_date: 2024-12-09 + # .. toggle_warning: For consistency, keep the value in sync with the setting of the same name in the LMS and CMS. + # .. toggle_tickets: https://github.com/openedx/edx-platform/pull/34442 + 'ENABLE_BLAKE2B_HASHING': False, } # Specifies extra XBlock fields that should available when requested via the Course Blocks API