2
0
mirror of https://github.com/inventree/InvenTree.git synced 2026-05-17 14:58:36 +00:00

refactor(backend): various SAST fixes (#11952)

* optimize asserts

* ensure redirect is safe

* sanatize token in log
This commit is contained in:
Matthias Mair
2026-05-15 23:53:37 +02:00
committed by GitHub
parent 2abaaff543
commit e3a22762e8
6 changed files with 34 additions and 12 deletions
@@ -1181,3 +1181,18 @@ def plugins_info(*args, **kwargs):
return [
{'name': plg.name, 'slug': plg.slug, 'version': plg.version} for plg in plugins
]
def sanitize_token(token_value: str, front=8, back=12) -> str:
"""Sanitize a token by replacing the middle characters with asterisks.
Args:
token_value: The token string to sanitize
front: Number of characters to show at the start of the token (default = 8)
back: Number of characters to show at the end of the token (default = 12)
Returns:
The sanitized token string
"""
middle = len(token_value) - (front + back)
return token_value[:front] + '*' * middle + token_value[-back:]
+13 -4
View File
@@ -10,12 +10,13 @@ from django.http import HttpRequest, HttpResponse, JsonResponse
from django.shortcuts import redirect, render
from django.urls import resolve, reverse, reverse_lazy
from django.utils.deprecation import MiddlewareMixin
from django.utils.http import is_same_domain
from django.utils.http import is_same_domain, url_has_allowed_host_and_scheme
from django.utils.translation import gettext_lazy as _
import structlog
from error_report.middleware import ExceptionProcessor
import InvenTree.helpers
from common.settings import get_global_setting
from InvenTree.cache import create_session_cache, delete_session_cache
from InvenTree.config import CONFIG_LOOKUPS, inventreeInstaller
@@ -126,7 +127,8 @@ class AuthRequiredMiddleware:
return True
except ApiToken.DoesNotExist: # pragma: no cover
logger.warning(
'Access denied for unknown token %s', token
'Access denied for unknown token %s',
InvenTree.helpers.sanitize_token(str(token)),
) # pragma: no cover
return False
@@ -163,9 +165,16 @@ class AuthRequiredMiddleware:
if path not in urls and not any(
path.startswith(p) for p in paths_ignore_handling
):
# Validate next url is safe to redirect to
next_url = request.path
if not url_has_allowed_host_and_scheme(
url=next_url,
allowed_hosts=settings.ALLOWED_HOSTS,
require_https=request.is_secure(),
):
return redirect(str(reverse_lazy('account_login')))
# Save the 'next' parameter to pass through to the login view
return redirect(f'{reverse_lazy("account_login")}?next={request.path}')
return redirect(f'{reverse_lazy("account_login")}?next={next_url}')
# Return a 401 (Unauthorized) response code for this request
return HttpResponse('Unauthorized', status=401)
@@ -299,7 +299,7 @@ class TestAddressMigration(MigratorTestCase):
c1 = Company.objects.filter(name='Company 1').first()
c2 = Company.objects.filter(name='Company 2').first()
self.assertEqual(len(Address.objects.all()), 2)
self.assertEqual(Address.objects.count(), 2)
a1 = Address.objects.filter(company=c1.pk).first()
a2 = Address.objects.filter(company=c2.pk).first()
+2 -2
View File
@@ -147,7 +147,7 @@ class MachineAPITest(TestMachineRegistryMixin, InvenTreeAPITestCase):
def test_machine_detail(self):
"""Test machine detail API endpoint."""
self.assertFalse(len(MachineConfig.objects.all()), 0)
self.assertFalse(MachineConfig.objects.count(), 0)
self.get(
reverse('api-machine-detail', kwargs={'pk': self.placeholder_uuid}),
expected_code=404,
@@ -185,7 +185,7 @@ class MachineAPITest(TestMachineRegistryMixin, InvenTreeAPITestCase):
response = self.delete(
reverse('api-machine-detail', kwargs={'pk': pk}), expected_code=204
)
self.assertFalse(len(MachineConfig.objects.all()), 0)
self.assertFalse(MachineConfig.objects.count(), 0)
# Create machine where the driver does not exist
machine_data['driver'] = 'non-existent-driver'
+2 -2
View File
@@ -43,8 +43,8 @@ class CategoryTest(TestCase):
self.assertTrue(self.electronics.has_children)
self.assertTrue(self.mechanical.has_children)
self.assertEqual(len(self.electronics.children.all()), 3)
self.assertEqual(len(self.mechanical.children.all()), 1)
self.assertEqual(self.electronics.children.count(), 3)
self.assertEqual(self.mechanical.children.count(), 1)
def test_unique_children(self):
"""Test the 'unique_children' functionality."""
+1 -3
View File
@@ -179,9 +179,7 @@ class ApiToken(AuthToken, InvenTree.models.MetadataMixin):
if self.pk is None:
return self.key # pragma: no cover
M = len(self.key) - 20
return self.key[:8] + '*' * M + self.key[-12:]
return InvenTree.helpers.sanitize_token(self.key)
@property
@admin.display(boolean=True, description=_('Expired'))