From 4dc6564a17bfc13df9c5bd022b04f6d46593d941 Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 30 Mar 2026 15:53:35 -0700 Subject: [PATCH] destroy() deletes ScriptModule, not Script DELETE /api/extras/scripts// now deletes the entire ScriptModule (matching the UI's delete view), including modules with no Script children (e.g. sync hasn't run yet). Permission check updated to delete_scriptmodule. The queryset restriction for destroy is removed since the module is deleted via script.module, not super().destroy(). Co-Authored-By: Claude Sonnet 4.6 --- netbox/extras/api/views.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/netbox/extras/api/views.py b/netbox/extras/api/views.py index 0144949b9..018375cc7 100644 --- a/netbox/extras/api/views.py +++ b/netbox/extras/api/views.py @@ -284,12 +284,7 @@ class ScriptViewSet(ModelViewSet): # Restrict the view's QuerySet to allow only the permitted objects if request.user.is_authenticated and self.action != 'create': - if self.action == 'destroy': - perm_action = 'delete' - elif request.method == 'POST': - perm_action = 'run' - else: - perm_action = 'view' + perm_action = 'run' if request.method == 'POST' else 'view' self.queryset = self.queryset.restrict(request.user, perm_action) def create(self, request, *args, **kwargs): @@ -320,9 +315,11 @@ class ScriptViewSet(ModelViewSet): raise MethodNotAllowed(request.method) def destroy(self, request, *args, **kwargs): - if not request.user.has_perm('extras.delete_script'): - raise PermissionDenied(_("This user does not have permission to delete scripts.")) - return super().destroy(request, *args, **kwargs) + if not request.user.has_perm('extras.delete_scriptmodule'): + raise PermissionDenied(_("This user does not have permission to delete script modules.")) + script = self._get_script(kwargs[self.lookup_field]) + script.module.delete() + return Response(status=status.HTTP_204_NO_CONTENT) def _get_script(self, pk): # If pk is numeric, retrieve script by ID