1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Allow bypass of "write" permission for render endpoint.

This commit is contained in:
Daniel Sheppard
2024-02-23 16:37:32 -06:00
parent edb7d24b45
commit 7600adc1e1
2 changed files with 27 additions and 1 deletions

View File

@ -4,6 +4,8 @@ from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response
from rest_framework.status import HTTP_400_BAD_REQUEST
from dcim.models import Device
from netbox.api.authentication import ViewOnlyPermissions
from netbox.api.renderers import TextRenderer
from .nested_serializers import NestedConfigTemplateSerializer
@ -61,14 +63,23 @@ class ConfigTemplateRenderMixin:
class RenderConfigMixin(ConfigTemplateRenderMixin):
"""
Override initial() to save a copy of the queryset for "un-restricting" the queryset when rendering.
"""
def initial(self, request, *args, **kwargs):
self.original_qs = self.queryset
super().initial(request, *args, **kwargs)
"""
Provides a /render-config/ endpoint for REST API views whose model may have a ConfigTemplate assigned.
"""
@action(detail=True, methods=['post'], url_path='render-config', renderer_classes=[JSONRenderer, TextRenderer])
@action(detail=True, methods=['post'], url_path='render-config', renderer_classes=[JSONRenderer, TextRenderer],
permission_classes=[ViewOnlyPermissions])
def render_config(self, request, pk):
"""
Resolve and render the preferred ConfigTemplate for this Device.
"""
self.queryset = self.original_queryset.restrict(request.user, 'view')
instance = self.get_object()
object_type = instance._meta.model_name
configtemplate = instance.get_config_template()

View File

@ -124,6 +124,21 @@ class TokenPermissions(DjangoObjectPermissions):
return super().has_object_permission(request, view, obj)
class ViewOnlyPermissions(TokenPermissions):
"""
Override the stock perm_map to require only view permissions
"""
perms_map = {
'GET': ['%(app_label)s.view_%(model_name)s'],
'OPTIONS': [],
'HEAD': ['%(app_label)s.view_%(model_name)s'],
'POST': ['%(app_label)s.view_%(model_name)s'],
'PUT': ['%(app_label)s.view_%(model_name)s'],
'PATCH': ['%(app_label)s.view_%(model_name)s'],
'DELETE': ['%(app_label)s.view_%(model_name)s'],
}
class IsAuthenticatedOrLoginNotRequired(BasePermission):
"""
Returns True if the user is authenticated or LOGIN_REQUIRED is False.