From 96e234114b494c40c375533bc8006961c2097c4f Mon Sep 17 00:00:00 2001 From: Christian Kreuzberger Date: Thu, 1 Aug 2019 16:26:18 +0200 Subject: [PATCH] Improve random number generator by using a better PRNG function provided by the os; fix tests sometimes failing --- README.md | 6 +++++- django_rest_passwordreset/tokens.py | 6 ++++-- tests/test/test_token_generators.py | 8 +++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 59bee2c..bee9d31 100644 --- a/README.md +++ b/README.md @@ -144,7 +144,7 @@ If you want to test this locally, I recommend using some kind of fake mailserver By default, `email` lookup is used to find the user instance. You can change that by adding ```python -DJANGO_REST_LOOKUP_FIELD = '' +DJANGO_REST_LOOKUP_FIELD = 'custom_email_field' ``` into Django settings.py file. @@ -183,6 +183,8 @@ DJANGO_REST_PASSWORDRESET_TOKEN_CONFIG = { } } ``` + +It uses `os.urandom()` to generate a good random string. ### RandomNumberTokenGenerator @@ -203,6 +205,8 @@ DJANGO_REST_PASSWORDRESET_TOKEN_CONFIG = { } ``` +It uses `random.SystemRandom().randint()` to generate a good random number. + ### Write your own Token Generator diff --git a/django_rest_passwordreset/tokens.py b/django_rest_passwordreset/tokens.py index e84d679..399e18f 100644 --- a/django_rest_passwordreset/tokens.py +++ b/django_rest_passwordreset/tokens.py @@ -71,12 +71,14 @@ def generate_token(self, *args, **kwargs): class RandomNumberTokenGenerator(BaseTokenGenerator): """ - Generates a random number + Generates a random number using random.SystemRandom() (which uses urandom in the background) """ def __init__(self, min_number=10000, max_number=99999, *args, **kwargs): self.min_number = min_number self.max_number = max_number def generate_token(self, *args, **kwargs): + r = random.SystemRandom() + # generate a random number between min_number and max_number - return str(random.randint(self.min_number, self.max_number)) + return str(r.randint(self.min_number, self.max_number)) diff --git a/tests/test/test_token_generators.py b/tests/test/test_token_generators.py index 70f95b9..9ed690e 100644 --- a/tests/test/test_token_generators.py +++ b/tests/test/test_token_generators.py @@ -41,7 +41,7 @@ def test_string_token_generator(self): ) def test_number_token_generator(self): - token_generator = RandomNumberTokenGenerator(min_number=100000, max_number=999999) + token_generator = RandomNumberTokenGenerator(min_number=1000000000, max_number=9999999999) tokens = [] @@ -72,10 +72,8 @@ def test_number_token_generator(self): self.assertEquals(is_number, True, msg="RandomNumberTokenGenerator must return a number, but returned " + token) - self.assertGreaterEqual(num, 100000, msg="RandomNumberTokenGenerator must return a number greater or " - "equal to 1000") - - self.assertLess(num, 999999, msg="RandomNumberTokenGenerator must return a number less or equal to 9999") + self.assertGreaterEqual(num, 1000000000, msg="RandomNumberTokenGenerator must return a number greater or equal to 1000000000") + self.assertLess(num, 9999999999, msg="RandomNumberTokenGenerator must return a number less or equal to 9999999999") def test_generate_token_generator_from_empty_settings(self): """