From 38204c87cf6fdd3d871a115d9786db73b17d1be6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sascha=20I=C3=9Fbr=C3=BCcker?= Date: Sun, 28 Jan 2024 23:58:03 +0100 Subject: [PATCH] Persist secret key in data folder (#620) * Persist secret key in data folder * use random secret key by default in prod * fix e2e test --- .../commands/generate_secret_key.py | 24 +++++++++++++++++++ bookmarks/templates/bookmarks/form.html | 5 +++- bootstrap.sh | 4 ++-- requirements.in | 1 - requirements.txt | 3 --- siteroot/settings/base.py | 1 - siteroot/settings/prod.py | 5 ++-- 7 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 bookmarks/management/commands/generate_secret_key.py diff --git a/bookmarks/management/commands/generate_secret_key.py b/bookmarks/management/commands/generate_secret_key.py new file mode 100644 index 0000000..f62749e --- /dev/null +++ b/bookmarks/management/commands/generate_secret_key.py @@ -0,0 +1,24 @@ +import logging +import os + +from django.core.management.base import BaseCommand +from django.core.management.utils import get_random_secret_key + + +logger = logging.getLogger(__name__) + + +class Command(BaseCommand): + help = "Generate secret key file if it does not exist" + + def handle(self, *args, **options): + secret_key_file = os.path.join("data", "secretkey.txt") + + if os.path.exists(secret_key_file): + logger.info(f"Secret key file already exists") + return + + secret_key = get_random_secret_key() + with open(secret_key_file, "w") as f: + f.write(secret_key) + logger.info(f"Generated secret key file") diff --git a/bookmarks/templates/bookmarks/form.html b/bookmarks/templates/bookmarks/form.html index b460a45..2dd05f8 100644 --- a/bookmarks/templates/bookmarks/form.html +++ b/bookmarks/templates/bookmarks/form.html @@ -127,7 +127,6 @@ const descriptionInput = document.getElementById('{{ form.description.id_for_label }}'); const notesDetails = document.querySelector('form details.notes'); const notesInput = document.getElementById('{{ form.notes.id_for_label }}'); - const tagsInput = document.getElementById('{{ form.tag_string.id_for_label }}'); const unreadCheckbox = document.getElementById('{{ form.unread.id_for_label }}'); const sharedCheckbox = document.getElementById('{{ form.shared.id_for_label }}'); const websiteTitleInput = document.getElementById('{{ form.website_title.id_for_label }}'); @@ -183,6 +182,10 @@ const bookmarkExistsHint = document.querySelector('.form-input-hint.bookmark-exists'); if (existingBookmark && !editedBookmarkId) { + // Workaround: tag input will be replaced by tag autocomplete, so + // defer getting the input until we need it + const tagsInput = document.getElementById('{{ form.tag_string.id_for_label }}'); + bookmarkExistsHint.style['display'] = 'block'; notesDetails.open = !!existingBookmark.notes; updateInput(titleInput, existingBookmark.title); diff --git a/bootstrap.sh b/bootstrap.sh index 5b7ec62..66c6101 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -8,12 +8,12 @@ mkdir -p data # Create favicon folder if it does not exist mkdir -p data/favicons +# Generate secret key file if it does not exist +python manage.py generate_secret_key # Run database migration python manage.py migrate # Enable WAL journal mode for SQLite databases python manage.py enable_wal -# Generate secret key file if it does not exist -python manage.py generate_secret_key # Create initial superuser if defined in options / environment variables python manage.py create_initial_superuser diff --git a/requirements.in b/requirements.in index 8be6237..dc8e4d6 100644 --- a/requirements.in +++ b/requirements.in @@ -2,7 +2,6 @@ beautifulsoup4 bleach bleach-allowlist Django -django-generate-secret-key django-registration django-sass-processor django-widget-tweaks diff --git a/requirements.txt b/requirements.txt index 2ba02fc..4e8081d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,11 +23,8 @@ confusable-homoglyphs==3.2.0 django==5.0.1 # via # -r requirements.in - # django-generate-secret-key # django-registration # djangorestframework -django-generate-secret-key==1.0.2 - # via -r requirements.in django-registration==3.4 # via -r requirements.in django-sass-processor==1.4 diff --git a/siteroot/settings/base.py b/siteroot/settings/base.py index d37fdab..a2096e3 100644 --- a/siteroot/settings/base.py +++ b/siteroot/settings/base.py @@ -40,7 +40,6 @@ INSTALLED_APPS = [ "django.contrib.staticfiles", "sass_processor", "widget_tweaks", - "django_generate_secret_key", "rest_framework", "rest_framework.authtoken", "background_task", diff --git a/siteroot/settings/prod.py b/siteroot/settings/prod.py index eae7635..5da0a24 100644 --- a/siteroot/settings/prod.py +++ b/siteroot/settings/prod.py @@ -6,6 +6,7 @@ Production settings for linkding webapp # noinspection PyUnresolvedReferences import os +from django.core.management.utils import get_random_secret_key from .base import * # Turn of debug mode @@ -15,10 +16,10 @@ SASS_PROCESSOR_ENABLED = False # Try read secret key from file try: - with open(os.path.join(BASE_DIR, "secretkey.txt")) as f: + with open(os.path.join(BASE_DIR, "data", "secretkey.txt")) as f: SECRET_KEY = f.read().strip() except: - pass + SECRET_KEY = get_random_secret_key() # Set ALLOWED_HOSTS # By default look in the HOST_NAME environment variable, if that is not set then allow all hosts