2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-28 11:36:44 +00:00

Improvements for model metadata introspection (#4585)

- Will improve API permissions checks
- Will improve API metadata checks
- Fixes missing model information on metadata options endpoints

Ref: https://github.com/inventree/InvenTree/pull/4579
This commit is contained in:
Oliver 2023-04-05 22:43:23 +10:00 committed by GitHub
parent ab7b03ac59
commit 0b6e2ee592
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 2 deletions

View File

@ -361,6 +361,10 @@ class MetadataView(RetrieveUpdateAPI):
return model return model
def get_permission_model(self):
"""Return the 'permission' model associated with this view"""
return self.get_model_type()
def get_queryset(self): def get_queryset(self):
"""Return the queryset for this endpoint""" """Return the queryset for this endpoint"""
return self.get_model_type().objects.all() return self.get_model_type().objects.all()

View File

@ -7,6 +7,7 @@ from rest_framework.fields import empty
from rest_framework.metadata import SimpleMetadata from rest_framework.metadata import SimpleMetadata
from rest_framework.utils import model_meta from rest_framework.utils import model_meta
import InvenTree.permissions
import users.models import users.models
from InvenTree.helpers import str2bool from InvenTree.helpers import str2bool
@ -58,7 +59,7 @@ class InvenTreeMetadata(SimpleMetadata):
try: try:
# Extract the model name associated with the view # Extract the model name associated with the view
self.model = view.serializer_class.Meta.model self.model = InvenTree.permissions.get_model_for_view(view)
# Construct the 'table name' from the model # Construct the 'table name' from the model
app_label = self.model._meta.app_label app_label = self.model._meta.app_label

View File

@ -7,6 +7,21 @@ from rest_framework import permissions
import users.models import users.models
def get_model_for_view(view, raise_error=True):
"""Attempt to introspect the 'model' type for an API view"""
if hasattr(view, 'get_permission_model'):
return view.get_permission_model()
if hasattr(view, 'serializer_class'):
return view.serializer_class.Meta.model
if hasattr(view, 'get_serializer_class'):
return view.get_serializr_class().Meta.model
raise AttributeError(f"Serializer class not specified for {view.__class__}")
class RolePermission(permissions.BasePermission): class RolePermission(permissions.BasePermission):
"""Role mixin for API endpoints, allowing us to specify the user "role" which is required for certain operations. """Role mixin for API endpoints, allowing us to specify the user "role" which is required for certain operations.
@ -55,7 +70,7 @@ class RolePermission(permissions.BasePermission):
try: try:
# Extract the model name associated with this request # Extract the model name associated with this request
model = view.serializer_class.Meta.model model = get_model_for_view(view)
app_label = model._meta.app_label app_label = model._meta.app_label
model_name = model._meta.model_name model_name = model._meta.model_name