Files

99 lines
3.9 KiB
Python
Raw Permalink Normal View History

2026-11-14 20:23:59 +01:00
from __future__ import annotations
import os
import secrets
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parents[1]
DATA_DIR = Path(os.getenv("CODEXPI_DATA_DIR", BASE_DIR / "data"))
DATA_DIR.mkdir(parents=True, exist_ok=True)
def env_bool(name: str, default: bool) -> bool:
value = os.getenv(name)
return default if value is None else value.lower() in {"1", "true", "yes", "on"}
def secret_key() -> str:
configured_file = os.getenv("CODEXPI_DJANGO_SECRET_KEY_FILE")
if configured_file:
value = Path(configured_file).read_text(encoding="utf-8").strip()
if len(value) < 32:
raise RuntimeError("CODEXPI_DJANGO_SECRET_KEY_FILE doit contenir un secret d’au moins 32 caractères")
return value
configured = os.getenv("CODEXPI_DJANGO_SECRET_KEY")
if configured:
if len(configured) < 32:
raise RuntimeError("CODEXPI_DJANGO_SECRET_KEY doit contenir au moins 32 caractères")
return configured
path = DATA_DIR / "django_secret_key"
if not path.exists():
try:
descriptor = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
with os.fdopen(descriptor, "w", encoding="utf-8") as target:
target.write(secrets.token_urlsafe(64))
except FileExistsError:
pass
return path.read_text(encoding="utf-8").strip()
SECRET_KEY = secret_key()
DEBUG = False
ALLOWED_HOSTS = [item.strip() for item in os.getenv("CODEXPI_DJANGO_ALLOWED_HOSTS", "localhost,127.0.0.1,.ts.net,nginx").split(",") if item.strip()]
CSRF_TRUSTED_ORIGINS = [item.strip() for item in os.getenv("CODEXPI_TRUSTED_ORIGINS", "https://*.ts.net").split(",") if item.strip()]
INSTALLED_APPS = [
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django_ui.identity",
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "django_ui.urls"
ASGI_APPLICATION = "django_ui.asgi.application"
WSGI_APPLICATION = "django_ui.wsgi.application"
DATABASES = {"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": DATA_DIR / "django.sqlite3", "OPTIONS": {"timeout": 30}}}
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
USE_TZ = True
TIME_ZONE = "Europe/Paris"
AUTH_PASSWORD_VALIDATORS = [
{"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"},
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", "OPTIONS": {"min_length": 12}},
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
]
PASSWORD_HASHERS = [
"django.contrib.auth.hashers.Argon2PasswordHasher",
"django.contrib.auth.hashers.PBKDF2PasswordHasher",
]
SESSION_ENGINE = "django.contrib.sessions.backends.db"
SESSION_COOKIE_NAME = os.getenv("CODEXPI_COOKIE_NAME", "codexpi_session")
SESSION_COOKIE_AGE = int(os.getenv("CODEXPI_SESSION_HOURS", "12")) * 3600
SESSION_COOKIE_SECURE = env_bool("CODEXPI_COOKIE_SECURE", True)
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = "Strict"
SESSION_SAVE_EVERY_REQUEST = False
CSRF_COOKIE_SECURE = SESSION_COOKIE_SECURE
CSRF_COOKIE_HTTPONLY = True
CSRF_COOKIE_SAMESITE = "Strict"
CSRF_HEADER_NAME = "HTTP_X_CSRF_TOKEN"
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
USE_X_FORWARDED_HOST = True
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_REFERRER_POLICY = "no-referrer"
SECURE_HSTS_SECONDS = 31_536_000
X_FRAME_OPTIONS = "DENY"
CACHES = {"default": {"BACKEND": "django.core.cache.backends.locmem.LocMemCache", "LOCATION": "codexpi-login-limiter"}}