Skip to content

Commit

Permalink
Merge pull request #254 from ppfeufer/django-sri
Browse files Browse the repository at this point in the history
  • Loading branch information
ppfeufer authored Feb 2, 2025
2 parents e9d37cd + 379f0bf commit 0510da0
Show file tree
Hide file tree
Showing 16 changed files with 221 additions and 102 deletions.
71 changes: 40 additions & 31 deletions .make/conf.d/django.mk
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
pot:
@echo "Creating or updating .pot file …"
@django-admin makemessages \
-l en \
--locale en \
--keep-pot \
--ignore 'build/*'
--ignore 'build/*' \
--ignore 'node_modules/*' \
--ignore 'testauth/*' \
--ignore 'runtests.py'
@current_app_version=$$(pip show $(appname) | grep 'Version: ' | awk '{print $$NF}'); \
sed -i "/\"Project-Id-Version: /c\\\"Project-Id-Version: $(appname_verbose) $$current_app_version\\\n\"" $(translation_template); \
sed -i "/\"Report-Msgid-Bugs-To: /c\\\"Report-Msgid-Bugs-To: $(git_repository_issues)\\\n\"" $(translation_template);
Expand All @@ -18,9 +21,12 @@ add_translation:
@echo "Adding a new translation"
@read -p "Enter the language code (e.g. 'en_GB'): " language_code; \
django-admin makemessages \
-l $$language_code \
--locale $$language_code \
--keep-pot \
--ignore 'build/*'; \
--ignore 'build/*' \
--ignore 'node_modules/*' \
--ignore 'testauth/*' \
--ignore 'runtests.py'; \
current_app_version=$$(pip show $(appname) | grep 'Version: ' | awk '{print $$NF}'); \
sed -i "/\"Project-Id-Version: /c\\\"Project-Id-Version: $(appname_verbose) $$current_app_version\\\n\"" $(translation_template); \
sed -i "/\"Report-Msgid-Bugs-To: /c\\\"Report-Msgid-Bugs-To: $(git_repository_issues)\\\n\"" $(translation_template); \
Expand All @@ -34,21 +40,24 @@ add_translation:
translations:
@echo "Creating or updating translation files"
@django-admin makemessages \
-l cs_CZ \
-l de \
-l es \
-l fr_FR \
-l it_IT \
-l ja \
-l ko_KR \
-l nl_NL \
-l pl_PL \
-l ru \
-l sk \
-l uk \
-l zh_Hans \
--locale cs_CZ \
--locale de \
--locale es \
--locale fr_FR \
--locale it_IT \
--locale ja \
--locale ko_KR \
--locale nl_NL \
--locale pl_PL \
--locale ru \
--locale sk \
--locale uk \
--locale zh_Hans \
--keep-pot \
--ignore 'build/*'
--ignore 'build/*' \
--ignore 'node_modules/*' \
--ignore 'testauth/*' \
--ignore 'runtests.py'
@current_app_version=$$(pip show $(appname) | grep 'Version: ' | awk '{print $$NF}'); \
sed -i "/\"Project-Id-Version: /c\\\"Project-Id-Version: $(appname_verbose) $$current_app_version\\\n\"" $(translation_template); \
sed -i "/\"Report-Msgid-Bugs-To: /c\\\"Report-Msgid-Bugs-To: $(git_repository_issues)\\\n\"" $(translation_template); \
Expand All @@ -69,19 +78,19 @@ translations:
compile_translations:
@echo "Compiling translation files"
@django-admin compilemessages \
-l cs_CZ \
-l de \
-l es \
-l fr_FR \
-l it_IT \
-l ja \
-l ko_KR \
-l nl_NL \
-l pl_PL \
-l ru \
-l sk \
-l uk \
-l zh_Hans
--locale cs_CZ \
--locale de \
--locale es \
--locale fr_FR \
--locale it_IT \
--locale ja \
--locale ko_KR \
--locale nl_NL \
--locale pl_PL \
--locale ru \
--locale sk \
--locale uk \
--locale zh_Hans

# Migrate all database changes
.PHONY: migrate
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ Section Order:
### Security
-->

### Changed

- Use `django-sri` for sri hashes
- Minimum requirements
- Alliance Auth >= 4.6.0

## [2.5.5] - 2025-01-13

### Fixed
Expand Down
8 changes: 8 additions & 0 deletions aasrp/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
Constants
"""

# Standard Library
import os

# Third Party
from requests.__version__ import __version__ as requests_version

Expand All @@ -21,6 +24,11 @@
f"{APP_NAME}/{__version__} +{GITHUB_URL} via requests/{requests_version}"
)

# aa-srp/aasrp
AA_SRP_BASE_DIR = os.path.join(os.path.dirname(__file__))
# aa-srp/aasrp/static/aasrp
AA_SRP_STATIC_DIR = os.path.join(AA_SRP_BASE_DIR, "static", "aasrp")


SRP_REQUEST_NOTIFICATION_INQUIRY_NOTE = _(
"If you have any questions regarding your SRP request, feel free to contact your "
Expand Down
41 changes: 41 additions & 0 deletions aasrp/helper/static_files.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""
Helper functions for static integrity calculations
"""

# Standard Library
import os
from pathlib import Path

# Third Party
from sri import Algorithm, calculate_integrity

# Alliance Auth
from allianceauth.services.hooks import get_extension_logger

# Alliance Auth (External Libs)
from app_utils.logging import LoggerAddTag

# AA SRP
from aasrp import __title__
from aasrp.constants import AA_SRP_STATIC_DIR

logger = LoggerAddTag(my_logger=get_extension_logger(__name__), prefix=__title__)


def calculate_integrity_hash(relative_file_path: str) -> str:
"""
Calculates the integrity hash for a given static file
:param self:
:type self:
:param relative_file_path: The file path relative to the `aa-srp/aasrp/static/aasrp` folder
:type relative_file_path: str
:return: The integrity hash
:rtype: str
"""

file_path = os.path.join(AA_SRP_STATIC_DIR, relative_file_path)
integrity_hash = calculate_integrity(
path=Path(file_path), algorithm=Algorithm.SHA512
)

return integrity_hash
7 changes: 1 addition & 6 deletions aasrp/templates/aasrp/bundles/aa-srp-css.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
{% load aasrp %}

<link
rel="stylesheet"
href="{% aasrp_static 'aasrp/css/aa-srp.min.css' %}"
integrity="sha512-eeN/pqBQ+41AVmNR+UyHjrSZvK0fpd5c14yV4NHnQEEXseMMZQu794m/PJ4usfZyQnZS2t4kFWDusnWZhC+HWw=="
crossorigin="anonymous"
>
{% aasrp_static "css/aa-srp.min.css" %}
7 changes: 1 addition & 6 deletions aasrp/templates/aasrp/bundles/aa-srp-form-css.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
{% load aasrp %}

<link
rel="stylesheet"
href="{% aasrp_static 'aasrp/css/aa-srp-form.min.css' %}"
integrity="sha512-y6ANPtPgBNxGQhYYNN3EI5bpLtzy/IVAJ18I5MdjnCIel2fCnD34H3dkHdOpt8ZiaKb9T/NRjS5rxlQynP9hlQ=="
crossorigin="anonymous"
>
{% aasrp_static "css/aa-srp-form.min.css" %}
6 changes: 1 addition & 5 deletions aasrp/templates/aasrp/bundles/aa-srp-form-js.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
{% load aasrp %}

<script
src="{% aasrp_static 'aasrp/javascript/form.min.js' %}"
integrity="sha512-ln1VzEG3ExrwRcfqIxE9WUXh81N4t2LJSq+bLrMGx4m1X/kwxbtSpDGD7EMwsDgtRCxKecPrnvw2VRf5lG8M9w=="
crossorigin="anonymous"
></script>
{% aasrp_static "javascript/form.min.js" %}
6 changes: 1 addition & 5 deletions aasrp/templates/aasrp/bundles/aa-srp-js.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
{% load aasrp %}

<script
src="{% aasrp_static 'aasrp/javascript/aa-srp.min.js' %}"
integrity="sha512-SKL5pQAdZ1elLpwQNAi7E/kiO9txWBFPyYzCuClBx4psUpPwezz0LviMO8VEO09m0C7/q1KWLZPxXNJA/Igwxg=="
crossorigin="anonymous"
></script>
{% aasrp_static "javascript/aa-srp.min.js" %}
6 changes: 1 addition & 5 deletions aasrp/templates/aasrp/bundles/my-srp-requests-js.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
{% load aasrp %}

<script
src="{% aasrp_static 'aasrp/javascript/my-srp-requests.min.js' %}"
integrity="sha512-HAmMdsguzaj4WiEQFNjvu6ykL70u/Tucj8aggl5grtLcSHNq8+Qcqi+oAhR02DI6WI04WfsFGVsIZsiPiHbohQ=="
crossorigin="anonymous"
></script>
{% aasrp_static "javascript/my-srp-requests.min.js" %}
6 changes: 1 addition & 5 deletions aasrp/templates/aasrp/bundles/srp-links-js.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
{% load aasrp %}

<script
src="{% aasrp_static 'aasrp/javascript/srp-links.min.js' %}"
integrity="sha512-qIB1r3Oqer36+Ujp4Y/cihZVpUf3mAEYerpQ2UqIjVkLpPMHAqoSOrf+wGq22isAKTjfSK4+9GWJlHbLnViaTw=="
crossorigin="anonymous"
></script>
{% aasrp_static "javascript/srp-links.min.js" %}
6 changes: 1 addition & 5 deletions aasrp/templates/aasrp/bundles/view-requests-js.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
{% load aasrp %}

<script
src="{% aasrp_static 'aasrp/javascript/view-requests.min.js' %}"
integrity="sha512-OX093crku4t8qUaI+nb6M29X6XPXNcikn/yZcjYEGq0VeP4f862u3uynXwky/MkFKOHBucuaPLDjcCU7RGhrKQ=="
crossorigin="anonymous"
></script>
{% aasrp_static "javascript/view-requests.min.js" %}
9 changes: 2 additions & 7 deletions aasrp/templates/aasrp/bundles/x-editable-css.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
{% load static %}
{% load aasrp %}

<link
rel="stylesheet"
href="{% static 'aasrp/libs/x-editable/1.5.4/bootstrap5-editable/css/bootstrap-editable.min.css' %}"
integrity="sha512-52DL7BCZnjDkln1qrZMe9qSt6KFBwrGAa4JqmrmwYrz+QIfBXyacLvmTrpIyqJdjcEqzw/3YOM4Xj32mDz4x3A=="
crossorigin="anonymous"
>
{% aasrp_static "libs/x-editable/1.5.4/bootstrap5-editable/css/bootstrap-editable.min.css" %}
8 changes: 2 additions & 6 deletions aasrp/templates/aasrp/bundles/x-editable-js.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
{% load static %}
{% load aasrp %}

<script
src="{% static 'aasrp/libs/x-editable/1.5.4/bootstrap5-editable/js/bootstrap-editable.min.js' %}"
integrity="sha512-GpwuhZ2LkD9jnasqgssH1FJQLHvIeW9T36ax9W3dv+8KSA3xURDoTffS1SD95KSb2fXuYWg0Z5sDoZ/Xx10GHA=="
crossorigin="anonymous"
></script>
{% aasrp_static "libs/x-editable/1.5.4/bootstrap5-editable/js/bootstrap-editable.min.js" %}
74 changes: 61 additions & 13 deletions aasrp/templatetags/aasrp.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,85 @@
Versioned static URLs to break browser caches when changing the app version
"""

# Standard Library
import os

# Django
from django.conf import settings
from django.contrib.auth.models import User
from django.template.defaulttags import register
from django.templatetags.static import static
from django.utils.safestring import mark_safe

# Alliance Auth
from allianceauth.framework.api.user import get_main_character_name_from_user
from allianceauth.services.hooks import get_extension_logger

# Alliance Auth (External Libs)
from app_utils.logging import LoggerAddTag

# AA SRP
from aasrp import __version__
from aasrp import __title__, __version__
from aasrp.helper.static_files import calculate_integrity_hash

logger = LoggerAddTag(my_logger=get_extension_logger(__name__), prefix=__title__)


@register.simple_tag
def aasrp_static(path: str) -> str:
def aasrp_static(relative_file_path: str, script_type: str = None) -> str | None:
"""
Versioned static URL
Adding the app version to any static file we load through this function.
This is to make sure to break the browser cache on app updates.
Example: /static/myapp/css/myapp.css?ver=1.0.0
:param path:
:type path:
:return:
:rtype:
:param relative_file_path: The file path relative to the `aa-srp/aasrp/static/aasrp` folder
:type relative_file_path: str
:param script_type: The script type
:type script_type: str
:return: Versioned static URL
:rtype: str
"""

static_url = static(path)
versioned_url = static_url + "?v=" + __version__
logger.debug(f"Getting versioned static URL for: {relative_file_path}")

file_type = os.path.splitext(relative_file_path)[1][1:]

logger.debug(f"File extension: {file_type}")

# Only support CSS and JS files
if file_type not in ["css", "js"]:
raise ValueError(f"Unsupported file type: {file_type}")

static_file_path = os.path.join("aasrp", relative_file_path)
static_url = static(static_file_path)

# Integrity hash calculation only for non-debug mode
sri_string = (
f' integrity="{calculate_integrity_hash(relative_file_path)}" crossorigin="anonymous"'
if not settings.DEBUG
else ""
)

# Versioned URL for CSS and JS files
# Add version query parameter to break browser caches when changing the app version
# Do not add version query parameter for libs as they are already versioned through their file path
versioned_url = (
static_url
if relative_file_path.startswith("libs/")
else static_url + "?v=" + __version__
)

# Return the versioned URL with integrity hash for CSS
if file_type == "css":
return mark_safe(f'<link rel="stylesheet" href="{versioned_url}"{sri_string}>')

# Return the versioned URL with integrity hash for JS files
if file_type == "js":
js_type = f' type="{script_type}"' if script_type else ""

return mark_safe(
f'<script{js_type} src="{versioned_url}"{sri_string}></script>'
)

return versioned_url
return None


@register.filter
Expand Down
Loading

0 comments on commit 0510da0

Please sign in to comment.