diff --git a/InvenTree/InvenTree/permissions.py b/InvenTree/InvenTree/permissions.py index 9f34c0d918..2b7f5d4085 100644 --- a/InvenTree/InvenTree/permissions.py +++ b/InvenTree/InvenTree/permissions.py @@ -60,28 +60,12 @@ class RolePermission(permissions.BasePermission): permission = rolemap[request.method] - role = getattr(view, 'role_required', None) + # Extract the model name associated with this request + model = view.serializer_class.Meta.model - if not role: - # Role not specified - allow access - return True - - roles = [] + # And the specific database table + table = model._meta.db_table - if type(role) is str: - roles = [role] - elif type(role) in [list, tuple]: - roles = role - else: - raise TypeError(f"'role_required' is of incorrect type ({type(role)}) for view {type(view).__name__}") + result = users.models.RuleSet.check_table_permission(user, table, permission) - for role in roles: - - if role not in users.models.RuleSet.RULESET_NAMES: - raise ValueError(f"Role '{role}' is not a valid role") - - if not users.models.check_user_role(user, role, permission): - return False - - # All checks passed - return True + return result diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py index c20d6bee60..9a0e3a2a68 100644 --- a/InvenTree/part/api.py +++ b/InvenTree/part/api.py @@ -48,8 +48,6 @@ class PartCategoryTree(TreeSerializer): def get_items(self): return PartCategory.objects.all().prefetch_related('parts', 'children') - role_required = 'part' - class CategoryList(generics.ListCreateAPIView): """ API endpoint for accessing a list of PartCategory objects. @@ -106,16 +104,12 @@ class CategoryList(generics.ListCreateAPIView): 'description', ] - role_required = 'part' - class CategoryDetail(generics.RetrieveUpdateDestroyAPIView): """ API endpoint for detail view of a single PartCategory object """ serializer_class = part_serializers.CategorySerializer queryset = PartCategory.objects.all() - role_required = 'part' - class CategoryParameters(generics.ListAPIView): """ API endpoint for accessing a list of PartCategoryParameterTemplate objects. @@ -126,8 +120,6 @@ class CategoryParameters(generics.ListAPIView): queryset = PartCategoryParameterTemplate.objects.all() serializer_class = part_serializers.CategoryParameterTemplateSerializer - role_required = 'part' - def get_queryset(self): """ Custom filtering: @@ -172,8 +164,6 @@ class PartSalePriceList(generics.ListCreateAPIView): queryset = PartSellPriceBreak.objects.all() serializer_class = part_serializers.PartSalePriceSerializer - role_required = 'part' - filter_backends = [ DjangoFilterBackend ] @@ -191,8 +181,6 @@ class PartAttachmentList(generics.ListCreateAPIView, AttachmentMixin): queryset = PartAttachment.objects.all() serializer_class = part_serializers.PartAttachmentSerializer - role_required = 'part' - filter_backends = [ DjangoFilterBackend, ] @@ -210,8 +198,6 @@ class PartTestTemplateList(generics.ListCreateAPIView): queryset = PartTestTemplate.objects.all() serializer_class = part_serializers.PartTestTemplateSerializer - role_required = 'part' - def filter_queryset(self, queryset): """ Filter the test list queryset. @@ -253,8 +239,6 @@ class PartThumbs(generics.ListAPIView): API endpoint for retrieving information on available Part thumbnails """ - role_required = 'part' - queryset = Part.objects.all() serializer_class = part_serializers.PartThumbSerializer @@ -291,8 +275,6 @@ class PartThumbsUpdate(generics.RetrieveUpdateAPIView): queryset = Part.objects.all() serializer_class = part_serializers.PartThumbSerializerUpdate - role_required = 'part' - filter_backends = [ DjangoFilterBackend ] @@ -301,8 +283,6 @@ class PartThumbsUpdate(generics.RetrieveUpdateAPIView): class PartDetail(generics.RetrieveUpdateDestroyAPIView): """ API endpoint for detail view of a single Part object """ - role_required = 'part' - queryset = Part.objects.all() serializer_class = part_serializers.PartSerializer @@ -389,8 +369,6 @@ class PartList(generics.ListCreateAPIView): queryset = Part.objects.all() - role_required = 'part' - starred_parts = None def get_serializer(self, *args, **kwargs): @@ -717,8 +695,6 @@ class PartParameterTemplateList(generics.ListCreateAPIView): - POST: Create a new PartParameterTemplate object """ - role_required = 'part' - queryset = PartParameterTemplate.objects.all() serializer_class = part_serializers.PartParameterTemplateSerializer @@ -738,8 +714,6 @@ class PartParameterList(generics.ListCreateAPIView): - POST: Create a new PartParameter object """ - role_required = 'part' - queryset = PartParameter.objects.all() serializer_class = part_serializers.PartParameterSerializer @@ -760,8 +734,6 @@ class BomList(generics.ListCreateAPIView): - POST: Create a new BomItem object """ - role_required = 'part' - serializer_class = part_serializers.BomItemSerializer def list(self, request, *args, **kwargs): @@ -901,8 +873,6 @@ class BomList(generics.ListCreateAPIView): class BomDetail(generics.RetrieveUpdateDestroyAPIView): """ API endpoint for detail view of a single BomItem object """ - role_required = 'part' - queryset = BomItem.objects.all() serializer_class = part_serializers.BomItemSerializer @@ -910,8 +880,6 @@ class BomDetail(generics.RetrieveUpdateDestroyAPIView): class BomItemValidate(generics.UpdateAPIView): """ API endpoint for validating a BomItem """ - role_required = 'part' - # Very simple serializers class BomItemValidationSerializer(serializers.Serializer): diff --git a/InvenTree/users/models.py b/InvenTree/users/models.py index 614383ab30..478a8c3659 100644 --- a/InvenTree/users/models.py +++ b/InvenTree/users/models.py @@ -166,6 +166,25 @@ class RuleSet(models.Model): can_delete = models.BooleanField(verbose_name=_('Delete'), default=False, help_text=_('Permission to delete items')) + @classmethod + def check_table_permission(cls, user, table, permission): + """ + Check if the provided user has the specified permission against the table + """ + + # If the table does *not* require permissions + if table in cls.RULESET_IGNORE: + return True + + # Work out which roles touch the given table + for role in cls.RULESET_NAMES: + if table in cls.RULESET_MODELS[role]: + + if check_user_role(user, role, permission): + return True + + return False + @staticmethod def get_model_permission_string(model, permission): """