forked from ungleich-public/ungleich-user
The OTP server variables were read straight from the environment in views.py. They are now OTP_* settings next to everything else, under the same environment variable names, so existing deployments are unaffected. Remove LDAP_SERVER and LDAP_USERS_DN, which nothing used. env.sample moves to the repository root (where .env is read from) and lists every variable settings.py reads, including defaults and which values are secrets.
208 lines
5.7 KiB
Python
208 lines
5.7 KiB
Python
"""
|
|
Django settings for the ungleich account webapp (dal).
|
|
|
|
All deployment-specific values come from environment variables (or a
|
|
.env file in development), read here and nowhere else. See env.sample
|
|
for the full list, which ones are required, and which are secrets.
|
|
"""
|
|
|
|
import os
|
|
from decouple import config, Csv
|
|
|
|
# LDAP setup
|
|
# Space separated list of LDAP URIs; the first reachable one is used.
|
|
LDAP_SERVERS = config('LDAPSERVER').split()
|
|
|
|
LDAP_ADMIN_DN = config('LDAP_ADMIN_DN')
|
|
LDAP_ADMIN_PASSWORD = config('LDAP_ADMIN_PASSWORD')
|
|
|
|
LDAP_CUSTOMER_DN = config('LDAP_CUSTOMER_DN')
|
|
LDAP_CUSTOMER_GROUP_ID = config('LDAP_CUSTOMER_GROUP_ID', cast=int)
|
|
|
|
LDAP_DEFAULT_START_UID = config('LDAP_DEFAULT_START_UID', cast=int)
|
|
|
|
# Users log in from any of these (space separated) search bases.
|
|
LDAP_SEARCH_BASES = config('LDAPSEARCH').split()
|
|
|
|
# StartTLS on every connection (use ldaps:// URIs for implicit TLS).
|
|
LDAP_USE_TLS = config('LDAP_USE_TLS', default=False, cast=bool)
|
|
|
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
DEBUG = config('DEBUG', default=False, cast=bool)
|
|
|
|
EMAIL_FROM_ADDRESS = config('EMAIL_FROM_ADDRESS')
|
|
|
|
MAILERS = {
|
|
"default": {
|
|
"BACKEND": "django.core.mail.backends.smtp.EmailBackend",
|
|
"OPTIONS": {
|
|
"host": config("EMAIL_HOST", default="localhost"),
|
|
"port": config("EMAIL_PORT", default=25, cast=int),
|
|
"username": config("EMAIL_HOST_USER", default=""),
|
|
"password": config("EMAIL_HOST_PASSWORD", default=""),
|
|
"use_tls": config("EMAIL_USE_TLS", default=True, cast=bool),
|
|
"timeout": config("EMAIL_TIMEOUT", default=10, cast=int),
|
|
},
|
|
},
|
|
}
|
|
|
|
ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=Csv())
|
|
|
|
INSTALLED_APPS = [
|
|
'django.contrib.admin',
|
|
'django.contrib.auth',
|
|
'django.contrib.contenttypes',
|
|
'django.contrib.sessions',
|
|
'django.contrib.messages',
|
|
'django.contrib.staticfiles',
|
|
'bootstrap3',
|
|
'dal',
|
|
'rest_framework'
|
|
]
|
|
|
|
MIDDLEWARE = [
|
|
'django.middleware.security.SecurityMiddleware',
|
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
|
'django.middleware.common.CommonMiddleware',
|
|
'django.middleware.csrf.CsrfViewMiddleware',
|
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
|
'django.contrib.messages.middleware.MessageMiddleware',
|
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
|
]
|
|
|
|
AUTHENTICATION_BACKENDS = (
|
|
'dal.backends.LdapBackend',
|
|
)
|
|
|
|
|
|
ROOT_URLCONF = 'dal.urls'
|
|
|
|
TEMPLATES = [
|
|
{
|
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
|
'DIRS': [],
|
|
'APP_DIRS': True,
|
|
'OPTIONS': {
|
|
'context_processors': [
|
|
'django.template.context_processors.debug',
|
|
'django.template.context_processors.request',
|
|
'django.contrib.auth.context_processors.auth',
|
|
'django.contrib.messages.context_processors.messages',
|
|
],
|
|
},
|
|
},
|
|
]
|
|
|
|
WSGI_APPLICATION = 'dal.wsgi.application'
|
|
|
|
# Password validation
|
|
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
|
|
|
|
AUTH_PASSWORD_VALIDATORS = [
|
|
{
|
|
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
|
},
|
|
{
|
|
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
|
},
|
|
{
|
|
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
|
},
|
|
{
|
|
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
|
},
|
|
]
|
|
|
|
|
|
# Internationalization
|
|
# https://docs.djangoproject.com/en/1.10/topics/i18n/
|
|
|
|
LANGUAGE_CODE = 'en-us'
|
|
|
|
TIME_ZONE = 'UTC'
|
|
|
|
USE_I18N = True
|
|
|
|
USE_TZ = True
|
|
|
|
|
|
# Static files (CSS, JavaScript, Images)
|
|
# https://docs.djangoproject.com/en/1.10/howto/static-files/
|
|
|
|
STATIC_URL = '/static/'
|
|
|
|
############################# To be fixed
|
|
|
|
STATIC_ROOT= os.path.join(BASE_DIR, 'static/')
|
|
|
|
# Database
|
|
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases
|
|
|
|
DATABASES = {
|
|
'default': {
|
|
'ENGINE': 'django.db.backends.sqlite3',
|
|
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
|
}
|
|
}
|
|
SECRET_KEY = config('SECRET_KEY')
|
|
|
|
# Keep 32-bit ids: existing tables were created with AutoField.
|
|
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
|
|
|
|
AUTH_LDAP_USER_ATTR_MAP = {
|
|
"first_name": "givenName",
|
|
"last_name": "sn",
|
|
"email": "mail"
|
|
}
|
|
|
|
ENTIRE_SEARCH_BASE = config("ENTIRE_SEARCH_BASE")
|
|
|
|
# Everything goes to stdout/stderr (12-factor / Kubernetes friendly).
|
|
LOG_LEVEL = config('LOG_LEVEL', default='INFO').upper()
|
|
|
|
LOGGING = {
|
|
'version': 1,
|
|
'disable_existing_loggers': False,
|
|
'formatters': {
|
|
'standard': {
|
|
'format': '%(asctime)s %(levelname)s %(name)s %(funcName)s %(lineno)d: %(message)s'
|
|
}
|
|
},
|
|
'handlers': {
|
|
'console': {
|
|
'class': 'logging.StreamHandler',
|
|
'formatter': 'standard',
|
|
},
|
|
},
|
|
'root': {
|
|
'handlers': ['console'],
|
|
'level': LOG_LEVEL,
|
|
},
|
|
'loggers': {
|
|
# Keep Django's own request/DB chatter at INFO unless asked for.
|
|
'django': {
|
|
'level': config('DJANGO_LOG_LEVEL', default='INFO').upper(),
|
|
},
|
|
},
|
|
}
|
|
|
|
# ldap3 protocol logging is very verbose; opt in with LDAP3_LOG=1.
|
|
if config('LDAP3_LOG', default=False, cast=bool):
|
|
from ldap3.utils.log import set_library_log_detail_level, BASIC
|
|
set_library_log_detail_level(BASIC)
|
|
|
|
|
|
# OTP server that stores per-user TOTP seeds, accessed with an admin TOTP.
|
|
OTP_SERVER = config('OTPSERVER')
|
|
OTP_ADMIN_SEED = config('ADMIN_SEED')
|
|
OTP_ADMIN_NAME = config('ADMIN_NAME')
|
|
OTP_ADMIN_REALM = config('ADMIN_REALM')
|
|
OTP_USER_REALM = config('USER_REALM')
|
|
OTP_ALLOWED_REALMS = config('ALLOWED_REALMS', cast=Csv())
|
|
|
|
REST_FRAMEWORK = {
|
|
'DEFAULT_RENDERER_CLASSES': (
|
|
'rest_framework.renderers.JSONRenderer',
|
|
)
|
|
}
|