def to_settings(self, data, settings): # django-multisite annoyingly requires a working database and cache # at import time. So in "build" mode (used for collectstatic at build # time) we don't configure it. # Also if the CACHE_URL is locmem (used when calling # createcachetable) we ignore multisite. # TODO: find solutions upstream in django-multisite to prevent this # awkward CACHE_URL "if" situation. from aldryn_addons.utils import djsenv as env, boolean_ish DJANGO_MODE = env('DJANGO_MODE') settings['INSTALLED_APPS'].append('django_multisite_plus') settings['DJANGO_MULTISITE_PLUS_REWRITE_DOMAINS'] = boolean_ish(env( 'DJANGO_MULTISITE_PLUS_REWRITE_DOMAINS', data['rewrite_domains'], )) settings['DJANGO_MULTISITE_PLUS_REWRITE_DOMAIN_FORMAT'] = env( 'DJANGO_MULTISITE_PLUS_REWRITE_DOMAIN_FORMAT', data['rewrite_domain_format'] or '{}.divio.me', ) settings['DJANGO_MULTISITE_PLUS_AUTO_POPULATE_SITES'] = boolean_ish(env( 'DJANGO_MULTISITE_PLUS_AUTO_POPULATE_SITES', data['auto_populate_sites'], )) settings['DJANGO_MULTISITE_PLUS_USE_REAL_DOMAIN'] = boolean_ish(env( 'DJANGO_MULTISITE_PLUS_USE_REAL_DOMAIN', False, )) settings['DJANGO_MULTISITE_PLUS_SITES'] = env( 'DJANGO_MULTISITE_PLUS_SITES', {}, ) mode = env('DJANGO_MULTISITE_PLUS_MODE', data['mode']) settings['DJANGO_MULTISITE_PLUS_MODE'] = mode if DJANGO_MODE == 'build' and settings['CACHE_URL'] == 'locmem://': return settings if mode == 'single-process': self.single_process_settings(env, settings) elif mode == 'multi-process': self.multi_process_settings(settings) else: raise RuntimeError( ( 'DJANGO_MULTISITE_PLUS_MODE must be either single-process ' 'or multi-process. Not {}' ).format(mode) ) return settings
def to_settings(self, data, settings): from functools import partial from aldryn_addons.utils import boolean_ish, djsenv from aldryn_django import storage env = partial(djsenv, settings=settings) # django-filer settings['FILER_ENABLE_PERMISSIONS'] = False settings['FILER_DEBUG'] = boolean_ish( env('FILER_DEBUG', settings['DEBUG'])) settings['FILER_ENABLE_LOGGING'] = boolean_ish( env('FILER_ENABLE_LOGGING', True)) settings['FILER_IMAGE_USE_ICON'] = True settings['ADDON_URLS'].append('filer.server.urls') settings.setdefault('MEDIA_HEADERS', []).insert( 0, ( r'filer_public(?:_thumbnails)?/.*', { 'Cache-Control': 'public, max-age={}'.format(86400 * 365), }, )) # easy-thumbnails settings['THUMBNAIL_QUALITY'] = env('THUMBNAIL_QUALITY', 90) # FIXME: enabling THUMBNAIL_HIGH_RESOLUTION causes timeouts/500! settings['THUMBNAIL_HIGH_RESOLUTION'] = False settings['THUMBNAIL_PRESERVE_EXTENSIONS'] = ['png', 'gif'] settings['THUMBNAIL_PROCESSORS'] = ( 'easy_thumbnails.processors.colorspace', 'easy_thumbnails.processors.autocrop', 'filer.thumbnail_processors.scale_and_crop_with_subject_location', 'easy_thumbnails.processors.filters', ) settings['THUMBNAIL_SOURCE_GENERATORS'] = ( 'easy_thumbnails.source_generators.pil_image', ) settings['THUMBNAIL_CACHE_DIMENSIONS'] = True # easy_thumbnails uses django's default storage backend (local file # system storage) by default, even if the DEFAULT_FILE_STORAGE setting # points to something else. # If the DEFAULT_FILE_STORAGE has been set to a value known by # aldryn-django, then use that as THUMBNAIL_DEFAULT_STORAGE as well. for storage_backend in storage.SCHEMES.values(): if storage_backend == settings['DEFAULT_FILE_STORAGE']: settings['THUMBNAIL_DEFAULT_STORAGE'] = storage_backend break return settings
def configure_elastic_apm(self, settings, env): from aldryn_addons.utils import boolean_ish import yurl elastic_dsn = yurl.URL(env('DEFAULT_APM_DSN')) if elastic_dsn: service_name = elastic_dsn.username secret_token = elastic_dsn.authorization server_url = str(elastic_dsn.replace(userinfo='')) server_env = env('STAGE', 'local').lower() if server_env in { 'live', }: elastic_send_debug = False else: elastic_send_debug = True elastic_send_debug = boolean_ish( env('ELASTIC_SEND_DEBUG', elastic_send_debug)) elastic_service_name = '{}-{}'.format(service_name, server_env) elastic_service_name = env('ELASTIC_SERVICE_NAME', elastic_service_name) settings['ELASTIC_APM'] = { 'DEBUG': elastic_send_debug, 'SERVER_URL': server_url, 'SERVICE_NAME': elastic_service_name, 'SECRET_TOKEN': secret_token, }
def to_settings(self, data, settings): from aldryn_addons.utils import djsenv, boolean_ish from aldryn_haystack import haystack_url s = settings env = partial(djsenv, settings=settings) s['DEFAULT_HAYSTACK_URL'] = env('DEFAULT_HAYSTACK_URL') if env('DJANGO_MODE') == 'build': s['HAYSTACK_CONNECTIONS'] = { 'default': { 'ENGINE': 'haystack.backends.simple_backend.SimpleEngine', } } return s if not s['DEFAULT_HAYSTACK_URL']: return s s['ALDRYN_HAYSTACK_DEBUG'] = boolean_ish( env('ALDRYN_HAYSTACK_DEBUG', False)) s['DEFAULT_HAYSTACK_URL'] = env('DEFAULT_HAYSTACK_URL') s.setdefault('HAYSTACK_CONNECTIONS', {}) s['HAYSTACK_CONNECTIONS']['default'] = haystack_url.parse( url=s['DEFAULT_HAYSTACK_URL']) s['INSTALLED_APPS'].append('haystack') if s['ALDRYN_HAYSTACK_DEBUG']: s['LOGGING']['loggers']['elasticsearch.trace'] = { 'handlers': ['console'], 'level': 'INFO', } return s
def to_settings(self, data, settings): from functools import partial from aldryn_addons.utils import boolean_ish, djsenv from aldryn_django import storage env = partial(djsenv, settings=settings) # django-filer settings['FILER_DEBUG'] = boolean_ish(env('FILER_DEBUG', settings['DEBUG'])) settings['FILER_ENABLE_LOGGING'] = boolean_ish(env('FILER_ENABLE_LOGGING', True)) settings['FILER_IMAGE_USE_ICON'] = True settings['ADDON_URLS'].append( 'filer.server.urls' ) settings.setdefault('MEDIA_HEADERS', []).insert(0, ( r'filer_public(?:_thumbnails)?/.*', { 'Cache-Control': 'public, max-age={}'.format(86400 * 365), }, )) # easy-thumbnails settings['THUMBNAIL_QUALITY'] = env('THUMBNAIL_QUALITY', 90) # FIXME: enabling THUMBNAIL_HIGH_RESOLUTION causes timeouts/500! settings['THUMBNAIL_HIGH_RESOLUTION'] = False settings['THUMBNAIL_PRESERVE_EXTENSIONS'] = ['png', 'gif'] settings['THUMBNAIL_PROCESSORS'] = ( 'easy_thumbnails.processors.colorspace', 'easy_thumbnails.processors.autocrop', 'filer.thumbnail_processors.scale_and_crop_with_subject_location', 'easy_thumbnails.processors.filters', ) settings['THUMBNAIL_SOURCE_GENERATORS'] = ( 'easy_thumbnails.source_generators.pil_image', ) settings['THUMBNAIL_CACHE_DIMENSIONS'] = True # easy_thumbnails uses django's default storage backend (local file # system storage) by default, even if the DEFAULT_FILE_STORAGE setting # points to something else. # If the DEFAULT_FILE_STORAGE has been set to a value known by # aldryn-django, then use that as THUMBNAIL_DEFAULT_STORAGE as well. for storage_backend in storage.SCHEMES.values(): if storage_backend == settings['DEFAULT_FILE_STORAGE']: settings['THUMBNAIL_DEFAULT_STORAGE'] = storage_backend break return settings
def domain_settings(self, data, settings, env): from aldryn_addons.utils import boolean_ish settings["ALLOWED_HOSTS"] = env("ALLOWED_HOSTS", ["localhost", "*"]) # will take a full config dict from ALDRYN_SITES_DOMAINS if available, # otherwise fall back to constructing the dict from DOMAIN, # DOMAIN_ALIASES and DOMAIN_REDIRECTS domain = env("DOMAIN") if domain: settings["DOMAIN"] = domain domains = env("ALDRYN_SITES_DOMAINS", {}) permanent_redirect = boolean_ish( env("ALDRYN_SITES_REDIRECT_PERMANENT", False) ) if not domains and domain: domain_aliases = [ d.strip() for d in env("DOMAIN_ALIASES", "").split(",") if d.strip() ] domain_redirects = [ d.strip() for d in env("DOMAIN_REDIRECTS", "").split(",") if d.strip() ] domains = { 1: { "name": env("SITE_NAME", ""), "domain": domain, "aliases": domain_aliases, "redirects": domain_redirects, } } settings["ALDRYN_SITES_DOMAINS"] = domains settings["ALDRYN_SITES_REDIRECT_PERMANENT"] = permanent_redirect # This is ensured again by aldryn-sites, but we already do it here # as we need the full list of domains later when configuring # media/static serving, before aldryn-sites had a chance to run. site_domains = domains.get(settings["SITE_ID"]) if site_domains: settings["ALLOWED_HOSTS"].append(site_domains["domain"]) settings["ALLOWED_HOSTS"].extend(site_domains["aliases"]) settings["ALLOWED_HOSTS"].extend(site_domains["redirects"]) settings["INSTALLED_APPS"].append("aldryn_sites") settings["MIDDLEWARE_CLASSES"].insert( settings["MIDDLEWARE_CLASSES"].index( "django.middleware.common.CommonMiddleware" ), "aldryn_sites.middleware.SiteMiddleware", )
def web(ctx_obj): """ launch the webserver of choice (uwsgi) """ if any(boolean_ish(ctx_obj['settings'][key]) for key in ('ENABLE_NGINX', 'ENABLE_PAGESPEED', 'ENABLE_BROWSERCACHE')): # uwsgi behind nginx. possibly with pagespeed/browsercache start_with_nginx(ctx_obj['settings']) else: # pure uwsgi execute(start_uwsgi_command(settings=ctx_obj['settings'], port=80))
def to_settings(self, data, settings): from aldryn_addons.utils import boolean_ish, djsenv env = partial(djsenv, settings=settings) enable_elastic_apm = boolean_ish(env('ENABLE_ELASTIC_APM', True)) enable_elastic_apm = True if enable_elastic_apm: self.check_threads() self.configure_django(settings, env=env) self.configure_elastic_apm(settings, env=env) self.configure_elastic_logging(settings, env=env) return settings
def migration_settings(self, settings, env): from aldryn_django import storage from aldryn_addons.utils import boolean_ish settings.setdefault('MIGRATION_COMMANDS', []) mcmds = settings['MIGRATION_COMMANDS'] mcmds.append('CACHE_URL="locmem://" python manage.py createcachetable django_dbcache; exit 0') mcmds.append('python manage.py migrate --noinput') if not boolean_ish(env('DISABLE_S3_MEDIA_HEADERS_UPDATE')): if settings['DEFAULT_FILE_STORAGE'] == storage.SCHEMES['s3']: mcmds.append('python manage.py aldryn_update_s3_media_headers')
def domain_settings(self, data, settings, env): from aldryn_addons.utils import boolean_ish settings['ALLOWED_HOSTS'] = env('ALLOWED_HOSTS', ['localhost', '*']) # will take a full config dict from ALDRYN_SITES_DOMAINS if available, # otherwise fall back to constructing the dict from DOMAIN, # DOMAIN_ALIASES and DOMAIN_REDIRECTS domain = env('DOMAIN') if domain: settings['DOMAIN'] = domain domains = env('ALDRYN_SITES_DOMAINS', {}) permanent_redirect = boolean_ish( env('ALDRYN_SITES_REDIRECT_PERMANENT', False)) if not domains and domain: domain_aliases = [ d.strip() for d in env('DOMAIN_ALIASES', '').split(',') if d.strip() ] domain_redirects = [ d.strip() for d in env('DOMAIN_REDIRECTS', '').split(',') if d.strip() ] domains = { 1: { 'name': env('SITE_NAME', ''), 'domain': domain, 'aliases': domain_aliases, 'redirects': domain_redirects, }, } settings['ALDRYN_SITES_DOMAINS'] = domains settings['ALDRYN_SITES_REDIRECT_PERMANENT'] = permanent_redirect # This is ensured again by aldryn-sites, but we already do it here # as we need the full list of domains later when configuring # media/static serving, before aldryn-sites had a chance to run. site_domains = domains.get(settings['SITE_ID']) if site_domains: settings['ALLOWED_HOSTS'].append(site_domains['domain']) settings['ALLOWED_HOSTS'].extend(site_domains['aliases']) settings['ALLOWED_HOSTS'].extend(site_domains['redirects']) settings['INSTALLED_APPS'].append('aldryn_sites') settings['MIDDLEWARE'].insert( settings['MIDDLEWARE'].index( 'django.middleware.common.CommonMiddleware'), 'aldryn_sites.middleware.SiteMiddleware', )
def get_uwsgi_vassal_opts(settings, port): vassal_opts = get_uwsgi_regular_opts(settings, port) + [ 'chdir = /app', 'vacuum = true', # vacuum makes uwsgi delete sockets on exit ] if boolean_ish(os.environ.get('ENABLE_UWSGI_CHEAPER', 'on')): vassal_opts.extend([ 'cheaper = 1', 'cheaper-algo = busyness', 'cheaper-initial = 1', 'cheaper-business-verbose = 1', 'cheaper-business-backlog-alert = 10', 'cheaper-overload = 20', ]) if not settings['ENABLE_SYNCING']: serve_static = False if yurl.URL(settings['STATIC_URL'] ).host or not settings['STATIC_URL_IS_ON_OTHER_DOMAIN']: # TODO: we're currently starting the static url hosting on all vassals if STATIC_HOST is set. # We rely on the fallback for the unknown static domain to end up calling on the main vassal. # We should rather do this only on the main vassal or create a custom vassal just for static files. serve_static = True vassal_opts.extend( get_uwsgi_static_serving_opts(settings['STATIC_URL'], settings['STATIC_ROOT'], settings['STATIC_HEADERS'])) if not settings['MEDIA_URL_IS_ON_OTHER_DOMAIN']: serve_static = True vassal_opts.extend( get_uwsgi_static_serving_opts(settings['MEDIA_URL'], settings['MEDIA_ROOT'], settings['MEDIA_HEADERS'])) if serve_static: vassal_opts.extend([ 'offload-threads = 2', # Start 2 offloading threads for each worker 'static-cache-paths = 86400', 'static-cache-paths-name = staticpaths', 'cache2 = name=staticpaths,items=5000,blocksize=1k,purge_lru,ignore_full', 'static-gzip-all = true', # Serve .gz files if that version is available ]) return [ 'vassal-set = {}'.format(opt.replace(' = ', '=', 1)) for opt in vassal_opts ]
def configure_elastic_logging(self, settings, env): from aldryn_addons.utils import boolean_ish enable_elastic_logging = boolean_ish(env('ENABLE_ELASTIC_LOGGING', False)) if enable_elastic_logging: log_level = env('ELASTIC_LOG_LEVEL', 'INFO').upper() settings['LOGGING']['handlers'].update({ 'elasticapm': { 'level': log_level, 'class': 'elasticapm.contrib.django.handlers.LoggingHandler', } }) for k in settings['LOGGING']['loggers']: settings['LOGGING']['loggers'][k]['handlers'].append( 'elasticapm')
def get_env(): # setup default uwsgi environment variables env = { 'UWSGI_ENABLE_THREADS': '1', } if boolean_ish(os.environ.get('ENABLE_UWSGI_CHEAPER', 'on')): env.update({ 'UWSGI_CHEAPER': '1', 'UWSGI_CHEAPER_ALGO': 'busyness', 'UWSGI_CHEAPER_INITIAL': '1', 'UWSGI_CHEAPER_BUSINESS_VERBOSE': '1', 'UWSGI_CHEAPER_BUSINESS_BACKLOG_ALERT': '10', 'UWSGI_CHEAPER_OVERLOAD': '30', }) env.update(os.environ) return env
def to_settings(self, data, settings): from aldryn_addons.utils import djsenv, boolean_ish from aldryn_haystack import haystack_url s = settings env = partial(djsenv, settings=settings) s['DEFAULT_HAYSTACK_URL'] = env('DEFAULT_HAYSTACK_URL') if env('DJANGO_MODE') == 'build': s['HAYSTACK_CONNECTIONS'] = { 'default': { 'ENGINE': 'haystack.backends.simple_backend.SimpleEngine', } } return s if not s['DEFAULT_HAYSTACK_URL']: return s s['ALDRYN_HAYSTACK_DEBUG'] = boolean_ish( env('ALDRYN_HAYSTACK_DEBUG', False)) s['DEFAULT_HAYSTACK_URL'] = env('DEFAULT_HAYSTACK_URL') s.setdefault('HAYSTACK_CONNECTIONS', {}) s['HAYSTACK_CONNECTIONS']['default'] = haystack_url.parse( url=s['DEFAULT_HAYSTACK_URL'] ) s['INSTALLED_APPS'].append('haystack') if s['ALDRYN_HAYSTACK_DEBUG']: s['LOGGING']['loggers']['elasticsearch.trace'] = { 'handlers': ['console'], 'level': 'INFO', } return s
def to_settings(self, data, settings): from functools import partial from aldryn_addons.exceptions import ImproperlyConfigured from aldryn_addons.utils import boolean_ish from aldryn_addons.utils import djsenv from simple_sso.compat import reverse_lazy def boolean_ish_or(value, or_values=()): if value in or_values: return value return boolean_ish(value) env = partial(djsenv, settings=settings) if settings.get("MIDDLEWARE"): # Django>=1.10 MIDDLEWARE = settings["MIDDLEWARE"] else: # Django<1.10 MIDDLEWARE = settings["MIDDLEWARE_CLASSES"] settings["ALDRYN_SSO_HIDE_USER_MANAGEMENT"] = data[ "hide_user_management"] # if the SSO button is the only configured login option: redirect right # to the login without showing the page. settings["ALDRYN_SSO_ENABLE_AUTO_SSO_LOGIN"] = boolean_ish( env("ALDRYN_SSO_ENABLE_AUTO_SSO_LOGIN", True)) settings["SSO_DSN"] = env("SSO_DSN") settings["LOGIN_REDIRECT_URL"] = "/" settings["ALDRYN_SSO_ENABLE_SSO_LOGIN"] = boolean_ish( env( "ALDRYN_SSO_ENABLE_SSO_LOGIN", default=boolean_ish(settings["SSO_DSN"]), )) settings["ALDRYN_SSO_ENABLE_LOGIN_FORM"] = boolean_ish( env( "ALDRYN_SSO_ENABLE_LOGIN_FORM", default=not settings["ALDRYN_SSO_HIDE_USER_MANAGEMENT"], )) settings["ALDRYN_SSO_ENABLE_LOCALDEV"] = boolean_ish( env("ALDRYN_SSO_ENABLE_LOCALDEV", default=env("STAGE") == "local")) settings["ALDRYN_SSO_ALWAYS_REQUIRE_LOGIN"] = boolean_ish_or( env( "ALDRYN_SSO_ALWAYS_REQUIRE_LOGIN", default=env("STAGE") == "test", ), or_values=("basicauth", ), ) settings["ALDRYN_SSO_LOGIN_WHITE_LIST"] = env( "ALDRYN_SSO_LOGIN_WHITE_LIST", default=[]) settings["ADDON_URLS"].append("aldryn_sso.urls") settings["ADDON_URLS_I18N"].append("aldryn_sso.urls_i18n") # aldryn_sso must be after django.contrib.admin so it can unregister # the User/Group Admin if necessary. settings["INSTALLED_APPS"].insert( settings["INSTALLED_APPS"].index("django.contrib.admin"), "aldryn_sso", ) if settings["ALDRYN_SSO_ENABLE_SSO_LOGIN"]: # Expire user session every day because: # Users can change their data on the SSO server. # We cannot do a sync of "recently changed" user data due to these reasons: # - security risk, leaking user data to unauthorized websites, # - it would require some periodic tasks (celery?), # - stage websites are being paused during which the sync wouldn't work settings["CLOUD_USER_SESSION_EXPIRATION"] = (24 * 60 * 60 ) # 24h = 1day if not settings["SSO_DSN"]: raise ImproperlyConfigured( "ALDRYN_SSO_ENABLE_SSO_LOGIN is True, but no SSO_DSN is set." ) if settings["ALDRYN_SSO_ALWAYS_REQUIRE_LOGIN"] == "basicauth": basicauth_user = env("ALDRYN_SSO_BASICAUTH_USER") basicauth_password = env("ALDRYN_SSO_BASICAUTH_PASSWORD") if basicauth_user and basicauth_password: settings["ALDRYN_SSO_BASICAUTH_USER"] = basicauth_user settings["ALDRYN_SSO_BASICAUTH_PASSWORD"] = basicauth_password else: raise ImproperlyConfigured( 'ALDRYN_SSO_ALWAYS_REQUIRE_LOGIN set to "basicauth", but ' "ALDRYN_SSO_BASICAUTH_USER and ALDRYN_SSO_BASICAUTH_PASSWORD not set" ) position = (MIDDLEWARE.index( "django.contrib.auth.middleware.AuthenticationMiddleware") + 1) MIDDLEWARE.insert( position, "aldryn_sso.middleware.BasicAuthAccessControlMiddleware", ) elif settings["ALDRYN_SSO_ALWAYS_REQUIRE_LOGIN"]: position = (MIDDLEWARE.index( "django.contrib.auth.middleware.AuthenticationMiddleware") + 1) MIDDLEWARE.insert(position, "aldryn_sso.middleware.AccessControlMiddleware") settings["ALDRYN_SSO_LOGIN_WHITE_LIST"].extend([ reverse_lazy("simple-sso-login"), reverse_lazy("aldryn_sso_login"), reverse_lazy("aldryn_sso_localdev_login"), reverse_lazy("aldryn_localdev_create_user"), ]) if settings["ALDRYN_SSO_ALWAYS_REQUIRE_LOGIN"]: settings["SHARING_VIEW_ONLY_TOKEN_KEY_NAME"] = env( "SHARING_VIEW_ONLY_TOKEN_KEY_NAME") settings["SHARING_VIEW_ONLY_SECRET_TOKEN"] = env( "SHARING_VIEW_ONLY_SECRET_TOKEN") settings["ALDRYN_SSO_OVERIDE_ADMIN_LOGIN_VIEW"] = env( "ALDRYN_SSO_OVERIDE_ADMIN_LOGIN_VIEW", any([ settings["ALDRYN_SSO_ENABLE_SSO_LOGIN"], settings["ALDRYN_SSO_ENABLE_LOGIN_FORM"], settings["ALDRYN_SSO_ENABLE_LOCALDEV"], ]), ) if settings["ALDRYN_SSO_OVERIDE_ADMIN_LOGIN_VIEW"]: # configure our combined login view to be the default settings["LOGIN_URL"] = "aldryn_sso_login" # see admin.py for how we force admin to use this view as well return settings
def parse(url, suffix='default'): url = furl(url) connection = { 'ENGINE': '', 'URL': '', 'INDEX_NAME': '', 'KWARGS': {}, } engine, protocol, platform = None, None, None scheme_parts = url.scheme.split('+') if len(scheme_parts) == 2: engine, protocol = scheme_parts elif len(scheme_parts) == 3: engine, protocol, platform = scheme_parts else: error_url = furl(url.url) error_url.password = '******' raise Exception( ( 'The scheme in the haystack url {} is not supported. It must ' 'have a scheme in the form of backend+protocol+platform:// or ' 'backend+protocol://.' 'Examples: es+https+aws:// es+http://' ).format(error_url)) url.scheme = protocol if engine == 'es': connection['ENGINE'] = 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine' else: connection['ENGINE'] = engine if '*' in url.path.segments[0]: # If the index contains the wildcard, replace it with the suffix url.path.segments[0] = url.path.segments[0].replace('*', suffix) # extract the index name and remove the path from the original url index_name = '{}'.format(url.path.segments[0]) url.path.segments = [] connection['INDEX_NAME'] = index_name if platform == 'aws': aws_access_key_id = url.username aws_secret_key = url.password url.username = None url.password = None connection['URL'] = url.url region = url.host.split('.')[1] verify_certs = boolean_ish(url.query.params.get('verify_certs', True)) ConnectionClass = import_string(url.query.params.get( 'connection_class', 'elasticsearch.RequestsHttpConnection' )) Serializer = import_string(url.query.params.get( 'serializer', 'elasticsearch.serializer.JSONSerializer' )) if sys.version_info.major >= 3: # The workaround for the large payload issue below is causing # the underling Python `http` module to send the Content-Length # header twice when running on Python 3, which fails with a # 400 Bad Request on recent AWS ElasticSearch service endpoints. # Just drop the workaround as we were not able to reproduce the # issue anymore with any combination of recent dependencies and # we suppose that the issue does not exist anymore on Python 3 # because of its explicit handling of `bytes` and `str` as # different types. default_auth_class = 'requests_aws4auth.AWS4Auth' else: # The unicode handling of urllib3/pyopenssl combined with # AWS4Auth causes requests with large bodies (> 2MB) to fail. # For more details see the workaround referenced below. default_auth_class = 'aldryn_haystack.auth.AWS4AuthNotUnicode' AWS4Auth = import_string(url.query.params.get( 'aws_auth', default_auth_class, )) connection['KWARGS'] = { 'port': url.port, 'http_auth': AWS4Auth( aws_access_key_id, aws_secret_key, region, 'es', ), 'use_ssl': protocol == 'https', 'verify_certs': verify_certs, 'connection_class': ConnectionClass, 'serializer': Serializer(), } else: connection['URL'] = url.url connection['INDEX_NAME'] = index_name return connection
def to_settings(self, data, settings): import django_cache_url import dj_database_url import warnings from functools import partial from aldryn_addons.utils import boolean_ish, djsenv env = partial(djsenv, settings=settings) # BASE_DIR should already be set by aldryn-addons settings['BASE_DIR'] = env('BASE_DIR', required=True) settings['DATA_ROOT'] = env('DATA_ROOT', os.path.join(settings['BASE_DIR'], 'data')) settings['SECRET_KEY'] = env('SECRET_KEY', 'this-is-not-very-random') settings['DEBUG'] = boolean_ish(env('DEBUG', False)) settings['ENABLE_SYNCING'] = boolean_ish( env('ENABLE_SYNCING', settings['DEBUG'])) settings['DISABLE_TEMPLATE_CACHE'] = boolean_ish( env('DISABLE_TEMPLATE_CACHE', settings['DEBUG'])) settings['DATABASE_URL'] = env('DATABASE_URL') settings['CACHE_URL'] = env('CACHE_URL') if env('DJANGO_MODE') == 'build': # In build mode we don't have any connected services like db or # cache available. So we need to configure those things in a way # they can run without real backends. settings['DATABASE_URL'] = 'sqlite://:memory:' settings['CACHE_URL'] = 'locmem://' if not settings['DATABASE_URL']: settings['DATABASE_URL'] = 'sqlite:///{}'.format( os.path.join(settings['DATA_ROOT'], 'db.sqlite3')) warnings.warn( 'no database configured. Falling back to DATABASE_URL={0}'. format(settings['DATABASE_URL']), RuntimeWarning, ) settings['DATABASES']['default'] = dj_database_url.parse( settings['DATABASE_URL']) if not settings['CACHE_URL']: settings['CACHE_URL'] = 'locmem://' warnings.warn( 'no cache configured. Falling back to CACHE_URL={0}'.format( settings['CACHE_URL']), RuntimeWarning, ) settings['CACHES']['default'] = django_cache_url.parse( settings['CACHE_URL']) settings['ROOT_URLCONF'] = env('ROOT_URLCONF', 'urls') settings['ADDON_URLS_I18N'].append('aldryn_django.i18n_urls') settings['WSGI_APPLICATION'] = 'wsgi.application' settings['INSTALLED_APPS'].extend([ 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.admin', 'django.contrib.staticfiles', 'aldryn_django', ]) if settings['ENABLE_SYNCING'] or settings['DISABLE_TEMPLATE_CACHE']: loader_list_class = list else: loader_list_class = CachedLoader settings['TEMPLATES'] = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': env( 'TEMPLATE_DIRS', [os.path.join(settings['BASE_DIR'], 'templates')], ), 'OPTIONS': { 'debug': boolean_ish(env('TEMPLATE_DEBUG', settings['DEBUG'])), 'context_processors': [ 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', 'django.template.context_processors.i18n', 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.template.context_processors.media', 'django.template.context_processors.csrf', 'django.template.context_processors.tz', 'django.template.context_processors.static', 'aldryn_django.context_processors.debug', ], 'loaders': loader_list_class([ 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', 'django.template.loaders.eggs.Loader', ]), }, }, ] settings['MIDDLEWARE_CLASSES'] = [ 'django.contrib.sessions.middleware.SessionMiddleware', # 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', # 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.contrib.sites.middleware.CurrentSiteMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', # 'django.middleware.security.SecurityMiddleware', ] if not env('DISABLE_GZIP'): settings['MIDDLEWARE_CLASSES'].insert( 0, 'django.middleware.gzip.GZipMiddleware') settings['SITE_ID'] = env('SITE_ID', 1) settings['ADDON_URLS_I18N_LAST'] = 'aldryn_django.urls_redirect' self.domain_settings(data, settings, env=env) self.security_settings(data, settings, env=env) self.server_settings(settings, env=env) self.logging_settings(settings, env=env) # Order matters, sentry settings rely on logging being configured. self.sentry_settings(settings, env=env) self.storage_settings_for_media(settings, env=env) self.storage_settings_for_static(data, settings, env=env) self.email_settings(data, settings, env=env) self.i18n_settings(data, settings, env=env) self.migration_settings(settings, env=env) settings['ALDRYN_DJANGO_ENABLE_GIS'] = data['enable_gis'] if settings['ALDRYN_DJANGO_ENABLE_GIS']: self.gis_settings(settings, env=env) return settings
def to_settings(self, data, settings): from functools import partial from aldryn_addons.exceptions import ImproperlyConfigured from aldryn_addons.utils import boolean_ish from aldryn_addons.utils import djsenv from simple_sso.compat import reverse_lazy def boolean_ish_or(value, or_values=()): if value in or_values: return value return boolean_ish(value) env = partial(djsenv, settings=settings) if settings.get('MIDDLEWARE'): # Django>=1.10 MIDDLEWARE = settings['MIDDLEWARE'] else: # Django<1.10 MIDDLEWARE = settings['MIDDLEWARE_CLASSES'] settings['ALDRYN_SSO_HIDE_USER_MANAGEMENT'] = data['hide_user_management'] # if the SSO button is the only configured login option: redirect right # to the login without showing the page. settings['ALDRYN_SSO_ENABLE_AUTO_SSO_LOGIN'] = boolean_ish( env('ALDRYN_SSO_ENABLE_AUTO_SSO_LOGIN', True) ) settings['SSO_DSN'] = env('SSO_DSN') settings['LOGIN_REDIRECT_URL'] = '/' settings['ALDRYN_SSO_ENABLE_SSO_LOGIN'] = boolean_ish( env( 'ALDRYN_SSO_ENABLE_SSO_LOGIN', default=boolean_ish(settings['SSO_DSN']), ) ) settings['ALDRYN_SSO_ENABLE_LOGIN_FORM'] = boolean_ish( env( 'ALDRYN_SSO_ENABLE_LOGIN_FORM', default=not settings['ALDRYN_SSO_HIDE_USER_MANAGEMENT'], ) ) settings['ALDRYN_SSO_ENABLE_LOCALDEV'] = boolean_ish( env( 'ALDRYN_SSO_ENABLE_LOCALDEV', default=env('STAGE') == 'local', ) ) settings['ALDRYN_SSO_ALWAYS_REQUIRE_LOGIN'] = boolean_ish_or( env( 'ALDRYN_SSO_ALWAYS_REQUIRE_LOGIN', default=env('STAGE') == 'test', ), or_values=( 'basicauth', ) ) settings['ALDRYN_SSO_LOGIN_WHITE_LIST'] = env( 'ALDRYN_SSO_LOGIN_WHITE_LIST', default=[] ) settings['ADDON_URLS'].append('aldryn_sso.urls') settings['ADDON_URLS_I18N'].append('aldryn_sso.urls_i18n') # aldryn_sso must be after django.contrib.admin so it can unregister # the User/Group Admin if necessary. settings['INSTALLED_APPS'].insert( settings['INSTALLED_APPS'].index('django.contrib.admin'), 'aldryn_sso' ) if settings['ALDRYN_SSO_ENABLE_SSO_LOGIN']: # Expire user session every day because: # Users can change their data on the SSO server. # We cannot do a sync of "recently changed" user data due to these reasons: # - security risk, leaking user data to unauthorized websites, # - it would require some periodic tasks (celery?), # - stage websites are being paused during which the sync wouldn't work settings['CLOUD_USER_SESSION_EXPIRATION'] = 24 * 60 * 60 # 24h = 1day if not settings['SSO_DSN']: raise ImproperlyConfigured( 'ALDRYN_SSO_ENABLE_SSO_LOGIN is True, but no SSO_DSN is set.') if settings['ALDRYN_SSO_ALWAYS_REQUIRE_LOGIN'] == 'basicauth': basicauth_user = env('ALDRYN_SSO_BASICAUTH_USER') basicauth_password = env('ALDRYN_SSO_BASICAUTH_PASSWORD') if basicauth_user and basicauth_password: settings['ALDRYN_SSO_BASICAUTH_USER'] = basicauth_user settings['ALDRYN_SSO_BASICAUTH_PASSWORD'] = basicauth_password else: raise ImproperlyConfigured( 'ALDRYN_SSO_ALWAYS_REQUIRE_LOGIN set to "basicauth", but ' 'ALDRYN_SSO_BASICAUTH_USER and ALDRYN_SSO_BASICAUTH_PASSWORD not set' ) position = MIDDLEWARE.index('django.contrib.auth.middleware.AuthenticationMiddleware') + 1 MIDDLEWARE.insert(position, 'aldryn_sso.middleware.BasicAuthAccessControlMiddleware') elif settings['ALDRYN_SSO_ALWAYS_REQUIRE_LOGIN']: position = MIDDLEWARE.index('django.contrib.auth.middleware.AuthenticationMiddleware') + 1 MIDDLEWARE.insert(position, 'aldryn_sso.middleware.AccessControlMiddleware') settings['ALDRYN_SSO_LOGIN_WHITE_LIST'].extend([ reverse_lazy('simple-sso-login'), reverse_lazy('aldryn_sso_login'), reverse_lazy('aldryn_sso_localdev_login'), reverse_lazy('aldryn_localdev_create_user'), ]) if settings['ALDRYN_SSO_ALWAYS_REQUIRE_LOGIN']: settings['SHARING_VIEW_ONLY_TOKEN_KEY_NAME'] = env('SHARING_VIEW_ONLY_TOKEN_KEY_NAME') settings['SHARING_VIEW_ONLY_SECRET_TOKEN'] = env('SHARING_VIEW_ONLY_SECRET_TOKEN') settings['ALDRYN_SSO_OVERIDE_ADMIN_LOGIN_VIEW'] = env( 'ALDRYN_SSO_OVERIDE_ADMIN_LOGIN_VIEW', any([ settings['ALDRYN_SSO_ENABLE_SSO_LOGIN'], settings['ALDRYN_SSO_ENABLE_LOGIN_FORM'], settings['ALDRYN_SSO_ENABLE_LOCALDEV'], ]) ) if settings['ALDRYN_SSO_OVERIDE_ADMIN_LOGIN_VIEW']: # configure our combined login view to be the default settings['LOGIN_URL'] = 'aldryn_sso_login' # see admin.py for how we force admin to use this view as well return settings
def boolean_ish_or(value, or_values=()): if value in or_values: return value return boolean_ish(value)
def to_settings(self, data, settings): from functools import partial from aldryn_addons.utils import boolean_ish, djsenv from django.utils.translation import ugettext_lazy as _ env = partial(djsenv, settings=settings) s = settings temba_pkg_dir = os.path.join( os.path.dirname(__import__('temba').__file__)) # quickfix so analytics does not explode everywhere # TODO: fix rapidpro codebase to work without analytics configured s['SEGMENT_IO_KEY'] = env('SEGMENT_IO_KEY', '') import analytics analytics.write_key = s['SEGMENT_IO_KEY'] s['LIBRATO_USER'] = env('LIBRATO_USER', '') s['LIBRATO_TOKEN'] = env('LIBRATO_TOKEN', '') s['TWITTER_API_KEY'] = env('TWITTER_API_KEY', '') s['TWITTER_API_SECRET'] = env('TWITTER_API_SECRET', '') # The only thing IS_PROD=False seems to do is enable/disable analytics s['IS_PROD'] = boolean_ish(env('IS_PROD', False)) # s['STATIC_URL'] = '/static/' from temba import settings_common as temba_settings s['PERMISSIONS'] = temba_settings.PERMISSIONS s['GROUP_PERMISSIONS'] = temba_settings.GROUP_PERMISSIONS s['REST_FRAMEWORK'] = temba_settings.REST_FRAMEWORK s['AUTHENTICATION_BACKENDS'].extend([ 'smartmin.backends.CaseInsensitiveBackend', 'guardian.backends.ObjectPermissionBackend', ]) s['ANONYMOUS_USER_NAME'] = 'AnonymousUser' s['STATICFILES_DIRS'].append(os.path.join(temba_pkg_dir, 'media')) s['LOGIN_URL'] = "/users/login/" s['LOGOUT_URL'] = "/users/logout/" s['LOGIN_REDIRECT_URL'] = "/org/choose/" s['LOGOUT_REDIRECT_URL'] = "/" # FIXME: Branding. s['DEFAULT_BRAND'] = 'default' s['BRANDING'] = { 'default': { 'slug': 'rapidpro', 'name': 'RapidPro', 'org': 'UNICEF', 'colors': dict(primary='#0c6596'), 'styles': [ 'brands/rapidpro/font/style.css', 'brands/rapidpro/less/style.less' ], 'welcome_topup': 1000, 'email': '*****@*****.**', 'support_email': '*****@*****.**', 'link': 'https://app.rapidpro.io', 'api_link': 'https://api.rapidpro.io', 'docs_link': 'http://docs.rapidpro.io', 'domain': 'app.rapidpro.io', 'favico': 'brands/rapidpro/rapidpro.ico', 'splash': '/brands/rapidpro/splash.jpg', 'logo': '/brands/rapidpro/logo.png', 'allow_signups': True, 'tiers': dict(import_flows=0, multi_user=0, multi_org=0), 'bundles': [], 'welcome_packs': [ dict(size=5000, name="Demo Account"), dict(size=100000, name="UNICEF Account") ], 'description': _("Visually build nationally scalable mobile applications from anywhere in the world." ), 'credits': _("Copyright © 2012-2015 UNICEF, Nyaruka. All Rights Reserved." ) } } default_hostname = 'rapidpro.aldryn.me' s['HOSTNAME'] = s.get('DOMAIN', default_hostname) s['TEMBA_HOST'] = s.get('DOMAIN', default_hostname) s['USER_TIME_ZONE'] = 'UTC' s['USE_TZ'] = True # TODO: this should really be in aldryn-django as a default s['TIME_ZONE'] = 'UTC' # TODO: this should really be in aldryn-django as a default s['DEFAULT_LANGUAGE'] = s['LANGUAGE_CODE'] # settings required in migrations, but are probably outdated s['AWS_STORAGE_BUCKET_NAME'] = '' s['AWS_BUCKET_DOMAIN'] = '' s['INSTALLED_APPS'].extend([ 'django.contrib.humanize', 'django.contrib.sitemaps', 'redis', 'guardian', 'rest_framework', 'rest_framework.authtoken', # compress our CSS and js 'compressor', 'smartmin', 'smartmin.csv_imports', 'smartmin.users', 'modeltranslation', 'timezones', 'temba', # for templates, static, locale 'temba.assets', 'temba.auth_tweaks', 'temba.api', 'temba.public', 'temba.schedules', 'temba.orgs', 'temba.contacts', 'temba.channels', 'temba.msgs', 'temba.flows', 'temba.reports', 'temba.triggers', 'temba.utils', 'temba.campaigns', 'temba.ivr', 'temba.locations', 'temba.values', 'temba.airtime', ]) s['PERMISSIONS_APP'] = 'temba.airtime' # Because of ancient version of django-modeltranslation. # Is it REALLY needed? s['MODELTRANSLATION_TRANSLATION_REGISTRY'] = 'translation' # switch to new style TEMPLATES config? loaders = s['TEMPLATES'][0]['OPTIONS']['loaders'] loaders.insert(0, 'hamlpy.template.loaders.HamlPyFilesystemLoader') loaders.insert(1, 'hamlpy.template.loaders.HamlPyAppDirectoriesLoader') TEMPLATE_CONTEXT_PROCESSORS = [ 'temba.context_processors.branding', 'temba.orgs.context_processors.user_group_perms_processor', 'temba.orgs.context_processors.unread_count_processor', 'temba.channels.views.channel_status_processor', 'temba.msgs.views.send_message_auto_complete_processor', 'temba.api.views.webhook_status_processor', 'temba.orgs.context_processors.settings_includer', ] s['TEMPLATES'][0]['OPTIONS']['context_processors'].extend( TEMPLATE_CONTEXT_PROCESSORS) if 'EMAIL_CONTEXT_PROCESSORS' not in s: s['EMAIL_CONTEXT_PROCESSORS'] = [] s['EMAIL_CONTEXT_PROCESSORS'].append( 'temba.utils.email.link_components') s['MIDDLEWARE_CLASSES'].insert( s['MIDDLEWARE_CLASSES'].index( 'django.middleware.common.CommonMiddleware'), 'temba.utils.middleware.DisableMiddleware', ) s['MIDDLEWARE_CLASSES'].extend([ 'temba.middleware.BrandingMiddleware', 'temba.middleware.OrgTimezoneMiddleware', 'temba.middleware.FlowSimulationMiddleware', 'temba.middleware.ActivateLanguageMiddleware', 'temba.middleware.NonAtomicGetsMiddleware', ]) # s['TEMPLATES'][0]['DIRS'].append( # os.path.join(RAPIDPRO_PACKAGE_DIR, 'templates') # ) # There is a lot of unneeded stuff in temba.urls. but for simplicy # I'm just including all of them for now. s['ADDON_URLS'].append('temba.urls') if 'APP_URLS' not in s: s['APP_URLS'] = [] s['SITEMAP'] = [ 'public.public_index', 'public.public_blog', 'public.video_list', 'api', ] s['LOGGING']['loggers']['pycountry'] = { 'level': 'ERROR', 'handlers': ['console'], 'propagate': False, } # TODO: put into aldryn-django? s['LOGGING']['loggers']['django.db.backends'] = { 'level': 'ERROR', 'handlers': ['console'], 'propagate': False, } # django-compressor TODO: cleanup for deployment if 'compressor.finders.CompressorFinder' not in s[ 'STATICFILES_FINDERS']: s['STATICFILES_FINDERS'].append( 'compressor.finders.CompressorFinder') less_file_folder = os.path.abspath( os.path.join(os.path.dirname(__import__('temba').__file__), 'static/less')) s['COMPRESS_PRECOMPILERS'] = (( 'text/less', 'lessc --include-path="%s" {infile} {outfile}' % less_file_folder), ('text/coffeescript', 'coffee --compile --stdio')) s['COMPRESS_OFFLINE_CONTEXT'] = dict(STATIC_URL=s['STATIC_URL'], base_template='frame.html') s['COMPRESS_ENABLED'] = False s['COMPRESS_OFFLINE'] = False # defaults are STATIC_URL and STATIC_ROOT # s['COMPRESS_URL'] = s['STATIC_URL'] # s['COMPRESS_ROOT'] = s['STATIC_ROOT'] s['OUTGOING_PROXIES'] = {} s['MESSAGE_HANDLERS'] = temba_settings.MESSAGE_HANDLERS ###### # DANGER: only turn this on if you know what you are doing! # could cause messages to be sent to live customer aggregators s['SEND_MESSAGES'] = boolean_ish(env('RAPIDPRO_SEND_MESSAGES', False)) ###### # DANGER: only turn this on if you know what you are doing! # could cause external APIs to be called in test environment s['SEND_WEBHOOKS'] = boolean_ish(env('RAPIDPRO_SEND_WEBHOOKS', False)) ###### # DANGER: only turn this on if you know what you are doing! # could cause emails to be sent in test environment s['SEND_EMAILS'] = boolean_ish(env('RAPIDPRO_SEND_EMAILS', False)) ###### # DANGER: only turn this on if you know what you are doing! # could cause airtime transfers in test environment s['SEND_AIRTIME'] = boolean_ish(env('RAPIDPRO_SEND_AIRTIME', False)) s['IP_ADDRESSES'] = [] CELERYBEAT_SCHEDULE = s.setdefault('CELERYBEAT_SCHEDULE', {}) CELERYBEAT_SCHEDULE.update(temba_settings.CELERYBEAT_SCHEDULE) # Mapping of task name to task function path, used when CELERY_ALWAYS_EAGER is set to True CELERY_TASK_MAP = s.setdefault('CELERY_TASK_MAP', {}) CELERY_TASK_MAP.update(temba_settings.CELERY_TASK_MAP) s['MAGE_API_URL'] = env('MAGE_API_URL', '') s['MAGE_AUTH_TOKEN'] = env('MAGE_AUTH_TOKEN', '') s['HUB9_ENDPOINT'] = env('HUB9_ENDPOINT', '') return settings
def to_settings(self, data, settings): from django.core.urlresolvers import reverse_lazy from aldryn_addons.utils import boolean_ish, djsenv env = partial(djsenv, settings=settings) # TODO: break out a lot of this stuff into other Addons settings['INSTALLED_APPS'].extend([ 'cms', 'treebeard', 'menus', 'sekizai', 'reversion', 'hvad', 'parler', ]) settings['INSTALLED_APPS'].insert( settings['INSTALLED_APPS'].index('django.contrib.admin'), 'djangocms_admin_style', ) settings['TEMPLATE_CONTEXT_PROCESSORS'].extend([ 'sekizai.context_processors.sekizai', 'cms.context_processors.cms_settings', ]) settings['MIDDLEWARE_CLASSES'].extend([ 'cms.middleware.user.CurrentUserMiddleware', 'cms.middleware.page.CurrentPageMiddleware', 'cms.middleware.toolbar.ToolbarMiddleware', 'cms.middleware.language.LanguageCookieMiddleware', ]) settings['ADDON_URLS_I18N_LAST'] = 'cms.urls' old_cms_templates_json = os.path.join(settings['BASE_DIR'], 'cms_templates.json') if os.path.exists(old_cms_templates_json): # Backwards compatibility with v2 with open(old_cms_templates_json) as fobj: templates = json.load(fobj) else: templates = settings.get('CMS_TEMPLATES', json.loads(data['cms_templates'])) settings['CMS_TEMPLATES'] = templates # languages languages = [code for code, lang in settings['LANGUAGES']] settings['CMS_LANGUAGES'] = { 'default': { 'fallbacks': [fbcode for fbcode in languages], 'redirect_on_fallback': True, 'public': True, 'hide_untranslated': False, }, 1: [{ 'code': code, 'name': settings['ALL_LANGUAGES_DICT'][code], 'fallbacks': [fbcode for fbcode in languages if fbcode != code], 'public': True } for code in languages] } settings['PARLER_LANGUAGES'] = {} for site_id, languages in settings['CMS_LANGUAGES'].items(): if isinstance(site_id, int): langs = [{'code': lang['code']} for lang in languages] settings['PARLER_LANGUAGES'].update({site_id: langs}) parler_defaults = {'fallback': settings['LANGUAGE_CODE']} for k, v in settings['CMS_LANGUAGES'].get('default', {}).items(): if k in [ 'hide_untranslated', ]: parler_defaults.update({k: v}) settings['PARLER_LANGUAGES'].update({'default': parler_defaults}) # aldryn-boilerplates and aldryn-snake settings['ALDRYN_BOILERPLATE_NAME'] = settings.get( 'ALDRYN_BOILERPLATE_NAME', 'legacy') settings['INSTALLED_APPS'].append('aldryn_boilerplates') settings['TEMPLATE_CONTEXT_PROCESSORS'].extend([ 'aldryn_boilerplates.context_processors.boilerplate', 'aldryn_snake.template_api.template_processor', ]) settings['TEMPLATE_LOADERS'].insert( settings['TEMPLATE_LOADERS'].index( 'django.template.loaders.app_directories.Loader'), 'aldryn_boilerplates.template_loaders.AppDirectoriesLoader') settings['STATICFILES_FINDERS'].insert( settings['STATICFILES_FINDERS'].index( 'django.contrib.staticfiles.finders.AppDirectoriesFinder'), 'aldryn_boilerplates.staticfile_finders.AppDirectoriesFinder', ) # django sitemap support settings['INSTALLED_APPS'].append('django.contrib.sitemaps') # django-compressor settings['INSTALLED_APPS'].append('compressor') settings['STATICFILES_FINDERS'].append( 'compressor.finders.CompressorFinder') # django-robots settings['INSTALLED_APPS'].append('robots') # django-filer settings['INSTALLED_APPS'].extend([ 'filer', 'easy_thumbnails', 'mptt', 'polymorphic', ]) settings['FILER_DEBUG'] = boolean_ish( env('FILER_DEBUG', settings['DEBUG'])) settings['FILER_ENABLE_LOGGING'] = boolean_ish( env('FILER_ENABLE_LOGGING', True)) settings['FILER_IMAGE_USE_ICON'] = True # easy-thumbnails settings['INSTALLED_APPS'].extend([ 'easy_thumbnails', ]) settings['THUMBNAIL_QUALITY'] = env('THUMBNAIL_QUALITY', 90) settings[ 'THUMBNAIL_HIGH_RESOLUTION'] = False # FIXME: enabling THUMBNAIL_HIGH_RESOLUTION causes timeouts/500! settings['THUMBNAIL_PRESERVE_EXTENSIONS'] = ['png', 'gif'] settings['THUMBNAIL_PROCESSORS'] = ( 'easy_thumbnails.processors.colorspace', 'easy_thumbnails.processors.autocrop', 'filer.thumbnail_processors.scale_and_crop_with_subject_location', 'easy_thumbnails.processors.filters', ) settings['THUMBNAIL_SOURCE_GENERATORS'] = ( 'easy_thumbnails.source_generators.pil_image', ) settings['THUMBNAIL_CACHE_DIMENSIONS'] = True # commented out because fix-tree has a major bug # this should be ok with CMS >=3.1.4 # settings['MIGRATION_COMMANDS'].append( # 'python manage.py cms fix-tree --noinput' # ) # default plugins settings['INSTALLED_APPS'].extend([ 'djangocms_text_ckeditor', 'djangocms_link', 'djangocms_snippet', 'djangocms_googlemap', # cmsplugin-filer 'cmsplugin_filer_file', 'cmsplugin_filer_image', # required by aldryn-forms 'captcha', ]) # boilerplate must provide /static/js/modules/ckeditor.wysiwyg.js and /static/css/base.css CKEDITOR_SETTINGS = { 'height': 300, 'language': '{{ language }}', 'toolbar': 'CMS', 'skin': 'moono', 'extraPlugins': 'cmsplugins', 'toolbar_HTMLField': [ ['Undo', 'Redo'], ['cmsplugins', '-', 'ShowBlocks'], ['Format', 'Styles'], ['TextColor', 'BGColor', '-', 'PasteText', 'PasteFromWord'], ['Maximize', ''], '/', [ 'Bold', 'Italic', 'Underline', '-', 'Subscript', 'Superscript', '-', 'RemoveFormat' ], ['JustifyLeft', 'JustifyCenter', 'JustifyRight'], ['HorizontalRule'], ['Link', 'Unlink'], [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Table' ], ['Source'], ['Link', 'Unlink', 'Anchor'], ], } boilerplate_name = locals().get('ALDRYN_BOILERPLATE_NAME', 'legacy') if boilerplate_name == 'bootstrap3': CKEDITOR_SETTINGS[ 'stylesSet'] = 'default:/static/js/addons/ckeditor.wysiwyg.js' CKEDITOR_SETTINGS['contentsCss'] = ['/static/css/base.css'] else: CKEDITOR_SETTINGS[ 'stylesSet'] = 'default:/static/js/modules/ckeditor.wysiwyg.js' CKEDITOR_SETTINGS['contentsCss'] = ['/static/css/base.css'] # select2 (required by djangocms_link plugin) settings['INSTALLED_APPS'].extend([ 'django_select2', ]) settings['ADDON_URLS'].append('aldryn_cms.urls') settings['ADDON_URLS_I18N'].append('aldryn_cms.urls_i18n') restarer_url = env('RESTARTER_URL') if restarer_url: # restarter url endpoint has been set in env variable # so configure site settings with it. # This will be picked up by signal handler when cms needs a restart. settings['RESTARTER_URL'] = restarer_url settings['RESTARTER_PAYLOAD'] = env('RESTARTER_PAYLOAD') if 'ALDRYN_SSO_LOGIN_WHITE_LIST' in settings: # stage sso enabled # add internal endpoints that do not require authentication settings['ALDRYN_SSO_LOGIN_WHITE_LIST'].append( reverse_lazy('cms-check-uninstall')) # this is an internal django-cms url # which gets called when a user logs out from toolbar settings['ALDRYN_SSO_LOGIN_WHITE_LIST'].append( reverse_lazy('admin:cms_page_resolve')) return settings
def to_settings(self, data, settings): import dj_database_url import warnings from functools import partial from aldryn_addons.utils import boolean_ish, djsenv env = partial(djsenv, settings=settings) # BASE_DIR should already be set by aldryn-addons settings['BASE_DIR'] = env('BASE_DIR', required=True) settings['DATA_ROOT'] = env('DATA_ROOT', os.path.join(settings['BASE_DIR'], 'data')) settings['SECRET_KEY'] = env('SECRET_KEY', 'this-is-not-very-random') settings['DEBUG'] = boolean_ish(env('DEBUG', False)) settings['ENABLE_SYNCING'] = boolean_ish( env('ENABLE_SYNCING', settings['DEBUG'])) settings['DISABLE_TEMPLATE_CACHE'] = boolean_ish( env('DISABLE_TEMPLATE_CACHE', settings['DEBUG'])) settings['DATABASE_URL'] = env('DATABASE_URL') settings['CACHE_URL'] = env('CACHE_URL') if env('DJANGO_MODE') == 'build': # In build mode we don't have any connected services like db or # cache available. So we need to configure those things in a way # they can run without real backends. settings['DATABASE_URL'] = 'sqlite://:memory:' settings['CACHE_URL'] = 'locmem://' if not settings['DATABASE_URL']: settings['DATABASE_URL'] = 'sqlite:///{}'.format( os.path.join(settings['DATA_ROOT'], 'db.sqlite3') ) warnings.warn( 'no database configured. Falling back to DATABASE_URL={0}'.format( settings['DATABASE_URL'] ), RuntimeWarning, ) if not settings['CACHE_URL']: settings['CACHE_URL'] = 'locmem://' warnings.warn( 'no cache configured. Falling back to CACHE_URL={0}'.format( settings['CACHE_URL'] ), RuntimeWarning, ) settings['DATABASES']['default'] = dj_database_url.parse(settings['DATABASE_URL']) settings['ROOT_URLCONF'] = env('ROOT_URLCONF', 'urls') settings['ADDON_URLS'].append('aldryn_django.urls') settings['ADDON_URLS_I18N'].append('aldryn_django.i18n_urls') settings['WSGI_APPLICATION'] = 'wsgi.application' settings['INSTALLED_APPS'].extend([ 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.admin', 'django.contrib.staticfiles', 'aldryn_django', ]) if settings['ENABLE_SYNCING'] or settings['DISABLE_TEMPLATE_CACHE']: loader_list_class = list else: loader_list_class = CachedLoader settings['TEMPLATES'] = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': env('TEMPLATE_DIRS', [os.path.join(settings['BASE_DIR'], 'templates')], ), 'OPTIONS': { 'debug': boolean_ish(env('TEMPLATE_DEBUG', settings['DEBUG'])), 'context_processors': [ 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', 'django.core.context_processors.i18n', 'django.core.context_processors.debug', 'django.core.context_processors.request', 'django.core.context_processors.media', 'django.core.context_processors.csrf', 'django.core.context_processors.tz', 'django.core.context_processors.static', 'aldryn_django.context_processors.debug', ], 'loaders': loader_list_class([ 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', 'django.template.loaders.eggs.Loader', ]), }, }, ] settings['MIDDLEWARE_CLASSES'] = [ 'django.contrib.sessions.middleware.SessionMiddleware', # 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', # 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.contrib.sites.middleware.CurrentSiteMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', # 'django.middleware.security.SecurityMiddleware', ] if not env('DISABLE_GZIP'): settings['MIDDLEWARE_CLASSES'].insert( 0, 'django.middleware.gzip.GZipMiddleware') settings['SITE_ID'] = env('SITE_ID', 1) settings['ADDON_URLS_I18N_LAST'] = 'aldryn_django.urls_redirect' self.domain_settings(data, settings, env=env) self.security_settings(data, settings, env=env) self.server_settings(settings, env=env) self.logging_settings(settings, env=env) # Order matters, sentry settings rely on logging being configured. self.sentry_settings(settings, env=env) self.cache_settings(settings, env=env) self.storage_settings_for_media(settings, env=env) self.storage_settings_for_static(data, settings, env=env) self.i18n_settings(data, settings, env=env) self.migration_settings(settings, env=env) settings['ALDRYN_DJANGO_ENABLE_GIS'] = data['enable_gis'] if settings['ALDRYN_DJANGO_ENABLE_GIS']: self.gis_settings(settings, env=env) return settings
def to_settings(self, data, settings): import os import dj_database_url import warnings import yurl from functools import partial from aldryn_addons.utils import boolean_ish, djsenv env = partial(djsenv, settings=settings) # BASE_DIR should already be set by aldryn-addons settings['BASE_DIR'] = env('BASE_DIR', required=True) settings['DATA_ROOT'] = env('DATA_ROOT', os.path.join(settings['BASE_DIR'], 'data')) settings['SECRET_KEY'] = env('SECRET_KEY', 'this-is-not-very-random') settings['DEBUG'] = boolean_ish(env('DEBUG', False)) settings['TEMPLATE_DEBUG'] = boolean_ish(env('TEMPLATE_DEBUG', settings['DEBUG'])) settings['DATABASE_URL'] = env('DATABASE_URL') if settings['DATABASE_URL']: pass elif env('DJANGO_MODE') == 'build': settings['DATABASE_URL'] = 'sqlite://:memory:' else: settings['DATABASE_URL'] = 'sqlite:///{}'.format( os.path.join(settings['DATA_ROOT'], 'db.sqlite3') ) warnings.warn( 'no database configured. Falling back to DATABASE_URL={0}'.format( settings['DATABASE_URL'] ), RuntimeWarning, ) settings['DATABASES']['default'] = dj_database_url.parse(settings['DATABASE_URL']) settings['ROOT_URLCONF'] = env('ROOT_URLCONF', 'urls') settings['ADDON_URLS'].append('aldryn_django.urls') settings['ADDON_URLS_I18N'].append('aldryn_django.i18n_urls') settings['WSGI_APPLICATION'] = 'wsgi.application' settings['STATIC_URL'] = env('STATIC_URL', '/static/') settings['STATIC_URL_IS_ON_OTHER_DOMAIN'] = bool(yurl.URL(settings['STATIC_URL']).host) settings['STATIC_ROOT'] = env( 'STATIC_ROOT', os.path.join(settings['BASE_DIR'], 'static_collected'), ) settings['STATICFILES_DIRS'] = env( 'STATICFILES_DIRS', [os.path.join(settings['BASE_DIR'], 'static'),] ) settings['MEDIA_URL'] = env('MEDIA_URL', '/media/') settings['MEDIA_URL_IS_ON_OTHER_DOMAIN'] = bool(yurl.URL(settings['MEDIA_URL']).host) settings['MEDIA_ROOT'] = env('MEDIA_ROOT', os.path.join(settings['DATA_ROOT'], 'media')) settings['INSTALLED_APPS'].extend([ 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.admin', 'django.contrib.staticfiles', 'aldryn_django', ]) if 'sqlite3' not in settings['DATABASES']['default']['ENGINE']: settings['INSTALLED_APPS'].append('south') settings['TEMPLATE_CONTEXT_PROCESSORS'].extend([ 'django.core.context_processors.request', 'aldryn_django.context_processors.debug', ]) settings['MIDDLEWARE_CLASSES'].extend([ 'django.middleware.locale.LocaleMiddleware', 'aldryn_django.middleware.CurrentSiteMiddleware', ]) settings['TEMPLATE_DIRS'] = env( 'TEMPLATE_DIRS', [os.path.join(settings['BASE_DIR'], 'templates')], ) settings['SITE_ID'] = env('SITE_ID', 1) self.domain_settings(data, settings, env=env) self.server_settings(settings, env=env) self.logging_settings(settings, env=env) self.cache_settings(settings, env=env) self.storage_settings(settings, env=env) self.i18n_settings(data, settings, env=env) self.migration_settings(settings, env=env) return settings
def to_settings(self, data, settings): from functools import partial from django.core.urlresolvers import reverse_lazy from aldryn_addons.exceptions import ImproperlyConfigured from aldryn_addons.utils import boolean_ish from aldryn_addons.utils import djsenv def boolean_ish_or(value, or_values=()): if value in or_values: return value return boolean_ish(value) env = partial(djsenv, settings=settings) settings['ALDRYN_SSO_HIDE_USER_MANAGEMENT'] = data['hide_user_management'] # if the SSO button is the only configured login option: redirect right # to the login without showing the page. settings['ALDRYN_SSO_ENABLE_AUTO_SSO_LOGIN'] = boolean_ish( env('ALDRYN_SSO_ENABLE_AUTO_SSO_LOGIN', True) ) settings['SSO_DSN'] = env('SSO_DSN') settings['LOGIN_REDIRECT_URL'] = '/' settings['ALDRYN_SSO_ENABLE_SSO_LOGIN'] = boolean_ish( env( 'ALDRYN_SSO_ENABLE_SSO_LOGIN', default=boolean_ish(settings['SSO_DSN']), ) ) settings['ALDRYN_SSO_ENABLE_LOGIN_FORM'] = boolean_ish( env( 'ALDRYN_SSO_ENABLE_LOGIN_FORM', default=not settings['ALDRYN_SSO_HIDE_USER_MANAGEMENT'], ) ) settings['ALDRYN_SSO_ENABLE_LOCALDEV'] = boolean_ish( env( 'ALDRYN_SSO_ENABLE_LOCALDEV', default=env('STAGE') == 'local', ) ) settings['ALDRYN_SSO_ALWAYS_REQUIRE_LOGIN'] = boolean_ish_or( env( 'ALDRYN_SSO_ALWAYS_REQUIRE_LOGIN', default=env('STAGE') == 'test', ), or_values=( 'basicauth', ) ) settings['ALDRYN_SSO_LOGIN_WHITE_LIST'] = env( 'ALDRYN_SSO_LOGIN_WHITE_LIST', default=[] ) settings['ADDON_URLS'].append('aldryn_sso.urls') settings['ADDON_URLS_I18N'].append('aldryn_sso.urls_i18n') # aldryn_sso must be after django.contrib.admin so it can unregister # the User/Group Admin if necessary. settings['INSTALLED_APPS'].insert( settings['INSTALLED_APPS'].index('django.contrib.admin'), 'aldryn_sso' ) if settings['ALDRYN_SSO_ENABLE_SSO_LOGIN']: # Expire user session every day because: # Users can change their data on the SSO server. # We cannot do a sync of "recently changed" user data due to these reasons: # - security risk, leaking user data to unauthorized websites, # - it would require some periodic tasks (celery?), # - stage websites are being paused during which the sync wouldn't work settings['CLOUD_USER_SESSION_EXPIRATION'] = 24 * 60 * 60 # 24h = 1day if not settings['SSO_DSN']: raise ImproperlyConfigured( 'ALDRYN_SSO_ENABLE_SSO_LOGIN is True, but no SSO_DSN is set.') if settings['ALDRYN_SSO_ALWAYS_REQUIRE_LOGIN'] == 'basicauth': basicauth_user = env('ALDRYN_SSO_BASICAUTH_USER') basicauth_password = env('ALDRYN_SSO_BASICAUTH_PASSWORD') if basicauth_user and basicauth_password: settings['ALDRYN_SSO_BASICAUTH_USER'] = basicauth_user settings['ALDRYN_SSO_BASICAUTH_PASSWORD'] = basicauth_password else: raise ImproperlyConfigured( 'ALDRYN_SSO_ALWAYS_REQUIRE_LOGIN set to "basicauth", but ALDRYN_SSO_BASICAUTH_USER and ALDRYN_SSO_BASICAUTH_PASSWORD not set' ) position = settings['MIDDLEWARE_CLASSES'].index('django.contrib.auth.middleware.AuthenticationMiddleware') + 1 settings['MIDDLEWARE_CLASSES'].insert(position, 'aldryn_sso.middleware.BasicAuthAccessControlMiddleware') elif settings['ALDRYN_SSO_ALWAYS_REQUIRE_LOGIN']: position = settings['MIDDLEWARE_CLASSES'].index('django.contrib.auth.middleware.AuthenticationMiddleware') + 1 settings['MIDDLEWARE_CLASSES'].insert(position, 'aldryn_sso.middleware.AccessControlMiddleware') settings['ALDRYN_SSO_LOGIN_WHITE_LIST'].extend([ reverse_lazy('simple-sso-login'), reverse_lazy('aldryn_sso_login'), reverse_lazy('aldryn_sso_localdev_login'), reverse_lazy('aldryn_localdev_create_user'), ]) if settings['ALDRYN_SSO_ALWAYS_REQUIRE_LOGIN']: settings['SHARING_VIEW_ONLY_TOKEN_KEY_NAME'] = env('SHARING_VIEW_ONLY_TOKEN_KEY_NAME') settings['SHARING_VIEW_ONLY_SECRET_TOKEN'] = env('SHARING_VIEW_ONLY_SECRET_TOKEN') settings['ALDRYN_SSO_OVERIDE_ADMIN_LOGIN_VIEW'] = env( 'ALDRYN_SSO_OVERIDE_ADMIN_LOGIN_VIEW', any([ settings['ALDRYN_SSO_ENABLE_SSO_LOGIN'], settings['ALDRYN_SSO_ENABLE_LOGIN_FORM'], settings['ALDRYN_SSO_ENABLE_LOCALDEV'], ]) ) if settings['ALDRYN_SSO_OVERIDE_ADMIN_LOGIN_VIEW']: # configure our combined login view to be the default settings['LOGIN_URL'] = 'aldryn_sso_login' # see admin.py for how we force admin to use this view as well return settings
def to_settings(self, data, settings): import dj_database_url import warnings import yurl from functools import partial from aldryn_addons.utils import boolean_ish, djsenv env = partial(djsenv, settings=settings) # BASE_DIR should already be set by aldryn-addons settings['BASE_DIR'] = env('BASE_DIR', required=True) settings['DATA_ROOT'] = env('DATA_ROOT', os.path.join(settings['BASE_DIR'], 'data')) settings['SECRET_KEY'] = env('SECRET_KEY', 'this-is-not-very-random') settings['DEBUG'] = boolean_ish(env('DEBUG', False)) settings['TEMPLATE_DEBUG'] = boolean_ish( env('TEMPLATE_DEBUG', settings['DEBUG'])) settings['DATABASE_URL'] = env('DATABASE_URL') if settings['DATABASE_URL']: pass elif env('DJANGO_MODE') == 'build': settings['DATABASE_URL'] = 'sqlite://:memory:' else: settings['DATABASE_URL'] = 'sqlite:///{}'.format( os.path.join(settings['DATA_ROOT'], 'db.sqlite3')) warnings.warn( 'no database configured. Falling back to DATABASE_URL={0}'. format(settings['DATABASE_URL']), RuntimeWarning, ) settings['DATABASES']['default'] = dj_database_url.parse( settings['DATABASE_URL']) settings['ROOT_URLCONF'] = env('ROOT_URLCONF', 'urls') settings['ADDON_URLS'].append('aldryn_django.urls') settings['ADDON_URLS_I18N'].append('aldryn_django.i18n_urls') settings['WSGI_APPLICATION'] = 'wsgi.application' settings['STATIC_URL'] = env('STATIC_URL', '/static/') settings['STATIC_URL_IS_ON_OTHER_DOMAIN'] = bool( yurl.URL(settings['STATIC_URL']).host) settings['STATIC_ROOT'] = env( 'STATIC_ROOT', os.path.join(settings['BASE_DIR'], 'static_collected'), ) settings['STATICFILES_DIRS'] = env('STATICFILES_DIRS', [ os.path.join(settings['BASE_DIR'], 'static'), ]) settings['MEDIA_URL'] = env('MEDIA_URL', '/media/') settings['MEDIA_URL_IS_ON_OTHER_DOMAIN'] = bool( yurl.URL(settings['MEDIA_URL']).host) settings['MEDIA_ROOT'] = env( 'MEDIA_ROOT', os.path.join(settings['DATA_ROOT'], 'media')) settings['INSTALLED_APPS'].extend([ 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.admin', 'django.contrib.staticfiles', 'aldryn_django', ]) if 'sqlite3' not in settings['DATABASES']['default']['ENGINE']: settings['INSTALLED_APPS'].append('south') settings['TEMPLATE_CONTEXT_PROCESSORS'].extend([ 'django.core.context_processors.request', 'aldryn_django.context_processors.debug', ]) settings['MIDDLEWARE_CLASSES'].extend([ 'django.middleware.locale.LocaleMiddleware', 'aldryn_django.middleware.CurrentSiteMiddleware', ]) settings['TEMPLATE_DIRS'] = env( 'TEMPLATE_DIRS', [os.path.join(settings['BASE_DIR'], 'templates')], ) settings['SITE_ID'] = env('SITE_ID', 1) self.domain_settings(data, settings, env=env) self.server_settings(settings, env=env) self.logging_settings(settings, env=env) # Order matters, sentry settings rely on logging being configured. self.sentry_settings(settings, env=env) self.cache_settings(settings, env=env) self.storage_settings(settings, env=env) self.i18n_settings(data, settings, env=env) self.migration_settings(settings, env=env) return settings
def parse(url, suffix='default'): url = furl(url) connection = { 'ENGINE': '', 'URL': '', 'INDEX_NAME': '', 'KWARGS': {}, } engine, protocol, platform = None, None, None scheme_parts = url.scheme.split('+') if len(scheme_parts) == 2: engine, protocol = scheme_parts elif len(scheme_parts) == 3: engine, protocol, platform = scheme_parts else: error_url = furl(url.url) error_url.password = '******' raise Exception( ('The scheme in the haystack url {} is not supported. It must ' 'have a scheme in the form of backend+protocol+platform:// or ' 'backend+protocol://.' 'Examples: es+https+aws:// es+http://').format(error_url)) url.scheme = protocol if engine == 'es': connection[ 'ENGINE'] = 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine' else: connection['ENGINE'] = engine if '*' in url.path.segments[0]: # If the index contains the wildcard, replace it with the suffix url.path.segments[0] = url.path.segments[0].replace('*', suffix) # extract the index name and remove the path from the original url index_name = '{}'.format(url.path.segments[0]) url.path.segments = [] connection['INDEX_NAME'] = index_name if platform == 'aws': aws_access_key_id = url.username aws_secret_key = url.password url.username = None url.password = None connection['URL'] = url.url region = url.host.split('.')[1] verify_certs = boolean_ish(url.query.params.get('verify_certs', True)) ConnectionClass = import_string( url.query.params.get('connection_class', 'elasticsearch.RequestsHttpConnection')) Serializer = import_string( url.query.params.get('serializer', 'elasticsearch.serializer.JSONSerializer')) if sys.version_info.major >= 3: # The workaround for the large payload issue below is causing # the underling Python `http` module to send the Content-Length # header twice when running on Python 3, which fails with a # 400 Bad Request on recent AWS ElasticSearch service endpoints. # Just drop the workaround as we were not able to reproduce the # issue anymore with any combination of recent dependencies and # we suppose that the issue does not exist anymore on Python 3 # because of its explicit handling of `bytes` and `str` as # different types. default_auth_class = 'requests_aws4auth.AWS4Auth' else: # The unicode handling of urllib3/pyopenssl combined with # AWS4Auth causes requests with large bodies (> 2MB) to fail. # For more details see the workaround referenced below. default_auth_class = 'aldryn_haystack.auth.AWS4AuthNotUnicode' AWS4Auth = import_string( url.query.params.get( 'aws_auth', default_auth_class, )) connection['KWARGS'] = { 'port': url.port, 'http_auth': AWS4Auth( aws_access_key_id, aws_secret_key, region, 'es', ), 'use_ssl': protocol == 'https', 'verify_certs': verify_certs, 'connection_class': ConnectionClass, 'serializer': Serializer(), } else: connection['URL'] = url.url connection['INDEX_NAME'] = index_name return connection
def to_settings(self, data, settings): from functools import partial from django.core.urlresolvers import reverse_lazy from aldryn_addons.utils import boolean_ish, djsenv env = partial(djsenv, settings=settings) # Need to detect if these settings are for Django 1.8+ # Is there a better way? Can't import django to check version =( is_django_18_or_later = ('TEMPLATES' in settings) # Core CMS stuff settings['INSTALLED_APPS'].extend([ 'cms', # 'aldryn_django_cms' must be after 'cms', otherwise we get # import time exceptions on other packages (e.g alryn-bootstrap3 # returns: # link_page = cms.models.fields.PageField( # AttributeError: 'module' object has no attribute 'fields' # ) 'aldryn_django_cms', 'menus', 'sekizai', 'treebeard', 'reversion', ]) # TODO: break out this stuff into other addons settings['INSTALLED_APPS'].extend([ 'parler', ]) settings['INSTALLED_APPS'].insert( settings['INSTALLED_APPS'].index('django.contrib.admin'), 'djangocms_admin_style', ) if is_django_18_or_later: settings['MIGRATION_MODULES'] = { 'cmsplugin_filer_file': 'cmsplugin_filer_file.migrations_django', 'cmsplugin_filer_image': 'cmsplugin_filer_image.migrations_django', 'cmsplugin_filer_folder': 'cmsplugin_filer_folder.migrations_django', 'cmsplugin_filer_link': 'cmsplugin_filer_link.migrations_django', 'cmsplugin_filer_teaser': 'cmsplugin_filer_teaser.migrations_django', 'cmsplugin_filer_video': 'cmsplugin_filer_video.migrations_django', } if is_django_18_or_later: settings['TEMPLATES'][0]['OPTIONS']['context_processors'].extend([ 'sekizai.context_processors.sekizai', 'cms.context_processors.cms_settings', ]) else: settings['TEMPLATE_CONTEXT_PROCESSORS'].extend([ 'sekizai.context_processors.sekizai', 'cms.context_processors.cms_settings', ]) settings['MIDDLEWARE_CLASSES'].extend([ 'cms.middleware.user.CurrentUserMiddleware', 'cms.middleware.page.CurrentPageMiddleware', 'cms.middleware.toolbar.ToolbarMiddleware', 'cms.middleware.language.LanguageCookieMiddleware', ]) settings['MIDDLEWARE_CLASSES'].insert( 0, 'cms.middleware.utils.ApphookReloadMiddleware', ) settings['ADDON_URLS_I18N_LAST'] = 'cms.urls' settings['CMS_PERMISSION'] = data['permissions_enabled'] old_cms_templates_json = os.path.join(settings['BASE_DIR'], 'cms_templates.json') if os.path.exists(old_cms_templates_json): # Backwards compatibility with v2 with open(old_cms_templates_json) as fobj: templates = json.load(fobj) else: templates = settings.get('CMS_TEMPLATES', json.loads(data['cms_templates'])) settings['CMS_TEMPLATES'] = templates # languages language_codes = [code for code, lang in settings['LANGUAGES']] settings['CMS_LANGUAGES'] = { 'default': { 'fallbacks': [fbcode for fbcode in language_codes], 'redirect_on_fallback': True, 'public': True, 'hide_untranslated': False, }, 1: [{ 'code': code, 'name': settings['ALL_LANGUAGES_DICT'][code], 'fallbacks': [fbcode for fbcode in language_codes if fbcode != code], 'public': True } for code in language_codes] } settings['PARLER_LANGUAGES'] = {} for site_id, languages in settings['CMS_LANGUAGES'].items(): if isinstance(site_id, int): langs = [{ 'code': lang['code'], 'fallbacks': [ fbcode for fbcode in language_codes if fbcode != lang['code'] ] } for lang in languages] settings['PARLER_LANGUAGES'].update({site_id: langs}) parler_defaults = {'fallback': settings['LANGUAGE_CODE']} for k, v in settings['CMS_LANGUAGES'].get('default', {}).items(): if k in [ 'hide_untranslated', ]: parler_defaults.update({k: v}) settings['PARLER_LANGUAGES'].update({'default': parler_defaults}) # aldryn-boilerplates and aldryn-snake # FIXME: Make ALDRYN_BOILERPLATE_NAME a configurable parameter settings['ALDRYN_BOILERPLATE_NAME'] = env( 'ALDRYN_BOILERPLATE_NAME', data.get('boilerplate_name', 'legacy'), ) settings['INSTALLED_APPS'].append('aldryn_boilerplates') if is_django_18_or_later: TEMPLATE_CONTEXT_PROCESSORS = settings['TEMPLATES'][0]['OPTIONS'][ 'context_processors'] TEMPLATE_LOADERS = settings['TEMPLATES'][0]['OPTIONS']['loaders'] else: TEMPLATE_CONTEXT_PROCESSORS = settings[ 'TEMPLATE_CONTEXT_PROCESSORS'] TEMPLATE_LOADERS = settings['TEMPLATE_LOADERS'] TEMPLATE_CONTEXT_PROCESSORS.extend([ 'aldryn_boilerplates.context_processors.boilerplate', 'aldryn_snake.template_api.template_processor', ]) TEMPLATE_LOADERS.insert( TEMPLATE_LOADERS.index( 'django.template.loaders.app_directories.Loader'), 'aldryn_boilerplates.template_loaders.AppDirectoriesLoader') settings['STATICFILES_FINDERS'].insert( settings['STATICFILES_FINDERS'].index( 'django.contrib.staticfiles.finders.AppDirectoriesFinder'), 'aldryn_boilerplates.staticfile_finders.AppDirectoriesFinder', ) # django sitemap support settings['INSTALLED_APPS'].append('django.contrib.sitemaps') # django-compressor settings['INSTALLED_APPS'].append('compressor') settings['STATICFILES_FINDERS'].append( 'compressor.finders.CompressorFinder') # Disable django-comporessor for now. It does not work with the current # setup. The cache is shared, which holds the manifest. But the # compressed files reside in the docker container, which can go away at # any time. # Working solutions could be: # 1) use pre-compression # (https://django-compressor.readthedocs.org/en/latest/usage/#pre-compression) # at docker image build time. # 2) Use shared storage and save the manifest with the generated files. # Although that could be a problem if different versions of the same # app compete for the manifest file. # We're keeping compressor in INSTALLED_APPS for now, so that templates # in existing projects don't break. settings['COMPRESS_ENABLED'] = env('COMPRESS_ENABLED', False) # django-robots settings['INSTALLED_APPS'].append('robots') # django-filer settings['INSTALLED_APPS'].extend([ 'filer', 'easy_thumbnails', 'mptt', 'polymorphic', ]) settings['FILER_DEBUG'] = boolean_ish( env('FILER_DEBUG', settings['DEBUG'])) settings['FILER_ENABLE_LOGGING'] = boolean_ish( env('FILER_ENABLE_LOGGING', True)) settings['FILER_IMAGE_USE_ICON'] = True settings['ADDON_URLS'].append('filer.server.urls') # easy-thumbnails settings['INSTALLED_APPS'].extend([ 'easy_thumbnails', ]) settings['THUMBNAIL_QUALITY'] = env('THUMBNAIL_QUALITY', 90) # FIXME: enabling THUMBNAIL_HIGH_RESOLUTION causes timeouts/500! settings['THUMBNAIL_HIGH_RESOLUTION'] = False settings['THUMBNAIL_PRESERVE_EXTENSIONS'] = ['png', 'gif'] settings['THUMBNAIL_PROCESSORS'] = ( 'easy_thumbnails.processors.colorspace', 'easy_thumbnails.processors.autocrop', 'filer.thumbnail_processors.scale_and_crop_with_subject_location', 'easy_thumbnails.processors.filters', ) settings['THUMBNAIL_SOURCE_GENERATORS'] = ( 'easy_thumbnails.source_generators.pil_image', ) settings['THUMBNAIL_CACHE_DIMENSIONS'] = True # commented out because fix-tree has a major bug # this should be ok with CMS >=3.1.4 # settings['MIGRATION_COMMANDS'].append( # 'python manage.py cms fix-tree --noinput' # ) # default plugins settings['INSTALLED_APPS'].extend([ 'djangocms_text_ckeditor', 'djangocms_link', 'djangocms_snippet', 'djangocms_googlemap', # cmsplugin-filer 'cmsplugin_filer_file', 'cmsplugin_filer_image', # required by aldryn-forms 'captcha', ]) # boilerplate must provide /static/js/modules/ckeditor.wysiwyg.js and /static/css/base.css CKEDITOR_SETTINGS = { 'height': 300, 'language': '{{ language }}', 'toolbar': 'CMS', 'skin': 'moono', 'extraPlugins': 'cmsplugins', 'toolbar_HTMLField': [ ['Undo', 'Redo'], ['cmsplugins', '-', 'ShowBlocks'], ['Format', 'Styles'], ['TextColor', 'BGColor', '-', 'PasteText', 'PasteFromWord'], ['Maximize', ''], '/', [ 'Bold', 'Italic', 'Underline', '-', 'Subscript', 'Superscript', '-', 'RemoveFormat' ], ['JustifyLeft', 'JustifyCenter', 'JustifyRight'], ['HorizontalRule'], ['Link', 'Unlink'], [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Table' ], ['Source'], ['Link', 'Unlink', 'Anchor'], ], } boilerplate_name = settings['ALDRYN_BOILERPLATE_NAME'] if boilerplate_name == 'bootstrap3': CKEDITOR_SETTINGS[ 'stylesSet'] = 'default:/static/js/addons/ckeditor.wysiwyg.js' CKEDITOR_SETTINGS['contentsCss'] = ['/static/css/base.css'] else: CKEDITOR_SETTINGS[ 'stylesSet'] = 'default:/static/js/modules/ckeditor.wysiwyg.js' CKEDITOR_SETTINGS['contentsCss'] = ['/static/css/base.css'] # select2 (required by djangocms_link plugin) settings['INSTALLED_APPS'].extend([ 'django_select2', ]) settings['ADDON_URLS'].append('aldryn_django_cms.urls') settings['ADDON_URLS_I18N'].append('aldryn_django_cms.urls_i18n') if 'ALDRYN_SSO_LOGIN_WHITE_LIST' in settings: # stage sso enabled # add internal endpoints that do not require authentication settings['ALDRYN_SSO_LOGIN_WHITE_LIST'].append( reverse_lazy('cms-check-uninstall')) # this is an internal django-cms url # which gets called when a user logs out from toolbar settings['ALDRYN_SSO_LOGIN_WHITE_LIST'].append( reverse_lazy('admin:cms_page_resolve')) return settings
def to_settings(self, data, settings): import django_cache_url import dj_database_url import warnings from functools import partial from aldryn_addons.utils import boolean_ish, djsenv env = partial(djsenv, settings=settings) # BASE_DIR should already be set by aldryn-addons settings["BASE_DIR"] = env("BASE_DIR", required=True) settings["DATA_ROOT"] = env( "DATA_ROOT", os.path.join(settings["BASE_DIR"], "data") ) settings["SECRET_KEY"] = env("SECRET_KEY", "this-is-not-very-random") settings["DEBUG"] = boolean_ish(env("DEBUG", False)) settings["ENABLE_SYNCING"] = boolean_ish( env("ENABLE_SYNCING", settings["DEBUG"]) ) settings["DISABLE_TEMPLATE_CACHE"] = boolean_ish( env("DISABLE_TEMPLATE_CACHE", settings["DEBUG"]) ) settings["DATABASE_URL"] = env("DATABASE_URL") settings["CACHE_URL"] = env("CACHE_URL") if env("DJANGO_MODE") == "build": # In build mode we don't have any connected services like db or # cache available. So we need to configure those things in a way # they can run without real backends. settings["DATABASE_URL"] = "sqlite://:memory:" settings["CACHE_URL"] = "locmem://" if not settings["DATABASE_URL"]: settings["DATABASE_URL"] = "sqlite:///{}".format( os.path.join(settings["DATA_ROOT"], "db.sqlite3") ) warnings.warn( "no database configured. Falling back to DATABASE_URL={0}".format( settings["DATABASE_URL"] ), RuntimeWarning, ) settings["DATABASES"]["default"] = dj_database_url.parse( settings["DATABASE_URL"] ) if not settings["CACHE_URL"]: settings["CACHE_URL"] = "locmem://" warnings.warn( "no cache configured. Falling back to CACHE_URL={0}".format( settings["CACHE_URL"] ), RuntimeWarning, ) settings["CACHES"]["default"] = django_cache_url.parse( settings["CACHE_URL"] ) settings["ROOT_URLCONF"] = env("ROOT_URLCONF", "urls") settings["ADDON_URLS_I18N"].append("aldryn_django.i18n_urls") settings["WSGI_APPLICATION"] = "wsgi.application" settings["INSTALLED_APPS"].extend( [ "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.sites", "django.contrib.messages", "django.contrib.admin", "django.contrib.staticfiles", "aldryn_django", ] ) if settings["ENABLE_SYNCING"] or settings["DISABLE_TEMPLATE_CACHE"]: loader_list_class = list else: loader_list_class = CachedLoader settings["TEMPLATES"] = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": env( "TEMPLATE_DIRS", [os.path.join(settings["BASE_DIR"], "templates")], ), "OPTIONS": { "debug": boolean_ish( env("TEMPLATE_DEBUG", settings["DEBUG"]) ), "context_processors": [ "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", "django.template.context_processors.i18n", "django.template.context_processors.debug", "django.template.context_processors.request", "django.template.context_processors.media", "django.template.context_processors.csrf", "django.template.context_processors.tz", "django.template.context_processors.static", "aldryn_django.context_processors.debug", ], "loaders": loader_list_class( [ "django.template.loaders.filesystem.Loader", "django.template.loaders.app_directories.Loader", "django.template.loaders.eggs.Loader", ] ), }, } ] settings["MIDDLEWARE_CLASSES"] = [ "django.contrib.sessions.middleware.SessionMiddleware", # 'django.middleware.common.CommonMiddleware', "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", # 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.locale.LocaleMiddleware", "django.contrib.sites.middleware.CurrentSiteMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", # 'django.middleware.security.SecurityMiddleware', ] if not env("DISABLE_GZIP"): settings["MIDDLEWARE_CLASSES"].insert( 0, "django.middleware.gzip.GZipMiddleware" ) settings["SITE_ID"] = env("SITE_ID", 1) settings["ADDON_URLS_I18N_LAST"] = "aldryn_django.urls_redirect" self.domain_settings(data, settings, env=env) self.security_settings(data, settings, env=env) self.server_settings(settings, env=env) self.logging_settings(settings, env=env) # Order matters, sentry settings rely on logging being configured. self.sentry_settings(settings, env=env) self.storage_settings_for_media(settings, env=env) self.storage_settings_for_static(data, settings, env=env) self.email_settings(data, settings, env=env) self.i18n_settings(data, settings, env=env) self.migration_settings(settings, env=env) settings["ALDRYN_DJANGO_ENABLE_GIS"] = data["enable_gis"] if settings["ALDRYN_DJANGO_ENABLE_GIS"]: self.gis_settings(settings, env=env) return settings
# -*- coding: utf-8 -*- from __future__ import unicode_literals, absolute_import import os from aldryn_addons.utils import boolean_ish env = os.environ.get UWSGI_DEFAULT_DOMAIN = env('DJANGO_MULTISITE_PLUS_UWSGI_DEFAULT_DOMAIN') UWSGI_BASE_SOCKETS_DIR = env('DJANGO_MULTISITE_PLUS_UWSGI_BASE_SOCKETS_DIR', '/app/uwsgi/tmp/vassal-sockets/') UWSGI_BASE_CONFIG_DIR = env('DJANGO_MULTISITE_PLUS_UWSGI_BASE_CONFIG_DIR', '/app/uwsgi/') UWSGI_ALIAS_DOMAIN_MAPPING_DIR = env( 'DJANGO_MULTISITE_PLUS_UWSGI_ALIAS_DOMAIN_MAPPING_DIR', '/app/uwsgi/tmp/aliases/') UWSGI_LOCAL_TEST_MODE = boolean_ish( env('DJANGO_MULTISITE_PLUS_UWSGI_LOCAL_TEST_MODE')) UWSGI_LOCAL_TEST_KEY = env('DJANGO_MULTISITE_PLUS_UWSGI_LOCAL_TEST_KEY')