Bug fix for loading asset files in reports (#3596)

- Pathlib does not play well with SafeString
- Enforce string type' when loading an asset file
- Add unit tests
This commit is contained in:
Oliver 2022-08-24 11:26:38 +10:00 committed by GitHub
parent a3392ea4b1
commit 12509203d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 2 deletions

View File

@ -5,7 +5,7 @@ import os
from django import template from django import template
from django.conf import settings from django.conf import settings
from django.utils.safestring import mark_safe from django.utils.safestring import SafeString, mark_safe
import InvenTree.helpers import InvenTree.helpers
from common.models import InvenTreeSetting from common.models import InvenTreeSetting
@ -28,11 +28,15 @@ def asset(filename):
Raises: Raises:
FileNotFoundError if file does not exist FileNotFoundError if file does not exist
""" """
if type(filename) is SafeString:
# Prepend an empty string to enforce 'stringiness'
filename = '' + filename
# If in debug mode, return URL to the image, not a local file # If in debug mode, return URL to the image, not a local file
debug_mode = InvenTreeSetting.get_setting('REPORT_DEBUG_MODE') debug_mode = InvenTreeSetting.get_setting('REPORT_DEBUG_MODE')
# Test if the file actually exists # Test if the file actually exists
full_path = settings.MEDIA_ROOT.joinpath('report', 'assets', filename) full_path = settings.MEDIA_ROOT.joinpath('report', 'assets', filename).resolve()
if not full_path.exists() or not full_path.is_file(): if not full_path.exists() or not full_path.is_file():
raise FileNotFoundError(f"Asset file '{filename}' does not exist") raise FileNotFoundError(f"Asset file '{filename}' does not exist")
@ -55,6 +59,10 @@ def uploaded_image(filename, replace_missing=True, replacement_file='blank_image
A fully qualified path to the image A fully qualified path to the image
""" """
if type(filename) is SafeString:
# Prepend an empty string to enforce 'stringiness'
filename = '' + filename
# If in debug mode, return URL to the image, not a local file # If in debug mode, return URL to the image, not a local file
debug_mode = InvenTreeSetting.get_setting('REPORT_DEBUG_MODE') debug_mode = InvenTreeSetting.get_setting('REPORT_DEBUG_MODE')

View File

@ -9,6 +9,7 @@ from django.core.cache import cache
from django.http.response import StreamingHttpResponse from django.http.response import StreamingHttpResponse
from django.test import TestCase from django.test import TestCase
from django.urls import reverse from django.urls import reverse
from django.utils.safestring import SafeString
from PIL import Image from PIL import Image
@ -49,6 +50,10 @@ class ReportTagTest(TestCase):
asset = report_tags.asset('test.txt') asset = report_tags.asset('test.txt')
self.assertEqual(asset, '/media/report/assets/test.txt') self.assertEqual(asset, '/media/report/assets/test.txt')
# Ensure that a 'safe string' also works
asset = report_tags.asset(SafeString('test.txt'))
self.assertEqual(asset, '/media/report/assets/test.txt')
self.debug_mode(False) self.debug_mode(False)
asset = report_tags.asset('test.txt') asset = report_tags.asset('test.txt')
self.assertEqual(asset, f'file://{asset_dir}/test.txt') self.assertEqual(asset, f'file://{asset_dir}/test.txt')
@ -87,10 +92,17 @@ class ReportTagTest(TestCase):
img = report_tags.uploaded_image('part/images/test.jpg') img = report_tags.uploaded_image('part/images/test.jpg')
self.assertEqual(img, '/media/part/images/test.jpg') self.assertEqual(img, '/media/part/images/test.jpg')
# Ensure that a 'safe string' also works
img = report_tags.uploaded_image(SafeString('part/images/test.jpg'))
self.assertEqual(img, '/media/part/images/test.jpg')
self.debug_mode(False) self.debug_mode(False)
img = report_tags.uploaded_image('part/images/test.jpg') img = report_tags.uploaded_image('part/images/test.jpg')
self.assertEqual(img, f'file://{img_path.joinpath("test.jpg")}') self.assertEqual(img, f'file://{img_path.joinpath("test.jpg")}')
img = report_tags.uploaded_image(SafeString('part/images/test.jpg'))
self.assertEqual(img, f'file://{img_path.joinpath("test.jpg")}')
def test_part_image(self): def test_part_image(self):
"""Unit tests for the 'part_image' tag""" """Unit tests for the 'part_image' tag"""