start project
This commit is contained in:
@@ -7,7 +7,7 @@ back to an insecure default.
|
||||
"""
|
||||
|
||||
from .base import * # noqa: F403
|
||||
from .base import DEBUG, SECRET_KEY, env
|
||||
from .base import DATABASES, DEBUG, SECRET_KEY, env
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Fail fast on unsafe configuration
|
||||
@@ -18,11 +18,36 @@ if DEBUG: # pragma: no cover - configuration guard
|
||||
if len(SECRET_KEY) < 50: # pragma: no cover - configuration guard
|
||||
raise RuntimeError("DJANGO_SECRET_KEY must be at least 50 characters in production.")
|
||||
|
||||
# A length check alone is false comfort: the placeholder shipped in
|
||||
# .env.example is 68 characters long and would sail straight through it.
|
||||
_PLACEHOLDER_MARKERS = ("change-me", "changeme", "build-only", "not-a-real-secret")
|
||||
|
||||
|
||||
def _reject_placeholder(name: str, value: str) -> None: # pragma: no cover - guard
|
||||
lowered = value.lower()
|
||||
if any(marker in lowered for marker in _PLACEHOLDER_MARKERS):
|
||||
raise RuntimeError(
|
||||
f"{name} still holds a placeholder value from .env.example. "
|
||||
"Generate a real secret before deploying: "
|
||||
'python -c "import secrets; print(secrets.token_urlsafe(64))"'
|
||||
)
|
||||
|
||||
|
||||
_reject_placeholder("DJANGO_SECRET_KEY", SECRET_KEY)
|
||||
_reject_placeholder("POSTGRES_PASSWORD", DATABASES["default"].get("PASSWORD") or "")
|
||||
_reject_placeholder("ELASTICSEARCH_PASSWORD", env("ELASTICSEARCH_PASSWORD", default=""))
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Transport security
|
||||
# ---------------------------------------------------------------------------
|
||||
SECURE_SSL_REDIRECT = env.bool("SECURE_SSL_REDIRECT", default=True)
|
||||
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
|
||||
|
||||
# Container/orchestrator probes hit the API over plain HTTP on localhost, so
|
||||
# without an exemption every probe gets a 301 to https. `curl -fsS` treats a
|
||||
# 3xx as success, which means a completely broken container would still report
|
||||
# itself healthy - the probe has to reach the real view to be worth anything.
|
||||
SECURE_REDIRECT_EXEMPT = [r"^api/v1/health/"]
|
||||
SECURE_HSTS_SECONDS = 31_536_000 # one year
|
||||
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
|
||||
SECURE_HSTS_PRELOAD = True
|
||||
@@ -40,3 +65,8 @@ ADMIN_URL = env("DJANGO_ADMIN_URL", default="admin/")
|
||||
|
||||
# Deny by default; CORS_ALLOWED_ORIGINS must be set explicitly.
|
||||
CORS_ALLOW_ALL_ORIGINS = False
|
||||
|
||||
# The interactive docs describe every endpoint and payload in the service and
|
||||
# are served unauthenticated. Off unless the operator explicitly opts in (for
|
||||
# an internal-only origin, say) - see config/urls.py.
|
||||
SERVE_API_DOCS = env.bool("SERVE_API_DOCS", default=False)
|
||||
|
||||
Reference in New Issue
Block a user