Commit aa4a9d01 authored by Mickaël Desfrênes's avatar Mickaël Desfrênes
Browse files

remove hardcoded default SECRET_KEY, make JAMA_SECRET required

parent 820787ce
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@ aléatoire.
| Variable | Défaut | Description                                                                                                                                                                                |
| --- | --- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `JAMA_VAR_DIR` | `~/.jama` | Répertoire de base utilisé pour les données persistantes quand aucun chemin plus spécifique n'est configuré.                                                                               |
| `JAMA_SECRET` | Généré dans `JAMA_VAR_DIR/env`, sinon valeur de secours codée dans les settings | Secret Django. En production, il doit être défini explicitement et rester confidentiel.                                                                                                    |
| `JAMA_SECRET` | Généré lors de la création de `JAMA_VAR_DIR/env` | Secret Django obligatoire. Le démarrage échoue s'il est absent ou vide d'une configuration existante. Il doit rester confidentiel.                                                        |
| `JAMA_API_KEY_HASH_SECRET` | Même valeur que `JAMA_SECRET` | Secret utilisé pour calculer les empreintes des clefs d'API stockées en base. Le modifier invalide les clefs existantes.                                                                   |
| `JAMA_DEBUG` | `0` | Active le mode debug Django avec `1`. Ne pas activer en production.                                                                                                                        |
| `JAMA_SITE` | `http://localhost:8000/` | URL publique de base du site. Utilisée pour construire des URLs absolues, notamment RPC, IIIF, ARK et notifications.                                                                       |
+2 −1
Original line number Diff line number Diff line
@@ -83,7 +83,8 @@ cron process separately, for example with systemd.

At startup, Jamā reads environment variables and also loads an `env` file from
`JAMA_VAR_DIR`. If the file does not exist, Jamā creates it automatically with
documented defaults.
documented defaults and a random `JAMA_SECRET`. Existing configurations must
provide a non-empty `JAMA_SECRET` or startup will fail.

Important variables include:

+9 −3
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ import string
from urllib.parse import urlsplit

from corsheaders.defaults import default_headers
from django.core.exceptions import ImproperlyConfigured

for tool in [
    "vips",
@@ -36,6 +37,13 @@ def _env_list(name: str, default: list[str] | None = None) -> list[str]:
    return [item.strip() for item in value.split(",") if item.strip()]


def _required_env(name: str) -> str:
    value = os.getenv(name)
    if value is None or not value.strip():
        raise ImproperlyConfigured(f"{name} must be configured")
    return value


def _origin_from_url(url: str) -> str:
    # CSRF trusted origins must be scheme + host only; keeping a path from
    # JAMA_SITE would make Django reject otherwise valid same-site requests.
@@ -399,9 +407,7 @@ CACHE_FILE_LOCATION = Path(CACHE_FILE_LOCATION).resolve()
os.makedirs(CACHE_FILE_LOCATION, exist_ok=True)

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = (
    os.getenv("JAMA_SECRET") or "7d*_8c!d$vv963qpr45_x)@f2t-x6fu2&yi+m+d6s!p!lt+_j+"
)
SECRET_KEY = _required_env("JAMA_SECRET")
JAMA_API_KEY_HASH_SECRET = os.getenv("JAMA_API_KEY_HASH_SECRET") or SECRET_KEY

# SECURITY WARNING: don't run with debug  on in production!
+23 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ from tempfile import TemporaryDirectory
from unittest.mock import patch

from django.contrib.auth.models import User
from django.core.exceptions import ImproperlyConfigured
from django.db import DatabaseError, connection
from django.http import Http404
from django.test import (
@@ -132,6 +133,28 @@ class SettingsEnvTemplateTestCase(SimpleTestCase):
        self.assertIn("JAMA_SECRET=testsecret", content)
        self.assertIn(f"JAMA_FILES_DIR={var_dir / 'media_source_files'}", content)

    def test_required_env_rejects_missing_or_blank_values(self):
        with patch.dict(os.environ):
            os.environ.pop("JAMA_REQUIRED_TEST", None)
            with self.assertRaisesMessage(
                ImproperlyConfigured, "JAMA_REQUIRED_TEST must be configured"
            ):
                jama_settings._required_env("JAMA_REQUIRED_TEST")

        for value in ("", "   "):
            with (
                self.subTest(value=value),
                patch.dict(os.environ, {"JAMA_REQUIRED_TEST": value}),
                self.assertRaises(ImproperlyConfigured),
            ):
                jama_settings._required_env("JAMA_REQUIRED_TEST")

    def test_required_env_returns_configured_value(self):
        with patch.dict(os.environ, {"JAMA_REQUIRED_TEST": "secret value"}):
            self.assertEqual(
                jama_settings._required_env("JAMA_REQUIRED_TEST"), "secret value"
            )

    def test_env_file_edit_preserves_existing_comments(self):
        env_file = Path(self.enterContext(TemporaryDirectory())) / "env"
        env_file.write_text(