[API] Restrict barcode scan history (#12569)

- A non-staff user can only view their own results
This commit is contained in:
Oliver
2026-08-08 21:56:47 +10:00
committed by GitHub
parent 28fea388f6
commit c0ed42549f
2 changed files with 93 additions and 0 deletions
@@ -848,6 +848,16 @@ class BarcodeScanResultMixin:
"""Return the queryset for the BarcodeScan API.""" """Return the queryset for the BarcodeScan API."""
queryset = super().get_queryset() queryset = super().get_queryset()
try:
user = self.request.user
except AttributeError:
raise PermissionDenied('User information is not available')
# Allow staff users access to all BarcodeScanResult objects
if not user.is_staff:
# All other users are limited to viewing their own barcode scan history
queryset = queryset.filter(user=user)
# Pre-fetch user data # Pre-fetch user data
queryset = queryset.prefetch_related('user') queryset = queryset.prefetch_related('user')
@@ -256,6 +256,89 @@ class BarcodeAPITest(InvenTreeAPITestCase):
self.assertIn('object does not exist', str(response.data[k])) self.assertIn('object does not exist', str(response.data[k]))
class BarcodeScanResultAPITest(InvenTreeAPITestCase):
"""Tests for the BarcodeScanResult list / detail API endpoints."""
def setUp(self):
"""Create barcode scan results for two different users."""
super().setUp()
from django.contrib.auth import get_user_model
self.other_user = get_user_model().objects.create_user(
username='otheruser', password='otherpassword', email='other@testing.com'
)
self.own_result = BarcodeScanResult.objects.create(
data='own-barcode', user=self.user
)
self.other_result = BarcodeScanResult.objects.create(
data='other-barcode', user=self.other_user
)
def test_list_non_staff(self):
"""A non-staff user can only see their own barcode scan history."""
self.user.is_staff = False
self.user.save()
response = self.get(reverse('api-barcode-scan-result-list'), expected_code=200)
pks = [item['pk'] for item in response.data]
self.assertIn(self.own_result.pk, pks)
self.assertNotIn(self.other_result.pk, pks)
def test_list_staff(self):
"""A staff user can see barcode scan history for all users."""
self.user.is_staff = True
self.user.save()
response = self.get(reverse('api-barcode-scan-result-list'), expected_code=200)
pks = [item['pk'] for item in response.data]
self.assertIn(self.own_result.pk, pks)
self.assertIn(self.other_result.pk, pks)
def test_detail_non_staff(self):
"""A non-staff user cannot retrieve another user's barcode scan result."""
self.user.is_staff = False
self.user.save()
self.get(
reverse(
'api-barcode-scan-result-detail', kwargs={'pk': self.own_result.pk}
),
expected_code=200,
)
self.get(
reverse(
'api-barcode-scan-result-detail', kwargs={'pk': self.other_result.pk}
),
expected_code=404,
)
def test_detail_staff(self):
"""A staff user can retrieve any user's barcode scan result."""
self.user.is_staff = True
self.user.save()
self.get(
reverse(
'api-barcode-scan-result-detail', kwargs={'pk': self.own_result.pk}
),
expected_code=200,
)
self.get(
reverse(
'api-barcode-scan-result-detail', kwargs={'pk': self.other_result.pk}
),
expected_code=200,
)
class POAllocateTest(InvenTreeAPITestCase): class POAllocateTest(InvenTreeAPITestCase):
"""Unit tests for the barcode endpoint for allocating items to a purchase order.""" """Unit tests for the barcode endpoint for allocating items to a purchase order."""