2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-15 19:45:46 +00:00

Check user permissions before linking or un-linking barcodes (#3772)

* Check user permissions before linking or un-linking barcodse

* Bump API version

* Permission fixes for unit tests

* Fix permission issues

* Unit test fixes
This commit is contained in:
Oliver
2022-10-13 12:14:36 +11:00
committed by GitHub
parent fccbcad63f
commit 99d822ecdb
4 changed files with 60 additions and 2 deletions

View File

@ -2,11 +2,14 @@
# InvenTree API version # InvenTree API version
INVENTREE_API_VERSION = 76 INVENTREE_API_VERSION = 77
""" """
Increment this API version number whenever there is a significant change to the API that any clients need to know about Increment this API version number whenever there is a significant change to the API that any clients need to know about
v77 -> 2022-10-12 : https://github.com/inventree/InvenTree/pull/3772
- Adds model permission checks for barcode assignment actions
v76 -> 2022-09-10 : https://github.com/inventree/InvenTree/pull/3640 v76 -> 2022-09-10 : https://github.com/inventree/InvenTree/pull/3640
- Refactor of barcode data on the API - Refactor of barcode data on the API
- StockItem.uid renamed to StockItem.barcode_hash - StockItem.uid renamed to StockItem.barcode_hash

View File

@ -5,7 +5,7 @@ from django.urls import path, re_path
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from rest_framework import permissions from rest_framework import permissions
from rest_framework.exceptions import ValidationError from rest_framework.exceptions import PermissionDenied, ValidationError
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.views import APIView
@ -13,6 +13,7 @@ from InvenTree.helpers import hash_barcode
from plugin import registry from plugin import registry
from plugin.builtin.barcodes.inventree_barcode import ( from plugin.builtin.barcodes.inventree_barcode import (
InvenTreeExternalBarcodePlugin, InvenTreeInternalBarcodePlugin) InvenTreeExternalBarcodePlugin, InvenTreeInternalBarcodePlugin)
from users.models import RuleSet
class BarcodeScan(APIView): class BarcodeScan(APIView):
@ -139,6 +140,17 @@ class BarcodeAssign(APIView):
try: try:
instance = model.objects.get(pk=data[label]) instance = model.objects.get(pk=data[label])
# Check that the user has the required permission
app_label = model._meta.app_label
model_name = model._meta.model_name
table = f"{app_label}_{model_name}"
if not RuleSet.check_table_permission(request.user, table, "change"):
raise PermissionDenied({
"error": f"You do not have the required permissions for {table}"
})
instance.assign_barcode( instance.assign_barcode(
barcode_data=barcode_data, barcode_data=barcode_data,
barcode_hash=barcode_hash, barcode_hash=barcode_hash,
@ -210,6 +222,17 @@ class BarcodeUnassign(APIView):
label: _('No match found for provided value') label: _('No match found for provided value')
}) })
# Check that the user has the required permission
app_label = model._meta.app_label
model_name = model._meta.model_name
table = f"{app_label}_{model_name}"
if not RuleSet.check_table_permission(request.user, table, "change"):
raise PermissionDenied({
"error": f"You do not have the required permissions for {table}"
})
# Unassign the barcode data from the model instance # Unassign the barcode data from the model instance
instance.unassign_barcode() instance.unassign_barcode()

View File

@ -190,6 +190,8 @@ class BarcodeAPITest(InvenTreeAPITestCase):
"""Test that a barcode can be associated with a StockItem.""" """Test that a barcode can be associated with a StockItem."""
item = StockItem.objects.get(pk=522) item = StockItem.objects.get(pk=522)
self.assignRole('stock.change')
self.assertEqual(len(item.barcode_hash), 0) self.assertEqual(len(item.barcode_hash), 0)
barcode_data = 'A-TEST-BARCODE-STRING' barcode_data = 'A-TEST-BARCODE-STRING'

View File

@ -125,6 +125,19 @@ class TestInvenTreeBarcode(InvenTreeAPITestCase):
self.assertIn('Missing data:', str(response.data)) self.assertIn('Missing data:', str(response.data))
# Permission error check
response = self.assign(
{
'barcode': 'abcdefg',
'part': 1,
'stockitem': 1,
},
expected_code=403
)
self.assignRole('part.change')
self.assignRole('stock.change')
# Provide too many fields # Provide too many fields
response = self.assign( response = self.assign(
{ {
@ -188,6 +201,8 @@ class TestInvenTreeBarcode(InvenTreeAPITestCase):
barcode = 'xyz-123' barcode = 'xyz-123'
self.assignRole('part.change')
# Test that an initial scan yields no results # Test that an initial scan yields no results
response = self.scan( response = self.scan(
{ {
@ -196,6 +211,8 @@ class TestInvenTreeBarcode(InvenTreeAPITestCase):
expected_code=400 expected_code=400
) )
self.assignRole('part.change')
# Attempt to assign to an invalid part ID # Attempt to assign to an invalid part ID
response = self.assign( response = self.assign(
{ {
@ -247,6 +264,8 @@ class TestInvenTreeBarcode(InvenTreeAPITestCase):
self.assertIn('Barcode matches existing item', str(response.data['error'])) self.assertIn('Barcode matches existing item', str(response.data['error']))
self.assignRole('part.change')
# Now test that we can unassign the barcode data also # Now test that we can unassign the barcode data also
response = self.unassign( response = self.unassign(
{ {
@ -265,6 +284,17 @@ class TestInvenTreeBarcode(InvenTreeAPITestCase):
barcode = '555555555555555555555555' barcode = '555555555555555555555555'
# Assign random barcode data to a StockLocation instance
response = self.assign(
data={
'barcode': barcode,
'stocklocation': 1,
},
expected_code=403,
)
self.assignRole('stock_location.change')
# Assign random barcode data to a StockLocation instance # Assign random barcode data to a StockLocation instance
response = self.assign( response = self.assign(
data={ data={