Fixed #32664 -- Made PasswordResetTokenGenerator.secret validation lazy.

Django apps initialization to run management command triggers the admin
autodiscovery. Importing django.contrib.auth.tokens creates an instance
of PasswordResetTokenGenerator which required a SECRET_KEY.

For several management commands, the token generator is unused. It
should only complain about a missing SECRET_KEY when it is used.
This commit is contained in:
François Freitag 2021-04-19 09:58:34 +02:00 committed by Mariusz Felisiak
parent b13af4752f
commit 6b0b3eafd6
2 changed files with 18 additions and 2 deletions

View File

@ -12,12 +12,19 @@ class PasswordResetTokenGenerator:
"""
key_salt = "django.contrib.auth.tokens.PasswordResetTokenGenerator"
algorithm = None
secret = None
_secret = None
def __init__(self):
self.secret = self.secret or settings.SECRET_KEY
self.algorithm = self.algorithm or 'sha256'
def _get_secret(self):
return self._secret or settings.SECRET_KEY
def _set_secret(self, secret):
self._secret = secret
secret = property(_get_secret, _set_secret)
def make_token(self, user):
"""
Return a token that can be used once to do a password reset

View File

@ -3,7 +3,9 @@ from datetime import datetime, timedelta
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.core.exceptions import ImproperlyConfigured
from django.test import TestCase
from django.test.utils import override_settings
from .models import CustomEmailField
@ -131,3 +133,10 @@ class TokenGeneratorTest(TestCase):
tk_default = default_password_generator.make_token(user)
self.assertIs(custom_password_generator.check_token(user, tk_default), False)
self.assertIs(default_password_generator.check_token(user, tk_custom), False)
@override_settings(SECRET_KEY='')
def test_secret_lazy_validation(self):
default_token_generator = PasswordResetTokenGenerator()
msg = 'The SECRET_KEY setting must not be empty.'
with self.assertRaisesMessage(ImproperlyConfigured, msg):
default_token_generator.secret