mirror of
https://github.com/zulip/zulip.git
synced 2025-11-11 09:27:43 +00:00
Use standard functions for parsing/validating email addresses.
This adds two new functions for parsing out the domain and username
from an email address, and switches our backend to use them and
django.core.validators.valid_email() rather than custom parsing and
raw email.split("@").
(imported from commit 3d6e997d66908811eccb5f82f2f7fe349b40f238)
This commit is contained in:
@@ -9,7 +9,8 @@ from zephyr.models import Realm, Stream, UserProfile, UserActivity, \
|
||||
DefaultStream, UserPresence, MAX_SUBJECT_LENGTH, \
|
||||
MAX_MESSAGE_LENGTH, get_client, get_stream, get_recipient, get_huddle, \
|
||||
get_user_profile_by_id, PreregistrationUser, get_display_recipient, \
|
||||
to_dict_cache_key, get_realm, stringify_message_dict, bulk_get_recipients
|
||||
to_dict_cache_key, get_realm, stringify_message_dict, bulk_get_recipients, \
|
||||
email_to_domain, email_to_username
|
||||
from django.db import transaction, IntegrityError
|
||||
from django.db.models import F, Q
|
||||
from django.core.exceptions import ValidationError
|
||||
@@ -190,7 +191,7 @@ def create_mit_user_if_needed(realm, email):
|
||||
try:
|
||||
# Forge a user for this person
|
||||
return create_user(email, initial_password(email), realm,
|
||||
compute_mit_user_fullname(email), email.split("@")[0],
|
||||
compute_mit_user_fullname(email), email_to_username(email),
|
||||
active=False)
|
||||
except IntegrityError:
|
||||
# Unless we raced with another thread doing the same
|
||||
@@ -1358,12 +1359,14 @@ def do_invite_users(user_profile, invitee_emails, streams):
|
||||
if email == '':
|
||||
continue
|
||||
|
||||
if not validators.email_re.match(email):
|
||||
try:
|
||||
validators.validate_email(email)
|
||||
except ValidationError:
|
||||
errors.append((email, "Invalid address."))
|
||||
continue
|
||||
|
||||
if user_profile.realm.restricted_to_domain and \
|
||||
email.split('@', 1)[-1].lower() != user_profile.realm.domain.lower():
|
||||
email_to_domain(email).lower() != user_profile.realm.domain.lower():
|
||||
errors.append((email, "Outside your domain."))
|
||||
continue
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ from __future__ import absolute_import
|
||||
|
||||
from zephyr.lib.initial_password import initial_password
|
||||
from zephyr.models import Realm, Stream, UserProfile, Huddle, \
|
||||
Subscription, Recipient, Client, get_huddle_hash
|
||||
Subscription, Recipient, Client, get_huddle_hash, email_to_domain
|
||||
from zephyr.lib.create_user import create_user_profile
|
||||
|
||||
def bulk_create_realms(realm_list):
|
||||
@@ -31,7 +31,7 @@ def bulk_create_users(realms, users_raw):
|
||||
# Now create user_profiles
|
||||
profiles_to_create = []
|
||||
for (email, full_name, short_name, active) in users:
|
||||
domain = email.split('@')[1]
|
||||
domain = email_to_domain(email)
|
||||
profile = create_user_profile(realms[domain], email,
|
||||
initial_password(email), active, False,
|
||||
full_name, short_name, None)
|
||||
|
||||
@@ -8,7 +8,7 @@ from django.core.exceptions import ValidationError
|
||||
from django.db.utils import IntegrityError
|
||||
from django.core import validators
|
||||
|
||||
from zephyr.models import Realm
|
||||
from zephyr.models import Realm, email_to_username
|
||||
from zephyr.lib.actions import do_create_user
|
||||
from zephyr.views import notify_new_user
|
||||
from zephyr.lib.initial_password import initial_password
|
||||
@@ -67,7 +67,7 @@ parameters, or specify no parameters for interactive user creation.""")
|
||||
|
||||
try:
|
||||
notify_new_user(do_create_user(email, initial_password(email),
|
||||
realm, full_name, email.split('@')[0]),
|
||||
realm, full_name, email_to_username(email)),
|
||||
internal=True)
|
||||
except IntegrityError:
|
||||
raise CommandError("User already exists.")
|
||||
|
||||
@@ -6,7 +6,8 @@ from django.utils.timezone import now
|
||||
from django.contrib.sites.models import Site
|
||||
from zephyr.models import Message, UserProfile, Stream, Recipient, Client, \
|
||||
Subscription, Huddle, get_huddle, Realm, UserMessage, \
|
||||
get_huddle_hash, clear_database, get_client, get_user_profile_by_id
|
||||
get_huddle_hash, clear_database, get_client, get_user_profile_by_id, \
|
||||
email_to_domain, email_to_username
|
||||
from zephyr.lib.actions import do_send_message, set_default_streams, \
|
||||
do_activate_user, do_deactivate, do_change_password
|
||||
from zephyr.lib.parallel import run_parallel
|
||||
@@ -32,7 +33,7 @@ settings.TORNADO_SERVER = None
|
||||
def create_users(realms, name_list):
|
||||
user_set = set()
|
||||
for full_name, email in name_list:
|
||||
(short_name, domain) = email.split("@")
|
||||
short_name = email_to_username(email)
|
||||
user_set.add((email, full_name, short_name, True))
|
||||
bulk_create_users(realms, user_set)
|
||||
|
||||
@@ -336,7 +337,7 @@ def restore_saved_messages():
|
||||
|
||||
sender_email = old_message["sender_email"]
|
||||
|
||||
domain = sender_email.split('@')[1]
|
||||
domain = email_to_domain(sender_email)
|
||||
realm_set.add(domain)
|
||||
|
||||
if old_message["sender_email"] not in email_set:
|
||||
@@ -447,7 +448,7 @@ def restore_saved_messages():
|
||||
message = Message()
|
||||
|
||||
sender_email = old_message["sender_email"]
|
||||
domain = sender_email.split('@')[1]
|
||||
domain = email_to_domain(sender_email)
|
||||
realm = realms[domain]
|
||||
|
||||
message.sender = users[sender_email]
|
||||
|
||||
@@ -72,6 +72,18 @@ class Realm(models.Model):
|
||||
('administer', "Administer a realm"),
|
||||
)
|
||||
|
||||
# These functions should only be used on email addresses that have
|
||||
# been validated via django.core.validators.validate_email
|
||||
#
|
||||
# Note that we need to use some care, since can you have multiple @-signs; e.g.
|
||||
# "tabbott@test"@humbughq.com
|
||||
# is valid email address
|
||||
def email_to_username(email):
|
||||
return "@".join(email.split("@")[:-1])
|
||||
|
||||
def email_to_domain(email):
|
||||
return email.split("@")[-1]
|
||||
|
||||
class UserProfile(AbstractBaseUser, PermissionsMixin):
|
||||
# Fields from models.AbstractUser minus last_name and first_name,
|
||||
# which we don't use; email is modified to make it indexed and unique.
|
||||
|
||||
@@ -9,7 +9,7 @@ from django.db.models import Q
|
||||
from zephyr.models import Message, UserProfile, Stream, Recipient, Subscription, \
|
||||
get_display_recipient, Realm, Client, \
|
||||
PreregistrationUser, UserMessage, \
|
||||
get_user_profile_by_email
|
||||
get_user_profile_by_email, email_to_domain
|
||||
from zephyr.tornadoviews import json_get_updates, api_get_messages
|
||||
from zephyr.decorator import RespondAsynchronously, RequestVariableConversionError, profiled
|
||||
from zephyr.lib.initial_password import initial_password
|
||||
@@ -2558,7 +2558,7 @@ class UserPresenceTests(AuthedTestCase):
|
||||
self.assertEqual(json['presences'][email][client]['status'], 'idle')
|
||||
# We only want @humbughq.com emails
|
||||
for email in json['presences'].keys():
|
||||
self.assertEqual(email.split('@')[1], 'humbughq.com')
|
||||
self.assertEqual(email_to_domain(email), 'humbughq.com')
|
||||
|
||||
class UnreadCountTests(AuthedTestCase):
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ from zephyr.models import Message, UserProfile, Stream, Subscription, \
|
||||
PreregistrationUser, get_client, MitUser, UserActivity, \
|
||||
MAX_SUBJECT_LENGTH, get_stream, bulk_get_streams, UserPresence, \
|
||||
get_recipient, valid_stream_name, to_dict_cache_key, to_dict_cache_key_id, \
|
||||
extract_message_dict, stringify_message_dict, parse_usermessage_flags
|
||||
extract_message_dict, stringify_message_dict, parse_usermessage_flags, \
|
||||
email_to_domain, email_to_username
|
||||
from zephyr.lib.actions import do_remove_subscription, bulk_remove_subscriptions, \
|
||||
do_change_password, create_mit_user_if_needed, do_change_full_name, \
|
||||
do_change_enable_desktop_notifications, do_change_enter_sends, do_change_enable_sounds, \
|
||||
@@ -233,6 +234,7 @@ def accounts_register(request):
|
||||
email = prereg_user.email
|
||||
mit_beta_user = isinstance(confirmation.content_object, MitUser)
|
||||
|
||||
validators.validate_email(email)
|
||||
# If someone invited you, you are joining their realm regardless
|
||||
# of your e-mail address.
|
||||
#
|
||||
@@ -240,7 +242,7 @@ def accounts_register(request):
|
||||
if not mit_beta_user and prereg_user.referred_by:
|
||||
domain = prereg_user.referred_by.realm.domain
|
||||
else:
|
||||
domain = email.split('@')[-1]
|
||||
domain = email_to_domain(email)
|
||||
|
||||
try:
|
||||
if mit_beta_user:
|
||||
@@ -259,7 +261,7 @@ def accounts_register(request):
|
||||
if form.is_valid():
|
||||
password = form.cleaned_data['password']
|
||||
full_name = form.cleaned_data['full_name']
|
||||
short_name = email.split('@')[0]
|
||||
short_name = email_to_username(email)
|
||||
(realm, _) = Realm.objects.get_or_create(domain=domain)
|
||||
first_in_realm = len(UserProfile.objects.filter(realm=realm)) == 0
|
||||
|
||||
@@ -328,7 +330,7 @@ def accounts_register(request):
|
||||
@login_required(login_url = settings.HOME_NOT_LOGGED_IN)
|
||||
def accounts_accept_terms(request):
|
||||
email = request.user.email
|
||||
company_name = email.split('@')[-1]
|
||||
domain = email_to_domain(email)
|
||||
if request.method == "POST":
|
||||
form = ToSForm(request.POST)
|
||||
if form.is_valid():
|
||||
@@ -347,7 +349,7 @@ def accounts_accept_terms(request):
|
||||
else:
|
||||
form = ToSForm()
|
||||
return render_to_response('zephyr/accounts_accept_terms.html',
|
||||
{ 'form': form, 'company_name': company_name, 'email': email },
|
||||
{ 'form': form, 'company_name': domain, 'email': email },
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
def api_endpoint_docs(request):
|
||||
@@ -1012,14 +1014,14 @@ def mit_to_mit(user_profile, email):
|
||||
# We have to handle this specially, inferring the domain from the
|
||||
# e-mail address, because the recipient may not existing in Humbug
|
||||
# and we may need to make a stub MIT user on the fly.
|
||||
if not validators.email_re.match(email):
|
||||
try:
|
||||
validators.validate_email(email)
|
||||
except ValidationError:
|
||||
return False
|
||||
|
||||
if user_profile.realm.domain != "mit.edu":
|
||||
return False
|
||||
domain = email_to_domain(email)
|
||||
|
||||
domain = email.split("@", 1)[1]
|
||||
return user_profile.realm.domain == domain
|
||||
return user_profile.realm.domain == "mit.edu" and domain == "mit.edu"
|
||||
|
||||
def create_mirrored_message_users(request, user_profile, recipients):
|
||||
if "sender" not in request.POST:
|
||||
|
||||
Reference in New Issue
Block a user