Files
zulip/zerver/lib/subdomains.py
Anders Kaseorg 365fe0b3d5 python: Sort imports with isort.
Fixes #2665.

Regenerated by tabbott with `lint --fix` after a rebase and change in
parameters.

Note from tabbott: In a few cases, this converts technical debt in the
form of unsorted imports into different technical debt in the form of
our largest files having very long, ugly import sequences at the
start.  I expect this change will increase pressure for us to split
those files, which isn't a bad thing.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-06-11 16:45:32 -07:00

55 lines
2.0 KiB
Python

import re
from typing import Optional
from django.conf import settings
from django.http import HttpRequest
from zerver.models import Realm, UserProfile
def get_subdomain(request: HttpRequest) -> str:
# The HTTP spec allows, but doesn't require, a client to omit the
# port in the `Host` header if it's "the default port for the
# service requested", i.e. typically either 443 or 80; and
# whatever Django gets there, or from proxies reporting that via
# X-Forwarded-Host, it passes right through the same way. So our
# logic is a bit complicated to allow for that variation.
#
# For both EXTERNAL_HOST and REALM_HOSTS, we take a missing port
# to mean that any port should be accepted in Host. It's not
# totally clear that's the right behavior, but it keeps
# compatibility with older versions of Zulip, so that's a start.
host = request.get_host().lower()
return get_subdomain_from_hostname(host)
def get_subdomain_from_hostname(host: str) -> str:
m = re.search(fr'\.{settings.EXTERNAL_HOST}(:\d+)?$',
host)
if m:
subdomain = host[:m.start()]
if subdomain in settings.ROOT_SUBDOMAIN_ALIASES:
return Realm.SUBDOMAIN_FOR_ROOT_DOMAIN
return subdomain
for subdomain, realm_host in settings.REALM_HOSTS.items():
if re.search(fr'^{realm_host}(:\d+)?$',
host):
return subdomain
return Realm.SUBDOMAIN_FOR_ROOT_DOMAIN
def is_subdomain_root_or_alias(request: HttpRequest) -> bool:
return get_subdomain(request) == Realm.SUBDOMAIN_FOR_ROOT_DOMAIN
def user_matches_subdomain(realm_subdomain: Optional[str], user_profile: UserProfile) -> bool:
if realm_subdomain is None:
return True # nocoverage # This state may no longer be possible.
return user_profile.realm.subdomain == realm_subdomain
def is_root_domain_available() -> bool:
if settings.ROOT_DOMAIN_LANDING_PAGE:
return False
return not Realm.objects.filter(string_id=Realm.SUBDOMAIN_FOR_ROOT_DOMAIN).exists()