From e980c4d727e2647a52add7aeaf533b3f3587be7c Mon Sep 17 00:00:00 2001 From: imperosol Date: Sat, 31 Oct 2026 18:47:36 +0100 Subject: [PATCH] check email toxic domain at model-level --- antispam/forms.py | 4 ++-- antispam/models/__init__.py | 4 ++++ antispam/models/fields.py | 21 +++++++++++++++++++++ antispam/{ => models}/models.py | 0 antispam/tests/__init__.py | 0 core/models.py | 5 +++-- core/views/forms.py | 6 +----- 7 files changed, 31 insertions(+), 9 deletions(-) create mode 100644 antispam/models/__init__.py create mode 100644 antispam/models/fields.py rename antispam/{ => models}/models.py (100%) create mode 100644 antispam/tests/__init__.py diff --git a/antispam/forms.py b/antispam/forms.py index 0e327f2a..6576322c 100644 --- a/antispam/forms.py +++ b/antispam/forms.py @@ -2,7 +2,7 @@ from django import forms from django.core.validators import EmailValidator from django.utils.translation import gettext_lazy as _ -from antispam.models import ToxicDomain +from antispam.models.models import ToxicDomain class AntiSpamEmailValidator(EmailValidator): @@ -17,6 +17,6 @@ validate_antispam_email = AntiSpamEmailValidator() class AntiSpamEmailField(forms.EmailField): - """An email field that email addresses with a known toxic domain.""" + """An email field that forbids email addresses with a known toxic domain.""" default_validators = [validate_antispam_email] diff --git a/antispam/models/__init__.py b/antispam/models/__init__.py new file mode 100644 index 00000000..ab6041d3 --- /dev/null +++ b/antispam/models/__init__.py @@ -0,0 +1,4 @@ +from antispam.models.fields import AntiSpamEmailField +from antispam.models.models import ToxicDomain + +__all__ = ["AntiSpamEmailField", "ToxicDomain"] diff --git a/antispam/models/fields.py b/antispam/models/fields.py new file mode 100644 index 00000000..cc747e0b --- /dev/null +++ b/antispam/models/fields.py @@ -0,0 +1,21 @@ +from django.conf import settings +from django.db import models + +from antispam import forms + + +class AntiSpamEmailField(models.EmailField): + """An email field that forbids email addresses with a known toxic domain.""" + + default_validators = [forms.validate_antispam_email] + + +if settings.TESTING: + from model_bakery import baker + + baker.generators.add( + AntiSpamEmailField, lambda: baker.random_gen.gen_email(max_length=100) + ) +else: # pragma: no cover + # baker is only used in tests, so we don't need coverage for this part + pass diff --git a/antispam/models.py b/antispam/models/models.py similarity index 100% rename from antispam/models.py rename to antispam/models/models.py diff --git a/antispam/tests/__init__.py b/antispam/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/core/models.py b/core/models.py index 7baec8d1..e9bb28a6 100644 --- a/core/models.py +++ b/core/models.py @@ -55,6 +55,7 @@ from django.utils.translation import gettext_lazy as _ from phonenumber_field.modelfields import PhoneNumberField from PIL import Image, ImageOps +from antispam.models import AntiSpamEmailField from core.utils import get_last_promo if TYPE_CHECKING: @@ -158,7 +159,7 @@ class User(AbstractUser): first_name = models.CharField(_("first name"), max_length=64) last_name = models.CharField(_("last name"), max_length=64) - email = models.EmailField(_("email address"), unique=True) + email = AntiSpamEmailField(_("email address"), unique=True) date_of_birth = models.DateField(_("date of birth"), blank=True, null=True) nick_name = models.CharField(_("nick name"), max_length=64, null=True, blank=True) last_update = models.DateTimeField(_("last update"), auto_now=True) @@ -267,7 +268,7 @@ class User(AbstractUser): forum_signature = models.TextField( _("forum signature"), max_length=256, blank=True, default="" ) - second_email = models.EmailField(_("second email address"), null=True, blank=True) + second_email = AntiSpamEmailField(_("second email address"), null=True, blank=True) phone = PhoneNumberField(_("phone"), null=True, blank=True) parent_phone = PhoneNumberField(_("parent phone"), null=True, blank=True) address = models.CharField(_("address"), max_length=128, blank=True, default="") diff --git a/core/views/forms.py b/core/views/forms.py index cc235a2e..cc0af005 100644 --- a/core/views/forms.py +++ b/core/views/forms.py @@ -48,7 +48,6 @@ from django.utils.translation import gettext_lazy as _ from phonenumber_field.widgets import RegionalPhoneNumberWidget from PIL import Image -from antispam.forms import AntiSpamEmailField from core.models import Gift, Group, Page, PageRev, Preferences, SithFile, User from core.utils import resize_image from core.views.widgets.ajax_select import ( @@ -185,10 +184,7 @@ class RegisteringForm(UserCreationForm): class Meta: model = User fields = ("first_name", "last_name", "email", "cgu_approved_at") - field_classes = { - "email": AntiSpamEmailField, - "cgu_approved_at": CGUApprovalField, - } + field_classes = {"cgu_approved_at": CGUApprovalField} class CGUApprovalForm(forms.ModelForm):