425 lines
14 KiB
Python
425 lines
14 KiB
Python
# This file is sourced by "execfile" from django settings
|
|
|
|
# Example of django settings.py:
|
|
#
|
|
# (...)
|
|
# PROJECT_NAME = 'name'
|
|
# INSTALLED_APPS += ('mellon',) # SAML2 authentication
|
|
# execfile('/usr/lib/hoho/debian_config_common.py')
|
|
# execfile('/etc/%s/settings.py' % PROJECT_NAME)
|
|
|
|
import os
|
|
import warnings
|
|
|
|
import django
|
|
from django.conf import global_settings
|
|
from django.core.exceptions import ImproperlyConfigured
|
|
|
|
import hobo.logger
|
|
|
|
DEBUG = False
|
|
|
|
SECRET_KEY = open('/etc/%s/secret' % PROJECT_NAME).read()
|
|
|
|
ADMINS = (('Tous', 'root@localhost'),)
|
|
|
|
EMAIL_SUBJECT_PREFIX = ''
|
|
|
|
# sockets default timeout can be set to a small value in another thread by kombu
|
|
# https://github.com/celery/kombu/issues/838
|
|
# This prevents sockets created in smtplib to rely on the default timeout
|
|
# by setting their timeout value to 10 seconds.
|
|
EMAIL_TIMEOUT = 10.0
|
|
|
|
# send the SMTP Date header of email messages in the local time zone
|
|
# (since Django 1.11)
|
|
EMAIL_USE_LOCALTIME = True
|
|
|
|
# For high availability installations with multiple instances of Publik
|
|
# components, one should disable cron jobs execution on secondary servers;
|
|
# set the following variable True disables all tenant_commands launched with
|
|
# option "--all-tenants".
|
|
DISABLE_CRON_JOBS = False
|
|
|
|
# mode for newly updated files
|
|
FILE_UPLOAD_PERMISSIONS = 0o644
|
|
|
|
DEBUG_LOG_PATH = '/var/log/%s/debug' % PROJECT_NAME
|
|
DEBUG_LOG_FORMAT = (
|
|
'%(asctime)s \x1f%(tenant)s \x1f%(ip)s \x1f%(user)r \x1f%(request_id)s \x1f'
|
|
'%(levelname)s \x1f%(name)s \x1f%(message)s'
|
|
)
|
|
|
|
DISABLE_GLOBAL_HANDLERS = os.environ.get('DISABLE_GLOBAL_HANDLERS') == '1'
|
|
|
|
|
|
LOGGING = {
|
|
'version': 1,
|
|
'disable_existing_loggers': True,
|
|
'filters': {
|
|
'require_debug_false': {
|
|
'()': 'django.utils.log.RequireDebugFalse',
|
|
},
|
|
'require_debug_true': {
|
|
'()': 'django.utils.log.RequireDebugTrue',
|
|
},
|
|
'request_context': {
|
|
'()': 'hobo.logger.RequestContextFilter',
|
|
},
|
|
'force_debug': {
|
|
'()': 'hobo.logger.ForceDebugFilter',
|
|
},
|
|
'debug_log': {
|
|
'()': 'hobo.logger.DebugLogFilter',
|
|
},
|
|
'clamp_to_warning': {
|
|
'()': 'hobo.logger.ClampLogLevel',
|
|
'level': 'WARNING',
|
|
},
|
|
},
|
|
'formatters': {
|
|
'syslog': {
|
|
'format': '%(application)s %(levelname)s %(tenant)s %(ip)s %(user)s %(request_id)s'
|
|
' %(message)s',
|
|
},
|
|
'debug': {
|
|
'format': DEBUG_LOG_FORMAT,
|
|
},
|
|
'syslog_no_filter': {
|
|
'format': '%(levelname)s %(message)s',
|
|
},
|
|
},
|
|
'handlers': {
|
|
'syslog': {
|
|
'level': 'INFO',
|
|
'address': '/dev/log',
|
|
'class': 'logging.handlers.SysLogHandler',
|
|
'formatter': 'syslog',
|
|
'filters': ['request_context'],
|
|
},
|
|
'syslog_no_filter': {
|
|
'level': 'INFO',
|
|
'address': '/dev/log',
|
|
'class': 'logging.handlers.SysLogHandler',
|
|
'formatter': 'syslog_no_filter',
|
|
},
|
|
'mail_admins': {
|
|
'level': 'ERROR',
|
|
'class': 'hobo.multitenant.log.AdminEmailHandler',
|
|
'include_html': True,
|
|
},
|
|
'null': {
|
|
'class': 'logging.NullHandler',
|
|
},
|
|
'debug': {
|
|
'level': 'DEBUG',
|
|
'class': 'hobo.logger.TimedRotatingFileHandler',
|
|
'formatter': 'debug',
|
|
'filename': DEBUG_LOG_PATH,
|
|
'when': 'midnight',
|
|
'backupCount': 1,
|
|
'interval': 1,
|
|
'filters': ['request_context', 'debug_log'],
|
|
},
|
|
},
|
|
'loggers': {
|
|
'django.db': {
|
|
# even when debugging seeing SQL queries is too much
|
|
'level': 'INFO',
|
|
},
|
|
'django': {
|
|
# Override Django default values
|
|
'handlers': [],
|
|
'level': 'NOTSET',
|
|
'propagate': True,
|
|
},
|
|
'django.server': {
|
|
# Override Django 1.8 default values
|
|
'handlers': [],
|
|
'level': 'NOTSET',
|
|
'propagate': True,
|
|
},
|
|
'django.request': {
|
|
# Override Django default values
|
|
'handlers': [],
|
|
'level': 'NOTSET',
|
|
'propagate': True,
|
|
},
|
|
'django.security': {
|
|
# Override Django default values
|
|
'handlers': [],
|
|
'level': 'NOTSET',
|
|
'propagate': True,
|
|
},
|
|
'django.security.SuspiciousFileOperation': {
|
|
'filters': ['clamp_to_warning'],
|
|
},
|
|
'django.security.DisallowedRedirect': {
|
|
'filters': ['clamp_to_warning'],
|
|
},
|
|
'django.core.exceptions.DisallowedHost': {
|
|
'filters': ['clamp_to_warning'],
|
|
},
|
|
'django.template': {
|
|
# too much logs on DEBUG level
|
|
'handlers': [],
|
|
'level': 'INFO',
|
|
'propagate': True,
|
|
},
|
|
# lasso has the bad habit of logging everything as errors
|
|
'Lasso': {
|
|
'filters': ['force_debug'],
|
|
},
|
|
'libxml2': {
|
|
'filters': ['force_debug'],
|
|
},
|
|
'libxmlsec': {
|
|
'filters': ['force_debug'],
|
|
},
|
|
# log py.warnings to syslog
|
|
'py.warnings': {
|
|
'handlers': [] if DISABLE_GLOBAL_HANDLERS else ['syslog_no_filter'],
|
|
'level': 'WARNING',
|
|
'propagate': False,
|
|
},
|
|
'': {
|
|
'level': 'DEBUG',
|
|
'filters': ['request_context'],
|
|
'handlers': ([] if DISABLE_GLOBAL_HANDLERS else ['syslog']) + ['mail_admins', 'debug'],
|
|
},
|
|
},
|
|
}
|
|
|
|
# Journald support
|
|
if os.path.exists('/run/systemd/journal/socket') and not DISABLE_GLOBAL_HANDLERS:
|
|
try:
|
|
from systemd import journal
|
|
except ImportError:
|
|
warnings.warn('journald will not be used directly, please install python-systemd')
|
|
else:
|
|
LOGGING['handlers']['journald'] = {
|
|
'level': 'INFO',
|
|
'class': 'hobo.journal.JournalHandler',
|
|
'filters': ['request_context'],
|
|
'formatter': 'syslog',
|
|
}
|
|
LOGGING['loggers']['']['handlers'].remove('syslog')
|
|
LOGGING['loggers']['']['handlers'].append('journald')
|
|
|
|
elif not os.path.exists('/dev/log') and not DISABLE_GLOBAL_HANDLERS:
|
|
# if three's no syslog (for example when building a docker image), remove
|
|
# those loggers.
|
|
LOGGING['loggers']['']['handlers'].remove('syslog')
|
|
LOGGING['loggers']['py.warnings']['handlers'].remove('syslog_no_filter')
|
|
del LOGGING['handlers']['syslog']
|
|
del LOGGING['handlers']['syslog_no_filter']
|
|
|
|
|
|
ETC_DIR = '/etc/%s' % PROJECT_NAME
|
|
VAR_DIR = '/var/lib/%s' % PROJECT_NAME
|
|
|
|
# collecstatic destination
|
|
STATIC_ROOT = os.path.join(VAR_DIR, 'collectstatic')
|
|
|
|
# template settings
|
|
if 'TEMPLATE_DEBUG' in globals():
|
|
# compatibility with django<1.10
|
|
if PROJECT_NAME != 'wcs':
|
|
TEMPLATE_LOADERS = (
|
|
'hobo.multitenant.template_loader.FilesystemLoader',
|
|
) + global_settings.TEMPLATE_LOADERS
|
|
|
|
if not 'TEMPLATE_CONTEXT_PROCESSORS' in globals():
|
|
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS
|
|
|
|
if not 'django.core.context_processors.request' in TEMPLATE_CONTEXT_PROCESSORS:
|
|
TEMPLATE_CONTEXT_PROCESSORS = (
|
|
'django.core.context_processors.request',
|
|
) + TEMPLATE_CONTEXT_PROCESSORS
|
|
TEMPLATE_CONTEXT_PROCESSORS = (
|
|
'hobo.context_processors.template_vars',
|
|
'hobo.context_processors.theme_base',
|
|
'hobo.context_processors.portal_agent_url',
|
|
) + TEMPLATE_CONTEXT_PROCESSORS
|
|
else:
|
|
assert len(TEMPLATES)
|
|
assert TEMPLATES[0]['BACKEND'] == 'django.template.backends.django.DjangoTemplates'
|
|
|
|
if not 'loaders' in TEMPLATES[0]['OPTIONS']:
|
|
TEMPLATES[0]['APP_DIRS'] = False
|
|
TEMPLATES[0]['OPTIONS']['loaders'] = [
|
|
'django.template.loaders.filesystem.Loader',
|
|
'django.template.loaders.app_directories.Loader',
|
|
]
|
|
if PROJECT_NAME != 'wcs':
|
|
TEMPLATES[0]['OPTIONS']['loaders'].insert(0, 'hobo.multitenant.template_loader.FilesystemLoader')
|
|
|
|
if not 'django.template.context_processors.request' in TEMPLATES[0]['OPTIONS']['context_processors']:
|
|
TEMPLATES[0]['OPTIONS']['context_processors'].insert(0, 'django.template.context_processors.request')
|
|
|
|
TEMPLATES[0]['OPTIONS']['context_processors'] = [
|
|
'hobo.context_processors.template_vars',
|
|
'hobo.context_processors.theme_base',
|
|
'hobo.context_processors.portal_agent_url',
|
|
] + TEMPLATES[0]['OPTIONS']['context_processors']
|
|
|
|
# needed by hobo.context_processors.theme_base:
|
|
# THEME_SKELETON_URL = 'https://www.example.net/__skeleton__'
|
|
|
|
# Browsers may ensure that cookies are only sent under an HTTPS connection
|
|
CSRF_COOKIE_SECURE = True
|
|
CSRF_COOKIE_HTTPONLY = True
|
|
SESSION_COOKIE_SECURE = True
|
|
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
|
|
SESSION_COOKIE_AGE = 36000 # 10h
|
|
|
|
CSRF_COOKIE_SAMESITE = None
|
|
# Apply sessionNotOnOrAfter on session expiration date
|
|
SESSION_ENGINE = 'mellon.sessions_backends.cached_db'
|
|
|
|
# make it easier to use runserver behind nginx as reverse proxy
|
|
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
|
|
|
|
if 'MIDDLEWARE' not in globals():
|
|
MIDDLEWARE = global_settings.MIDDLEWARE
|
|
|
|
MIDDLEWARE = (
|
|
'hobo.middleware.VersionMiddleware', # /__version__
|
|
'hobo.middleware.cors.CORSMiddleware',
|
|
) + MIDDLEWARE
|
|
|
|
if PROJECT_NAME != 'wcs':
|
|
MIDDLEWARE = ('hobo.middleware.RobotsTxtMiddleware',) + MIDDLEWARE
|
|
|
|
if PROJECT_NAME != 'wcs' and 'authentic2' not in INSTALLED_APPS:
|
|
MIDDLEWARE = MIDDLEWARE + (
|
|
'mellon.middleware.PassiveAuthenticationMiddleware',
|
|
'hobo.provisionning.middleware.ProvisionningMiddleware',
|
|
)
|
|
|
|
if 'authentic2' in INSTALLED_APPS:
|
|
MIDDLEWARE = MIDDLEWARE + ('hobo.agent.authentic2.middleware.ProvisionningMiddleware',)
|
|
|
|
# Allow big provisionning messages
|
|
DATA_UPLOAD_MAX_MEMORY_SIZE = 50_000_000
|
|
|
|
if PROJECT_NAME != 'wcs':
|
|
# multitenant adaptations
|
|
|
|
TENANT_BASE = os.path.join(VAR_DIR, 'tenants')
|
|
TENANT_MODEL = 'multitenant.Tenant'
|
|
|
|
MIDDLEWARE = (
|
|
'hobo.multitenant.middleware.TenantMiddleware',
|
|
'hobo.middleware.CookiesSameSiteFixMiddleware',
|
|
'hobo.middleware.debug.InternalIPMiddleware',
|
|
) + MIDDLEWARE
|
|
|
|
DATABASES = {
|
|
'default': {
|
|
'ENGINE': 'tenant_schemas.postgresql_backend',
|
|
'NAME': PROJECT_NAME.replace('-', '_'),
|
|
}
|
|
}
|
|
|
|
DATABASE_ROUTERS = ('tenant_schemas.routers.TenantSyncRouter',)
|
|
|
|
TENANT_SETTINGS_LOADERS = (
|
|
'hobo.multitenant.settings_loaders.TemplateVars',
|
|
'hobo.multitenant.settings_loaders.KnownServices',
|
|
'hobo.multitenant.settings_loaders.ThemeSettings',
|
|
'hobo.multitenant.settings_loaders.CORSSettings',
|
|
'hobo.multitenant.settings_loaders.SharedThemeSettings',
|
|
'hobo.multitenant.settings_loaders.Mellon',
|
|
'hobo.multitenant.settings_loaders.SiteBaseUrl',
|
|
'hobo.multitenant.settings_loaders.CookieNames',
|
|
'hobo.multitenant.settings_loaders.SettingsJSON',
|
|
'hobo.multitenant.settings_loaders.SettingsVars',
|
|
'hobo.multitenant.settings_loaders.BackofficeLoginHint',
|
|
)
|
|
|
|
# templates in <tenant>/templates
|
|
TENANT_TEMPLATE_DIRS = (TENANT_BASE,)
|
|
|
|
# /media in <tenant>/media
|
|
DEFAULT_FILE_STORAGE = 'hobo.multitenant.storage.TenantFileSystemStorage'
|
|
|
|
# cache by tenant
|
|
CACHES = {
|
|
'default': {
|
|
'BACKEND': 'hobo.multitenant.cache.TenantCache',
|
|
# add a real Django cache backend, with its parameters if needed
|
|
'REAL_BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
|
|
'LOCATION': '127.0.0.1:11211',
|
|
}
|
|
}
|
|
|
|
# haystack by tenant
|
|
HAYSTACK_CONNECTIONS = {
|
|
'default': {
|
|
'ENGINE': 'hobo.multitenant.haystack.WhooshEngine',
|
|
}
|
|
}
|
|
|
|
# multitenant SHARED_APPS/TENANT_APPS/INSTALLED_APPS organization
|
|
SHARED_APPS = ()
|
|
|
|
INSTALLED_APPS = ('hobo.agent.common',) + INSTALLED_APPS
|
|
|
|
TENANT_APPS = INSTALLED_APPS
|
|
|
|
INSTALLED_APPS = ('hobo.multitenant',) + INSTALLED_APPS
|
|
|
|
# SAML2: search IdP in <tenant>
|
|
if 'authentic2' not in INSTALLED_APPS:
|
|
MELLON_ADAPTER = ('hobo.multitenant.mellon.MellonAdapter',)
|
|
|
|
|
|
if 'authentic2' not in INSTALLED_APPS:
|
|
MELLON_DEFAULT_ASSERTION_CONSUMER_BINDING = 'artifact'
|
|
MELLON_OPENED_SESSION_COOKIE_NAME = 'A2_OPENED_SESSION'
|
|
MELLON_ADD_AUTHNREQUEST_NEXT_URL_EXTENSION = True
|
|
|
|
MIDDLEWARE = (
|
|
'hobo.middleware.utils.StoreRequestMiddleware',
|
|
'hobo.middleware.xforwardedfor.XForwardedForMiddleware',
|
|
) + MIDDLEWARE
|
|
|
|
MIDDLEWARE = MIDDLEWARE + ('hobo.middleware.PrometheusStatsMiddleware',)
|
|
|
|
|
|
HOBO_MANAGER_HOMEPAGE_URL_VAR = 'portal_agent_url'
|
|
HOBO_MANAGER_HOMEPAGE_TITLE_VAR = 'portal_agent_title'
|
|
|
|
# Authentic2 role attributes for Publik
|
|
A2_MANAGER_ROLE_FORM_CLASS = 'hobo.agent.authentic2.role_forms.RoleForm'
|
|
|
|
# Locale and timezone
|
|
LANGUAGE_CODE = 'fr-fr'
|
|
TIME_ZONE = 'Europe/Paris'
|
|
LANGUAGES = (('fr', u'Fran\xe7ais'),)
|
|
USE_L10N = True
|
|
USE_TZ = True
|
|
|
|
# Celery configuration
|
|
BROKER_URL = 'amqp://'
|
|
BROKER_TASK_EXPIRES = 600
|
|
|
|
STATICS_HASH_COUNTER = '/var/lib/publik/statics-counter'
|
|
|
|
# Django Rest Framework: allow only Publik-signed URLs
|
|
if 'rest_framework' in INSTALLED_APPS:
|
|
if 'REST_FRAMEWORK' not in globals():
|
|
REST_FRAMEWORK = {}
|
|
REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES'] = ('hobo.rest_authentication.PublikAuthentication',)
|
|
REST_FRAMEWORK['DEFAULT_PERMISSION_CLASSES'] = ('rest_framework.permissions.IsAuthenticated',)
|
|
REST_FRAMEWORK['DEFAULT_RENDERER_CLASSES'] = ('rest_framework.renderers.JSONRenderer',)
|
|
|
|
HOBO_ANONYMOUS_SERVICE_USER_CLASS = 'hobo.rest_authentication.AnonymousAdminServiceUser'
|
|
|
|
THEMES_DIRECTORY = '/usr/share/publik/themes/'
|
|
|
|
USE_X_FORWARDED_FOR = True
|
|
|
|
EMAIL_BACKEND = 'hobo.emails.backend.EmailBackend'
|