From 78753bf57d357e7e887ccf1eed40ed38102c772f Mon Sep 17 00:00:00 2001 From: Alex Rocha Date: Fri, 10 Sep 2021 17:02:27 -0500 Subject: [PATCH 01/31] Adding support for CMS auth via core portal --- .dockerignore | 3 + .gitignore | 3 + Makefile | 2 +- taccsite_cms/default_secrets.py | 305 ------------- taccsite_cms/remote_cms_auth.py | 88 ++++ taccsite_cms/settings.py | 406 +++++++----------- .../templates/assets_site_delayed.html | 2 +- taccsite_cms/templates/header.html | 4 +- taccsite_cms/urls.py | 16 +- taccsite_custom | 2 +- 10 files changed, 271 insertions(+), 560 deletions(-) delete mode 100644 taccsite_cms/default_secrets.py create mode 100644 taccsite_cms/remote_cms_auth.py diff --git a/.dockerignore b/.dockerignore index 2a717da57..39f410288 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,9 @@ # Version Control .git +**settings_custom.py +**settings_local.py + # Python *.pyc *.pyo diff --git a/.gitignore b/.gitignore index 634ac29e1..f477e717f 100644 --- a/.gitignore +++ b/.gitignore @@ -107,3 +107,6 @@ publish # build script local files web/build/buildinfo.properties web/build/config/buildinfo.properties + +*settings_custom.py +*settings_local.py diff --git a/Makefile b/Makefile index f5e456abb..cd8476388 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -DOCKERHUB_REPO := taccwma/$(shell cat ./docker_repo.var) +DOCKERHUB_REPO := taccwma/core-portal-cms DOCKER_TAG ?= $(shell git rev-parse --short HEAD) DOCKER_IMAGE := $(DOCKERHUB_REPO):$(DOCKER_TAG) DOCKER_IMAGE_LATEST := $(DOCKERHUB_REPO):latest diff --git a/taccsite_cms/default_secrets.py b/taccsite_cms/default_secrets.py deleted file mode 100644 index 1d27a45ba..000000000 --- a/taccsite_cms/default_secrets.py +++ /dev/null @@ -1,305 +0,0 @@ -# TACC CMS SITE TEMPLATE SETTINGS. -# DEFAULT VALUES. -# CHANGE BEFOR DEV/PREPROD/PRODUCTION DEPLOYMENT. - -######################## -# DJANGO SETTINGS -######################## - -_SECRET_KEY = 'replacethiswithareallysecureandcomplexsecretkeystring' -_DEBUG = True # False for Prod. -_CONSOLE_LOG_ENABLED = False # Boolean check to turn on/off console logging statements. - -# Specify allowed hosts or use an asterisk to allow any host and simplify the config. -# _ALLOWED_HOSTS = ['hostname.tacc.utexas.edu', 'host.ip.v4.address', '0.0.0.0', 'localhost', '127.0.0.1'] # In production. -_ALLOWED_HOSTS = ['0.0.0.0', '127.0.0.1', 'localhost', '*'] # In development. - -# Boolean check to see if ldap is being used by the site. -# Requires django-auth-ldap ≥ 2.0.0 -_LDAP_ENABLED = False - -# Boolean check to determine the appropriate database settings when using containers. -_USING_CONTAINERS = True - -######################## -# DATABASE SETTINGS -######################## - -if _USING_CONTAINERS: - # used in container deployments. - _DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'PORT': '5432', - 'NAME': 'taccsite', - 'USER': 'postgresadmin', - 'PASSWORD': 'taccforever', # Change before live deployment. - 'HOST': 'core_cms_postgres' - } - } -else: - # used in local dev, venv or manual deployments. - _DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'PORT': '5432', - 'NAME': 'taccsite', - 'USER': 'postgresadmin', - 'PASSWORD': 'taccforever', # Change before live deployment. - 'HOST': 'localhost' - } - } - -######################## -# DJANGO CMS SETTINGS -######################## - -# CMS Site (allows for multiple sites on a single CMS) -_SITE_ID = 1 -_CMS_TEMPLATES = ( - # Customize this list in per-project `secrets.py` - # FAQ: First template is default template - # REF: http://docs.django-cms.org/en/latest/how_to/install.html#templates - - # For standard pages (has Container and Breadcrumbs) - ('standard.html', 'Standard'), - # For content that spans full window width (no Container nor Breadcrumbs) - ('fullwidth.html', 'Full Width'), - - # Any project that needs per-project styles must have a custom template - # FAQ: This is a tedious solution until a cleaner solution is devised - # TODO: Automate per-project asset load and update exisitng sites as needed - # ('name-of-project/templates/fullwidth.html', 'Fullwidth (Custom)'), - # NOTE: If project later uses custom template, then for that project: - # 1. Rename standard default template to "DEPRECATED […]". - # 2. Update all pages to use the custom default template. - # 3. Disable standard default template (remove from `_CMS_TEMPLATES`). - # ('fullwidth.html', 'DEPRECATED Fullwidth'), - - # Any portal whose homepage has NO design must enable and use this template - # ('home_portal.html', 'Standard Portal Homepage'), - - # All portals should enable all of these templates - # FAQ: If this becomes mandatory, then in `settings.py`: - # `if _PORTAL: [ manually add these entries ]` - # ('guide.html', 'Guide'), - # ('guides/getting_started.html', 'Guide: Getting Started'), - # ('guides/data_transfer.html', 'Guide: Data Transfer'), - # ('guides/data_transfer.globus.html', 'Guide: Globus Data Transfer'), - # ('guides/portal_technology.html', 'Guide: Portal Technology Stack'), - - # For now, only Core portal should enable this template - # FAQ: We know not yet how to auto-replicate pages and plugins across sites - # ('style_guide.html', 'Style Guide'), -) - -######################## -# GOOGLE ANALYTICS -######################## - -# To use during dev, Tracking Protection in browser needs to be turned OFF. -_GOOGLE_ANALYTICS_PROPERTY_ID = "UA-123ABC@%$&-#" -_GOOGLE_ANALYTICS_PRELOAD = True - -######################## -# CMS FORMS -######################## - -# Create CMS Forms -# SEE: https://pypi.org/project/djangocms-forms/ -# SEE: https://www.google.com/recaptcha/admin/create -_DJANGOCMS_FORMS_RECAPTCHA_PUBLIC_KEY = "" -_DJANGOCMS_FORMS_RECAPTCHA_SECRET_KEY = "" - -######################## -# ELASTICSEARCH -######################## - -_ES_AUTH = 'username:password' -_ES_HOSTS = 'http://elasticsearch:9200' -_ES_INDEX_PREFIX = 'cms-dev-{}' -_ES_DOMAIN = 'http://localhost:8000' - -######################## -# FEATURES -######################## - -""" -Features for the CMS that can be turned either ON or OFF - -Usage: - -- For baked-in features, like BRANDING or PORTAL, see relevant section instead. -- For optional features, look below, and enable feature(s) via _FEATURES list. - -Baked-In Feature Setting Example. - -# Desctipion of feature X -# SEE: [link to user/div guide about feature] -_FEATURE_A = "someValue" - -Optional Feature Toggle Example. - -_FEATURES = { - # Desctipion of feature X - # SEE: [link to user/dev guide about feature] - "X": True, - - # Desctipion of feature Y - # SEE: [link to user/dev guide about feature] - "Y": False, - - # Desctipion of feature Z - # SEE: [link to user/dev guide about feature] - "Z": True, -} - -""" - -_FEATURES = { - # Blog/News & Social Media Metadata - # GL-42: Split this into two features - # SEE: https://confluence.tacc.utexas.edu/x/EwDeCg - # SEE: https://confluence.tacc.utexas.edu/x/FAA9Cw - "blog": False, -} - -######################## -# BRANDING & LOGOS & FAVICON -######################## -# TODO: GH-59: Use Dict Not Array for Branding Settings - -# Branding settings for portal and navigation. - -""" -Additional Branding and Portal Logos for Partner & Affiliate Organizations - -Usage: - -- For each beand used in the templating, add corresponding new settings values to this file (see example below). -- New branding settings must be added to the _BRANDING list to render in the template. -- The order of the _BRANDING list determines the rendering order of the elements in the template. -- The portal logo setting must be assigned to the _LOGO variable to render in the template. -- The following VALUES for new elements set in the configuration object must exist in the portal css as well: - - Any new selectors or css styles (add to /taccsite_cms/static/site_cms/css/src/_imports/branding_logos.css) - - Image files being references (add to /taccsite_cms/static/site_cms/img/org_logos) - -Values to populate (for an array): - -_SETTING_NAME = [ # The name of the branding or logo config setting object. - "org_name", # The name of the organization the branding belongs too. - "img_file_src", # Path and filename relative to the static files folder. - "img_element_classes", # The list of selectors to apply to the rendered element, these need to exist in the css/scss. - "a_target_url", # The href link to follow when clicked, use "/" for portal logos. - "a_target_type", # The target to open the new link in, use _blank for external links, _self for internal links. - "alt_text", # The text to read or render for web assistance standards. - "cors_setting", # The CORS setting for the image, set to anonymous by default. - "visibility" # Toggles wether or not to display the element in the template, use True to render, False to hide. -] - -Values to populate (for a dict): - -_SETTING_NAME = { # The name of the favicon config setting object. - "img_file_src": "…", # Path and filename relative to the static files folder. -} - -Branding Configuration Example. - -_ANORG_BRANDING = [ - "anorg", - "site_cms/img/org_logos/anorg-logo.png" - "branding-anorg", - "https://www.anorg.com/" - "_blank", - "ANORG Logo", - "anonymous", - "True" -] - -Logo Configuration Example. - -_ANORG_LOGO = [ - "anorg", - "site_cms/img/org_logos/anorg-logo.png" - "branding-anorg", - "/" - "_self", - "ANORG Logo", - "anonymous", - "True" -] - -Favicon Configuration Example. - -_ANORG_FAVICON = { - "img_file_src": "site_cms/img/favicons/favicon.ico" -} -""" - -######################## -# BRANDING - -_TACC_BRANDING = [ - "tacc", - "site_cms/img/org_logos/tacc-white.png", - "branding-tacc", - "https://www.tacc.utexas.edu/", - "_blank", - "TACC Logo", - "anonymous", - "True" -] - -_UTEXAS_BRANDING = [ - "utexas", - "site_cms/img/org_logos/utaustin-white.png", - "branding-utaustin", - "https://www.utexas.edu/", - "_blank", - "University of Texas at Austin Logo", - "anonymous", - "True" -] - -_NSF_BRANDING = [ - "nsf", - "site_cms/img/org_logos/nsf-white.png", - "branding-nsf", - "https://www.nsf.gov/", - "_blank", - "NSF Logo", - "anonymous", - "True" -] - -_BRANDING = [ _TACC_BRANDING, _UTEXAS_BRANDING ] # Default TACC Portal. -# _BRANDING = [ _NSF_BRANDING, _TACC_BRANDING, _UTEXAS_BRANDING ] # NSF Funded TACC Portal. - -######################## -# LOGOS - -_PORTAL_LOGO = [ - "portal", - "site_cms/img/org_logos/portal.png", - "", - "/", - "_self", - "Portal Logo", - "anonymous", - "True" -] - -_LOGO = _PORTAL_LOGO # Default Portal Logo. - -######################## -# FAVICON - -_FAVICON = { - "img_file_src": "site_cms/img/favicons/favicon.ico" -} - -######################## -# PORTAL -######################## - -_PORTAL = False # True for any CMS that is part of a Portal. diff --git a/taccsite_cms/remote_cms_auth.py b/taccsite_cms/remote_cms_auth.py new file mode 100644 index 000000000..5357ea4bf --- /dev/null +++ b/taccsite_cms/remote_cms_auth.py @@ -0,0 +1,88 @@ +import inspect +from django.http import HttpResponse, HttpResponseRedirect +from django.contrib.auth.backends import ModelBackend +from django.contrib.auth import get_user_model +from django.contrib import auth as auth +import requests +import logging +from django.conf import settings +UserModel = get_user_model() + +logger = logging.getLogger(__name__) + + +def verify_and_auth(request): + user = auth.authenticate(request) + if user: + # User is valid. Set request.user and persist user in the session by logging the user in. + request.user = user + auth.login(request, user) + response = HttpResponseRedirect(request.GET.get('next', '/workbench/dashboard/')) + else: + response = HttpResponseRedirect('/') + return response + +class CorePortalAuthBackend(ModelBackend): + """ + Validates core portal session + Extends Django ModelBackend, parts of this were taken from Django's source: + https://github.com/django/django/blob/stable/2.2.x/django/contrib/auth/backends.py#L128 + """ + create_unknown_user = True + + def authenticate(self, request): + response = requests.get('{0}/api/users/auth/'.format(\ + getattr(settings,'CEP_AUTH_VERIFICATION_ENDPOINT','http://django:6000')), + cookies={'coresessionid': request.COOKIES.get('coresessionid')}) + user_data = response.json() + if user_data is None or user_data['username'] is None: + return None + username = user_data['username'] + email = user_data['email'] + + if request.user.is_authenticated: + self._remove_invalid_user(request) + + if self.create_unknown_user: + user, created = UserModel._default_manager.get_or_create(**{ + UserModel.USERNAME_FIELD: username, UserModel.EMAIL_FIELD: email + }) + if created: + args = (request, user) + try: + inspect.getcallargs(self.configure_user, request, user) + except TypeError: + args = (user,) + warnings.warn( + 'Update %s.configure_user() to accept `request` as ' + 'the first argument.' + % self.__class__.__name__, RemovedInDjango31Warning + ) + user = self.configure_user(*args) + else: + try: + user = UserModel._default_manager.get_by_natural_key(username) + except UserModel.DoesNotExist: + pass + return user if self.user_can_authenticate(user) else None + + def _remove_invalid_user(self, request): + """ + Remove the current authenticated user + """ + try: + stored_backend = load_backend(request.session.get(auth.BACKEND_SESSION_KEY, '')) + except ImportError: + # backend failed to load + auth.logout(request) + else: + if isinstance(stored_backend, RemoteUserBackend): + auth.logout(request) + + def configure_user(self, request, user): + """ + Configure a user after creation and return the updated user. + By default, return the user unmodified. + """ + return user + diff --git a/taccsite_cms/settings.py b/taccsite_cms/settings.py index 66794e77b..d8ff22e43 100644 --- a/taccsite_cms/settings.py +++ b/taccsite_cms/settings.py @@ -1,13 +1,9 @@ -# taccsite_cms/settings.py """ -Django settings for taccsite_cms project. - +Django settings Generated by 'django-admin startproject' using Django 1.11.22. - For more information on this file, see https://docs.djangoproject.com/en/2.2/topics/settings/ - For the full list of settings and their values, see https://docs.djangoproject.com/en/2.2/ref/settings/ """ @@ -15,90 +11,162 @@ import logging import os from glob import glob +import ldap +from django_auth_ldap.config import LDAPSearch, GroupOfNamesType - +SECRET_KEY = 'CHANGE_ME' def gettext(s): return s +DATA_DIR = os.path.dirname(os.path.dirname(__file__)) -# Import secret values dynamically without breaking portal. -def getsecrets(): - new_secrets = {}; # Var to hold secret values once imported succesfully. - # Check for production secrets. - try: - print('Checking for secret production values') - import taccsite_cms.secrets as secrets # Prod/Staging/Local Dev values (used instead of the default values if present) - new_secrets = secrets - print('Production secrets found, using values') - except ModuleNotFoundError as err: - # Error handling - print(err) - print('No production secrets found') - pass - # Check for the default secret values. - try: - print('Checking for default secret values') - import taccsite_cms.default_secrets as default_secrets # Default demo values (works for basic local dev out of the box) - new_secrets = default_secrets - print('Default secrets found, using default values') - except ModuleNotFoundError as err: - # Error handling - print(err) - print('No default secrets found') - print('Check that you have a secrets.py or default_secrets.py') - finally: - # Return the secret values if they are found. - return new_secrets - -# Assign secret settings values. -current_secrets = getsecrets() - -# Boolean check to turn on/off console logging statements. -CONSOLE_LOG_ENABLED = current_secrets._CONSOLE_LOG_ENABLED - -# Verifying console logging is on. -if CONSOLE_LOG_ENABLED: - print("--> Variable CONSOLE_LOG_ENABLED: ", CONSOLE_LOG_ENABLED) - -LDAP_ENABLED = current_secrets._LDAP_ENABLED - -if CONSOLE_LOG_ENABLED: - print("--> Variable LDAP_ENABLED: ", LDAP_ENABLED) - -if LDAP_ENABLED: - import ldap - from django_auth_ldap.config \ - import LDAPSearch, GroupOfNamesType +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -DATA_DIR = os.path.dirname(os.path.dirname(__file__)) +################################################################################################### -if CONSOLE_LOG_ENABLED: - print("--> Variable DATA_DIR: ", DATA_DIR) -# Build paths inside the project like this: os.path.join(BASE_DIR, ...) -BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +DEBUG = True # False for Prod. + +# Specify allowed hosts or use an asterisk to allow any host and simplify the config. +# ALLOWED_HOSTS = ['hostname.tacc.utexas.edu', 'host.ip.v4.address', '0.0.0.0', 'localhost', '127.0.0.1'] # In production. +ALLOWED_HOSTS = ['0.0.0.0', '127.0.0.1', 'localhost', '*'] # In development. -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ +# Requires django-auth-ldap ≥ 2.0.0 +LDAP_ENABLED = True -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = current_secrets._SECRET_KEY -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = current_secrets._DEBUG +######################## +# DATABASE SETTINGS +######################## -# Host Access. -ALLOWED_HOSTS = current_secrets._ALLOWED_HOSTS +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'PORT': '5432', + 'NAME': 'taccsite', + 'USER': 'postgresadmin', + 'PASSWORD': 'taccforever', # Change before live deployment. + 'HOST': 'core_cms_postgres' + } +} -# Custom Branding. -BRANDING = current_secrets._BRANDING -LOGO = current_secrets._LOGO -FAVICON = current_secrets._FAVICON +AUTHENTICATION_BACKENDS = [ + "django.contrib.auth.backends.ModelBackend", + "taccsite_cms.remote_cms_auth.CorePortalAuthBackend", + "django_auth_ldap.backend.LDAPBackend" +] + +''' LDAP Auth Settings ''' +AUTH_LDAP_SERVER_URI = "ldap://ldap.tacc.utexas.edu" +AUTH_LDAP_CONNECTION_OPTIONS = {ldap.OPT_REFERRALS: 0} +AUTH_LDAP_START_TLS = True +AUTH_LDAP_BIND_AS_AUTHENTICATING_USER = True -# Configure Portal. -PORTAL = current_secrets._PORTAL +AUTH_LDAP_BIND_DN = "" +AUTH_LDAP_BIND_PASSWORD = "" +AUTH_LDAP_USER_SEARCH = LDAPSearch( + "ou=People,dc=tacc,dc=utexas,dc=edu", ldap.SCOPE_SUBTREE, "(uid=%(user)s)" +) -# Optional features. -FEATURES = current_secrets._FEATURES +AUTH_LDAP_AUTHORIZE_ALL_USERS = True + +AUTH_LDAP_USER_ATTR_MAP = { + "first_name": "givenName", + "last_name": "sn", + "email": "mail", +} + +SITE_ID = 1 +CMS_TEMPLATES = ( + ('standard.html', 'Standard'), + ('fullwidth.html', 'Full Width'), +) + +######################## +# GOOGLE ANALYTICS +######################## + +# To use during dev, Tracking Protection in browser needs to be turned OFF. +GOOGLE_ANALYTICS_PROPERTY_ID = "UA-123ABC@%$&-#" +GOOGLE_ANALYTICS_PRELOAD = True + +######################## +# CMS FORMS +######################## + +# Create CMS Forms +# SEE: https://pypi.org/project/djangocms-forms/ +# SEE: https://www.google.com/recaptcha/admin/create +DJANGOCMS_FORMS_RECAPTCHA_PUBLIC_KEY = "" +DJANGOCMS_FORMS_RECAPTCHA_SECRET_KEY = "" + +######################## +# ELASTICSEARCH +######################## + +ES_AUTH = 'username:password' +ES_HOSTS = 'http://elasticsearch:9200' +ES_INDEX_PREFIX = 'cms-dev-{}' +ES_DOMAIN = 'http://localhost:8000' + +TACC_BRANDING = [ + "tacc", + "site_cms/img/org_logos/tacc-white.png", + "branding-tacc", + "https://www.tacc.utexas.edu/", + "_blank", + "TACC Logo", + "anonymous", + "True" +] + +UTEXAS_BRANDING = [ + "utexas", + "site_cms/img/org_logos/utaustin-white.png", + "branding-utaustin", + "https://www.utexas.edu/", + "_blank", + "University of Texas at Austin Logo", + "anonymous", + "True" +] + +NSF_BRANDING = [ + "nsf", + "site_cms/img/org_logos/nsf-white.png", + "branding-nsf", + "https://www.nsf.gov/", + "_blank", + "NSF Logo", + "anonymous", + "True" +] + +BRANDING = [ TACC_BRANDING, UTEXAS_BRANDING ] + +PORTAL_LOGO = [ + "portal", + "site_cms/img/org_logos/portal.png", + "", + "/", + "_self", + "Portal Logo", + "anonymous", + "True" +] + +LOGO = PORTAL_LOGO + +FAVICON = { + "img_file_src": "site_cms/img/favicons/favicon.ico" +} + +INCLUDES_CORE_PORTAL = True +LOGOUT_REDIRECT_URL='/' +## using container name to avoid cep.dev dns issues locally +## this will need to be updated for dev/pprd/prod systems +## for example, CEP_AUTH_VERIFICATION_ENDPOINT=https://dev.cep.tacc.utexas.edu +CEP_AUTH_VERIFICATION_ENDPOINT='http://django:6000' +################################################################################################### # Application definition ROOT_URLCONF = 'taccsite_cms.urls' @@ -108,9 +176,6 @@ def getsecrets(): STATIC_URL = '/static/' STATIC_ROOT = os.path.join(DATA_DIR, 'static') -if CONSOLE_LOG_ENABLED: - print("--> Variable STATIC_ROOT: ", STATIC_ROOT) - STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'taccsite_cms', 'static'), # os.path.join(BASE_DIR, 'taccsite_cms', 'en', 'static'), @@ -118,16 +183,9 @@ def getsecrets(): os.path.join(BASE_DIR, 'taccsite_custom', '*', 'static') )) -if CONSOLE_LOG_ENABLED: - print("--> Variable STATICFILES_DIRS: ", STATICFILES_DIRS) - # User Uploaded Files Location. MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(DATA_DIR, 'media') - -if CONSOLE_LOG_ENABLED: - print("--> Variable MEDIA_ROOT: ", MEDIA_ROOT) - TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', @@ -168,9 +226,6 @@ def getsecrets(): }, ] -if CONSOLE_LOG_ENABLED: - print("--> Variable TEMPLATES: ", TEMPLATES) - MIDDLEWARE = [ 'cms.middleware.utils.ApphookReloadMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', @@ -206,10 +261,8 @@ def getsecrets(): 'djangocms_text_ckeditor', 'filer', 'easy_thumbnails', - # 'djangocms_audio', 'djangocms_column', 'djangocms_file', - # 'djangocms_forms', # FP-416: Pending full support 'djangocms_link', 'djangocms_picture', 'djangocms_style', @@ -234,15 +287,10 @@ def getsecrets(): 'djangocms_bootstrap4.contrib.bootstrap4_utilities', 'haystack', 'aldryn_apphooks_config', - # For faster testing, disable migrations during database creation - # SEE: https://stackoverflow.com/a/37150997 'test_without_migrations', 'taccsite_cms', - # Restore djangocms plugins that bootstrap4 hides 'taccsite_cms.contrib.bootstrap4_djangocms_link', 'taccsite_cms.contrib.bootstrap4_djangocms_picture', - # TODO: Extract TACC CMS UI components into pip-installable plugins - # FAQ: The djangocms_bootstrap4 library can serve as an example 'taccsite_cms.contrib.taccsite_sample', 'taccsite_cms.contrib.taccsite_system_monitor', 'taccsite_cms.contrib.taccsite_data_list' @@ -269,77 +317,12 @@ def get_subdirs_as_module_names(path): INSTALLED_APPS_APPEND = get_subdirs_as_module_names(CUSTOM_CMS_DIR) INSTALLED_APPS = INSTALLED_APPS + INSTALLED_APPS_APPEND - -if CONSOLE_LOG_ENABLED: - print("--> Variable INSTALLED_APPS: ", INSTALLED_APPS) - -AUTHENTICATION_BACKENDS = [ - "django.contrib.auth.backends.ModelBackend", -] - -if LDAP_ENABLED: - AUTHENTICATION_BACKENDS.insert(0, - "django_auth_ldap.backend.LDAPBackend" - ) - - ''' LDAP Auth Settings ''' - AUTH_LDAP_SERVER_URI = "ldap://ldap.tacc.utexas.edu" - AUTH_LDAP_CONNECTION_OPTIONS = {ldap.OPT_REFERRALS: 0} - AUTH_LDAP_START_TLS = True - AUTH_LDAP_BIND_AS_AUTHENTICATING_USER = True - - AUTH_LDAP_BIND_DN = "" - AUTH_LDAP_BIND_PASSWORD = "" - AUTH_LDAP_USER_SEARCH = LDAPSearch( - "ou=People,dc=tacc,dc=utexas,dc=edu", ldap.SCOPE_SUBTREE, "(uid=%(user)s)" - ) - - AUTH_LDAP_AUTHORIZE_ALL_USERS = True - - AUTH_LDAP_USER_ATTR_MAP = { - "first_name": "givenName", - "last_name": "sn", - "email": "mail", - } - - ''' - # More customizations - - AUTH_LDAP_REQUIRE_GROUP = "cn=TACC-ACI-WMA,ou=Groups,dc=tacc,dc=utexas,dc=edu" - AUTH_LDAP_GROUP_SEARCH = LDAPSearch( - "ou=Groups,dc=tacc,dc=utexas,dc=edu", - ldap.SCOPE_SUBTREE, - "(objectClass=groupOfUniqueNames)", - ) - AUTH_LDAP_GROUP_TYPE = GroupOfNamesType(name_attr="cn") - ''' - ''' End LDAP Auth Settings ''' - -if getattr(current_secrets, '_CACHES', None): - CACHES = secrets._CACHES # Are we actually using this setting? - -DATABASES = current_secrets._DATABASES - MIGRATION_MODULES = { } - -# SSL Setup. -# SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') -# SECURE_SSL_REDIRECT = True -# SESSION_COOKIE_SECURE = True -# CSRF_COOKIE_SECURE = True - -# Internationalization -# https://docs.djangoproject.com/en/2.2/topics/i18n/ - LANGUAGE_CODE = 'en' TIME_ZONE = 'America/Chicago' USE_I18N = True USE_L10N = True USE_TZ = True - -# DjangoCMS Setup. -SITE_ID = current_secrets._SITE_ID - LANGUAGES = ( # Customize this ('en', gettext('en')), @@ -363,7 +346,6 @@ def get_subdirs_as_module_names(path): }, } -CMS_TEMPLATES = current_secrets._CMS_TEMPLATES CMS_PERMISSION = True CMS_PLACEHOLDER_CONF = {} @@ -375,52 +357,6 @@ def get_subdirs_as_module_names(path): 'easy_thumbnails.processors.filters' ) - -# FEATURES. -if CONSOLE_LOG_ENABLED: - print("--> Variable FEATURES: ") - for feature in FEATURES: - print(feature + ": ", FEATURES[feature]) - -if current_secrets._FEATURES['blog']: - # Install required apps - INSTALLED_APPS += [ - # Blog/News - # 'filer', # Already added - # 'easy_thumbnails', # Already added - 'parler', - 'taggit', - 'taggit_autosuggest', - 'meta', # also supports `djangocms_page_meta` - 'sortedm2m', - 'djangocms_blog', - - # Metadata - 'djangocms_page_meta', - ] - - # Metadata: Configure - META_SITE_PROTOCOL = 'http' - META_USE_SITES = True - META_USE_OG_PROPERTIES = True - META_USE_TWITTER_PROPERTIES = True - META_USE_GOOGLEPLUS_PROPERTIES = True # django-meta 1.x+ - # META_USE_SCHEMAORG_PROPERTIES=True # django-meta 2.x+ - - # Blog/News: Set custom paths for templates - BLOG_PLUGIN_TEMPLATE_FOLDERS = ( - ('plugins/default', 'Default template'), # i.e. `templates/djangocms_blog/plugins/default/` - ('plugins/default-clone', 'Clone of default template'), # i.e. `templates/djangocms_blog/plugins/default-clone/` - ) - - # Blog/News: Change default values for the auto-setup of one `BlogConfig` - # SEE: https://github.com/nephila/djangocms-blog/issues/629 - BLOG_AUTO_SETUP = True - BLOG_AUTO_HOME_TITLE ='Home' - BLOG_AUTO_BLOG_TITLE = 'News' - BLOG_AUTO_APP_TITLE = 'News' - - DJANGOCMS_PICTURE_NESTING = True DJANGOCMS_PICTURE_RESPONSIVE_IMAGES = True DJANGOCMS_PICTURE_RESPONSIVE_IMAGES_VIEWPORT_BREAKPOINTS = [ @@ -436,39 +372,19 @@ def get_subdirs_as_module_names(path): FILE_UPLOAD_PERMISSIONS = 0o644 FILE_UPLOAD_MAX_MEMORY_SIZE = 20000000 # 20MB -# Custom picture templates - if required. -# DJANGOCMS_PICTURE_TEMPLATES = [ -# ('background', _('Background image')), # Need to design these first! -# ] - DJANGOCMS_AUDIO_ALLOWED_EXTENSIONS = ['mp3', 'ogg', 'wav'] -# Custom audio templates - if required. -# DJANGOCMS_AUDIO_TEMPLATES = [ -# ('feature', _('Featured Version')), -# ] # Djangocms Forms Settings. # SEE: https://github.com/mishbahr/djangocms-forms#configuration DJANGOCMS_FORMS_PLUGIN_MODULE = ('Generic') DJANGOCMS_FORMS_PLUGIN_NAME = ('Form') -# DJANGOCMS_FORMS_DEFAULT_TEMPLATE = 'djangocms_forms/form_template/default.html' + DJANGOCMS_FORMS_TEMPLATES = ( ('djangocms_forms/form_template/default.html', ('Default')), ) DJANGOCMS_FORMS_USE_HTML5_REQUIRED = False -# DJANGOCMS_FORMS_WIDGET_CSS_CLASSES = {'__all__': ('form-control', ) } -DJANGOCMS_FORMS_REDIRECT_DELAY = 10000 # 10 seconds - -DJANGOCMS_FORMS_RECAPTCHA_PUBLIC_KEY = current_secrets._DJANGOCMS_FORMS_RECAPTCHA_PUBLIC_KEY -DJANGOCMS_FORMS_RECAPTCHA_SECRET_KEY = current_secrets._DJANGOCMS_FORMS_RECAPTCHA_SECRET_KEY -# Google Analytics. -GOOGLE_ANALYTICS_PROPERTY_ID = current_secrets._GOOGLE_ANALYTICS_PROPERTY_ID -GOOGLE_ANALYTICS_PRELOAD = current_secrets._GOOGLE_ANALYTICS_PRELOAD - -# SETTINGS VARIABLE EXPORTS. -# Use a custom namespace (using default settings.VARIABLE configuration) -SETTINGS_EXPORT_VARIABLE_NAME = 'settings' +DJANGOCMS_FORMS_REDIRECT_DELAY = 1 # Elasticsearch Indexing HAYSTACK_ROUTERS = ['aldryn_search.router.LanguageRouter',] @@ -478,27 +394,37 @@ def get_subdirs_as_module_names(path): HAYSTACK_CONNECTIONS = { 'default': { 'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine', - 'URL': current_secrets._ES_HOSTS, - 'INDEX_NAME': current_secrets._ES_INDEX_PREFIX.format('cms'), - 'KWARGS': {'http_auth': current_secrets._ES_AUTH } + 'URL': ES_HOSTS, + 'INDEX_NAME': 'cms', + 'KWARGS': {'http_auth': ES_AUTH } } } -ES_DOMAIN = current_secrets._ES_DOMAIN +SETTINGS_EXPORT_VARIABLE_NAME = 'settings' +DEBUG = True +FEATURES = '' -# Exported settings. SETTINGS_EXPORT = [ 'DEBUG', + 'FEATURES', 'BRANDING', 'LOGO', 'FAVICON', - 'PORTAL', - 'FEATURES', + 'INCLUDES_CORE_PORTAL', 'GOOGLE_ANALYTICS_PROPERTY_ID', 'GOOGLE_ANALYTICS_PRELOAD' ] -if CONSOLE_LOG_ENABLED: - print("--> Variable SETTINGS_EXPORT: ") - for setting in SETTINGS_EXPORT: - print(setting) +try: + from taccsite_cms import settings_custom +except: + None + # do nothing + +try: + from taccsite_cms import settings_local +except: + None + # do nothing + + diff --git a/taccsite_cms/templates/assets_site_delayed.html b/taccsite_cms/templates/assets_site_delayed.html index 398724f1d..6d9df5ff3 100644 --- a/taccsite_cms/templates/assets_site_delayed.html +++ b/taccsite_cms/templates/assets_site_delayed.html @@ -18,7 +18,7 @@ {# FAQ: Not loaded in `assets_font.html` because these is NOT font for content which should avoid FOUT, FOIT, FOFT; but decorative, thus superfluous, icons #} -{% if settings.PORTAL %} +{% if settings.INCLUDES_CORE_PORTAL %} {% endif %} diff --git a/taccsite_cms/templates/header.html b/taccsite_cms/templates/header.html index d02a41c53..62eed4674 100644 --- a/taccsite_cms/templates/header.html +++ b/taccsite_cms/templates/header.html @@ -6,7 +6,7 @@ {% include "header_branding.html" %} -