diff --git a/antispam/forms.py b/antispam/forms.py index a2f97124..0e327f2a 100644 --- a/antispam/forms.py +++ b/antispam/forms.py @@ -1,5 +1,3 @@ -import re - from django import forms from django.core.validators import EmailValidator from django.utils.translation import gettext_lazy as _ @@ -7,12 +5,18 @@ from django.utils.translation import gettext_lazy as _ from antispam.models import ToxicDomain +class AntiSpamEmailValidator(EmailValidator): + def __call__(self, value: str): + super().__call__(value) + domain_part = value.rsplit("@", 1)[1] + if ToxicDomain.objects.filter(domain=domain_part).exists(): + raise forms.ValidationError(_("Email domain is not allowed.")) + + +validate_antispam_email = AntiSpamEmailValidator() + + class AntiSpamEmailField(forms.EmailField): """An email field that email addresses with a known toxic domain.""" - def run_validators(self, value: str): - super().run_validators(value) - # Domain part should exist since email validation is guaranteed to run first - domain = re.search(EmailValidator.domain_regex, value) - if ToxicDomain.objects.filter(domain=domain[0]).exists(): - raise forms.ValidationError(_("Email domain is not allowed.")) + default_validators = [validate_antispam_email] diff --git a/core/tests/test_core.py b/core/tests/test_core.py index 930e8819..964b7823 100644 --- a/core/tests/test_core.py +++ b/core/tests/test_core.py @@ -100,8 +100,9 @@ class TestUserRegistration: payload = valid_payload | payload_edit response = client.post(reverse("core:register"), payload) assert response.status_code == 200 - error_html = f'' - assertInHTML(error_html, str(response.content.decode())) + errors = BeautifulSoup(response.text, "lxml").find_all(class_="errorlist") + assert len(errors) == 1 + assert errors[0].text == expected_error assert not User.objects.filter(email=payload["email"]).exists() def test_register_honeypot_fail(self, client: Client, valid_payload):