Merge pull request #375 from ThomasWaldmann/validate-registration-email
validate email address in registration form
This commit is contained in:
commit
bd0fa0f040
75
nsupdate/accounts/registration_form.py
Normal file
75
nsupdate/accounts/registration_form.py
Normal file
@ -0,0 +1,75 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import re
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from registration.forms import RegistrationForm
|
||||
|
||||
import dns.resolver
|
||||
import dns.name
|
||||
|
||||
|
||||
resolver = dns.resolver.Resolver()
|
||||
resolver.search = [dns.name.root, ]
|
||||
resolver.lifetime = 5.0
|
||||
resolver.nameservers = settings.NAMESERVERS
|
||||
|
||||
|
||||
maildomain_blacklist = settings.MAILDOMAIN_BLACKLIST.strip().splitlines()
|
||||
|
||||
|
||||
def check_mx(domain):
|
||||
valid = False
|
||||
try:
|
||||
mx_answers = resolver.query(domain, 'MX')
|
||||
# domain exists in DNS, domain has MX
|
||||
mx_entries = sorted([(mx_rdata.preference, mx_rdata.exchange) for mx_rdata in mx_answers])
|
||||
for preference, mx in mx_entries:
|
||||
try:
|
||||
addr_answers = resolver.query(mx, 'A')
|
||||
except dns.resolver.NoAnswer:
|
||||
addr_answers = resolver.query(mx, 'AAAA')
|
||||
# MX has IP addr
|
||||
mx_addrs = [addr_rdata.address for addr_rdata in addr_answers]
|
||||
for mx_addr in mx_addrs:
|
||||
if mx_addr not in (u'127.0.0.1', u'::1', u'0.0.0.0', ):
|
||||
valid = True
|
||||
break
|
||||
if valid:
|
||||
break
|
||||
except (dns.resolver.Timeout, dns.resolver.NoAnswer, dns.resolver.NoNameservers, dns.resolver.NXDOMAIN, ):
|
||||
# expected exceptions (e.g. due to non-existing or misconfigured crap domains)
|
||||
pass
|
||||
return valid
|
||||
|
||||
|
||||
def check_blacklist(domain):
|
||||
for blacklisted_re in maildomain_blacklist:
|
||||
if re.search(blacklisted_re, domain):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class RegistrationFormValidateEmail(RegistrationForm):
|
||||
def clean_email(self):
|
||||
"""
|
||||
Validate the supplied email address to avoid undeliverable email and mailer daemon spam.
|
||||
"""
|
||||
email = self.cleaned_data.get('email')
|
||||
valid_mx = False
|
||||
try:
|
||||
domain = email.split('@')[1]
|
||||
valid_mx = check_mx(domain)
|
||||
except Exception as e:
|
||||
logger.exception('RegistrationFormValidateEmail raised an exception:')
|
||||
not_blacklisted = check_blacklist(domain)
|
||||
if valid_mx and not_blacklisted:
|
||||
return email
|
||||
logger.info('RegistrationFormValidateEmail: rejecting email address %r' % email)
|
||||
raise forms.ValidationError(_("Enter a valid email address."))
|
@ -51,6 +51,21 @@ BAD_AGENTS = set([]) # list can have str elements
|
||||
from netaddr import IPSet, IPAddress, IPNetwork
|
||||
BAD_IPS_HOST = IPSet([]) # inner list can have IPAddress and IPNetwork elements
|
||||
|
||||
# nameservers used e.g. for MX lookups in the registration email validation.
|
||||
# google / cloudflare DNS IPs are only given as example / fallback -
|
||||
# please configure your own nameservers in your local settings file.
|
||||
NAMESERVERS = ['8.8.8.8', '1.1.1.1', ]
|
||||
|
||||
# registration email validation: disallow specific email domains,
|
||||
# e.g. domains that have a non-working mx / that are frequently abused.
|
||||
# we use a multiline string here with one regex per line (used with re.search).
|
||||
# the domains given below are just examples, please configure your own
|
||||
# regexes in your local settings file.
|
||||
MAILDOMAIN_BLACKLIST = """
|
||||
mailcatch\.com$
|
||||
mailspam\.xyz$
|
||||
"""
|
||||
|
||||
# Local time zone for this installation. Choices can be found here:
|
||||
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
||||
# although not all choices may be available on all operating systems.
|
||||
@ -245,6 +260,7 @@ SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
|
||||
|
||||
ACCOUNT_ACTIVATION_DAYS = 7
|
||||
REGISTRATION_EMAIL_HTML = False # we override the text, but not the html email template
|
||||
REGISTRATION_FORM = 'nsupdate.accounts.registration_form.RegistrationFormValidateEmail'
|
||||
|
||||
LOGIN_REDIRECT_URL = '/overview/'
|
||||
LOGOUT_REDIRECT_URL = '/'
|
||||
|
Loading…
x
Reference in New Issue
Block a user