From 77162c5e0f2e42c2ba5e24110e8f51c65ce5f68e Mon Sep 17 00:00:00 2001 From: Dave Lawrence Date: Thu, 25 Jun 2026 13:37:09 +0930 Subject: [PATCH] library: secure SECRET_KEY generation and tidy IconWithTooltip - Generate the Django SECRET_KEY with django.core.management.utils.get_random_secret_key() instead of the home-grown random-based generator (only affects fresh deployments where django_secret_key.txt does not yet exist) - Build IconWithTooltip markup with format_html() rather than hand-assembling a SafeString, removing now-unused imports --- library/django_utils/django_secret_key.py | 24 +++-------------------- library/utils/html_utils.py | 10 ++++------ 2 files changed, 7 insertions(+), 27 deletions(-) diff --git a/library/django_utils/django_secret_key.py b/library/django_utils/django_secret_key.py index bf5d90c2c..5a61506a2 100644 --- a/library/django_utils/django_secret_key.py +++ b/library/django_utils/django_secret_key.py @@ -1,31 +1,13 @@ import os -import random -from base64 import urlsafe_b64encode as b64encode -random.seed() - - -def generate_key(max_length, seed_length): - """ - Generate a Base64-encoded 'random' key by hashing the data. - data is a tuple of seeding values. Pass arbitrary encoder and - digester for specific hashing and formatting of keys - - From: https://gist.github.com/airtonix/6204802 - - """ - PATTERN = "%%0%dX" - JUNK_LEN = 1024 - junk = (PATTERN % (JUNK_LEN * 2)) % random.getrandbits(JUNK_LEN * seed_length) - key = str(junk).encode() - return b64encode(key)[:max_length] +from django.core.management.utils import get_random_secret_key def get_or_create_django_secret_key(key_dir): key_filename = os.path.join(key_dir, "django_secret_key.txt") if not os.path.exists(key_filename): - secret_key = generate_key(50, 128) - with open(key_filename, "wb") as f: + secret_key = get_random_secret_key() + with open(key_filename, "w", encoding="utf-8") as f: f.write(secret_key) else: with open(key_filename, encoding="utf-8") as f: diff --git a/library/utils/html_utils.py b/library/utils/html_utils.py index e49530dc2..939fab618 100644 --- a/library/utils/html_utils.py +++ b/library/utils/html_utils.py @@ -1,10 +1,9 @@ import re import uuid -from html import escape from typing import Optional from bs4 import BeautifulSoup -from django.utils.safestring import SafeString +from django.utils.html import format_html def html_id_safe(text: str) -> str: @@ -86,10 +85,9 @@ def __init__(self, icon: str, tooltip: Optional[str] = None): self.tooltip = tooltip def __str__(self): - title = "" - if tooltip := self.tooltip: - title = f'title="{escape(tooltip)}"' - return SafeString(f'') + if self.tooltip: + return format_html('', self.icon, self.tooltip) + return format_html('', self.icon) def as_json(self) -> dict: return {