zulip/zerver/context_processors.py

192 lines
7.5 KiB
Python

from typing import Any, Dict, Optional
from django.http import HttpRequest
from django.conf import settings
from django.urls import reverse
from zerver.models import UserProfile, get_realm, Realm
from zproject.backends import (
any_oauth_backend_enabled,
password_auth_enabled,
require_email_format_usernames,
auth_enabled_helper,
AUTH_BACKEND_NAME_MAP,
SOCIAL_AUTH_BACKENDS,
)
from zerver.decorator import get_client_name
from zerver.lib.send_email import FromAddress
from zerver.lib.subdomains import get_subdomain
from zerver.lib.realm_icon import get_realm_icon_url
from zerver.lib.realm_description import get_realm_rendered_description
from version import ZULIP_VERSION, LATEST_RELEASE_VERSION, LATEST_MAJOR_VERSION, \
LATEST_RELEASE_ANNOUNCEMENT
def common_context(user: UserProfile) -> Dict[str, Any]:
"""Common context used for things like outgoing emails that don't
have a request.
"""
return {
'realm_uri': user.realm.uri,
'realm_name': user.realm.name,
'root_domain_uri': settings.ROOT_DOMAIN_URI,
'external_uri_scheme': settings.EXTERNAL_URI_SCHEME,
'external_host': settings.EXTERNAL_HOST,
'user_name': user.full_name,
}
def get_realm_from_request(request: HttpRequest) -> Optional[Realm]:
if hasattr(request, "user") and hasattr(request.user, "realm"):
return request.user.realm
if not hasattr(request, "realm"):
# We cache the realm object from this function on the request,
# so that functions that call get_realm_from_request don't
# need to do duplicate queries on the same realm while
# processing a single request.
subdomain = get_subdomain(request)
request.realm = get_realm(subdomain)
return request.realm
def zulip_default_context(request: HttpRequest) -> Dict[str, Any]:
"""Context available to all Zulip Jinja2 templates that have a request
passed in. Designed to provide the long list of variables at the
bottom of this function in a wide range of situations: logged-in
or logged-out, subdomains or not, etc.
The main variable in the below is whether we know what realm the
user is trying to interact with.
"""
realm = get_realm_from_request(request)
if realm is None:
realm_uri = settings.ROOT_DOMAIN_URI
realm_name = None
realm_icon = None
else:
realm_uri = realm.uri
realm_name = realm.name
realm_icon = get_realm_icon_url(realm)
register_link_disabled = settings.REGISTER_LINK_DISABLED
login_link_disabled = settings.LOGIN_LINK_DISABLED
find_team_link_disabled = settings.FIND_TEAM_LINK_DISABLED
allow_search_engine_indexing = False
if (settings.ROOT_DOMAIN_LANDING_PAGE
and get_subdomain(request) == Realm.SUBDOMAIN_FOR_ROOT_DOMAIN):
register_link_disabled = True
login_link_disabled = True
find_team_link_disabled = False
allow_search_engine_indexing = True
apps_page_url = 'https://zulipchat.com/apps/'
if settings.ZILENCER_ENABLED:
apps_page_url = '/apps/'
user_is_authenticated = False
if hasattr(request, 'user') and hasattr(request.user, 'is_authenticated'):
user_is_authenticated = request.user.is_authenticated.value
if settings.DEVELOPMENT:
secrets_path = "zproject/dev-secrets.conf"
settings_path = "zproject/dev_settings.py"
settings_comments_path = "zproject/prod_settings_template.py"
else:
secrets_path = "/etc/zulip/zulip-secrets.conf"
settings_path = "/etc/zulip/settings.py"
settings_comments_path = "/etc/zulip/settings.py"
# We can't use request.client here because we might not be using
# an auth decorator that sets it, but we can call its helper to
# get the same result.
platform = get_client_name(request, True)
context = {
'root_domain_landing_page': settings.ROOT_DOMAIN_LANDING_PAGE,
'custom_logo_url': settings.CUSTOM_LOGO_URL,
'register_link_disabled': register_link_disabled,
'login_link_disabled': login_link_disabled,
'terms_of_service': settings.TERMS_OF_SERVICE,
'privacy_policy': settings.PRIVACY_POLICY,
'login_url': settings.HOME_NOT_LOGGED_IN,
'only_sso': settings.ONLY_SSO,
'external_host': settings.EXTERNAL_HOST,
'external_uri_scheme': settings.EXTERNAL_URI_SCHEME,
'realm_uri': realm_uri,
'realm_name': realm_name,
'realm_icon': realm_icon,
'root_domain_uri': settings.ROOT_DOMAIN_URI,
'apps_page_url': apps_page_url,
'open_realm_creation': settings.OPEN_REALM_CREATION,
'development_environment': settings.DEVELOPMENT,
'support_email': FromAddress.SUPPORT,
'find_team_link_disabled': find_team_link_disabled,
'password_min_length': settings.PASSWORD_MIN_LENGTH,
'password_min_guesses': settings.PASSWORD_MIN_GUESSES,
'jitsi_server_url': settings.JITSI_SERVER_URL,
'zulip_version': ZULIP_VERSION,
'user_is_authenticated': user_is_authenticated,
'settings_path': settings_path,
'secrets_path': secrets_path,
'settings_comments_path': settings_comments_path,
'platform': platform,
'allow_search_engine_indexing': allow_search_engine_indexing,
}
return context
def login_context(request: HttpRequest) -> Dict[str, Any]:
realm = get_realm_from_request(request)
if realm is None:
realm_description = None
realm_invite_required = False
else:
realm_description = get_realm_rendered_description(realm)
realm_invite_required = realm.invite_required
context = {
'realm_invite_required': realm_invite_required,
'realm_description': realm_description,
'require_email_format_usernames': require_email_format_usernames(realm),
'password_auth_enabled': password_auth_enabled(realm),
'any_oauth_backend_enabled': any_oauth_backend_enabled(realm),
'two_factor_authentication_enabled': settings.TWO_FACTOR_AUTHENTICATION_ENABLED,
} # type: Dict[str, Any]
# Add the keys for our standard authentication backends.
no_auth_enabled = True
social_backends = []
for auth_backend_name in AUTH_BACKEND_NAME_MAP:
name_lower = auth_backend_name.lower()
key = "%s_auth_enabled" % (name_lower,)
is_enabled = auth_enabled_helper([auth_backend_name], realm)
context[key] = is_enabled
if is_enabled:
no_auth_enabled = False
# Now add the enabled social backends to the social_backends
# list used to generate buttons for login/register pages.
backend = AUTH_BACKEND_NAME_MAP[auth_backend_name]
if not is_enabled or backend not in SOCIAL_AUTH_BACKENDS:
continue
social_backends.append({
'name': backend.name,
'display_name': backend.auth_backend_name,
'login_url': reverse('login-social', args=(backend.name,)),
'signup_url': reverse('signup-social', args=(backend.name,)),
'sort_order': backend.sort_order,
})
context['social_backends'] = sorted(social_backends, key=lambda x: x['sort_order'], reverse=True)
context['no_auth_enabled'] = no_auth_enabled
return context
def latest_info_context() -> Dict[str, str]:
context = {
'latest_release_version': LATEST_RELEASE_VERSION,
'latest_major_version': LATEST_MAJOR_VERSION,
'latest_release_announcement': LATEST_RELEASE_ANNOUNCEMENT,
}
return context