extend barcode scans with user perm check
This commit is contained in:
parent
6057aafe65
commit
87e118df42
|
|
@ -54,14 +54,14 @@ class InvenTreeBarcodePlugin(BarcodeMixin, InvenTreePlugin):
|
||||||
VERSION = "0.0.1"
|
VERSION = "0.0.1"
|
||||||
AUTHOR = "Michael"
|
AUTHOR = "Michael"
|
||||||
|
|
||||||
def scan(self, barcode_data):
|
def scan(self, barcode_data, user, **kwargs):
|
||||||
if barcode_data.startswith("PART-"):
|
if barcode_data.startswith("PART-"):
|
||||||
try:
|
try:
|
||||||
pk = int(barcode_data.split("PART-")[1])
|
pk = int(barcode_data.split("PART-")[1])
|
||||||
instance = Part.objects.get(pk=pk)
|
instance = Part.objects.get(pk=pk)
|
||||||
label = Part.barcode_model_type()
|
label = Part.barcode_model_type()
|
||||||
|
|
||||||
return {label: instance.format_matched_response()}
|
return {label: instance.format_matched_response(user=user)}
|
||||||
except Part.DoesNotExist:
|
except Part.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ from typing import Any, Optional
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.contrib.contenttypes.fields import GenericRelation
|
from django.contrib.contenttypes.fields import GenericRelation
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import PermissionDenied, ValidationError
|
||||||
from django.db import models, transaction
|
from django.db import models, transaction
|
||||||
from django.db.models import QuerySet
|
from django.db.models import QuerySet
|
||||||
from django.db.models.signals import post_save
|
from django.db.models.signals import post_save
|
||||||
|
|
@ -33,6 +33,7 @@ import InvenTree.format
|
||||||
import InvenTree.helpers
|
import InvenTree.helpers
|
||||||
import InvenTree.helpers_model
|
import InvenTree.helpers_model
|
||||||
import InvenTree.sentry
|
import InvenTree.sentry
|
||||||
|
from InvenTree.users.permissions import check_user_permission
|
||||||
|
|
||||||
logger = structlog.get_logger('inventree')
|
logger = structlog.get_logger('inventree')
|
||||||
|
|
||||||
|
|
@ -1334,8 +1335,14 @@ class InvenTreeBarcodeMixin(models.Model):
|
||||||
|
|
||||||
return generate_barcode(self)
|
return generate_barcode(self)
|
||||||
|
|
||||||
def format_matched_response(self):
|
def format_matched_response(self, user, **kwargs):
|
||||||
"""Format a standard response for a matched barcode."""
|
"""Format a standard response for a matched barcode."""
|
||||||
|
# Check permission for this object
|
||||||
|
if not check_user_permission(user, self, 'view'):
|
||||||
|
raise PermissionDenied(
|
||||||
|
_('User does not have permission to view this object')
|
||||||
|
)
|
||||||
|
|
||||||
data = {'pk': self.pk}
|
data = {'pk': self.pk}
|
||||||
|
|
||||||
if hasattr(self, 'get_api_url'):
|
if hasattr(self, 'get_api_url'):
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@ class BarcodeView(CreateAPIView):
|
||||||
|
|
||||||
for current_plugin in plugins:
|
for current_plugin in plugins:
|
||||||
try:
|
try:
|
||||||
result = current_plugin.scan(barcode)
|
result = current_plugin.scan(barcode, user=request.user, **kwargs)
|
||||||
except Exception:
|
except Exception:
|
||||||
log_error('BarcodeView.scan_barcode', plugin=current_plugin.slug)
|
log_error('BarcodeView.scan_barcode', plugin=current_plugin.slug)
|
||||||
continue
|
continue
|
||||||
|
|
@ -282,7 +282,7 @@ class BarcodeAssign(BarcodeView):
|
||||||
|
|
||||||
# First check if the provided barcode matches an existing database entry
|
# First check if the provided barcode matches an existing database entry
|
||||||
if inventree_barcode_plugin:
|
if inventree_barcode_plugin:
|
||||||
result = inventree_barcode_plugin.scan(barcode)
|
result = inventree_barcode_plugin.scan(barcode, user=request.user, **kwargs)
|
||||||
|
|
||||||
if result is not None:
|
if result is not None:
|
||||||
result['error'] = _('Barcode matches existing item')
|
result['error'] = _('Barcode matches existing item')
|
||||||
|
|
@ -459,7 +459,9 @@ class BarcodePOAllocate(BarcodeView):
|
||||||
manufacturer_part=response.get('manufacturerpart', None),
|
manufacturer_part=response.get('manufacturerpart', None),
|
||||||
)
|
)
|
||||||
response['success'] = _('Matched supplier part')
|
response['success'] = _('Matched supplier part')
|
||||||
response['supplierpart'] = supplier_part.format_matched_response()
|
response['supplierpart'] = supplier_part.format_matched_response(
|
||||||
|
user=request.user
|
||||||
|
)
|
||||||
except ValidationError as e:
|
except ValidationError as e:
|
||||||
response['error'] = str(e)
|
response['error'] = str(e)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ class BarcodeMixin:
|
||||||
"""Does this plugin have everything needed to process a barcode."""
|
"""Does this plugin have everything needed to process a barcode."""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def scan(self, barcode_data):
|
def scan(self, barcode_data: str, user, **kwargs) -> dict | None:
|
||||||
"""Scan a barcode against this plugin.
|
"""Scan a barcode against this plugin.
|
||||||
|
|
||||||
This method is explicitly called from the /scan/ API endpoint,
|
This method is explicitly called from the /scan/ API endpoint,
|
||||||
|
|
@ -261,7 +261,7 @@ class SupplierBarcodeMixin(BarcodeMixin):
|
||||||
'extract_barcode_fields must be implemented by each plugin'
|
'extract_barcode_fields must be implemented by each plugin'
|
||||||
)
|
)
|
||||||
|
|
||||||
def scan(self, barcode_data: str) -> dict | None:
|
def scan(self, barcode_data: str, user, **kwargs) -> dict | None:
|
||||||
"""Perform a generic 'scan' operation on a supplier barcode.
|
"""Perform a generic 'scan' operation on a supplier barcode.
|
||||||
|
|
||||||
The supplier barcode may provide sufficient information to match against
|
The supplier barcode may provide sufficient information to match against
|
||||||
|
|
@ -297,7 +297,7 @@ class SupplierBarcodeMixin(BarcodeMixin):
|
||||||
for k, v in matches.items():
|
for k, v in matches.items():
|
||||||
if v and hasattr(v, 'pk'):
|
if v and hasattr(v, 'pk'):
|
||||||
has_match = True
|
has_match = True
|
||||||
data[k] = v.format_matched_response()
|
data[k] = v.format_matched_response(user=user)
|
||||||
|
|
||||||
if not has_match:
|
if not has_match:
|
||||||
return None
|
return None
|
||||||
|
|
|
||||||
|
|
@ -48,11 +48,11 @@ class InvenTreeInternalBarcodePlugin(SettingsMixin, BarcodeMixin, InvenTreePlugi
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
def format_matched_response(self, label, model, instance):
|
def format_matched_response(self, label, model, instance, user, **kwargs):
|
||||||
"""Format a response for the scanned data."""
|
"""Format a response for the scanned data."""
|
||||||
return {label: instance.format_matched_response()}
|
return {label: instance.format_matched_response(user=user, **kwargs)}
|
||||||
|
|
||||||
def scan(self, barcode_data):
|
def scan(self, barcode_data, user, **kwargs):
|
||||||
"""Scan a barcode against this plugin.
|
"""Scan a barcode against this plugin.
|
||||||
|
|
||||||
Here we are looking for a dict object which contains a reference to a particular InvenTree database object
|
Here we are looking for a dict object which contains a reference to a particular InvenTree database object
|
||||||
|
|
@ -79,7 +79,8 @@ class InvenTreeInternalBarcodePlugin(SettingsMixin, BarcodeMixin, InvenTreePlugi
|
||||||
|
|
||||||
try:
|
try:
|
||||||
instance = model.objects.get(pk=int(pk))
|
instance = model.objects.get(pk=int(pk))
|
||||||
return self.format_matched_response(label, model, instance)
|
user = getattr(self, 'user', None)
|
||||||
|
return self.format_matched_response(label, model, instance, user=user)
|
||||||
except (ValueError, model.DoesNotExist):
|
except (ValueError, model.DoesNotExist):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
@ -111,7 +112,9 @@ class InvenTreeInternalBarcodePlugin(SettingsMixin, BarcodeMixin, InvenTreePlugi
|
||||||
instance = model.objects.get(pk=pk)
|
instance = model.objects.get(pk=pk)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
**self.format_matched_response(label, model, instance),
|
**self.format_matched_response(
|
||||||
|
label, model, instance, user=user
|
||||||
|
),
|
||||||
'success': succcess_message,
|
'success': succcess_message,
|
||||||
}
|
}
|
||||||
except (ValueError, model.DoesNotExist):
|
except (ValueError, model.DoesNotExist):
|
||||||
|
|
@ -129,7 +132,7 @@ class InvenTreeInternalBarcodePlugin(SettingsMixin, BarcodeMixin, InvenTreePlugi
|
||||||
|
|
||||||
if instance is not None:
|
if instance is not None:
|
||||||
return {
|
return {
|
||||||
**self.format_matched_response(label, model, instance),
|
**self.format_matched_response(label, model, instance, user=user),
|
||||||
'success': succcess_message,
|
'success': succcess_message,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue