summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2020-07-31 20:56:33 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-08-04 09:39:29 +0200
commit985735265563d4bb0ff44cf6b823446e1813fa34 (patch)
tree868c216cb98ead051b9e56fcaf49c862a3382127 /tests
parentacb7866b1fdda7592d9a16f0d0cc98f5d86a0a56 (diff)
[3.1.x] Fixed #31842 -- Added DEFAULT_HASHING_ALGORITHM transitional setting.
It's a transitional setting helpful in migrating multiple instance of the same project to Django 3.1+. Thanks Markus Holtermann for the report and review, Florian Apolloner for the implementation idea and review, and Carlton Gibson for the review. Backport of d907371ef99a1e4ca6bc1660f57d81f265750984 from master.
Diffstat (limited to 'tests')
-rw-r--r--tests/auth_tests/test_middleware.py10
-rw-r--r--tests/auth_tests/test_password_reset_timeout_days.py1
-rw-r--r--tests/auth_tests/test_tokens.py12
-rw-r--r--tests/deprecation/test_default_hashing_algorithm.py55
-rw-r--r--tests/messages_tests/test_cookie.py13
-rw-r--r--tests/signing/tests.py18
6 files changed, 107 insertions, 2 deletions
diff --git a/tests/auth_tests/test_middleware.py b/tests/auth_tests/test_middleware.py
index 5538225acb..f86f8c6b27 100644
--- a/tests/auth_tests/test_middleware.py
+++ b/tests/auth_tests/test_middleware.py
@@ -2,7 +2,9 @@ from django.contrib.auth import HASH_SESSION_KEY
from django.contrib.auth.middleware import AuthenticationMiddleware
from django.contrib.auth.models import User
from django.http import HttpRequest, HttpResponse
-from django.test import TestCase
+from django.test import TestCase, override_settings
+from django.test.utils import ignore_warnings
+from django.utils.deprecation import RemovedInDjango40Warning
class TestAuthenticationMiddleware(TestCase):
@@ -29,6 +31,12 @@ class TestAuthenticationMiddleware(TestCase):
self.assertIsNotNone(self.request.user)
self.assertFalse(self.request.user.is_anonymous)
+ @ignore_warnings(category=RemovedInDjango40Warning)
+ def test_session_default_hashing_algorithm(self):
+ hash_session = self.client.session[HASH_SESSION_KEY]
+ with override_settings(DEFAULT_HASHING_ALGORITHM='sha1'):
+ self.assertNotEqual(hash_session, self.user.get_session_auth_hash())
+
def test_changed_password_invalidates_session(self):
# After password change, user should be anonymous
self.user.set_password('new_password')
diff --git a/tests/auth_tests/test_password_reset_timeout_days.py b/tests/auth_tests/test_password_reset_timeout_days.py
index 4bd5410f12..17aba80567 100644
--- a/tests/auth_tests/test_password_reset_timeout_days.py
+++ b/tests/auth_tests/test_password_reset_timeout_days.py
@@ -23,6 +23,7 @@ class DeprecationTests(TestCase):
class Mocked(PasswordResetTokenGenerator):
def __init__(self, now):
self._now_val = now
+ super().__init__()
def _now(self):
return self._now_val
diff --git a/tests/auth_tests/test_tokens.py b/tests/auth_tests/test_tokens.py
index eaff78bd57..bba435be84 100644
--- a/tests/auth_tests/test_tokens.py
+++ b/tests/auth_tests/test_tokens.py
@@ -4,11 +4,14 @@ from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.test import TestCase
+from django.test.utils import ignore_warnings
+from django.utils.deprecation import RemovedInDjango40Warning
class MockedPasswordResetTokenGenerator(PasswordResetTokenGenerator):
def __init__(self, now):
self._now_val = now
+ super().__init__()
def _now(self):
return self._now_val
@@ -88,6 +91,15 @@ class TokenGeneratorTest(TestCase):
self.assertIs(p0.check_token(user, tk1), False)
self.assertIs(p1.check_token(user, tk0), False)
+ @ignore_warnings(category=RemovedInDjango40Warning)
+ def test_token_default_hashing_algorithm(self):
+ user = User.objects.create_user('tokentestuser', 'test2@example.com', 'testpw')
+ with self.settings(DEFAULT_HASHING_ALGORITHM='sha1'):
+ generator = PasswordResetTokenGenerator()
+ self.assertEqual(generator.algorithm, 'sha1')
+ token = generator.make_token(user)
+ self.assertIs(generator.check_token(user, token), True)
+
def test_legacy_token_validation(self):
# RemovedInDjango40Warning: pre-Django 3.1 tokens will be invalid.
user = User.objects.create_user('tokentestuser', 'test2@example.com', 'testpw')
diff --git a/tests/deprecation/test_default_hashing_algorithm.py b/tests/deprecation/test_default_hashing_algorithm.py
new file mode 100644
index 0000000000..078449ce4e
--- /dev/null
+++ b/tests/deprecation/test_default_hashing_algorithm.py
@@ -0,0 +1,55 @@
+import sys
+from types import ModuleType
+
+from django.conf import (
+ DEFAULT_HASHING_ALGORITHM_DEPRECATED_MSG, Settings, settings,
+)
+from django.core.checks.security import base as security_base
+from django.test import TestCase, ignore_warnings
+from django.utils.deprecation import RemovedInDjango40Warning
+
+
+class DefaultHashingAlgorithmDeprecationTests(TestCase):
+ msg = DEFAULT_HASHING_ALGORITHM_DEPRECATED_MSG
+
+ def test_override_settings_warning(self):
+ with self.assertRaisesMessage(RemovedInDjango40Warning, self.msg):
+ with self.settings(DEFAULT_HASHING_ALGORITHM='sha1'):
+ pass
+
+ def test_settings_init_warning(self):
+ settings_module = ModuleType('fake_settings_module')
+ settings_module.SECRET_KEY = 'foo'
+ settings_module.DEFAULT_HASHING_ALGORITHM = 'sha1'
+ sys.modules['fake_settings_module'] = settings_module
+ try:
+ with self.assertRaisesMessage(RemovedInDjango40Warning, self.msg):
+ Settings('fake_settings_module')
+ finally:
+ del sys.modules['fake_settings_module']
+
+ def test_access(self):
+ # Warning is not raised on access.
+ self.assertEqual(settings.DEFAULT_HASHING_ALGORITHM, 'sha256')
+
+ @ignore_warnings(category=RemovedInDjango40Warning)
+ def test_system_check_invalid_value(self):
+ tests = [
+ None,
+ 256,
+ 'invalid',
+ 'md5',
+ 'sha512',
+ ]
+ for value in tests:
+ with self.subTest(value=value), self.settings(DEFAULT_HASHING_ALGORITHM=value):
+ self.assertEqual(
+ security_base.check_default_hashing_algorithm(None),
+ [security_base.E100],
+ )
+
+ @ignore_warnings(category=RemovedInDjango40Warning)
+ def test_system_check_valid_value(self):
+ for value in ['sha1', 'sha256']:
+ with self.subTest(value=value), self.settings(DEFAULT_HASHING_ALGORITHM=value):
+ self.assertEqual(security_base.check_default_hashing_algorithm(None), [])
diff --git a/tests/messages_tests/test_cookie.py b/tests/messages_tests/test_cookie.py
index f1428fdf32..5d5fb42d67 100644
--- a/tests/messages_tests/test_cookie.py
+++ b/tests/messages_tests/test_cookie.py
@@ -7,6 +7,8 @@ from django.contrib.messages.storage.cookie import (
CookieStorage, MessageDecoder, MessageEncoder,
)
from django.test import SimpleTestCase, override_settings
+from django.test.utils import ignore_warnings
+from django.utils.deprecation import RemovedInDjango40Warning
from django.utils.safestring import SafeData, mark_safe
from .base import BaseTests
@@ -169,3 +171,14 @@ class CookieTests(BaseTests, SimpleTestCase):
encoded_messages = '%s$%s' % (storage._legacy_hash(value), value)
decoded_messages = storage._decode(encoded_messages)
self.assertEqual(messages, decoded_messages)
+
+ @ignore_warnings(category=RemovedInDjango40Warning)
+ def test_default_hashing_algorithm(self):
+ messages = Message(constants.DEBUG, ['this', 'that'])
+ with self.settings(DEFAULT_HASHING_ALGORITHM='sha1'):
+ storage = self.get_storage()
+ encoded = storage._encode(messages)
+ decoded = storage._decode(encoded)
+ self.assertEqual(decoded, messages)
+ storage_default = self.get_storage()
+ self.assertNotEqual(encoded, storage_default._encode(messages))
diff --git a/tests/signing/tests.py b/tests/signing/tests.py
index df7cad9747..835ca4d6b2 100644
--- a/tests/signing/tests.py
+++ b/tests/signing/tests.py
@@ -2,8 +2,9 @@ import datetime
from django.core import signing
from django.test import SimpleTestCase
-from django.test.utils import freeze_time
+from django.test.utils import freeze_time, ignore_warnings
from django.utils.crypto import InvalidAlgorithm
+from django.utils.deprecation import RemovedInDjango40Warning
class TestSigner(SimpleTestCase):
@@ -52,6 +53,14 @@ class TestSigner(SimpleTestCase):
'VzO9_jVu7R-VkqknHYNvw',
)
+ @ignore_warnings(category=RemovedInDjango40Warning)
+ def test_default_hashing_algorithm(self):
+ signer = signing.Signer('predictable-secret', algorithm='sha1')
+ signature_sha1 = signer.signature('hello')
+ with self.settings(DEFAULT_HASHING_ALGORITHM='sha1'):
+ signer = signing.Signer('predictable-secret')
+ self.assertEqual(signer.signature('hello'), signature_sha1)
+
def test_invalid_algorithm(self):
signer = signing.Signer('predictable-secret', algorithm='whatever')
msg = "'whatever' is not an algorithm accepted by the hashlib module."
@@ -134,6 +143,13 @@ class TestSigner(SimpleTestCase):
signed = 'ImEgc3RyaW5nIFx1MjAyMCI:1k1beT:ZfNhN1kdws7KosUleOvuYroPHEc'
self.assertEqual(signing.loads(signed), value)
+ @ignore_warnings(category=RemovedInDjango40Warning)
+ def test_dumps_loads_default_hashing_algorithm_sha1(self):
+ value = 'a string \u2020'
+ with self.settings(DEFAULT_HASHING_ALGORITHM='sha1'):
+ signed = signing.dumps(value)
+ self.assertEqual(signing.loads(signed), value)
+
def test_decode_detects_tampering(self):
"loads should raise exception for tampered objects"
transforms = (