Browse Source

Fixed #33764 -- Deprecated BaseUserManager.make_random_password().

Ciaran McCormick 2 years ago
parent
commit
286e7d076c

+ 1 - 0
AUTHORS

@@ -209,6 +209,7 @@ answer newbie questions, and generally made Django that much better:
     Chris Wagner <cw264701@ohio.edu>
     Chris Wesseling <Chris.Wesseling@cwi.nl>
     Chris Wilson <chris+github@qwirx.com>
+    Ciaran McCormick <ciaran@ciaranmccormick.com>
     Claude Paroz <claude@2xlibre.net>
     Clint Ecker
     colin@owlfish.com

+ 7 - 0
django/contrib/auth/base_user.py

@@ -3,6 +3,7 @@ This module allows importing AbstractBaseUser even when django.contrib.auth is
 not in INSTALLED_APPS.
 """
 import unicodedata
+import warnings
 
 from django.contrib.auth import password_validation
 from django.contrib.auth.hashers import (
@@ -12,6 +13,7 @@ from django.contrib.auth.hashers import (
 )
 from django.db import models
 from django.utils.crypto import get_random_string, salted_hmac
+from django.utils.deprecation import RemovedInDjango51Warning
 from django.utils.translation import gettext_lazy as _
 
 
@@ -40,6 +42,11 @@ class BaseUserManager(models.Manager):
         allowed_chars. The default value of allowed_chars does not have "I" or
         "O" or letters and digits that look similar -- just to avoid confusion.
         """
+        warnings.warn(
+            "BaseUserManager.make_random_password() is deprecated.",
+            category=RemovedInDjango51Warning,
+            stacklevel=2,
+        )
         return get_random_string(length, allowed_chars)
 
     def get_by_natural_key(self, username):

+ 2 - 0
docs/internals/deprecation.txt

@@ -15,6 +15,8 @@ about each item can often be found in the release notes of two versions prior.
 See the :ref:`Django 4.2 release notes <deprecated-features-4.2>` for more
 details on these changes.
 
+* The ``BaseUserManager.make_random_password()`` method will be removed.
+
 .. _deprecation-removed-in-5.0:
 
 5.0

+ 4 - 1
docs/releases/4.2.txt

@@ -250,4 +250,7 @@ Features deprecated in 4.2
 Miscellaneous
 -------------
 
-* ...
+* The ``BaseUserManager.make_random_password()`` method is deprecated. See
+  `recipes and best practices
+  <https://docs.python.org/3/library/secrets.html#recipes-and-best-practices>`_
+  for using Python's :py:mod:`secrets` module to generate passwords.

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

@@ -772,6 +772,8 @@ utility methods:
 
     .. method:: models.BaseUserManager.make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')
 
+        .. deprecated:: 4.2
+
         Returns a random password with the given length and given string of
         allowed characters. Note that the default value of ``allowed_chars``
         doesn't contain letters that can cause user confusion, including:

+ 8 - 0
tests/auth_tests/test_models.py

@@ -18,6 +18,8 @@ from django.db import connection, migrations
 from django.db.migrations.state import ModelState, ProjectState
 from django.db.models.signals import post_save
 from django.test import SimpleTestCase, TestCase, TransactionTestCase, override_settings
+from django.test.utils import ignore_warnings
+from django.utils.deprecation import RemovedInDjango51Warning
 
 from .models import CustomEmailField, IntegerUsernameUser
 
@@ -164,6 +166,7 @@ class UserManagerTestCase(TransactionTestCase):
                 is_staff=False,
             )
 
+    @ignore_warnings(category=RemovedInDjango51Warning)
     def test_make_random_password(self):
         allowed_chars = "abcdefg"
         password = UserManager().make_random_password(5, allowed_chars)
@@ -171,6 +174,11 @@ class UserManagerTestCase(TransactionTestCase):
         for char in password:
             self.assertIn(char, allowed_chars)
 
+    def test_make_random_password_warning(self):
+        msg = "BaseUserManager.make_random_password() is deprecated."
+        with self.assertWarnsMessage(RemovedInDjango51Warning, msg):
+            UserManager().make_random_password()
+
     def test_runpython_manager_methods(self):
         def forwards(apps, schema_editor):
             UserModel = apps.get_model("auth", "User")