import sys from datetime import date, timedelta from django.conf import settings from django.contrib.auth.models import User from django.contrib.auth.tokens import PasswordResetTokenGenerator from django.contrib.auth.tests.utils import skipIfCustomUser from django.test import TestCase from django.utils import unittest @skipIfCustomUser class TokenGeneratorTest(TestCase): def test_make_token(self): """ Ensure that we can make a token and that it is valid """ user = User.objects.create_user('tokentestuser', 'test2@example.com', 'testpw') p0 = PasswordResetTokenGenerator() tk1 = p0.make_token(user) self.assertTrue(p0.check_token(user, tk1)) def test_10265(self): """ Ensure that the token generated for a user created in the same request will work correctly. """ # See ticket #10265 user = User.objects.create_user('comebackkid', 'test3@example.com', 'testpw') p0 = PasswordResetTokenGenerator() tk1 = p0.make_token(user) reload = User.objects.get(username='comebackkid') tk2 = p0.make_token(reload) self.assertEqual(tk1, tk2) def test_timeout(self): """ Ensure we can use the token after n days, but no greater. """ # Uses a mocked version of PasswordResetTokenGenerator so we can change # the value of 'today' class Mocked(PasswordResetTokenGenerator): def __init__(self, today): self._today_val = today def _today(self): return self._today_val user = User.objects.create_user('tokentestuser', 'test2@example.com', 'testpw') p0 = PasswordResetTokenGenerator() tk1 = p0.make_token(user) p1 = Mocked(date.today() + timedelta(settings.PASSWORD_RESET_TIMEOUT_DAYS)) self.assertTrue(p1.check_token(user, tk1)) p2 = Mocked(date.today() + timedelta(settings.PASSWORD_RESET_TIMEOUT_DAYS + 1)) self.assertFalse(p2.check_token(user, tk1)) @unittest.skipIf(sys.version_info[:2] >= (3, 0), "Unnecessary test with Python 3") def test_date_length(self): """ Make sure we don't allow overly long dates, causing a potential DoS. """ user = User.objects.create_user('ima1337h4x0r', 'test4@example.com', 'p4ssw0rd') p0 = PasswordResetTokenGenerator() # This will put a 14-digit base36 timestamp into the token, which is too large. self.assertRaises(ValueError, p0._make_token_with_timestamp, user, 175455491841851871349)