From c6ea6bf47d4c4599783a49972001732faad3fa21 Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Sat, 18 Nov 2023 19:40:09 +0000 Subject: [PATCH] feat(accounts): Allow disabling email sending to unknown addresses Add a setting to the accounts app which disables sending emails to addresses which do not have an account. For many sites this behaviour will be undesirable since it sends potentially unsolicited email to someone who has not shared it with us. --- ChangeLog.rst | 3 +++ allauth/account/app_settings.py | 4 ++++ allauth/account/forms.py | 3 ++- allauth/account/tests/test_reset_password.py | 24 ++++++++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/ChangeLog.rst b/ChangeLog.rst index 5b800ea561..ce32429115 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -16,6 +16,9 @@ Note worthy changes available that can be used to prevent users from deactivating e.g. their TOTP authenticator. +- Added a setting ``ACCOUNT_EMAIL_UNKNOWN_ADDRESSES`` to disable sending of + emails to unknown accounts. + 0.58.2 (2023-11-06) ******************* diff --git a/allauth/account/app_settings.py b/allauth/account/app_settings.py index 86eea74c3a..fe1c2a2156 100644 --- a/allauth/account/app_settings.py +++ b/allauth/account/app_settings.py @@ -386,6 +386,10 @@ def PASSWORD_RESET_TOKEN_GENERATOR(self): token_generator = EmailAwarePasswordResetTokenGenerator return token_generator + @property + def EMAIL_UNKNOWN_ACCOUNTS(self): + return self._setting("EMAIL_UNKNOWN_ACCOUNTS", True) + @property def REAUTHENTICATION_TIMEOUT(self): return self._setting("REAUTHENTICATION_TIMEOUT", 300) diff --git a/allauth/account/forms.py b/allauth/account/forms.py index dcc83ac6d8..a370153f1f 100644 --- a/allauth/account/forms.py +++ b/allauth/account/forms.py @@ -582,7 +582,8 @@ def clean_email(self): def save(self, request, **kwargs): email = self.cleaned_data["email"] if not self.users: - self._send_unknown_account_mail(request, email) + if app_settings.EMAIL_UNKNOWN_ACCOUNTS: + self._send_unknown_account_mail(request, email) else: self._send_password_reset_mail(request, email, self.users, **kwargs) return email diff --git a/allauth/account/tests/test_reset_password.py b/allauth/account/tests/test_reset_password.py index 8e7c48450e..85652a5d15 100644 --- a/allauth/account/tests/test_reset_password.py +++ b/allauth/account/tests/test_reset_password.py @@ -6,12 +6,36 @@ from django.test.utils import override_settings from django.urls import reverse +import pytest + from allauth.account import app_settings from allauth.account.forms import ResetPasswordForm from allauth.account.models import EmailAddress from allauth.tests import TestCase +@pytest.mark.django_db +def test_reset_password_unknown_account(client, settings): + settings.ACCOUNT_PREVENT_ENUMERATION = True + client.post( + reverse("account_reset_password"), + data={"email": "unknown@example.org"}, + ) + assert len(mail.outbox) == 1 + assert mail.outbox[0].to == ["unknown@example.org"] + + +@pytest.mark.django_db +def test_reset_password_unknown_account_disabled(client, settings): + settings.ACCOUNT_PREVENT_ENUMERATION = True + settings.ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS = False + client.post( + reverse("account_reset_password"), + data={"email": "unknown@example.org"}, + ) + assert len(mail.outbox) == 0 + + @override_settings( ACCOUNT_PREVENT_ENUMERATION=False, ACCOUNT_DEFAULT_HTTP_PROTOCOL="https",