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.
90 lines
3.8 KiB
Python
90 lines
3.8 KiB
Python
import sys
|
|
from datetime import datetime, timedelta
|
|
from types import ModuleType
|
|
|
|
from django.conf import (
|
|
PASSWORD_RESET_TIMEOUT_DAYS_DEPRECATED_MSG, Settings, 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, ignore_warnings
|
|
from django.utils.deprecation import RemovedInDjango40Warning
|
|
|
|
|
|
class DeprecationTests(TestCase):
|
|
msg = PASSWORD_RESET_TIMEOUT_DAYS_DEPRECATED_MSG
|
|
|
|
@ignore_warnings(category=RemovedInDjango40Warning)
|
|
def test_timeout(self):
|
|
"""The token is valid after n days, but no greater."""
|
|
# Uses a mocked version of PasswordResetTokenGenerator so we can change
|
|
# the value of 'now'.
|
|
class Mocked(PasswordResetTokenGenerator):
|
|
def __init__(self, now):
|
|
self._now_val = now
|
|
super().__init__()
|
|
|
|
def _now(self):
|
|
return self._now_val
|
|
|
|
user = User.objects.create_user('tokentestuser', 'test2@example.com', 'testpw')
|
|
p0 = PasswordResetTokenGenerator()
|
|
tk1 = p0.make_token(user)
|
|
p1 = Mocked(datetime.now() + timedelta(settings.PASSWORD_RESET_TIMEOUT_DAYS))
|
|
self.assertIs(p1.check_token(user, tk1), True)
|
|
p2 = Mocked(datetime.now() + timedelta(settings.PASSWORD_RESET_TIMEOUT_DAYS + 1))
|
|
self.assertIs(p2.check_token(user, tk1), False)
|
|
with self.settings(PASSWORD_RESET_TIMEOUT_DAYS=1):
|
|
self.assertEqual(settings.PASSWORD_RESET_TIMEOUT, 60 * 60 * 24)
|
|
p3 = Mocked(datetime.now() + timedelta(settings.PASSWORD_RESET_TIMEOUT_DAYS))
|
|
self.assertIs(p3.check_token(user, tk1), True)
|
|
p4 = Mocked(datetime.now() + timedelta(settings.PASSWORD_RESET_TIMEOUT_DAYS + 1))
|
|
self.assertIs(p4.check_token(user, tk1), False)
|
|
|
|
def test_override_settings_warning(self):
|
|
with self.assertRaisesMessage(RemovedInDjango40Warning, self.msg):
|
|
with self.settings(PASSWORD_RESET_TIMEOUT_DAYS=2):
|
|
pass
|
|
|
|
def test_settings_init_warning(self):
|
|
settings_module = ModuleType('fake_settings_module')
|
|
settings_module.SECRET_KEY = 'foo'
|
|
settings_module.PASSWORD_RESET_TIMEOUT_DAYS = 2
|
|
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_warning(self):
|
|
with self.assertRaisesMessage(RemovedInDjango40Warning, self.msg):
|
|
settings.PASSWORD_RESET_TIMEOUT_DAYS
|
|
# Works a second time.
|
|
with self.assertRaisesMessage(RemovedInDjango40Warning, self.msg):
|
|
settings.PASSWORD_RESET_TIMEOUT_DAYS
|
|
|
|
@ignore_warnings(category=RemovedInDjango40Warning)
|
|
def test_access(self):
|
|
with self.settings(PASSWORD_RESET_TIMEOUT_DAYS=2):
|
|
self.assertEqual(settings.PASSWORD_RESET_TIMEOUT_DAYS, 2)
|
|
# Works a second time.
|
|
self.assertEqual(settings.PASSWORD_RESET_TIMEOUT_DAYS, 2)
|
|
|
|
def test_use_both_settings_init_error(self):
|
|
msg = (
|
|
'PASSWORD_RESET_TIMEOUT_DAYS/PASSWORD_RESET_TIMEOUT are '
|
|
'mutually exclusive.'
|
|
)
|
|
settings_module = ModuleType('fake_settings_module')
|
|
settings_module.SECRET_KEY = 'foo'
|
|
settings_module.PASSWORD_RESET_TIMEOUT_DAYS = 2
|
|
settings_module.PASSWORD_RESET_TIMEOUT = 2000
|
|
sys.modules['fake_settings_module'] = settings_module
|
|
try:
|
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
|
Settings('fake_settings_module')
|
|
finally:
|
|
del sys.modules['fake_settings_module']
|