362 lines
11 KiB
Python
362 lines
11 KiB
Python
# authentic2 - versatile identity manager
|
|
# Copyright (C) 2010-2019 Entr'ouvert
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify it
|
|
# under the terms of the GNU Affero General Public License as published
|
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import logging
|
|
import logging.config
|
|
# Load default from Django
|
|
from django.conf import global_settings
|
|
import os
|
|
|
|
|
|
from gadjo.templatetags.gadjo import xstatic
|
|
from . import plugins, logger
|
|
|
|
# debian/debian_config.py::extract_settings_from_environ expects CACHES to be in its NAMESPACE
|
|
CACHES = global_settings.CACHES
|
|
|
|
BASE_DIR = os.path.dirname(__file__)
|
|
|
|
# Quick-start development settings - unsuitable for production
|
|
# See https://docs.djangoproject.com/en/dev/howto/deployment/checklist/
|
|
|
|
# SECURITY WARNING: keep the secret key used in production secret!
|
|
SECRET_KEY = 'please-change-me-with-a-very-long-random-string'
|
|
|
|
# SECURITY WARNING: don't run with debug turned on in production!
|
|
DEBUG = False
|
|
DEBUG_DB = False
|
|
MEDIA = 'media'
|
|
MEDIA_ROOT = 'media'
|
|
MEDIA_URL = '/media/'
|
|
|
|
# See https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts
|
|
ALLOWED_HOSTS = []
|
|
INTERNAL_IPS = ('127.0.0.1',)
|
|
|
|
DATABASES = {
|
|
'default': {
|
|
'ENGINE': 'django.db.backends.postgresql_psycopg2',
|
|
'NAME': 'authentic2',
|
|
}
|
|
}
|
|
|
|
# Hey Entr'ouvert is in France !!
|
|
TIME_ZONE = 'Europe/Paris'
|
|
LANGUAGE_CODE = 'fr'
|
|
USE_L10N = True
|
|
USE_TZ = True
|
|
|
|
# Static files
|
|
|
|
STATIC_URL = '/static/'
|
|
|
|
TEMPLATES = [
|
|
{
|
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
|
'DIRS': [
|
|
os.path.join(BASE_DIR, 'templates'),
|
|
],
|
|
'APP_DIRS': True,
|
|
'OPTIONS': {
|
|
'context_processors': [
|
|
'django.contrib.auth.context_processors.auth',
|
|
'django_rbac.context_processors.auth',
|
|
'django.template.context_processors.debug',
|
|
'django.template.context_processors.i18n',
|
|
'django.template.context_processors.media',
|
|
'django.template.context_processors.request',
|
|
'django.contrib.messages.context_processors.messages',
|
|
'django.template.context_processors.static',
|
|
'authentic2.context_processors.a2_processor',
|
|
],
|
|
},
|
|
},
|
|
]
|
|
|
|
|
|
MIDDLEWARE = (
|
|
'authentic2.middleware.null_character_middleware',
|
|
'authentic2.middleware.StoreRequestMiddleware',
|
|
'authentic2.middleware.RequestIdMiddleware',
|
|
'authentic2.middleware.ServiceAccessControlMiddleware',
|
|
'authentic2.middleware.CookieTestMiddleware',
|
|
'django.middleware.common.CommonMiddleware',
|
|
'django.middleware.http.ConditionalGetMiddleware',
|
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
|
'authentic2.middleware.SaveServiceInSessionMiddleware',
|
|
'django.middleware.csrf.CsrfViewMiddleware',
|
|
'django.middleware.locale.LocaleMiddleware',
|
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
|
'django.contrib.messages.middleware.MessageMiddleware',
|
|
'authentic2.middleware.journal_middleware',
|
|
)
|
|
|
|
DATABASES['default']['ATOMIC_REQUESTS'] = True
|
|
|
|
MIDDLEWARE += (
|
|
'authentic2.middleware.DisplayMessageBeforeRedirectMiddleware',
|
|
'authentic2.middleware.CollectIPMiddleware',
|
|
'authentic2.middleware.ViewRestrictionMiddleware',
|
|
'authentic2.middleware.OpenedSessionCookieMiddleware',
|
|
)
|
|
|
|
MIDDLEWARE = plugins.register_plugins_middleware(MIDDLEWARE)
|
|
|
|
ROOT_URLCONF = 'authentic2.urls'
|
|
|
|
STATICFILES_FINDERS = list(global_settings.STATICFILES_FINDERS) + ['gadjo.finders.XStaticFinder']
|
|
|
|
LOCALE_PATHS = (os.path.join(BASE_DIR, 'locale'), )
|
|
|
|
INSTALLED_APPS = (
|
|
'django.contrib.staticfiles',
|
|
'django.contrib.contenttypes',
|
|
'authentic2.custom_user',
|
|
'django.contrib.auth',
|
|
'django.contrib.sessions',
|
|
'django.contrib.messages',
|
|
'django.contrib.admin',
|
|
'django.contrib.humanize',
|
|
'django.contrib.postgres',
|
|
'django_select2',
|
|
'django_tables2',
|
|
'mellon',
|
|
'authentic2_auth_fc',
|
|
'authentic2_auth_saml',
|
|
'authentic2_auth_oidc',
|
|
'authentic2_idp_cas',
|
|
'authentic2_idp_oidc',
|
|
'authentic2.nonce',
|
|
'authentic2.saml',
|
|
'authentic2.idp',
|
|
'authentic2.idp.saml',
|
|
'authentic2.attribute_aggregator',
|
|
'authentic2.disco_service',
|
|
'authentic2.manager',
|
|
'authentic2.apps.journal',
|
|
'authentic2',
|
|
'django_rbac',
|
|
'authentic2.a2_rbac',
|
|
'gadjo',
|
|
'rest_framework',
|
|
'xstatic.pkg.jquery',
|
|
'xstatic.pkg.jquery_ui',
|
|
'xstatic.pkg.select2',
|
|
)
|
|
|
|
INSTALLED_APPS = tuple(plugins.register_plugins_installed_apps(INSTALLED_APPS))
|
|
|
|
# authentication
|
|
AUTHENTICATION_BACKENDS = (
|
|
'authentic2.backends.models_backend.ModelBackend',
|
|
'authentic2.backends.ldap_backend.LDAPBackend',
|
|
'authentic2.backends.ldap_backend.LDAPBackendPasswordLost',
|
|
'authentic2.backends.models_backend.DummyModelBackend',
|
|
'django_rbac.backends.DjangoRBACBackend',
|
|
'authentic2_auth_saml.backends.SAMLBackend',
|
|
'authentic2_auth_oidc.backends.OIDCBackend',
|
|
'authentic2_auth_fc.backends.FcBackend',
|
|
)
|
|
AUTHENTICATION_BACKENDS = plugins.register_plugins_authentication_backends(AUTHENTICATION_BACKENDS)
|
|
CSRF_FAILURE_VIEW = 'authentic2.views.csrf_failure_view'
|
|
|
|
|
|
LOGIN_REDIRECT_URL = '/'
|
|
LOGIN_URL = '/login/'
|
|
LOGOUT_URL = '/logout/'
|
|
|
|
# Registration
|
|
ACCOUNT_ACTIVATION_DAYS = 2
|
|
|
|
# Authentic2 settings
|
|
|
|
###########################
|
|
# Authentication settings
|
|
###########################
|
|
AUTH_USER_MODEL = 'custom_user.User'
|
|
AUTH_FRONTENDS = (
|
|
'authentic2_auth_saml.authenticators.SAMLAuthenticator',
|
|
'authentic2_auth_oidc.authenticators.OIDCAuthenticator',
|
|
'authentic2_auth_fc.authenticators.FcAuthenticator',
|
|
) + plugins.register_plugins_authenticators((
|
|
'authentic2.authenticators.LoginPasswordAuthenticator',))
|
|
|
|
###########################
|
|
# RBAC settings
|
|
###########################
|
|
RBAC_OU_MODEL = 'a2_rbac.OrganizationalUnit'
|
|
RBAC_PERMISSION_MODEL = 'a2_rbac.Permission'
|
|
RBAC_ROLE_MODEL = 'a2_rbac.Role'
|
|
RBAC_ROLE_PARENTING_MODEL = 'a2_rbac.RoleParenting'
|
|
|
|
#############################
|
|
# Identity Provider settings
|
|
#############################
|
|
|
|
# List of IdP backends, mainly used to show available services in the homepage
|
|
# of user, and to handle SLO for each protocols
|
|
IDP_BACKENDS = ('authentic2.idp.saml.backend.SamlBackend',) + plugins.register_plugins_idp_backends(())
|
|
|
|
# Whether to autoload SAML 2.0 identity providers and services metadata
|
|
# Only https URLS are accepted.
|
|
# Can be none, sp, idp or both
|
|
|
|
PASSWORD_HASHERS = list(global_settings.PASSWORD_HASHERS) + [
|
|
'authentic2.hashers.Drupal7PasswordHasher',
|
|
'authentic2.hashers.SHA256PasswordHasher',
|
|
'authentic2.hashers.SSHA1PasswordHasher',
|
|
'authentic2.hashers.SMD5PasswordHasher',
|
|
'authentic2.hashers.SHA1OLDAPPasswordHasher',
|
|
'authentic2.hashers.MD5OLDAPPasswordHasher',
|
|
'authentic2.hashers.PloneSHA1PasswordHasher',
|
|
]
|
|
|
|
# Serialization module to support natural keys in generic foreign keys
|
|
SERIALIZATION_MODULES = {
|
|
'json': 'authentic2.serializers',
|
|
}
|
|
|
|
LOGGING_CONFIG = None
|
|
LOGGING = {
|
|
'version': 1,
|
|
'disable_existing_loggers': True,
|
|
'filters': {
|
|
'cleaning': {
|
|
'()': 'authentic2.utils.CleanLogMessage',
|
|
},
|
|
'request_context': {
|
|
'()': 'authentic2.log_filters.RequestContextFilter',
|
|
},
|
|
'force_debug': {
|
|
'()': 'authentic2.log_filters.ForceDebugFilter',
|
|
}
|
|
},
|
|
'formatters': {
|
|
'verbose': {
|
|
'format': '[%(asctime)s] %(ip)s %(user)s %(request_id)s %(levelname)s %(name)s.%(funcName)s: %(message)s',
|
|
'datefmt': '%Y-%m-%d %a %H:%M:%S'
|
|
},
|
|
'verbose_db': {
|
|
'format': '[%(asctime)s] - - - %(levelname)s %(name)s.%(funcName)s: %(message)s',
|
|
'datefmt': '%Y-%m-%d %a %H:%M:%S'
|
|
},
|
|
},
|
|
'handlers': {
|
|
'console': {
|
|
'level': 'DEBUG',
|
|
'class': 'logging.StreamHandler',
|
|
'formatter': 'verbose',
|
|
'filters': ['cleaning', 'request_context'],
|
|
},
|
|
# remove request_context filter for db log to prevent infinite loop
|
|
# when logging sql query to retrieve the session user
|
|
'console_db': {
|
|
'level': 'DEBUG',
|
|
'class': 'logging.StreamHandler',
|
|
'formatter': 'verbose_db',
|
|
'filters': ['cleaning'],
|
|
},
|
|
},
|
|
'loggers': {
|
|
# even when debugging seeing SQL queries is too much, activate it
|
|
# explicitly using DEBUG_DB
|
|
'django.db': {
|
|
'handlers': ['console_db'],
|
|
'level': logger.SettingsLogLevel('INFO', debug_setting='DEBUG_DB'),
|
|
'propagate': False,
|
|
},
|
|
'django': {
|
|
'level': 'INFO',
|
|
},
|
|
# django_select2 outputs debug message at level INFO
|
|
'django_select2': {
|
|
'level': 'WARNING',
|
|
},
|
|
# lasso has the bad habit of logging everything as errors
|
|
'Lasso': {
|
|
'filters': ['force_debug'],
|
|
},
|
|
'libxml2': {
|
|
'filters': ['force_debug'],
|
|
},
|
|
'libxmlsec': {
|
|
'filters': ['force_debug'],
|
|
},
|
|
'': {
|
|
'handlers': ['console'],
|
|
'level': logger.SettingsLogLevel('INFO'),
|
|
},
|
|
},
|
|
}
|
|
|
|
MIGRATION_MODULES = {
|
|
'auth': 'authentic2.auth_migrations_18',
|
|
}
|
|
|
|
# Django REST Framework
|
|
REST_FRAMEWORK = {
|
|
'NON_FIELD_ERRORS_KEY': '__all__',
|
|
'DEFAULT_AUTHENTICATION_CLASSES': (
|
|
'authentic2.authentication.Authentic2Authentication',
|
|
'rest_framework.authentication.SessionAuthentication',
|
|
),
|
|
'DEFAULT_PERMISSION_CLASSES': (
|
|
'rest_framework.permissions.IsAuthenticated',
|
|
),
|
|
'DEFAULT_FILTER_BACKENDS': (
|
|
'django_filters.rest_framework.DjangoFilterBackend',
|
|
'rest_framework.filters.OrderingFilter',
|
|
),
|
|
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
|
|
'PAGE_SIZE': 100,
|
|
}
|
|
|
|
|
|
# Authentic2 Auth SAML
|
|
MELLON_ADAPTER = ('authentic2_auth_saml.adapters.AuthenticAdapter',)
|
|
|
|
# Permissions
|
|
|
|
DJANGO_RBAC_PERMISSIONS_HIERARCHY = {
|
|
'view': ['search'],
|
|
'change_password': ['view', 'search'],
|
|
'change_email': ['view', 'search'],
|
|
'reset_password': ['view', 'search'],
|
|
'activate': ['view', 'search'],
|
|
'admin': ['change', 'delete', 'add', 'view', 'change_password', 'reset_password', 'activate',
|
|
'search', 'change_email', 'manage_members', 'manage_authorizations'],
|
|
'change': ['view', 'search', 'manage_members'],
|
|
'delete': ['view', 'search'],
|
|
'add': ['view', 'search'],
|
|
'manage_members': ['view', 'search'],
|
|
'manage_authorizations': ['view', 'search'],
|
|
}
|
|
|
|
SILENCED_SYSTEM_CHECKS = ["auth.W004"]
|
|
|
|
# Get select2 from local copy.
|
|
SELECT2_JS = xstatic('select2', 'select2.min.js')
|
|
SELECT2_CSS = xstatic('select2', 'select2.min.css')
|
|
|
|
#
|
|
# Load configuration file
|
|
#
|
|
|
|
if 'AUTHENTIC2_SETTINGS_FILE' in os.environ:
|
|
with open(os.environ['AUTHENTIC2_SETTINGS_FILE']) as fd:
|
|
exec(fd.read())
|
|
logging.config.dictConfig(LOGGING)
|