python: Use a real parser for email addresses.

Now that we can assume Python 3.6+, we can use the
email.headerregistry module to replace hacky manual email address
parsing.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg
2022-07-27 14:33:49 -07:00
committed by Tim Abbott
parent 8c2d478e6a
commit b945aa3443
31 changed files with 165 additions and 139 deletions

View File

@@ -1,5 +1,6 @@
import logging
import re
from email.headerregistry import Address
from typing import Any, Dict, List, Optional, Tuple
import DNS
@@ -39,7 +40,6 @@ from zerver.models import (
EmailContainsPlusError,
Realm,
UserProfile,
email_to_domain,
get_realm,
get_user_by_delivery_email,
is_cross_realm_bot_email,
@@ -68,11 +68,11 @@ PASSWORD_TOO_WEAK_ERROR = gettext_lazy("The password is too weak.")
def email_is_not_mit_mailing_list(email: str) -> None:
"""Prevent MIT mailing lists from signing up for Zulip"""
if "@mit.edu" in email:
username = email.rsplit("@", 1)[0]
address = Address(addr_spec=email)
if address.domain == "mit.edu":
# Check whether the user exists and can get mail.
try:
DNS.dnslookup(f"{username}.pobox.ns.athena.mit.edu", DNS.Type.TXT)
DNS.dnslookup(f"{address.username}.pobox.ns.athena.mit.edu", DNS.Type.TXT)
except DNS.Base.ServerError as e:
if e.rcode == DNS.Status.NXDOMAIN:
# This error is mark_safe only because 1. it needs to render HTML
@@ -240,7 +240,7 @@ def email_not_system_bot(email: str) -> None:
def email_is_not_disposable(email: str) -> None:
if is_disposable_domain(email_to_domain(email)):
if is_disposable_domain(Address(addr_spec=email).domain):
raise ValidationError(_("Please use your real email address."))