diff --git a/netbox/extras/api/serializers_/scripts.py b/netbox/extras/api/serializers_/scripts.py index 2d450dc8a..58f395a70 100644 --- a/netbox/extras/api/serializers_/scripts.py +++ b/netbox/extras/api/serializers_/scripts.py @@ -19,7 +19,7 @@ __all__ = ( class ScriptModuleSerializer(ValidatedModelSerializer): - url = serializers.SerializerMethodField(read_only=True) + url = None data_source = DataSourceSerializer(nested=True, required=False, allow_null=True) data_file = DataFileSerializer(nested=True, required=False, allow_null=True) upload_file = serializers.FileField(write_only=True, required=False, allow_null=True) @@ -28,17 +28,11 @@ class ScriptModuleSerializer(ValidatedModelSerializer): class Meta: model = ScriptModule fields = [ - 'id', 'url', 'display', 'file_path', 'upload_file', + 'id', 'display', 'file_path', 'upload_file', 'data_source', 'data_file', 'auto_sync_enabled', 'created', 'last_updated', ] - brief_fields = ('id', 'url', 'display') - - @extend_schema_field(serializers.URLField()) - def get_url(self, obj): - from rest_framework.reverse import reverse - request = self.context.get('request') - return reverse('extras-api:script-list', request=request) + brief_fields = ('id', 'display') def validate(self, data): upload_file = data.pop('upload_file', None) @@ -57,17 +51,16 @@ class ScriptModuleSerializer(ValidatedModelSerializer): raise serializers.ValidationError( _("Cannot upload a file and sync from a data source.") ) - if self.instance is None and not upload_file and not data.get('data_file'): + if self.instance is None and not upload_file and not data.get('data_file') and not data.get('data_source'): raise serializers.ValidationError( - _("Must upload a file or select a data file to sync.") + _("Must upload a file or provide a data source or data file to sync.") ) return data def _save_upload(self, upload_file, validated_data): storage = storages.create_storage(storages.backends["scripts"]) - storage.save(upload_file.name, upload_file) - validated_data['file_path'] = upload_file.name + validated_data['file_path'] = storage.save(upload_file.name, upload_file) def create(self, validated_data): upload_file = validated_data.pop('upload_file', None) diff --git a/netbox/extras/api/views.py b/netbox/extras/api/views.py index ad4bdbe23..9c395a0fb 100644 --- a/netbox/extras/api/views.py +++ b/netbox/extras/api/views.py @@ -5,7 +5,7 @@ from django_rq.queues import get_connection from drf_spectacular.utils import extend_schema, extend_schema_view from rest_framework import status from rest_framework.decorators import action -from rest_framework.exceptions import PermissionDenied +from rest_framework.exceptions import MethodNotAllowed, PermissionDenied from rest_framework.generics import RetrieveUpdateDestroyAPIView from rest_framework.mixins import ListModelMixin, RetrieveModelMixin from rest_framework.renderers import JSONRenderer @@ -267,8 +267,8 @@ class ConfigTemplateViewSet(SyncedDataMixin, ConfigTemplateRenderMixin, NetBoxMo @extend_schema_view( create=extend_schema(request=serializers.ScriptModuleSerializer), - update=extend_schema(responses=serializers.ScriptSerializer), - partial_update=extend_schema(responses=serializers.ScriptSerializer), + update=extend_schema(exclude=True), + partial_update=extend_schema(exclude=True), ) class ScriptViewSet(ModelViewSet): permission_classes = [IsAuthenticatedOrLoginNotRequired] @@ -286,8 +286,6 @@ class ScriptViewSet(ModelViewSet): if request.user.is_authenticated and self.action != 'create': if self.action == 'destroy': perm_action = 'delete' - elif self.action in ('update', 'partial_update'): - perm_action = 'change' elif request.method == 'POST': perm_action = 'run' else: @@ -313,9 +311,10 @@ class ScriptViewSet(ModelViewSet): return Response(serializer.data, status=status.HTTP_201_CREATED) def update(self, request, *args, **kwargs): - if not request.user.has_perm('extras.change_scriptmodule'): - raise PermissionDenied(_("This user does not have permission to modify script modules.")) - return super().update(request, *args, **kwargs) + raise MethodNotAllowed(request.method) + + def partial_update(self, request, *args, **kwargs): + raise MethodNotAllowed(request.method) def destroy(self, request, *args, **kwargs): if not request.user.has_perm('extras.delete_scriptmodule'):