ungleich-user/dal/settings.py
Sajeyks 0cb0344ac8 Compute the next uidNumber from LDAP instead of a local file
The highest uidNumber was cached in dal/ldap_max_uid_file. That breaks
with more than one replica and is lost on every container restart. The
uniqueness check behind it searched base '' (the root DSE), which
OpenLDAP never matches, so nothing caught a stale file. The error path
also referenced a setting that does not exist.

Now a paged search over ENTIRE_SEARCH_BASE finds the highest uidNumber
on each activation. Numbering is unchanged: the next number is above
both LDAP_DEFAULT_START_UID and every existing uidNumber.
LDAP_MAX_UID_FILE_PATH is no longer used.
2026-11-06 15:03:57 +03:00

212 lines
5.6 KiB
Python

"""
Django settings for dal project.
Generated by 'django-admin startproject' using Django 1.10.7.
For more information on this file, see
https://docs.djangoproject.com/en/1.10/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.10/ref/settings/
"""
import os
from decouple import config, Csv
import ldap
from django_auth_ldap.config import LDAPSearch, LDAPSearchUnion
# LDAP setup
LDAP_SERVER = config('LDAP_SERVER')
AUTH_LDAP_SERVER_URI = config('LDAPSERVER')
LDAP_ADMIN_DN = config('LDAP_ADMIN_DN')
LDAP_ADMIN_PASSWORD = config('LDAP_ADMIN_PASSWORD')
AUTH_LDAP_BIND_DN = LDAP_ADMIN_DN
AUTH_LDAP_BIND_PASSWORD = LDAP_ADMIN_PASSWORD
AUTH_LDAP_SERVER = AUTH_LDAP_SERVER_URI
LDAP_CUSTOMER_DN = config('LDAP_CUSTOMER_DN')
LDAP_USERS_DN = config('LDAP_USERS_DN')
LDAP_CUSTOMER_GROUP_ID = config('LDAP_CUSTOMER_GROUP_ID', cast=int)
LDAP_DEFAULT_START_UID = config('LDAP_DEFAULT_START_UID', cast=int)
# Search union over OUs
search_base = config('LDAPSEARCH').split()
search_base_ldap = [ LDAPSearch(x, ldap.SCOPE_SUBTREE, "(uid=%(user)s)") for x in search_base ]
AUTH_LDAP_USER_SEARCH = LDAPSearchUnion(*search_base_ldap)
AUTH_LDAP_START_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')
EMAIL_HOST = config("EMAIL_HOST", default="localhost")
EMAIL_PORT = config("EMAIL_PORT", default=25, cast=int)
EMAIL_USE_TLS = config("EMAIL_USE_TLS", default=True, cast=bool)
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 = (
'django_auth_ldap.backend.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_L10N = 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')
AUTH_LDAP_USER_ATTR_MAP = {
"first_name": "givenName",
"last_name": "sn",
"email": "mail"
}
ENTIRE_SEARCH_BASE = config("ENTIRE_SEARCH_BASE")
LOGGING = {
'disable_existing_loggers': False,
'version': 1,
'formatters': {
'standard': {
'format': '%(asctime)s %(levelname)s %(name)s %(funcName)s %(lineno)d: %(message)s'
}
},
'handlers': {
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filename': 'logs/debug.log',
'maxBytes': 1024*1024*5,
'backupCount': 10,
'formatter': 'standard',
},
'console': {
'class': 'logging.StreamHandler',
},
},
}
if config('ENABLE_DEBUG_LOG', default=False, cast=bool):
loggers_dict = {}
modules_to_log_list = config(
'MODULES_TO_LOG', default='django', cast=Csv()
)
for custom_module in modules_to_log_list:
logger_item = {
custom_module: {
'handlers': ['default'],
'level': 'INFO',
'propagate': True
}
}
loggers_dict.update(logger_item)
LOGGING['loggers'] = loggers_dict
if 'ldap3' in modules_to_log_list:
from ldap3.utils.log import (
set_library_log_detail_level, OFF, BASIC, NETWORK, EXTENDED
)
set_library_log_detail_level(BASIC)
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
)
}