mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-01-21 07:55:00 +00:00
web_framework: Generate and retain a secret key
- Secret is important for various functions of Django. There is no impact on existing installations due to the change. Improves the security of existing functions in minor ways and will be useful in future usage of Django. - Create the file in /var/lib/plinth/ with 0o600 permissions. - Make git ignore the file in code folder. - Don't copy the file during './setup.py install' operation. Impact to users after upgrade: - All existing sessions will get logged out. This is because SECRET_KEY is used to generate user session hash that is used to logout users when their password changes. Tests performed: - Run development version of service. File should get created in data/var/lib/plinth/django-secret.key. Permissions should be 0o600. - Run again, the file should not be overwritten. Printing django.conf.settings.SECRET_KEY should match the one in the file. - Run `setup.py install`. This should not install django-secret.key in /var/lib/plinth. - Run `sudo -u plinth plinth`. This should create the secret key file in /var/lib/plinth/django-secret.key. Permissions on the file should be 0o600. Ownership should be plinth:plinth. - Remove the file in both cases, a fresh new file should get created with new key. - Truncate the file to less than 128 chars, the existing file should get overwritten with new key. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
parent
1548785a09
commit
fd345aca80
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,6 +2,7 @@
|
||||
*.py.bak
|
||||
*.tiny.css
|
||||
data/var/log/plinth/*.log
|
||||
data/var/lib/plinth/django-secret.key
|
||||
data/var/lib/plinth/*.sqlite3
|
||||
data/var/lib/plinth/sessions/*
|
||||
data/var/lib/plinth/.ssh/
|
||||
|
||||
@ -5,6 +5,8 @@ Setup Django web framework.
|
||||
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
import random
|
||||
import stat
|
||||
|
||||
import django.conf
|
||||
@ -34,6 +36,7 @@ def init():
|
||||
settings.LANGUAGES = get_languages()
|
||||
settings.LOGGING = log.get_configuration()
|
||||
settings.MESSAGE_TAGS = {message_constants.ERROR: 'danger'}
|
||||
settings.SECRET_KEY = _get_secret_key()
|
||||
settings.SESSION_FILE_PATH = os.path.join(cfg.data_dir, 'sessions')
|
||||
settings.STATIC_URL = '/'.join([cfg.server_dir,
|
||||
'static/']).replace('//', '/')
|
||||
@ -57,6 +60,35 @@ def init():
|
||||
os.chmod(cfg.store_file, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP)
|
||||
|
||||
|
||||
def _get_secret_key():
|
||||
"""Retrieve or create a new Django secret key."""
|
||||
secret_key_file = pathlib.Path(cfg.data_dir) / 'django-secret.key'
|
||||
if secret_key_file.exists():
|
||||
secret_key = secret_key_file.read_text()
|
||||
if len(secret_key) >= 128:
|
||||
return secret_key
|
||||
|
||||
secret_key = _generate_secret_key()
|
||||
# File should be created with permission 0o700
|
||||
old_umask = os.umask(0o077)
|
||||
try:
|
||||
secret_key_file.write_text(secret_key)
|
||||
finally:
|
||||
os.umask(old_umask)
|
||||
|
||||
return secret_key
|
||||
|
||||
|
||||
def _generate_secret_key():
|
||||
"""Generate a new random secret key for use with Django."""
|
||||
# We could have used django.core.management.utils.get_random_secret_key
|
||||
# but it is not documented and should be considered private.
|
||||
length = 128
|
||||
chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
|
||||
rand = random.SystemRandom()
|
||||
return ''.join(rand.choice(chars) for _ in range(length))
|
||||
|
||||
|
||||
def get_languages():
|
||||
"""Return list of languages to show in the interface.
|
||||
|
||||
|
||||
2
setup.py
2
setup.py
@ -173,7 +173,7 @@ def _ignore_data_file(file_name):
|
||||
ignore_patterns = [
|
||||
r'\.log$', r'\.pid$', r'\.py.bak$', r'\.pyc$', r'\.pytest_cache$',
|
||||
r'\.sqlite3$', r'\.swp$', r'^#', r'^\.', r'^__pycache__$',
|
||||
r'^sessionid\w*$', r'~$'
|
||||
r'^sessionid\w*$', r'~$', r'django-secret.key'
|
||||
]
|
||||
for pattern in ignore_patterns:
|
||||
if re.match(pattern, file_name):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user