diff --git a/zerver/forms.py b/zerver/forms.py index fbe77e34ee..757197410f 100644 --- a/zerver/forms.py +++ b/zerver/forms.py @@ -14,7 +14,7 @@ from zerver.lib.actions import do_change_password, is_inactive, user_email_is_un from zerver.lib.name_restrictions import is_reserved_subdomain, is_disposable_domain from zerver.lib.utils import get_subdomain, check_subdomain from zerver.models import Realm, get_user_profile_by_email, UserProfile, \ - completely_open, resolve_email_to_domain, get_realm, get_realm_by_string_id, \ + completely_open, get_realm, get_realm_by_email_domain, get_realm_by_string_id, \ get_unique_open_realm, split_email_to_domain, email_allowed_for_realm from zproject.backends import password_auth_enabled @@ -127,7 +127,7 @@ class HomepageForm(forms.Form): if self.string_id: realm = get_realm_by_string_id(self.string_id) elif not settings.REALMS_HAVE_SUBDOMAINS: - realm = get_realm(resolve_email_to_domain(email)) + realm = get_realm_by_email_domain(email) if realm is None: if settings.REALMS_HAVE_SUBDOMAINS: diff --git a/zerver/lib/test_classes.py b/zerver/lib/test_classes.py index 8903e08224..83946a7a25 100644 --- a/zerver/lib/test_classes.py +++ b/zerver/lib/test_classes.py @@ -35,7 +35,7 @@ from zerver.models import ( get_realm, get_stream, get_user_profile_by_email, - resolve_email_to_domain, + get_realm_by_email_domain, Client, Message, Realm, @@ -339,7 +339,7 @@ class ZulipTestCase(TestCase): def subscribe_to_stream(self, email, stream_name, realm=None): # type: (text_type, text_type, Optional[Realm]) -> None if realm is None: - realm = get_realm(resolve_email_to_domain(email)) + realm = get_realm_by_email_domain(email) stream = get_stream(stream_name, realm) if stream is None: stream, _ = create_stream_if_needed(realm, stream_name) @@ -462,4 +462,3 @@ class WebhookTestCase(ZulipTestCase): # type: (Message, Optional[text_type]) -> None if expected_message is not None: self.assertEqual(msg.content, expected_message) - diff --git a/zerver/lib/test_helpers.py b/zerver/lib/test_helpers.py index 2269d31485..e625fb6d42 100644 --- a/zerver/lib/test_helpers.py +++ b/zerver/lib/test_helpers.py @@ -31,7 +31,6 @@ from zerver.models import ( get_realm, get_stream, get_user_profile_by_email, - resolve_email_to_domain, Client, Message, Realm, diff --git a/zerver/models.py b/zerver/models.py index 180aa8e197..a72c3efdc3 100644 --- a/zerver/models.py +++ b/zerver/models.py @@ -319,15 +319,19 @@ def split_email_to_domain(email): # type: (text_type) -> text_type return email.split("@")[-1].lower() -# Returns the domain, potentually de-aliased, for the realm -# that this user's email is in -def resolve_email_to_domain(email): - # type: (text_type) -> text_type - domain = split_email_to_domain(email) - alias = alias_for_realm(domain) - if alias is not None: - domain = alias.realm.domain - return domain +class GetRealmByDomainException(Exception): + pass + +def get_realm_by_email_domain(email): + # type: (text_type) -> Optional[Realm] + if settings.REALMS_HAVE_SUBDOMAINS: + raise GetRealmByDomainException( + "Cannot get realm from email domain when settings.REALMS_HAVE_SUBDOMAINS = True") + try: + alias = RealmAlias.objects.select_related('realm').get(domain = split_email_to_domain(email)) + return alias.realm + except RealmAlias.DoesNotExist: + return None # Is a user with the given email address allowed to be in the given realm? # (This function does not check whether the user has been invited to the realm. @@ -340,13 +344,6 @@ def email_allowed_for_realm(email, realm): domain = split_email_to_domain(email) return RealmAlias.objects.filter(realm = realm, domain = domain).exists() -def alias_for_realm(domain): - # type: (text_type) -> Optional[RealmAlias] - try: - return RealmAlias.objects.get(domain=domain) - except RealmAlias.DoesNotExist: - return None - def list_of_domains_for_realm(realm): # type: (Realm) -> List[text_type] return list(RealmAlias.objects.filter(realm = realm).values_list('domain', flat=True)) diff --git a/zerver/tests/tests.py b/zerver/tests/tests.py index 3738f2e3d0..cb5ffad4a2 100644 --- a/zerver/tests/tests.py +++ b/zerver/tests/tests.py @@ -21,9 +21,9 @@ from zerver.forms import WRONG_SUBDOMAIN_ERROR from zerver.models import UserProfile, Recipient, \ Realm, RealmAlias, UserActivity, \ - get_user_profile_by_email, get_realm, \ + get_user_profile_by_email, get_realm, get_realm_by_email_domain, \ get_client, get_stream, Message, get_unique_open_realm, \ - completely_open + completely_open, GetRealmByDomainException from zerver.lib.avatar import get_avatar_url from zerver.lib.initial_password import initial_password @@ -265,6 +265,16 @@ class RealmTest(ZulipTestCase): self.assertNotEqual(realm.default_language, invalid_lang) +class RealmAliasTest(ZulipTestCase): + def test_get_realm_by_email_domain(self): + # type: () -> None + self.assertEqual(get_realm_by_email_domain('user@zulip.com').string_id, 'zulip') + self.assertEqual(get_realm_by_email_domain('user@fakedomain.com'), None) + with self.settings(REALMS_HAVE_SUBDOMAINS = True), \ + self.assertRaises(GetRealmByDomainException): + get_realm_by_email_domain('user@zulip.com') + + class PermissionTest(ZulipTestCase): def test_get_admin_users(self): # type: () -> None diff --git a/zerver/views/__init__.py b/zerver/views/__init__.py index 5ef19d8ac8..c7d62f90b3 100644 --- a/zerver/views/__init__.py +++ b/zerver/views/__init__.py @@ -20,9 +20,9 @@ from zerver.models import Message, UserProfile, Stream, Subscription, Huddle, \ RealmFilter, \ PreregistrationUser, get_client, UserActivity, \ get_stream, UserPresence, get_recipient, name_changes_disabled, \ - split_email_to_domain, resolve_email_to_domain, email_to_username, get_realm, \ + split_email_to_domain, email_to_username, get_realm, \ completely_open, get_unique_open_realm, email_allowed_for_realm, \ - get_realm_by_string_id, list_of_domains_for_realm + get_realm_by_string_id, get_realm_by_email_domain, list_of_domains_for_realm from zerver.lib.actions import do_change_password, do_change_full_name, do_change_is_admin, \ do_activate_user, do_create_user, do_create_realm, set_default_streams, \ update_user_presence, do_events_register, \ @@ -118,7 +118,7 @@ def accounts_register(request): elif settings.REALMS_HAVE_SUBDOMAINS: realm = get_realm_by_string_id(get_subdomain(request)) else: - realm = get_realm(resolve_email_to_domain(email)) + realm = get_realm_by_email_domain(email) if realm and not email_allowed_for_realm(email, realm): return render_to_response("zerver/closed_realm.html", {"closed_domain_name": realm.name}) diff --git a/zerver/views/messages.py b/zerver/views/messages.py index 606607e6c4..53052d39dd 100644 --- a/zerver/views/messages.py +++ b/zerver/views/messages.py @@ -38,10 +38,10 @@ from zerver.lib.utils import statsd from zerver.lib.validator import \ check_list, check_int, check_dict, check_string, check_bool from zerver.models import Message, UserProfile, Stream, Subscription, \ - Realm, Recipient, UserMessage, bulk_get_recipients, get_recipient, \ + Realm, RealmAlias, Recipient, UserMessage, bulk_get_recipients, get_recipient, \ get_user_profile_by_email, get_stream, \ parse_usermessage_flags, \ - resolve_email_to_domain, get_realm, get_active_streams, \ + split_email_to_domain, get_realm, get_active_streams, \ bulk_get_streams, get_user_profile_by_id from sqlalchemy import func @@ -754,9 +754,10 @@ def same_realm_zephyr_user(user_profile, email): except ValidationError: return False - domain = resolve_email_to_domain(email) + domain = split_email_to_domain(email) - return user_profile.realm.domain == domain and user_profile.realm.is_zephyr_mirror_realm + return user_profile.realm.is_zephyr_mirror_realm and \ + RealmAlias.objects.filter(realm=user_profile.realm, domain=domain).exists() def same_realm_irc_user(user_profile, email): # type: (UserProfile, text_type) -> bool @@ -768,9 +769,9 @@ def same_realm_irc_user(user_profile, email): except ValidationError: return False - domain = resolve_email_to_domain(email) + domain = split_email_to_domain(email).replace("irc.", "") - return user_profile.realm.domain == domain.replace("irc.", "") + return RealmAlias.objects.filter(realm=user_profile.realm, domain=domain).exists() def same_realm_jabber_user(user_profile, email): # type: (UserProfile, text_type) -> bool @@ -779,11 +780,11 @@ def same_realm_jabber_user(user_profile, email): except ValidationError: return False - domain = resolve_email_to_domain(email) - # If your Jabber users have a different email domain than the # Zulip users, this is where you would do any translation. - return user_profile.realm.domain == domain + domain = split_email_to_domain(email) + + return RealmAlias.objects.filter(realm=user_profile.realm, domain=domain).exists() # We do not @require_login for send_message_backend, since it is used # both from the API and the web service. Code calling diff --git a/zilencer/views.py b/zilencer/views.py index c595718179..b723126c24 100644 --- a/zilencer/views.py +++ b/zilencer/views.py @@ -13,7 +13,7 @@ from zerver.lib.actions import internal_send_message from zerver.lib.redis_utils import get_redis_client from zerver.lib.response import json_success, json_error, json_response from zerver.lib.validator import check_dict -from zerver.models import get_realm, get_user_profile_by_email, resolve_email_to_domain, \ +from zerver.models import get_realm, get_user_profile_by_email, get_realm_by_email_domain, \ UserProfile, Realm from .error_notify import notify_server_error, notify_browser_error @@ -106,7 +106,7 @@ def realm_for_email(email): except UserProfile.DoesNotExist: pass - return get_realm(resolve_email_to_domain(email)) + return get_realm_by_email_domain(email) # Requests made to this endpoint are UNAUTHENTICATED @csrf_exempt diff --git a/zproject/backends.py b/zproject/backends.py index a0a96d2a95..555d40a85b 100644 --- a/zproject/backends.py +++ b/zproject/backends.py @@ -14,7 +14,7 @@ from zerver.lib.actions import do_create_user from zerver.models import UserProfile, Realm, get_user_profile_by_id, \ get_user_profile_by_email, remote_user_to_email, email_to_username, \ - resolve_email_to_domain, get_realm + get_realm, get_realm_by_email_domain from apiclient.sample_tools import client as googleapiclient from oauth2client.crypt import AppIdentityError @@ -335,8 +335,7 @@ class ZulipLDAPAuthBackend(ZulipLDAPAuthBackendBase): raise ZulipLDAPException("LDAP Authentication is not enabled") return user_profile, False except UserProfile.DoesNotExist: - domain = resolve_email_to_domain(username) - realm = get_realm(domain) + realm = get_realm_by_email_domain(username) # No need to check for an inactive user since they don't exist yet if realm.deactivated: raise ZulipLDAPException("Realm has been deactivated")