mirror of
https://github.com/zulip/zulip.git
synced 2026-07-15 21:03:26 +08:00
We treat these exceptions the same way we treat fatal errors: report the error message to our server and then allow the exception to reach the top level. We could also override document.onerror, but don't. There are a couple of ramifications of this: * Exceptions caused by event handlers directly attached to DOM elements aren't handled * Exceptions caused by code at the top level that triggers an error (such as parse errors in our Javascript files) aren't handled The reason we don't override document.onerror is because the document.onerror handler has a limited interface and doesn't receive the exception object. It only gets the message, file, and line number of the error. Additionally, exceptions that we allow to propogate out of blueslip trigger an onerror event when they're never caught. In order to avoid handling the error twice (once by blueslip and once by the onerror handler), we'd have to encode the fact that the error has already been handled in the error message, which is pretty ugly. (imported from commit 7f049ae519dc198a9f7cfd41fd5dd18e584bd061)
432 lines
14 KiB
Python
432 lines
14 KiB
Python
# Django settings for humbug project.
|
|
import os
|
|
import platform
|
|
|
|
from zephyr.openid import openid_failure_handler
|
|
|
|
DEPLOYED = (('humbughq.com' in platform.node())
|
|
or os.path.exists('/etc/humbug-server'))
|
|
STAGING_DEPLOYED = (platform.node() == 'staging.humbughq.com')
|
|
|
|
DEBUG = not DEPLOYED
|
|
TEMPLATE_DEBUG = DEBUG
|
|
TEST_SUITE = False
|
|
|
|
if DEBUG:
|
|
INTERNAL_IPS = ('127.0.0.1',)
|
|
|
|
ADMINS = (
|
|
('Devel', 'devel@humbughq.com'),
|
|
)
|
|
|
|
MANAGERS = ADMINS
|
|
|
|
DATABASES = {"default": {
|
|
'ENGINE': 'django.db.backends.postgresql_psycopg2',
|
|
'NAME': 'humbug',
|
|
'USER': 'humbug',
|
|
'PASSWORD': '', # Authentication done via certificates
|
|
'HOST': '10.254.4.99',
|
|
'SCHEMA': 'humbug',
|
|
'OPTIONS': {
|
|
# Note that 'verify-ca' only checks that the server certificate was
|
|
# signed by a trusted root. You need 'verify-full' if you want to
|
|
# check that the server's hostname in the certificate matches the
|
|
# host you connect to.
|
|
#
|
|
# We don't currently do 'verify-full' because the web servers
|
|
# connect to the database using its AWS internal IP address, which
|
|
# doesn't reverse-resolve to its hostname. And because the
|
|
# database's certificate is for its hostname instead of its internal
|
|
# IP address, the frontend can't verify that the certificate is for
|
|
# the correct machine. This can be solved by running DNS
|
|
# internally. For now, 'verify-ca' is probably sufficient because
|
|
# the certificates are signed by our own CA.
|
|
'sslmode': 'verify-ca',
|
|
},
|
|
},
|
|
}
|
|
|
|
if not DEPLOYED:
|
|
# We can delete this if statement and the whole else clause below
|
|
# once everyone is off sqlite.
|
|
if False:
|
|
DATABASES["default"].update({
|
|
'PASSWORD': 'xxxxxxxxxxxx',
|
|
'HOST': 'localhost',
|
|
'OPTIONS': {}
|
|
})
|
|
else:
|
|
DATABASES = {
|
|
'default': {
|
|
'ENGINE': 'django.db.backends.sqlite3',
|
|
'NAME': 'zephyrdb',
|
|
'USER': '', # Not used with sqlite3.
|
|
'PASSWORD': '', # Not used with sqlite3.
|
|
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
|
|
'PORT': '', # Set to empty string for default. Not used with sqlite3.
|
|
'OPTIONS': {
|
|
'timeout': 20,
|
|
},
|
|
},
|
|
}
|
|
|
|
# Local time zone for this installation. Choices can be found here:
|
|
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
|
# although not all choices may be available on all operating systems.
|
|
# In a Windows environment this must be set to your system time zone.
|
|
TIME_ZONE = 'America/New_York'
|
|
|
|
# Language code for this installation. All choices can be found here:
|
|
# http://www.i18nguy.com/unicode/language-identifiers.html
|
|
LANGUAGE_CODE = 'en-us'
|
|
|
|
# The ID, as an integer, of the current site in the django_site database table.
|
|
# This is used so that application data can hook into specific site(s) and a
|
|
# single database can manage content for multiple sites.
|
|
#
|
|
# We set this site's domain to 'humbughq.com' in populate_db.
|
|
SITE_ID = 1
|
|
|
|
# If you set this to False, Django will make some optimizations so as not
|
|
# to load the internationalization machinery.
|
|
USE_I18N = True
|
|
|
|
# If you set this to False, Django will not format dates, numbers and
|
|
# calendars according to the current locale.
|
|
USE_L10N = True
|
|
|
|
# If you set this to False, Django will not use timezone-aware datetimes.
|
|
USE_TZ = True
|
|
|
|
SITE_ROOT = os.path.realpath(os.path.dirname(__file__))
|
|
TEMPLATE_DIRS = ( os.path.join(SITE_ROOT, '..', 'templates'),)
|
|
|
|
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
|
|
# trailing slash.
|
|
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
|
|
MEDIA_URL = ''
|
|
|
|
# Make this unique, and don't share it with anybody.
|
|
SECRET_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
|
|
|
# A fixed salt used for hashing in certain places, e.g. email-based
|
|
# username generation.
|
|
HASH_SALT = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
|
|
|
# Tell the browser to never send our cookies without encryption, e.g.
|
|
# when executing the initial http -> https redirect.
|
|
#
|
|
# Turn it off for local testing because we don't have SSL.
|
|
if DEPLOYED:
|
|
SESSION_COOKIE_SECURE = True
|
|
CSRF_COOKIE_SECURE = True
|
|
|
|
# Prevent Javascript from reading the CSRF token from cookies. Our code gets
|
|
# the token from the DOM, which means malicious code could too. But hiding the
|
|
# cookie will slow down some attackers.
|
|
CSRF_COOKIE_PATH = '/;HttpOnly'
|
|
|
|
# Used just for generating initial passwords and API keys.
|
|
INITIAL_PASSWORD_SALT = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
|
INITIAL_API_KEY_SALT = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
|
|
|
# A shared secret, used to authenticate different parts of the app to each other.
|
|
# FIXME: store this password more securely
|
|
SHARED_SECRET = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
|
|
|
# Base URL of the Tornado server
|
|
# We set it to None when running backend tests or populate_db.
|
|
# We override the port number when running frontend tests.
|
|
TORNADO_SERVER = 'http://localhost:9993'
|
|
RUNNING_INSIDE_TORNADO = False
|
|
|
|
# Make redirects work properly behind a reverse proxy
|
|
USE_X_FORWARDED_HOST = True
|
|
|
|
# List of callables that know how to import templates from various sources.
|
|
TEMPLATE_LOADERS = (
|
|
'django.template.loaders.filesystem.Loader',
|
|
'django.template.loaders.app_directories.Loader',
|
|
)
|
|
|
|
MIDDLEWARE_CLASSES = (
|
|
# Our logging middleware should be the first middleware item.
|
|
'zephyr.middleware.LogRequests',
|
|
'zephyr.middleware.JsonErrorHandler',
|
|
'django.middleware.common.CommonMiddleware',
|
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
|
'django.middleware.csrf.CsrfViewMiddleware',
|
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
|
)
|
|
|
|
AUTHENTICATION_BACKENDS = ('humbug.backends.EmailAuthBackend',
|
|
'humbug.backends.GoogleBackend')
|
|
|
|
TEST_RUNNER = 'zephyr.tests.Runner'
|
|
|
|
ROOT_URLCONF = 'humbug.urls'
|
|
|
|
# Python dotted path to the WSGI application used by Django's runserver.
|
|
WSGI_APPLICATION = 'humbug.wsgi.application'
|
|
|
|
INSTALLED_APPS = (
|
|
'django.contrib.auth',
|
|
'humbug.authhack',
|
|
'django.contrib.contenttypes',
|
|
'django.contrib.sessions',
|
|
'django.contrib.sites',
|
|
'django.contrib.staticfiles',
|
|
'south',
|
|
'django_openid_auth',
|
|
'jstemplate',
|
|
'confirmation',
|
|
'pipeline',
|
|
'zephyr',
|
|
)
|
|
|
|
|
|
# Static files and minification
|
|
|
|
STATIC_URL = '/static/'
|
|
|
|
STATICFILES_FINDERS = (
|
|
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
|
|
)
|
|
|
|
# PipelineCachedStorage inserts a file hash into filenames,
|
|
# to prevent the browser from using stale files from cache.
|
|
#
|
|
# Unlike PipelineStorage, it requires the files to exist in
|
|
# STATIC_ROOT even for dev servers. So we only use
|
|
# PipelineCachedStorage when not DEBUG.
|
|
|
|
if DEBUG:
|
|
STATICFILES_STORAGE = 'pipeline.storage.PipelineStorage'
|
|
else:
|
|
STATICFILES_STORAGE = 'pipeline.storage.PipelineCachedStorage'
|
|
|
|
STATIC_ROOT = 'prod-static/collected'
|
|
|
|
# This is the default behavior from Pipeline, but we set it
|
|
# here so that urls.py can read it.
|
|
PIPELINE = not DEBUG
|
|
|
|
# To use minified files in dev, set PIPELINE = True.
|
|
#
|
|
# You will need to run ./tools/update-prod-static after
|
|
# changing static files.
|
|
|
|
PIPELINE_CSS = {
|
|
'activity': {
|
|
'source_filenames': ('styles/activity.css',),
|
|
'output_filename': 'min/activity.css'
|
|
},
|
|
'portico': {
|
|
'source_filenames': (
|
|
'styles/portico.css',
|
|
'styles/pygments.css',
|
|
),
|
|
'output_filename': 'min/portico.css'
|
|
},
|
|
'app': {
|
|
'source_filenames': (
|
|
'styles/zephyr.css',
|
|
'styles/pygments.css',
|
|
),
|
|
'output_filename': 'min/app.css'
|
|
},
|
|
}
|
|
|
|
PIPELINE_JS = {
|
|
'common': {
|
|
'source_filenames': ('js/common.js',),
|
|
'output_filename': 'min/common.js'
|
|
},
|
|
'signup': {
|
|
'source_filenames': ('js/signup.js',),
|
|
'output_filename': 'min/signup.js'
|
|
},
|
|
'app_debug': {
|
|
'source_filenames': ('js/debug.js',),
|
|
'output_filename': 'min/app_debug.js'
|
|
},
|
|
'app': {
|
|
'source_filenames': (
|
|
'js/blueslip.js',
|
|
'js/util.js',
|
|
'js/setup.js',
|
|
'js/rows.js',
|
|
'js/narrow.js',
|
|
'js/reload.js',
|
|
'js/notifications_bar.js',
|
|
'js/compose.js',
|
|
'js/subs.js',
|
|
'js/ui.js',
|
|
'js/typeahead_helper.js',
|
|
'js/search.js',
|
|
'js/composebox_typeahead.js',
|
|
'js/hotkey.js',
|
|
'js/notifications.js',
|
|
'js/hashchange.js',
|
|
'js/invite.js',
|
|
'js/message_list.js',
|
|
'js/zephyr.js',
|
|
'js/activity.js',
|
|
'js/colorspace.js',
|
|
'js/timerender.js',
|
|
'js/tutorial.js',
|
|
),
|
|
'output_filename': 'min/app.js'
|
|
},
|
|
}
|
|
|
|
PIPELINE_CSS_COMPRESSOR = 'pipeline.compressors.yui.YUICompressor'
|
|
PIPELINE_JS_COMPRESSOR = 'pipeline.compressors.yui.YUICompressor'
|
|
PIPELINE_YUI_BINARY = '/usr/bin/env yui-compressor'
|
|
|
|
# Disable stuffing the entire JavaScript codebase inside an anonymous function.
|
|
# We need modules to be externally visible, so that methods can be called from
|
|
# event handlers defined in HTML.
|
|
PIPELINE_DISABLE_WRAPPER = True
|
|
|
|
|
|
USING_RABBITMQ = DEPLOYED
|
|
# This password also appears in servers/configure-rabbitmq
|
|
RABBITMQ_PASSWORD = 'xxxxxxxxxxxxxxxx'
|
|
|
|
# Caching
|
|
if DEPLOYED:
|
|
CACHES = {
|
|
'default': {
|
|
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
|
|
'LOCATION': '127.0.0.1:11211',
|
|
'TIMEOUT': 3600
|
|
},
|
|
}
|
|
SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
|
|
else:
|
|
CACHES = { 'default': {
|
|
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
|
|
'LOCATION': 'humbug-default-local-cache',
|
|
'TIMEOUT': 3600,
|
|
'OPTIONS': {
|
|
'MAX_ENTRIES': 100000
|
|
}
|
|
} }
|
|
CACHES['database'] = {
|
|
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
|
|
'LOCATION': 'third_party_api_results',
|
|
# Basically never timeout. Setting to 0 isn't guaranteed
|
|
# to work, see https://code.djangoproject.com/ticket/9595
|
|
'TIMEOUT': 2000000000,
|
|
'OPTIONS': {
|
|
'MAX_ENTRIES': 100000000,
|
|
'CULL_FREQUENCY': 10,
|
|
},
|
|
}
|
|
|
|
LOGGING = {
|
|
'version': 1,
|
|
'disable_existing_loggers': True,
|
|
'formatters': {
|
|
'default': {
|
|
'format': '%(asctime)s %(levelname)-8s %(message)s'
|
|
}
|
|
},
|
|
'filters': {
|
|
'HumbugLimiter': {
|
|
'()': 'humbug.ratelimit.HumbugLimiter',
|
|
},
|
|
'EmailLimiter': {
|
|
'()': 'humbug.ratelimit.EmailLimiter',
|
|
},
|
|
'require_debug_false': {
|
|
'()': 'django.utils.log.RequireDebugFalse',
|
|
}
|
|
},
|
|
'handlers': {
|
|
'inapp': {
|
|
'level': 'ERROR',
|
|
'class': 'zephyr.handlers.AdminHumbugHandler',
|
|
'filters': ['HumbugLimiter', 'require_debug_false'],
|
|
'formatter': 'default'
|
|
},
|
|
'console': {
|
|
'level': 'DEBUG',
|
|
'class': 'logging.StreamHandler',
|
|
'formatter': 'default'
|
|
},
|
|
'file': {
|
|
'level': 'DEBUG',
|
|
'class': 'logging.FileHandler',
|
|
'formatter': 'default',
|
|
'filename': 'server.log'
|
|
},
|
|
'mail_admins': {
|
|
'level': 'ERROR',
|
|
'class': 'zephyr.handlers.HumbugAdminEmailHandler',
|
|
'filters': ['EmailLimiter', 'require_debug_false'],
|
|
},
|
|
},
|
|
'loggers': {
|
|
'': {
|
|
'handlers': ['inapp', 'console', 'file', 'mail_admins'],
|
|
'level': 'INFO'
|
|
}
|
|
}
|
|
}
|
|
|
|
TEMPLATE_CONTEXT_PROCESSORS = (
|
|
'zephyr.context_processors.add_settings',
|
|
)
|
|
|
|
ACCOUNT_ACTIVATION_DAYS=7
|
|
EMAIL_USE_TLS = True
|
|
EMAIL_HOST = 'smtp.gmail.com'
|
|
EMAIL_HOST_USER = 'humbug@humbughq.com'
|
|
EMAIL_HOST_PASSWORD = 'xxxxxxxxxxxxxxxx'
|
|
EMAIL_PORT = 587
|
|
|
|
DEFAULT_FROM_EMAIL = "Humbug <humbug@humbughq.com>"
|
|
|
|
LOGIN_REDIRECT_URL='/'
|
|
OPENID_SSO_SERVER_URL = 'https://www.google.com/accounts/o8/id'
|
|
OPENID_CREATE_USERS = True
|
|
OPENID_RENDER_FAILURE = openid_failure_handler
|
|
|
|
EVENT_LOG_DIR = 'event_log'
|
|
|
|
# Polling timeout for get_updates, in milliseconds.
|
|
# We configure this here so that the client test suite can override it.
|
|
# The default is 55 seconds, to deal with crappy home wireless routers that
|
|
# kill "inactive" http connections.
|
|
#POLL_TIMEOUT = 55 * 1000
|
|
# As a stopgap to deal with increased load, increase the polling
|
|
# timeout to 5 minutes.
|
|
POLL_TIMEOUT = 5 * 60 * 1000
|
|
|
|
if DEPLOYED:
|
|
ALLOW_REGISTER = False
|
|
FULL_NAVBAR = False
|
|
HOME_NOT_LOGGED_IN = '/accounts/login'
|
|
else:
|
|
ALLOW_REGISTER = True
|
|
FULL_NAVBAR = True
|
|
HOME_NOT_LOGGED_IN = '/accounts/home'
|
|
|
|
# For testing, you may want to have emails be printed to the console.
|
|
if not DEPLOYED:
|
|
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
|
|
|
# Use fast password hashing for creating testing users when not
|
|
# DEPLOYED
|
|
PASSWORD_HASHERS = (
|
|
'django.contrib.auth.hashers.SHA1PasswordHasher',
|
|
'django.contrib.auth.hashers.PBKDF2PasswordHasher'
|
|
)
|
|
|
|
if DEPLOYED:
|
|
# Filter out user data
|
|
DEFAULT_EXCEPTION_REPORTER_FILTER = 'zephyr.filters.HumbugExceptionReporterFilter'
|