mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-23 07:56:44 -06:00
14025 add file extension validation and simplify get logic
This commit is contained in:
parent
d337283095
commit
de30f55134
@ -1,12 +1,14 @@
|
|||||||
import copy
|
import copy
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from core.forms.mixins import SyncedDataMixin
|
from core.forms.mixins import SyncedDataMixin
|
||||||
from core.models import *
|
from core.models import *
|
||||||
from netbox.forms import NetBoxModelForm
|
from netbox.forms import NetBoxModelForm
|
||||||
from netbox.registry import registry
|
from netbox.registry import registry
|
||||||
|
from pathlib import Path
|
||||||
from utilities.forms import get_field_value
|
from utilities.forms import get_field_value
|
||||||
from utilities.forms.fields import CommentField
|
from utilities.forms.fields import CommentField
|
||||||
from utilities.forms.widgets import HTMXSelect
|
from utilities.forms.widgets import HTMXSelect
|
||||||
@ -88,14 +90,34 @@ class ManagedFileForm(SyncedDataMixin, NetBoxModelForm):
|
|||||||
model = ManagedFile
|
model = ManagedFile
|
||||||
fields = ('data_source', 'data_file', 'auto_sync_enabled')
|
fields = ('data_source', 'data_file', 'auto_sync_enabled')
|
||||||
|
|
||||||
|
def _validate_file_extension(self, file):
|
||||||
|
if file:
|
||||||
|
extension = Path(file.name).suffix[1:].lower()
|
||||||
|
|
||||||
|
if extension != "py":
|
||||||
|
raise ValidationError(
|
||||||
|
"File extension “%(extension)s” is not allowed .py extension is required",
|
||||||
|
code="invalid_extension",
|
||||||
|
params={
|
||||||
|
"extension": extension,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
super().clean()
|
super().clean()
|
||||||
|
|
||||||
if self.cleaned_data.get('upload_file') and self.cleaned_data.get('data_file'):
|
upload_file = self.cleaned_data['upload_file']
|
||||||
|
data_file = self.cleaned_data['data_file']
|
||||||
|
|
||||||
|
if upload_file and data_file:
|
||||||
|
extension = Path(upload_file.name).suffix[1:].lower()
|
||||||
raise forms.ValidationError("Cannot upload a file and sync from an existing file")
|
raise forms.ValidationError("Cannot upload a file and sync from an existing file")
|
||||||
if not self.cleaned_data.get('upload_file') and not self.cleaned_data.get('data_file'):
|
if not upload_file and not data_file:
|
||||||
raise forms.ValidationError("Must upload a file or select a data file to sync")
|
raise forms.ValidationError("Must upload a file or select a data file to sync")
|
||||||
|
|
||||||
|
self._validate_file_extension(upload_file)
|
||||||
|
self._validate_file_extension(data_file)
|
||||||
|
|
||||||
return self.cleaned_data
|
return self.cleaned_data
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
|
@ -3,7 +3,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin
|
|||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.core.paginator import EmptyPage
|
from django.core.paginator import EmptyPage
|
||||||
from django.db.models import Count, Q
|
from django.db.models import Count, Q
|
||||||
from django.http import HttpResponseBadRequest, HttpResponseForbidden, HttpResponse, Http404
|
from django.http import HttpResponseBadRequest, HttpResponseForbidden, HttpResponse
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
@ -1152,20 +1152,7 @@ class ScriptListView(ContentTypePermissionRequiredMixin, View):
|
|||||||
|
|
||||||
|
|
||||||
def get_script_module(module, request):
|
def get_script_module(module, request):
|
||||||
modules = ScriptModule.objects.restrict(request.user).filter(file_path__startswith=module)
|
return get_object_or_404(ScriptModule.objects.restrict(request.user), file_path=f"{module}.py")
|
||||||
if not modules:
|
|
||||||
raise Http404
|
|
||||||
|
|
||||||
if len(modules) == 1:
|
|
||||||
return modules[0]
|
|
||||||
|
|
||||||
# module is without the ".py" so startswith=module can return multiple if the file_path has
|
|
||||||
# two modules starting with the same characters "test.py" and "testfile.py"
|
|
||||||
for obj in modules:
|
|
||||||
if obj.file_path == module or obj.file_path == module + ".py":
|
|
||||||
return obj
|
|
||||||
|
|
||||||
raise Http404
|
|
||||||
|
|
||||||
|
|
||||||
class ScriptView(ContentTypePermissionRequiredMixin, View):
|
class ScriptView(ContentTypePermissionRequiredMixin, View):
|
||||||
|
Loading…
Reference in New Issue
Block a user