From 4cc792cabeccec0f2b8883808d5442ee541a3629 Mon Sep 17 00:00:00 2001 From: Jay Crumb Date: Thu, 10 Mar 2022 13:08:45 -0700 Subject: [PATCH] feat: make the password reset token generator configurable This adds facilities to override the default EmailAwarePasswordResetTokenGenrator for users who wish to have custom behaviour in this flow. Prior to this, the TokenForm class hardcoded only one option, and even subclassing the view was not sufficient to change the behaviour. --- ChangeLog.rst | 3 +++ allauth/account/app_settings.py | 12 ++++++++++++ allauth/account/forms.py | 2 +- docs/configuration.rst | 6 ++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/ChangeLog.rst b/ChangeLog.rst index c8a1666962..ed8d4243f7 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -4,6 +4,9 @@ Note worthy changes ------------------- +- Introduced a new setting ``ACCOUNT_PASSWORD_RESET_TOKEN_GENERATOR`` that + allows you to specify the token generator for password resets. + - Dropped support for Django 2.x and 3.0. - Officially support Django 4.2. diff --git a/allauth/account/app_settings.py b/allauth/account/app_settings.py index 97eea581d9..bd86fe9ec2 100644 --- a/allauth/account/app_settings.py +++ b/allauth/account/app_settings.py @@ -364,6 +364,18 @@ def USERNAME_VALIDATORS(self): ret = [] return ret + @property + def PASSWORD_RESET_TOKEN_GENERATOR(self): + from allauth.account.forms import EmailAwarePasswordResetTokenGenerator + from allauth.utils import import_attribute + + token_generator_path = self._setting("PASSWORD_RESET_TOKEN_GENERATOR", None) + if token_generator_path is not None: + token_generator = import_attribute(token_generator_path) + else: + token_generator = EmailAwarePasswordResetTokenGenerator + return token_generator + # Ugly? Guido recommends this himself ... # http://mail.python.org/pipermail/python-ideas/2012-May/014969.html diff --git a/allauth/account/forms.py b/allauth/account/forms.py index adb2bcdcd8..450f548062 100644 --- a/allauth/account/forms.py +++ b/allauth/account/forms.py @@ -47,7 +47,7 @@ def _make_hash_value(self, user, timestamp): return ret -default_token_generator = EmailAwarePasswordResetTokenGenerator() +default_token_generator = app_settings.PASSWORD_RESET_TOKEN_GENERATOR() class PasswordVerificationMixin(object): diff --git a/docs/configuration.rst b/docs/configuration.rst index c651cc8911..8fa6c4a84a 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -159,6 +159,12 @@ ACCOUNT_LOGOUT_REDIRECT_URL (=`settings.LOGOUT_REDIRECT_URL or "/"`) ACCOUNT_PASSWORD_INPUT_RENDER_VALUE (=False) ``render_value`` parameter as passed to ``PasswordInput`` fields. +ACCOUNT_PASSWORD_RESET_TOKEN_GENERATOR (=allauth.account.forms.EmailAwarePasswordResetTokenGenerator) + A string pointing to a custom token generator + (e.g. 'myapp.auth.CustomTokenGenerator') for password resets. This class + should implement the same methods as + ``django.contrib.auth.tokens.PasswordResetTokenGenerator`` or subclass it. + ACCOUNT_PRESERVE_USERNAME_CASING (=True) This setting determines whether the username is stored in lowercase (``False``) or whether its casing is to be preserved (``True``). Note that when