Repository: pennersr/django-allauth
Pull request #3528 (2023-11-18 19:51:37)

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.

# Submitting Pull Requests

## General

 - [x] Make sure you use [semantic commit messages](https://seesparkbox.com/foundry/semantic_commit_messages).
       Examples: `"fix(google): Fixed foobar bug"`, `"feat(accounts): Added foobar feature"`.
 - [x] All Python code must formatted using Black, and clean from pep8 and isort issues.
 - [x] JavaScript code should adhere to [StandardJS](https://standardjs.com).
 - [x] If your changes are significant, please update `ChangeLog.rst`.
 - [x] If your change is substantial, feel free to add yourself to `AUTHORS`.

 ## Provider Specifics

 In case you add a new provider:

- [x] Make sure unit tests are available.
- [x] Add an entry of your provider in `test_settings.py::INSTALLED_APPS` and `docs/installation.rst::INSTALLED_APPS`.
- [x] Add documentation to `docs/providers/<provider name>.rst` and `docs/providers/index.rst` Provider Specifics toctree.
- [x] Add an entry to the list of supported providers over at `docs/overview.rst`.


coveralls: 
[![Coverage Status](https://coveralls.io/builds/64043423/badge)](https://coveralls.io/builds/64043423)

coverage: 95.765% (+0.03%) from 95.736%
when pulling **c500e18da7a199192e79d0d5db75cdd6f47ca35b on riconnon:no-unknown-account-emails**
into **c03fecba1690e6b8f6bf424d37855d4e96bb6e16 on pennersr:main**.


Patch:
diff --git a/ChangeLog.rst b/ChangeLog.rst
index 6c7ec632..aca18753 100644
--- a/ChangeLog.rst
+++ b/ChangeLog.rst
@@ -22,6 +22,9 @@ Note worthy changes
 - A configurable timeout (``SOCIALACCOUNT_REQUESTS_TIMEOUT``) is now applied to
   all upstream requests.
 
+- Added a setting ``ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS`` to disable sending of
+  emails to unknown accounts.
+
 
 Backwards incompatible changes
 ------------------------------
diff --git a/allauth/account/app_settings.py b/allauth/account/app_settings.py
index 86eea74c..fe1c2a21 100644
--- a/allauth/account/app_settings.py
+++ b/allauth/account/app_settings.py
@@ -386,6 +386,10 @@ class AppSettings(object):
             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 193d1226..c1c866ca 100644
--- a/allauth/account/forms.py
+++ b/allauth/account/forms.py
@@ -588,7 +588,8 @@ class ResetPasswordForm(forms.Form):
     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/docs/account/configuration.rst b/docs/account/configuration.rst
index de4b5152..b45b57a6 100644
--- a/docs/account/configuration.rst
+++ b/docs/account/configuration.rst
@@ -72,6 +72,10 @@ Available settings:
   Subject-line prefix to use for email messages sent. By default, the
   name of the current ``Site`` (``django.contrib.sites``) is used.
 
+``ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS`` (default: ``True``)
+  Configures whether password reset attempts for email addresses which do not
+  have an account result in sending an email.
+
 ``ACCOUNT_DEFAULT_HTTP_PROTOCOL`` (default: ``"http"``)
   The default protocol used for when generating URLs, e.g. for the
   password forgotten procedure. Note that this is a default only --


Test patch:
diff --git a/allauth/account/tests/test_reset_password.py b/allauth/account/tests/test_reset_password.py
index 8e7c4845..85652a5d 100644
--- a/allauth/account/tests/test_reset_password.py
+++ b/allauth/account/tests/test_reset_password.py
@@ -6,12 +6,36 @@ from django.core import mail
 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",