2016-10-06 01:42:24 +02:00
|
|
|
import os
|
2017-11-10 23:44:00 +01:00
|
|
|
import pwd
|
2020-06-08 03:46:26 +02:00
|
|
|
from typing import Optional, Set, Tuple
|
2016-06-17 02:30:48 +02:00
|
|
|
|
2020-06-27 02:37:49 +02:00
|
|
|
from six.moves.urllib.parse import SplitResult
|
|
|
|
|
2020-06-08 03:24:49 +02:00
|
|
|
ZULIP_ADMINISTRATOR = "desdemona+admin@zulip.com"
|
|
|
|
|
2019-02-15 20:23:54 +01:00
|
|
|
# We want LOCAL_UPLOADS_DIR to be an absolute path so that code can
|
2020-06-10 11:11:00 +02:00
|
|
|
# chdir without having problems accessing it. Unfortunately, this
|
|
|
|
# means we need a duplicate definition of DEPLOY_ROOT with the one in
|
|
|
|
# settings.py.
|
|
|
|
DEPLOY_ROOT = os.path.realpath(os.path.dirname(os.path.dirname(__file__)))
|
2019-02-15 20:23:54 +01:00
|
|
|
LOCAL_UPLOADS_DIR = os.path.join(DEPLOY_ROOT, 'var/uploads')
|
|
|
|
|
2020-04-25 05:07:50 +02:00
|
|
|
# We assume dev droplets are the only places where
|
|
|
|
# users use zulipdev as the user.
|
|
|
|
IS_DEV_DROPLET = pwd.getpwuid(os.getuid()).pw_name == 'zulipdev'
|
2020-04-24 20:47:22 +02:00
|
|
|
|
2017-10-25 01:58:05 +02:00
|
|
|
FORWARD_ADDRESS_CONFIG_FILE = "var/forward_address.ini"
|
2016-10-27 23:14:23 +02:00
|
|
|
# Check if test_settings.py set EXTERNAL_HOST.
|
2019-07-24 02:21:03 +02:00
|
|
|
external_host_env = os.getenv('EXTERNAL_HOST')
|
|
|
|
if external_host_env is None:
|
2020-04-24 20:47:22 +02:00
|
|
|
if IS_DEV_DROPLET:
|
2020-04-27 20:35:16 +02:00
|
|
|
# For our droplets, we use the hostname (eg github_username.zulipdev.org) by default.
|
|
|
|
EXTERNAL_HOST = os.uname()[1].lower() + ":9991"
|
2017-11-10 23:44:00 +01:00
|
|
|
else:
|
|
|
|
# For local development environments, we use localhost by
|
|
|
|
# default, via the "zulipdev.com" hostname.
|
|
|
|
EXTERNAL_HOST = 'zulipdev.com:9991'
|
2017-11-11 21:32:33 +01:00
|
|
|
# Serve the main dev realm at the literal name "localhost",
|
|
|
|
# so it works out of the box even when not on the Internet.
|
|
|
|
REALM_HOSTS = {
|
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
|
|
|
'zulip': 'localhost:9991',
|
2017-11-11 21:32:33 +01:00
|
|
|
}
|
2018-03-13 13:20:59 +01:00
|
|
|
else:
|
2019-07-24 02:21:03 +02:00
|
|
|
EXTERNAL_HOST = external_host_env
|
2018-03-13 13:20:59 +01:00
|
|
|
REALM_HOSTS = {
|
|
|
|
'zulip': EXTERNAL_HOST,
|
|
|
|
}
|
|
|
|
|
2020-06-27 02:37:49 +02:00
|
|
|
# TODO: Replace with scripts.lib.zulip_tools.deport when this no longer needs to
|
|
|
|
# be Python 2 compatible for zthumbor.
|
|
|
|
r = SplitResult("", EXTERNAL_HOST, "", "", "")
|
|
|
|
assert r.hostname is not None
|
|
|
|
EXTERNAL_HOST_WITHOUT_PORT = "[" + r.hostname + "]" if ":" in r.hostname else r.hostname
|
|
|
|
|
2016-07-19 14:35:08 +02:00
|
|
|
ALLOWED_HOSTS = ['*']
|
2017-03-18 01:58:45 +01:00
|
|
|
|
|
|
|
# Uncomment extra backends if you want to test with them. Note that
|
|
|
|
# for Google and GitHub auth you'll need to do some pre-setup.
|
2020-06-10 11:11:55 +02:00
|
|
|
AUTHENTICATION_BACKENDS = (
|
2017-03-18 01:58:45 +01:00
|
|
|
'zproject.backends.DevAuthBackend',
|
|
|
|
'zproject.backends.EmailAuthBackend',
|
2017-08-16 18:19:03 +02:00
|
|
|
'zproject.backends.GitHubAuthBackend',
|
2019-02-02 16:51:26 +01:00
|
|
|
'zproject.backends.GoogleAuthBackend',
|
2019-09-29 06:32:56 +02:00
|
|
|
'zproject.backends.SAMLAuthBackend',
|
2018-10-05 14:32:02 +02:00
|
|
|
# 'zproject.backends.AzureADAuthBackend',
|
2020-01-31 18:19:53 +01:00
|
|
|
'zproject.backends.GitLabAuthBackend',
|
2020-06-09 12:04:21 +02:00
|
|
|
'zproject.backends.AppleAuthBackend',
|
2020-06-10 11:11:55 +02:00
|
|
|
) # type: Tuple[str, ...]
|
2017-03-18 01:58:45 +01:00
|
|
|
|
2016-06-17 02:30:48 +02:00
|
|
|
EXTERNAL_URI_SCHEME = "http://"
|
2020-06-27 02:37:49 +02:00
|
|
|
EMAIL_GATEWAY_PATTERN = "%s@" + EXTERNAL_HOST_WITHOUT_PORT
|
2016-06-17 02:30:48 +02:00
|
|
|
NOTIFICATION_BOT = "notification-bot@zulip.com"
|
|
|
|
ERROR_BOT = "error-bot@zulip.com"
|
|
|
|
EMAIL_GATEWAY_BOT = "emailgateway@zulip.com"
|
2017-10-19 04:09:53 +02:00
|
|
|
PHYSICAL_ADDRESS = "Zulip Headquarters, 123 Octo Stream, South Pacific Ocean"
|
2020-06-09 12:24:32 +02:00
|
|
|
STAFF_SUBDOMAIN = "zulip"
|
2018-09-25 12:24:11 +02:00
|
|
|
EXTRA_INSTALLED_APPS = ["zilencer", "analytics", "corporate"]
|
2016-06-17 02:30:48 +02:00
|
|
|
# Disable Camo in development
|
|
|
|
CAMO_URI = ''
|
2017-12-05 06:31:21 +01:00
|
|
|
|
2016-06-03 01:02:58 +02:00
|
|
|
OPEN_REALM_CREATION = True
|
2017-12-05 06:31:21 +01:00
|
|
|
INVITES_MIN_USER_AGE_DAYS = 0
|
2016-06-03 01:02:58 +02:00
|
|
|
|
2017-07-14 16:44:07 +02:00
|
|
|
EMBEDDED_BOTS_ENABLED = True
|
|
|
|
|
2016-07-19 06:44:48 +02:00
|
|
|
SAVE_FRONTEND_STACKTRACES = True
|
2016-08-12 20:09:38 +02:00
|
|
|
EVENT_LOGS_ENABLED = True
|
2017-12-01 02:16:30 +01:00
|
|
|
STAGING_ERROR_NOTIFICATIONS = True
|
|
|
|
|
2017-07-09 01:41:52 +02:00
|
|
|
SYSTEM_ONLY_REALMS = set() # type: Set[str]
|
2016-04-24 17:08:51 +02:00
|
|
|
USING_PGROONGA = True
|
2016-10-17 18:11:16 +02:00
|
|
|
# Flush cache after migration.
|
|
|
|
POST_MIGRATION_CACHE_FLUSHING = True # type: bool
|
2016-10-27 12:06:44 +02:00
|
|
|
|
2017-03-22 21:08:56 +01:00
|
|
|
# Don't require anything about password strength in development
|
|
|
|
PASSWORD_MIN_LENGTH = 0
|
passwords: Express the quality threshold as guesses required.
The original "quality score" was invented purely for populating
our password-strength progress bar, and isn't expressed in terms
that are particularly meaningful. For configuration and the core
accept/reject logic, it's better to use units that are readily
understood. Switch to those.
I considered using "bits of entropy", defined loosely as the log
of this number, but both the zxcvbn paper and the linked CACM
article (which I recommend!) are written in terms of the number
of guesses. And reading (most of) those two papers made me
less happy about referring to "entropy" in our terminology.
I already knew that notion was a little fuzzy if looked at
too closely, and I gained a better appreciation of how it's
contributed to confusion in discussing password policies and
to adoption of perverse policies that favor "Password1!" over
"derived unusual ravioli raft". So, "guesses" it is.
And although the log is handy for some analysis purposes
(certainly for a graph like those in the zxcvbn paper), it adds
a layer of abstraction, and I think makes it harder to think
clearly about attacks, especially in the online setting. So
just use the actual number, and if someone wants to set a
gigantic value, they will have the pleasure of seeing just
how many digits are involved.
(Thanks to @YJDave for a prototype that the code changes in this
commit are based on.)
2017-10-03 19:48:06 +02:00
|
|
|
PASSWORD_MIN_GUESSES = 0
|
2017-10-25 01:58:05 +02:00
|
|
|
|
|
|
|
# SMTP settings for forwarding emails sent in development
|
|
|
|
# environment to an email account.
|
|
|
|
EMAIL_HOST = ""
|
|
|
|
EMAIL_HOST_USER = ""
|
2017-07-12 09:36:51 +02:00
|
|
|
|
|
|
|
# Two factor authentication: Use the fake backend for development.
|
|
|
|
TWO_FACTOR_CALL_GATEWAY = 'two_factor.gateways.fake.Fake'
|
|
|
|
TWO_FACTOR_SMS_GATEWAY = 'two_factor.gateways.fake.Fake'
|
2018-02-12 18:18:03 +01:00
|
|
|
|
|
|
|
# Make sendfile use django to serve files in development
|
2020-02-05 07:27:45 +01:00
|
|
|
SENDFILE_BACKEND = 'django_sendfile.backends.development'
|
2018-03-18 20:59:10 +01:00
|
|
|
|
|
|
|
# Set this True to send all hotspots in development
|
|
|
|
ALWAYS_SEND_ALL_HOTSPOTS = False # type: bool
|
2018-03-08 09:37:09 +01:00
|
|
|
|
2018-08-04 01:44:49 +02:00
|
|
|
# FAKE_LDAP_MODE supports using a fake LDAP database in the
|
|
|
|
# development environment, without needing an LDAP server!
|
|
|
|
#
|
|
|
|
# Three modes are allowed, and each will setup Zulip and the fake LDAP
|
|
|
|
# database in a way appropriate for the corresponding mode described
|
2018-09-27 22:30:29 +02:00
|
|
|
# in https://zulip.readthedocs.io/en/latest/production/authentication-methods.html#ldap-including-active-directory
|
2018-08-04 01:44:49 +02:00
|
|
|
# (A) If users' email addresses are in LDAP and used as username.
|
|
|
|
# (B) If LDAP only has usernames but email addresses are of the form
|
|
|
|
# username@example.com
|
|
|
|
# (C) If LDAP usernames are completely unrelated to email addresses.
|
|
|
|
#
|
2018-09-27 22:30:29 +02:00
|
|
|
# Fake LDAP data has e.g. ("ldapuser1", "ldapuser1@zulip.com") for username/email.
|
2018-08-04 01:44:49 +02:00
|
|
|
FAKE_LDAP_MODE = None # type: Optional[str]
|
2018-08-18 02:35:19 +02:00
|
|
|
# FAKE_LDAP_NUM_USERS = 8
|
2018-08-04 01:44:49 +02:00
|
|
|
|
|
|
|
if FAKE_LDAP_MODE:
|
2019-11-07 06:57:09 +01:00
|
|
|
import ldap
|
|
|
|
from django_auth_ldap.config import LDAPSearch
|
2020-06-11 00:54:34 +02:00
|
|
|
|
2019-06-17 22:11:29 +02:00
|
|
|
# To understand these parameters, read the docs in
|
|
|
|
# prod_settings_template.py and on ReadTheDocs.
|
2018-08-04 01:44:49 +02:00
|
|
|
LDAP_APPEND_DOMAIN = None
|
2019-11-07 06:57:09 +01:00
|
|
|
AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=users,dc=zulip,dc=com",
|
|
|
|
ldap.SCOPE_ONELEVEL, "(uid=%(user)s)")
|
|
|
|
AUTH_LDAP_REVERSE_EMAIL_SEARCH = LDAPSearch("ou=users,dc=zulip,dc=com",
|
|
|
|
ldap.SCOPE_ONELEVEL, "(email=%(email)s)")
|
2018-08-04 01:44:49 +02:00
|
|
|
|
|
|
|
if FAKE_LDAP_MODE == 'a':
|
2019-11-07 06:57:09 +01:00
|
|
|
AUTH_LDAP_REVERSE_EMAIL_SEARCH = LDAPSearch("ou=users,dc=zulip,dc=com",
|
|
|
|
ldap.SCOPE_ONELEVEL, "(uid=%(email)s)")
|
|
|
|
AUTH_LDAP_USERNAME_ATTR = "uid"
|
2019-06-17 22:11:29 +02:00
|
|
|
AUTH_LDAP_USER_ATTR_MAP = {
|
|
|
|
"full_name": "cn",
|
|
|
|
"avatar": "thumbnailPhoto",
|
|
|
|
# This won't do much unless one changes the fact that
|
|
|
|
# all users have LDAP_USER_ACCOUNT_CONTROL_NORMAL in
|
|
|
|
# zerver/lib/dev_ldap_directory.py
|
|
|
|
"userAccountControl": "userAccountControl",
|
|
|
|
}
|
2018-08-04 01:44:49 +02:00
|
|
|
elif FAKE_LDAP_MODE == 'b':
|
|
|
|
LDAP_APPEND_DOMAIN = 'zulip.com'
|
2019-06-17 22:11:29 +02:00
|
|
|
AUTH_LDAP_USER_ATTR_MAP = {
|
|
|
|
"full_name": "cn",
|
|
|
|
"avatar": "jpegPhoto",
|
|
|
|
"custom_profile_field__birthday": "birthDate",
|
|
|
|
"custom_profile_field__phone_number": "phoneNumber",
|
|
|
|
}
|
2018-08-04 01:44:49 +02:00
|
|
|
elif FAKE_LDAP_MODE == 'c':
|
2019-11-07 06:57:09 +01:00
|
|
|
AUTH_LDAP_USERNAME_ATTR = "uid"
|
2019-07-24 08:13:55 +02:00
|
|
|
LDAP_EMAIL_ATTR = 'email'
|
2019-06-17 22:11:29 +02:00
|
|
|
AUTH_LDAP_USER_ATTR_MAP = {
|
|
|
|
"full_name": "cn",
|
|
|
|
}
|
2019-08-10 00:30:35 +02:00
|
|
|
AUTHENTICATION_BACKENDS += ('zproject.backends.ZulipLDAPAuthBackend',)
|
2018-08-04 01:44:49 +02:00
|
|
|
|
2018-03-08 09:37:09 +01:00
|
|
|
THUMBOR_URL = 'http://127.0.0.1:9995'
|
2019-01-04 16:22:04 +01:00
|
|
|
THUMBNAIL_IMAGES = True
|
2018-07-14 11:32:08 +02:00
|
|
|
|
2019-11-13 02:53:01 +01:00
|
|
|
SEARCH_PILLS_ENABLED = bool(os.getenv('SEARCH_PILLS_ENABLED', False))
|
2018-08-09 21:38:22 +02:00
|
|
|
|
|
|
|
BILLING_ENABLED = True
|
2020-05-21 16:36:14 +02:00
|
|
|
LANDING_PAGE_NAVBAR_MESSAGE = None
|
2019-07-23 02:34:59 +02:00
|
|
|
|
|
|
|
# Test Custom TOS template rendering
|
|
|
|
TERMS_OF_SERVICE = 'corporate/terms.md'
|
2019-10-07 06:16:51 +02:00
|
|
|
|
|
|
|
# Our run-dev.py proxy uses X-Forwarded-Port to communicate to Django
|
|
|
|
# that the request is actually on port 9991, not port 9992 (the Django
|
|
|
|
# server's own port); this setting tells Django to read that HTTP
|
|
|
|
# header. Important for SAML authentication in the development
|
|
|
|
# environment.
|
|
|
|
USE_X_FORWARDED_PORT = True
|
2019-09-29 06:32:56 +02:00
|
|
|
|
|
|
|
# Override the default SAML entity ID
|
2020-04-30 14:46:19 +02:00
|
|
|
SOCIAL_AUTH_SAML_SP_ENTITY_ID = "http://localhost:9991"
|
2020-01-02 23:19:27 +01:00
|
|
|
|
|
|
|
MEMCACHED_USERNAME = None
|