Validate email addresses fo valid DNS names

This commit is contained in:
Raphael Michel
2021-01-01 20:13:09 +01:00
parent 23aba9b5ef
commit 0b495a4070
3 changed files with 37 additions and 4 deletions
+35 -4
View File
@@ -1,6 +1,8 @@
from itertools import chain from itertools import chain
import dns
from django import forms from django import forms
from django.core.cache import cache
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.utils.encoding import force_str from django.utils.encoding import force_str
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@@ -18,12 +20,41 @@ from pretix.base.validators import EmailBanlistValidator
from pretix.presale.signals import contact_form_fields from pretix.presale.signals import contact_form_fields
class EmailDNSValidator():
def __call__(self, value):
domain = value.split('@')[-1]
works = cache.get(f"mail_domain_exists_{domain}")
if works:
return value
resolver = dns.resolver.Resolver()
resolver.lifetime = 0.5
resolver.timeout = 0.5
record_types = ('MX', 'AAAA', 'A')
for record_type in record_types:
try:
if len(resolver.query(domain, record_type)):
cache.set(f"mail_domain_exists_{domain}", "true", 3600 * 24 * 7)
return value
except:
continue
raise ValidationError(
_('Please check your email domain, it does not look like "%(value)s" is able to receive emails.'),
code='dns',
params={'value': domain},
)
class ContactForm(forms.Form): class ContactForm(forms.Form):
required_css_class = 'required' required_css_class = 'required'
email = forms.EmailField(label=_('E-mail'), email = forms.EmailField(
validators=[EmailBanlistValidator()], label=_('E-mail'),
widget=forms.EmailInput(attrs={'autocomplete': 'section-contact email'}) validators=[
) EmailBanlistValidator(),
EmailDNSValidator(),
],
widget=forms.EmailInput(attrs={'autocomplete': 'section-contact email'})
)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.event = kwargs.pop('event') self.event = kwargs.pop('event')
+1
View File
@@ -44,6 +44,7 @@ oauthlib==3.1.*
django-jsonfallback>=2.1.2 django-jsonfallback>=2.1.2
psycopg2-binary psycopg2-binary
tqdm==4.* tqdm==4.*
dnspython==1.16.*
# Stripe # Stripe
stripe==2.42.* stripe==2.42.*
# PayPal # PayPal
+1
View File
@@ -134,6 +134,7 @@ setup(
'django-i18nfield>=1.7.0', 'django-i18nfield>=1.7.0',
'django-jsonfallback>=2.1.2', 'django-jsonfallback>=2.1.2',
'psycopg2-binary', 'psycopg2-binary',
'dnspython==1.16.*',
'tqdm==4.*', 'tqdm==4.*',
'vobject==0.9.*', 'vobject==0.9.*',
'pycountry', 'pycountry',