mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Add RolePermission for API endpoints
This commit is contained in:
parent
1dfda5b0ed
commit
cd8c6fa81a
@ -20,6 +20,8 @@ from rest_framework.views import APIView
|
|||||||
from .views import AjaxView
|
from .views import AjaxView
|
||||||
from .version import inventreeVersion, inventreeInstanceName
|
from .version import inventreeVersion, inventreeInstanceName
|
||||||
|
|
||||||
|
from users.models import check_user_role, RuleSet
|
||||||
|
|
||||||
from plugins import plugins as inventree_plugins
|
from plugins import plugins as inventree_plugins
|
||||||
|
|
||||||
|
|
||||||
@ -70,6 +72,85 @@ class AttachmentMixin:
|
|||||||
attachment.save()
|
attachment.save()
|
||||||
|
|
||||||
|
|
||||||
|
class RolePermission(permissions.BasePermission):
|
||||||
|
"""
|
||||||
|
Role mixin for API endpoints, allowing us to specify the user "role"
|
||||||
|
which is required for certain operations.
|
||||||
|
|
||||||
|
Each endpoint can have one or more of the following actions:
|
||||||
|
- GET
|
||||||
|
- POST
|
||||||
|
- PUT
|
||||||
|
- PATCH
|
||||||
|
- DELETE
|
||||||
|
|
||||||
|
Specify the required "role" using the role_required attribute.
|
||||||
|
|
||||||
|
e.g.
|
||||||
|
|
||||||
|
role_required = "part"
|
||||||
|
|
||||||
|
The RoleMixin class will then determine if the user has the required permission
|
||||||
|
to perform the specified action.
|
||||||
|
|
||||||
|
For example, a DELETE action will be rejected unless the user has the "part.remove" permission
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def has_permission(self, request, view):
|
||||||
|
"""
|
||||||
|
Determine if the current user has the specified permissions
|
||||||
|
"""
|
||||||
|
|
||||||
|
# First, check that the user is authenticated!
|
||||||
|
auth = permissions.IsAuthenticated()
|
||||||
|
|
||||||
|
if not auth.has_permission(request, view):
|
||||||
|
return False
|
||||||
|
|
||||||
|
user = request.user
|
||||||
|
|
||||||
|
# Superuser can do it all
|
||||||
|
if False and user.is_superuser:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Map the request method to a permission type
|
||||||
|
rolemap = {
|
||||||
|
'GET': 'view',
|
||||||
|
'OPTIONS': 'view',
|
||||||
|
'POST': 'add',
|
||||||
|
'PUT': 'change',
|
||||||
|
'PATCH': 'change',
|
||||||
|
'DELETE': 'delete',
|
||||||
|
}
|
||||||
|
|
||||||
|
permission = rolemap[request.method]
|
||||||
|
|
||||||
|
role = getattr(view, 'role_required', None)
|
||||||
|
|
||||||
|
if not role:
|
||||||
|
raise AttributeError(f"'role_required' not specified for view {type(view).__name__}")
|
||||||
|
|
||||||
|
roles = []
|
||||||
|
|
||||||
|
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__}")
|
||||||
|
|
||||||
|
for role in roles:
|
||||||
|
|
||||||
|
if role not in RuleSet.RULESET_NAMES:
|
||||||
|
raise ValueError(f"Role '{role}' is not a valid role")
|
||||||
|
|
||||||
|
if not check_user_role(user, role, permission):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# All checks passed
|
||||||
|
return True
|
||||||
|
|
||||||
class ActionPluginView(APIView):
|
class ActionPluginView(APIView):
|
||||||
"""
|
"""
|
||||||
Endpoint for running custom action plugins.
|
Endpoint for running custom action plugins.
|
||||||
|
@ -29,7 +29,8 @@ from . import serializers as part_serializers
|
|||||||
|
|
||||||
from InvenTree.views import TreeSerializer
|
from InvenTree.views import TreeSerializer
|
||||||
from InvenTree.helpers import str2bool, isNull
|
from InvenTree.helpers import str2bool, isNull
|
||||||
from InvenTree.api import AttachmentMixin
|
from InvenTree.api import AttachmentMixin, RolePermission
|
||||||
|
|
||||||
from InvenTree.status_codes import BuildStatus
|
from InvenTree.status_codes import BuildStatus
|
||||||
|
|
||||||
|
|
||||||
@ -105,6 +106,12 @@ class CategoryList(generics.ListCreateAPIView):
|
|||||||
'description',
|
'description',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
role_required = 'part'
|
||||||
|
|
||||||
|
permission_classes = [
|
||||||
|
RolePermission,
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class CategoryDetail(generics.RetrieveUpdateDestroyAPIView):
|
class CategoryDetail(generics.RetrieveUpdateDestroyAPIView):
|
||||||
""" API endpoint for detail view of a single PartCategory object """
|
""" API endpoint for detail view of a single PartCategory object """
|
||||||
|
Loading…
Reference in New Issue
Block a user