Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
85 changes: 50 additions & 35 deletions blt/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,18 @@
"dj_rest_auth.registration",
"storages",
"channels",
"silk",
)

if DEBUG:
INSTALLED_APPS += ("livereload",)
INSTALLED_APPS += ("debug_toolbar", "livereload")
Comment on lines +104 to +107
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Silk enabled unconditionally in production.

"silk" is added to INSTALLED_APPS outside the DEBUG block, meaning it will be installed and active in production. This adds unnecessary overhead and potential security exposure.

Move silk inside the DEBUG condition:

     "channels",
-    "silk",
 )
 if DEBUG:
-    INSTALLED_APPS += ("debug_toolbar", "livereload")
+    INSTALLED_APPS += ("silk", "debug_toolbar", "livereload")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"silk",
)
if DEBUG:
INSTALLED_APPS += ("livereload",)
INSTALLED_APPS += ("debug_toolbar", "livereload")
"channels",
)
if DEBUG:
INSTALLED_APPS += ("silk", "debug_toolbar", "livereload")
🤖 Prompt for AI Agents
In blt/settings.py around lines 104 to 107, "silk" is currently added to
INSTALLED_APPS unconditionally; remove it from the global INSTALLED_APPS list
and instead append it only when DEBUG is True (e.g. inside the DEBUG block do
INSTALLED_APPS += ("silk",) or similar), so silk is enabled only in development;
ensure tuple/comma syntax is correct when appending.



SOCIAL_AUTH_GITHUB_KEY = os.environ.get("GITHUB_CLIENT_ID", "blank")
SOCIAL_AUTH_GITHUB_SECRET = os.environ.get("GITHUB_CLIENT_SECRET", "blank")


MIDDLEWARE = [
"silk.middleware.SilkyMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"blt.middleware.domain.DomainMiddleware",
"django.middleware.locale.LocaleMiddleware",
Expand All @@ -128,8 +130,10 @@
"blt.middleware.user_visit_tracking.VisitTrackingMiddleware",
]


if DEBUG:
MIDDLEWARE += ("livereload.middleware.LiveReloadScript",)
MIDDLEWARE += ("livereload.middleware.LiveReloadScript", "debug_toolbar.middleware.DebugToolbarMiddleware")
INTERNAL_IPS = ["127.0.0.1"]

BLUESKY_USERNAME = env("BLUESKY_USERNAME", default="default_username")
BLUESKY_PASSWORD = env("BLUESKY_PASSWORD", default="default_password")
Expand All @@ -156,46 +160,56 @@
"SHOW_TOOLBAR_CALLBACK": lambda request: True,
}

INSTALLED_APPS += ("debug_toolbar",)

MIDDLEWARE += ("debug_toolbar.middleware.DebugToolbarMiddleware",)

ROOT_URLCONF = "blt.urls"

TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [os.path.join(BASE_DIR, "website", "templates")],
"APP_DIRS": False,
"OPTIONS": {
"debug": DEBUG,
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.template.context_processors.media",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
"django.template.context_processors.i18n",
],
"loaders": (
[
"django.template.loaders.filesystem.Loader",
"django.template.loaders.app_directories.Loader",
]
if DEBUG
else [
if DEBUG:
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [os.path.join(BASE_DIR, "website", "templates")],
"APP_DIRS": True,
"OPTIONS": {
"debug": True,
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.template.context_processors.media",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
"django.template.context_processors.i18n",
],
},
}
]
else:
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [os.path.join(BASE_DIR, "website", "templates")],
"APP_DIRS": False,
"OPTIONS": {
"debug": False,
"loaders": [
(
"django.template.loaders.cached.Loader",
[
"django.template.loaders.filesystem.Loader",
"django.template.loaders.app_directories.Loader",
],
),
]
),
},
},
]
)
],
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.template.context_processors.media",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
"django.template.context_processors.i18n",
],
},
}
]


AUTHENTICATION_BACKENDS = (
"django.contrib.auth.backends.ModelBackend",
Expand Down Expand Up @@ -363,6 +377,7 @@
ALLOWED_HOSTS = ["*"]

STATIC_ROOT = os.path.join(PROJECT_ROOT, "staticfiles")
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
Comment on lines 379 to +380
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Django 5.2 STATICFILES_STORAGE deprecated STORAGES setting precedence

💡 Result:

Short answer: In Django 4.2+ (including 5.2) STATICFILES_STORAGE is deprecated in favour of the new STORAGES mapping. Django will use the storage configured under STORAGES["staticfiles"] as the staticfiles backend; STATICFILES_STORAGE is only used as the deprecated fallback when no STORAGES["staticfiles"] config is provided. See the STORAGES note in the 4.2 release notes and the SETTINGS docs. [1][2]

Sources

  • Django 4.2 release notes (STORAGES / deprecation of STATICFILES_STORAGE). [1]
  • django.conf.settings — STATICFILES_STORAGE doc (notes about STORAGES["staticfiles"] and deprecated STATICFILES_STORAGE). [2]

🏁 Script executed:

fd -t f "settings.py" | head -5

Repository: OWASP-BLT/BLT

Length of output: 121


🏁 Script executed:

sed -n '308,334p' blt/settings.py
sed -n '375,385p' blt/settings.py

Repository: OWASP-BLT/BLT

Length of output: 1135


Remove deprecated STATICFILES_STORAGE and update STORAGES["staticfiles"] to use WhiteNoise.

In Django 4.2+, STORAGES["staticfiles"] takes precedence over the deprecated STATICFILES_STORAGE setting. Line 380 is dead code since both STORAGES configurations (lines 316-318 and 331-333) already define the staticfiles backend.

To enable WhiteNoise compressed static files storage, remove the deprecated setting and update both STORAGES definitions:

-STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"

Update the GCS STORAGES block (around line 316):

         "staticfiles": {
-            "BACKEND": "django.contrib.staticfiles.storage.ManifestStaticFilesStorage",
+            "BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
         },

Update the non-GCS STORAGES block (around line 331):

         "staticfiles": {
-            "BACKEND": "django.contrib.staticfiles.storage.ManifestStaticFilesStorage",
+            "BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
         },

Committable suggestion skipped: line range outside the PR's diff.

STATIC_URL = "/static/"

STATICFILES_DIRS = (os.path.join(BASE_DIR, "website", "static"),)
Expand Down
6 changes: 6 additions & 0 deletions blt/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -1261,3 +1261,9 @@
] + urlpatterns

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

if settings.DEBUG:
urlpatterns += [
path("silk/", include("silk.urls", namespace="silk")),
path("__debug__/", include("debug_toolbar.urls")),
]
Comment on lines +1264 to +1269
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Duplicate debug_toolbar URL registration.

The __debug__/ URL pattern for debug_toolbar is already registered at line 1249. This block adds it again at line 1268, resulting in duplicate URL patterns when DEBUG=True.

Remove the duplicate debug_toolbar registration and keep only the silk URLs:

 if settings.DEBUG:
     urlpatterns += [
         path("silk/", include("silk.urls", namespace="silk")),
-        path("__debug__/", include("debug_toolbar.urls")),
     ]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if settings.DEBUG:
urlpatterns += [
path("silk/", include("silk.urls", namespace="silk")),
path("__debug__/", include("debug_toolbar.urls")),
]
if settings.DEBUG:
urlpatterns += [
path("silk/", include("silk.urls", namespace="silk")),
]
🤖 Prompt for AI Agents
In blt/urls.py around lines 1264 to 1269, the debug_toolbar "__debug__/" URL is
being registered a second time causing duplicate URL patterns; edit this
DEBUG-only block to remove the path("__debug__/", include("debug_toolbar.urls"))
entry and leave only the silk registration (path("silk/", include("silk.urls",
namespace="silk"))), ensuring imports remain correct and no other code relies on
this redundant registration.

36 changes: 34 additions & 2 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ tweepy = "^4.15.0"
better-profanity = "^0.7.0"
django-bleach = "^3.1.0"
pyjwt = {extras = ["crypto"], version = "^2.0.0"}
django-silk = "^5.0.1"
django-debug-toolbar = "^4.3.0"
Comment on lines +73 to +74
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Development tools added to production dependencies.

django-silk and django-debug-toolbar are development/debugging tools that shouldn't be installed in production. Additionally, django-debug-toolbar is already declared in dev dependencies at line 85 with version ^4.4.6, creating a version conflict with ^4.3.0 here.

Move these to dev dependencies and remove the duplicate:

 pyjwt = {extras = ["crypto"], version = "^2.0.0"}
-django-silk = "^5.0.1"
-django-debug-toolbar = "^4.3.0"

In the dev dependencies section, add silk:

 [tool.poetry.group.dev.dependencies]
 black = "^25.12.0"
 isort = "^5.13.2"
 ruff = "^0.14.8"
 pre-commit = "^4.5.0"
 selenium = "^4.39.0"
 webdriver-manager = "^4.0.2"
 chromedriver-autoinstaller = "^0.6.4"
 django-debug-toolbar = "^4.4.6"
 django-livereload-server = "^0.5.1"
 watchfiles = "^1.0.4"
+django-silk = "^5.0.1"

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In pyproject.toml around lines 73-74, django-silk and django-debug-toolbar are
incorrectly listed in production dependencies and django-debug-toolbar is
duplicated with a conflicting version at line 85; remove the two lines from the
main [tool.poetry.dependencies] (or equivalent production deps section), add
django-silk = "^5.0.1" to the dev dependencies section alongside the existing
django-debug-toolbar entry, and ensure the duplicate django-debug-toolbar =
"^4.3.0" is removed so only the dev dependency entry (keep ^4.4.6) remains.



[tool.poetry.group.dev.dependencies]
Expand Down
59 changes: 59 additions & 0 deletions scripts/convert_images_to_webp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# scripts/convert_images_to_webp.py

import shutil
from pathlib import Path

from PIL import Image

# Directories to process
SOURCE_DIRS = [
"website/static/images",
"website/static/img",
"website/static/img/browser-logos",
]
Comment on lines +9 to +13
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Overlapping directories will cause duplicate processing.

website/static/img/browser-logos is a subdirectory of website/static/img. Since rglob("*.png") is used, PNGs in browser-logos will be processed twice - once when iterating website/static/img and again when iterating website/static/img/browser-logos.

Remove the subdirectory from SOURCE_DIRS:

 SOURCE_DIRS = [
     "website/static/images",
     "website/static/img",
-    "website/static/img/browser-logos",
 ]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
SOURCE_DIRS = [
"website/static/images",
"website/static/img",
"website/static/img/browser-logos",
]
SOURCE_DIRS = [
"website/static/images",
"website/static/img",
]
🤖 Prompt for AI Agents
In scripts/convert_images_to_webp.py around lines 9 to 13, the SOURCE_DIRS list
contains a nested path ("website/static/img/browser-logos") inside
"website/static/img", causing duplicate processing because rglob("*.png") will
find files twice; remove the nested "website/static/img/browser-logos" entry
from SOURCE_DIRS (or alternatively dedupe paths before walking) so each PNG is
processed only once.


BACKUP_DIR = "website/static/_image_backups"


def ensure_backup_dir():
Path(BACKUP_DIR).mkdir(parents=True, exist_ok=True)


def convert_png(png_path: Path):
try:
webp_path = png_path.with_suffix(".webp")

# Skip if already converted
if webp_path.exists():
return

# Backup original
rel = png_path.relative_to("website/static")
backup_path = Path(BACKUP_DIR) / rel
backup_path.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(png_path, backup_path)

# Convert to WebP
img = Image.open(png_path).convert("RGBA")
img.save(webp_path, "webp", quality=85, method=6)

# Optimize original PNG (overwrite)
img.save(png_path, optimize=True)

except Exception:
# Silent failure by design (CI-safe)
pass


def main():
ensure_backup_dir()
for d in SOURCE_DIRS:
p = Path(d)
if not p.exists():
continue
for png in p.rglob("*.png"):
convert_png(png)


if __name__ == "__main__":
main()
Binary file added website/static/_image_backups/images/bacon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added website/static/_image_backups/images/bch qr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added website/static/_image_backups/images/close.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions website/static/_image_backups/images/default-team-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added website/static/_image_backups/images/gsoc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added website/static/_image_backups/images/next.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added website/static/_image_backups/images/prev.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added website/static/_image_backups/img/TM.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading