Files
codexpi/django_ui/settings.py
CodexPi 995b17a6e2
Some checks are pending
Qualité / tests (push) Waiting to run
feat: publish CodexPi contest snapshot
2026-11-14 20:23:59 +01:00

99 lines
3.9 KiB
Python
Raw 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.
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"}}