Browse Source

Fixed #33691 -- Deprecated django.contrib.auth.hashers.CryptPasswordHasher.

Mariusz Felisiak 2 years ago
parent
commit
02dbf1667c

+ 10 - 0
django/contrib/auth/hashers.py

@@ -17,6 +17,7 @@ from django.utils.crypto import (
     md5,
     pbkdf2,
 )
+from django.utils.deprecation import RemovedInDjango50Warning
 from django.utils.module_loading import import_string
 from django.utils.translation import gettext_noop as _
 
@@ -797,6 +798,7 @@ class UnsaltedMD5PasswordHasher(BasePasswordHasher):
         pass
 
 
+# RemovedInDjango50Warning.
 class CryptPasswordHasher(BasePasswordHasher):
     """
     Password hashing using UNIX crypt (not recommended)
@@ -807,6 +809,14 @@ class CryptPasswordHasher(BasePasswordHasher):
     algorithm = "crypt"
     library = "crypt"
 
+    def __init__(self, *args, **kwargs):
+        warnings.warn(
+            "django.contrib.auth.hashers.CryptPasswordHasher is deprecated.",
+            RemovedInDjango50Warning,
+            stacklevel=2,
+        )
+        super().__init__(*args, **kwargs)
+
     def salt(self):
         return get_random_string(2)
 

+ 2 - 0
docs/internals/deprecation.txt

@@ -103,6 +103,8 @@ details on these changes.
 
 * The ``django.contrib.gis.admin.OpenLayersWidget`` will be removed.
 
+* The ``django.contrib.auth.hashers.CryptPasswordHasher`` will be removed.
+
 .. _deprecation-removed-in-4.1:
 
 4.1

+ 2 - 0
docs/releases/4.1.txt

@@ -683,6 +683,8 @@ Miscellaneous
 
 * The undocumented ``django.contrib.gis.admin.OpenLayersWidget`` is deprecated.
 
+* ``django.contrib.auth.hashers.CryptPasswordHasher`` is deprecated.
+
 Features removed in 4.1
 =======================
 

+ 0 - 2
docs/topics/auth/passwords.txt

@@ -439,7 +439,6 @@ The full list of hashers included in Django is::
         'django.contrib.auth.hashers.MD5PasswordHasher',
         'django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher',
         'django.contrib.auth.hashers.UnsaltedMD5PasswordHasher',
-        'django.contrib.auth.hashers.CryptPasswordHasher',
     ]
 
 The corresponding algorithm names are:
@@ -454,7 +453,6 @@ The corresponding algorithm names are:
 * ``md5``
 * ``unsalted_sha1``
 * ``unsalted_md5``
-* ``crypt``
 
 .. _write-your-own-password-hasher:
 

+ 15 - 1
tests/auth_tests/test_hashers.py

@@ -18,9 +18,11 @@ from django.contrib.auth.hashers import (
     is_password_usable,
     make_password,
 )
-from django.test import SimpleTestCase
+from django.test import SimpleTestCase, ignore_warnings
 from django.test.utils import override_settings
+from django.utils.deprecation import RemovedInDjango50Warning
 
+# RemovedInDjango50Warning.
 try:
     import crypt
 except ImportError:
@@ -201,6 +203,7 @@ class TestUtilsHashPass(SimpleTestCase):
         with self.assertRaisesMessage(ValueError, msg):
             hasher.encode("password", salt="salt")
 
+    @ignore_warnings(category=RemovedInDjango50Warning)
     @skipUnless(crypt, "no crypt module to generate password.")
     @override_settings(
         PASSWORD_HASHERS=["django.contrib.auth.hashers.CryptPasswordHasher"]
@@ -219,6 +222,7 @@ class TestUtilsHashPass(SimpleTestCase):
         self.assertTrue(check_password("", blank_encoded))
         self.assertFalse(check_password(" ", blank_encoded))
 
+    @ignore_warnings(category=RemovedInDjango50Warning)
     @skipUnless(crypt, "no crypt module to generate password.")
     @override_settings(
         PASSWORD_HASHERS=["django.contrib.auth.hashers.CryptPasswordHasher"]
@@ -229,6 +233,7 @@ class TestUtilsHashPass(SimpleTestCase):
         with self.assertRaisesMessage(ValueError, msg):
             hasher.encode("password", salt="a")
 
+    @ignore_warnings(category=RemovedInDjango50Warning)
     @skipUnless(crypt, "no crypt module to generate password.")
     @override_settings(
         PASSWORD_HASHERS=["django.contrib.auth.hashers.CryptPasswordHasher"]
@@ -240,6 +245,15 @@ class TestUtilsHashPass(SimpleTestCase):
             with self.assertRaisesMessage(TypeError, msg):
                 hasher.encode("password", salt="ab")
 
+    @skipUnless(crypt, "no crypt module to generate password.")
+    @override_settings(
+        PASSWORD_HASHERS=["django.contrib.auth.hashers.CryptPasswordHasher"]
+    )
+    def test_crypt_deprecation_warning(self):
+        msg = "django.contrib.auth.hashers.CryptPasswordHasher is deprecated."
+        with self.assertRaisesMessage(RemovedInDjango50Warning, msg):
+            get_hasher("crypt")
+
     @skipUnless(bcrypt, "bcrypt not installed")
     def test_bcrypt_sha256(self):
         encoded = make_password("lètmein", hasher="bcrypt_sha256")