mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	Prevent code from using email domain to determine realm when subdomains.
Also removes the intermediate step of going through Realm.domain in the non-subdomains case. Part of a larger project to remove Realm.domain entirely.
This commit is contained in:
		@@ -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:
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,6 @@ from zerver.models import (
 | 
			
		||||
    get_realm,
 | 
			
		||||
    get_stream,
 | 
			
		||||
    get_user_profile_by_email,
 | 
			
		||||
    resolve_email_to_domain,
 | 
			
		||||
    Client,
 | 
			
		||||
    Message,
 | 
			
		||||
    Realm,
 | 
			
		||||
 
 | 
			
		||||
@@ -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))
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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})
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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")
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user