Files

167 lines
6.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Настройки портала администрирования.
Все секреты и параметры окружения читаются через python-decouple.
При запуске под systemd переменные передаются через EnvironmentFile
(/etc/admin-portal/admin-portal.env, см. systemd/admin-portal.service),
поэтому наличие .env-файла рядом с manage.py не обязательно, но
поддерживается для локальной разработки/отладки на самой ВМ.
"""
import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType, LDAPGroupQuery
from decouple import Config, RepositoryEnv, config as env_config, Csv
from pathlib import Path
import os
BASE_DIR = Path(__file__).resolve().parent.parent
# Если рядом лежит .env (локальная разработка) — используем его, иначе
# полагаемся на переменные окружения процесса (боевой режим, systemd).
_dotenv_path = BASE_DIR / ".env"
config = Config(RepositoryEnv(_dotenv_path)) if _dotenv_path.exists() else env_config
SECRET_KEY = config("DJANGO_SECRET_KEY")
DEBUG = config("DJANGO_DEBUG", default=False, cast=bool)
ALLOWED_HOSTS = config("DJANGO_ALLOWED_HOSTS", cast=Csv(), default="*")
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"portal",
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware",
"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",
]
ROOT_URLCONF = "config.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / "portal" / "templates"],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
WSGI_APPLICATION = "config.wsgi.application"
# ---------------------------------------------------------------------------
# База данных — локальный PostgreSQL на этой же ВМ (или указанный хост)
# ---------------------------------------------------------------------------
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": config("POSTGRES_DB"),
"USER": config("POSTGRES_USER"),
"PASSWORD": config("POSTGRES_PASSWORD"),
"HOST": config("POSTGRES_HOST", default="127.0.0.1"),
"PORT": config("POSTGRES_PORT", default="5432"),
}
}
# ---------------------------------------------------------------------------
# Кэш и сессии — локальный Redis на этой же ВМ (или указанный хост)
# ---------------------------------------------------------------------------
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": config("REDIS_URL", default="redis://127.0.0.1:6379/1"),
"OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient"},
}
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
SESSION_COOKIE_NAME = "sessionid"
SESSION_COOKIE_AGE = 60 * 60 * 8 # 8 часов
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = "Lax"
CSRF_COOKIE_SECURE = True
# ---------------------------------------------------------------------------
# Авторизация через Active Directory (LDAP)
# ---------------------------------------------------------------------------
AUTH_LDAP_SERVER_URI = config("AD_SERVER_URI")
AUTH_LDAP_BIND_DN = config("AD_BIND_DN")
AUTH_LDAP_BIND_PASSWORD = config("AD_BIND_PASSWORD")
AUTH_LDAP_USER_SEARCH = LDAPSearch(
config("AD_USER_SEARCH_BASE"),
ldap.SCOPE_SUBTREE,
"(sAMAccountName=%(user)s)",
)
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
config("AD_GROUP_SEARCH_BASE"),
ldap.SCOPE_SUBTREE,
"(objectClass=group)",
)
AUTH_LDAP_GROUP_TYPE = GroupOfNamesType(name_attr="cn")
# Атрибуты, которые тянем из AD в модель User при первом логине/обновлении
AUTH_LDAP_USER_ATTR_MAP = {
"first_name": "givenName",
"last_name": "sn",
"email": "mail",
}
# В Django группы AD не мапятся на Django Group автоматически (нам это не нужно —
# группы читаются напрямую из LDAP через .ldap_user.group_names при построении
# каталога ресурсов, см. portal/services.py), но кэшируем сам LDAP-объект юзера.
AUTH_LDAP_ALWAYS_UPDATE_USER = True
AUTH_LDAP_CACHE_TIMEOUT = config("AD_GROUP_CACHE_TTL_SECONDS", default=600, cast=int)
AUTH_LDAP_CONNECTION_OPTIONS = {
ldap.OPT_REFERRALS: 0,
ldap.OPT_NETWORK_TIMEOUT: 5,
}
AUTHENTICATION_BACKENDS = [
"django_auth_ldap.backend.LDAPBackend",
"django.contrib.auth.backends.ModelBackend", # для локального суперпользователя
]
LOGIN_URL = "/login/"
LOGIN_REDIRECT_URL = "/"
LOGOUT_REDIRECT_URL = "/login/"
# ---------------------------------------------------------------------------
# Токен для backend admin panels (см. docs/architecture.md, раздел 6)
# ---------------------------------------------------------------------------
RESOURCE_TOKEN_SECRET = config("RESOURCE_TOKEN_SECRET")
RESOURCE_TOKEN_TTL_SECONDS = config("RESOURCE_TOKEN_TTL_SECONDS", default=60, cast=int)
RESOURCE_TOKEN_COOKIE_NAME = "resource_token"
STATIC_URL = "static/"
STATIC_ROOT = BASE_DIR / "staticfiles"
STORAGES = {
"staticfiles": {
"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
},
}
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
LANGUAGE_CODE = "ru-ru"
TIME_ZONE = "Europe/Moscow"
USE_I18N = True
USE_TZ = True