Persist secret key in data folder (#620)

* Persist secret key in data folder

* use random secret key by default in prod

* fix e2e test
This commit is contained in:
Sascha Ißbrücker 2024-01-28 23:58:03 +01:00 committed by GitHub
parent 96ee4746ad
commit 38204c87cf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 33 additions and 10 deletions

View file

@ -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")

View file

@ -127,7 +127,6 @@
const descriptionInput = document.getElementById('{{ form.description.id_for_label }}'); const descriptionInput = document.getElementById('{{ form.description.id_for_label }}');
const notesDetails = document.querySelector('form details.notes'); const notesDetails = document.querySelector('form details.notes');
const notesInput = document.getElementById('{{ form.notes.id_for_label }}'); 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 unreadCheckbox = document.getElementById('{{ form.unread.id_for_label }}');
const sharedCheckbox = document.getElementById('{{ form.shared.id_for_label }}'); const sharedCheckbox = document.getElementById('{{ form.shared.id_for_label }}');
const websiteTitleInput = document.getElementById('{{ form.website_title.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'); const bookmarkExistsHint = document.querySelector('.form-input-hint.bookmark-exists');
if (existingBookmark && !editedBookmarkId) { 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'; bookmarkExistsHint.style['display'] = 'block';
notesDetails.open = !!existingBookmark.notes; notesDetails.open = !!existingBookmark.notes;
updateInput(titleInput, existingBookmark.title); updateInput(titleInput, existingBookmark.title);

View file

@ -8,12 +8,12 @@ mkdir -p data
# Create favicon folder if it does not exist # Create favicon folder if it does not exist
mkdir -p data/favicons mkdir -p data/favicons
# Generate secret key file if it does not exist
python manage.py generate_secret_key
# Run database migration # Run database migration
python manage.py migrate python manage.py migrate
# Enable WAL journal mode for SQLite databases # Enable WAL journal mode for SQLite databases
python manage.py enable_wal 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 # Create initial superuser if defined in options / environment variables
python manage.py create_initial_superuser python manage.py create_initial_superuser

View file

@ -2,7 +2,6 @@ beautifulsoup4
bleach bleach
bleach-allowlist bleach-allowlist
Django Django
django-generate-secret-key
django-registration django-registration
django-sass-processor django-sass-processor
django-widget-tweaks django-widget-tweaks

View file

@ -23,11 +23,8 @@ confusable-homoglyphs==3.2.0
django==5.0.1 django==5.0.1
# via # via
# -r requirements.in # -r requirements.in
# django-generate-secret-key
# django-registration # django-registration
# djangorestframework # djangorestframework
django-generate-secret-key==1.0.2
# via -r requirements.in
django-registration==3.4 django-registration==3.4
# via -r requirements.in # via -r requirements.in
django-sass-processor==1.4 django-sass-processor==1.4

View file

@ -40,7 +40,6 @@ INSTALLED_APPS = [
"django.contrib.staticfiles", "django.contrib.staticfiles",
"sass_processor", "sass_processor",
"widget_tweaks", "widget_tweaks",
"django_generate_secret_key",
"rest_framework", "rest_framework",
"rest_framework.authtoken", "rest_framework.authtoken",
"background_task", "background_task",

View file

@ -6,6 +6,7 @@ Production settings for linkding webapp
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
import os import os
from django.core.management.utils import get_random_secret_key
from .base import * from .base import *
# Turn of debug mode # Turn of debug mode
@ -15,10 +16,10 @@ SASS_PROCESSOR_ENABLED = False
# Try read secret key from file # Try read secret key from file
try: 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() SECRET_KEY = f.read().strip()
except: except:
pass SECRET_KEY = get_random_secret_key()
# Set ALLOWED_HOSTS # Set ALLOWED_HOSTS
# By default look in the HOST_NAME environment variable, if that is not set then allow all hosts # By default look in the HOST_NAME environment variable, if that is not set then allow all hosts