From 3826b6fb66e7cd7a4aed49e0a01aca1148dae39a 2024-03-20 03:10:00 From: Ben Sturmfels Date: 2024-03-20 03:10:00 Subject: [PATCH] Switch settings to use "the one true way" approach The advantage of this approach is that the production and dev configurations are in version control, so there's less opportunity for surprises. As advocated by Jacob Kaplan-Moss (OSCON 2011) and Two Scoops of Django book. --- diff --git a/.gitignore b/.gitignore index 8dd723932b42fa4f6ca458a481aeedbcbe959807..405e2499e30e2b6cb0a83713577d19ae9ae6358e 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ conservancy/static/docs/SFC_response_to_summary_judgement.pdf conservancy/static/docs/Vizio_summary_judgement_reply_brief.pdf conservancy/static/docs/2023-4-28 VIZIOs Motion for Summary Judgment with Reservation.pdf +/conservancy/secrets.json diff --git a/Dockerfile-debian-bookworm b/Dockerfile-debian-bookworm index 446a27f0c2b178dbcf3b9f9090790943155f7ef8..b47896d0509c20ed9a1e51ba85037bede1c26215 100644 --- a/Dockerfile-debian-bookworm +++ b/Dockerfile-debian-bookworm @@ -1,9 +1,6 @@ # To build the Docker image with the necessary dependencies: # docker build --tag sfconservancy.org-bookworm --file Dockerfile-debian-bookworm . # -# To run the website, first ensure you have a -# "conservancy/djangocommonsettings.py" file, with an appropriate database path. -# # [FIRST RUN ONLY] If you don't have an existing copy of the database, run: # touch conservancy-website.sqlite3 # diff --git a/README.md b/README.md index e2ca086aa812e8b53fa69d10159e8da5722967ed..3cc137999d07fc596f3705d74a0efd1838022606 100644 --- a/README.md +++ b/README.md @@ -38,10 +38,6 @@ Debian: python3 -m pip install -r requirements.txt -You'll need a copy of `conservancy/djangocommonsettings.py`, a file that not -committed to the repository that has database settings and other -environment-specific config. - To run the tests, install `pytest-django` and run pytest: python3 -m pip install pytest-django diff --git a/TODO.md b/TODO.md index 0ee08db4fd5edc955b56bd63af3153f9e3affd48..a2b33aa4f3216c4952987a170eb50e43d1536dec 100644 --- a/TODO.md +++ b/TODO.md @@ -5,12 +5,12 @@ * use `` elements for supporter page hidden sections, rather than complex jQuery - or consider Alpine.js * replace `internalNavigate` with inline flexbox layout * add tests for main pages returning 200 -* standardise settings to replace `settings.py` and `djangocommonsettings.py` - with `settings/prod.py` and move `SECRET_KEY` to an environment variable # Done +* standardise settings to replace `settings.py` and `djangocommonsettings.py` + with `settings/prod.py` and move `SECRET_KEY` to an environment variable * migrate to Django 4.2 LTS * review `apache2` directory - may be unused * add deployment script that runs migrations and collects static files diff --git a/conservancy/local_context_processors.py b/conservancy/local_context_processors.py index 5cfd986917720a99412bd7669c738ceb76e141af..9e9499e1507afbee6349c2a6b4e03bf0711739b6 100644 --- a/conservancy/local_context_processors.py +++ b/conservancy/local_context_processors.py @@ -1,6 +1,7 @@ from datetime import datetime as DateTime -from . import settings +from django.conf import settings + from .fundgoal.models import FundraisingGoal SITE_FUNDGOAL = 'cy2023-end-year-match' diff --git a/conservancy/settings/__init__.py b/conservancy/settings/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/conservancy/settings.py b/conservancy/settings/base.py similarity index 96% rename from conservancy/settings.py rename to conservancy/settings/base.py index 6440570fb5eff0d46852d151233db65121b46cd5..611ce1a01ff7d7a5a5de35da62a581916f577df8 100644 --- a/conservancy/settings.py +++ b/conservancy/settings/base.py @@ -19,13 +19,9 @@ from pathlib import Path -from .djangocommonsettings import * - SITE_ID = 2 ROOT_URLCONF = 'conservancy.urls' -FORCE_CANONICAL_HOSTNAME = False if DEBUG else 'sfconservancy.org' - REDIRECT_TABLE = { 'www.sf-conservancy.org': 'sfconservancy.org', } @@ -101,7 +97,7 @@ INSTALLED_APPS = [ DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' -BASE_DIR = Path(__file__).resolve().parent +BASE_DIR = Path(__file__).resolve().parent.parent TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', diff --git a/conservancy/settings/dev.py b/conservancy/settings/dev.py new file mode 100644 index 0000000000000000000000000000000000000000..b77d2d078cc4ab80089df86ee8f3af0395a6565f --- /dev/null +++ b/conservancy/settings/dev.py @@ -0,0 +1,17 @@ +from .base import * + +DEBUG = True +ALLOWED_HOSTS = ['*'] + +FORCE_CANONICAL_HOSTNAME = False + +DATABASES = { + 'default': { + 'NAME': 'conservancy-website.sqlite3', + 'ENGINE': 'django.db.backends.sqlite3', + } +} + +SECRET_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' + +EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' diff --git a/conservancy/settings/prod.py b/conservancy/settings/prod.py new file mode 100644 index 0000000000000000000000000000000000000000..e1c97300eb43fcf1284739c9200f046378f38fe4 --- /dev/null +++ b/conservancy/settings/prod.py @@ -0,0 +1,41 @@ +import json + +from django.core.exceptions import ImproperlyConfigured + +from .base import * + +DEBUG = False +ALLOWED_HOSTS = ['www.sfconservancy.org', 'sfconservancy.org'] + +FORCE_CANONICAL_HOSTNAME = 'sfconservancy.org' + +ADMINS = [ + ('Bradley M. Kuhn', 'sysadmin@sfconservancy.org'), + ('Ben Sturmfels', 'sysadmin+conservancy@sturm.com.au'), +] + +MANAGERS = [ + ('Bradley M. Kuhn', 'sysadmin@sfconservancy.org'), +] + +DATABASES = { + 'default': { + 'NAME': '/var/lib/www/database/conservancy-website.sqlite3', + 'ENGINE': 'django.db.backends.sqlite3', + } +} + +# Apache/mod_wsgi doesn't make it straightforward to pass environment variables +# to Django (can't use the Apache config). +with open(BASE_DIR / 'secrets.json') as f: + secrets = json.load(f) + +def get_secret(secrets, setting): + try: + return secrets[setting] + except KeyError: + raise ImproperlyConfigured(f'Missing secret \'{setting}\'') + +SECRET_KEY = get_secret(secrets, 'SECRET_KEY') + +SESSION_COOKIE_SECURE = True diff --git a/manage.py b/manage.py index acbc97323f61f88a3f4ac180317338211e60faac..c3f44dcae0c13321a79b910c6f1ea76fe1f9314e 100755 --- a/manage.py +++ b/manage.py @@ -7,7 +7,7 @@ import os import sys if __name__ == '__main__': - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'conservancy.settings') + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'conservancy.settings.dev') try: from django.core.management import execute_from_command_line except ImportError as exc: