Enforce constrained permissions when bulk renaming objects

This commit is contained in:
Jeremy Stretch 2020-07-14 13:18:22 -04:00
parent 81ed03575d
commit 4458ce69df

View File

@ -1054,12 +1054,16 @@ class BulkRenameView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
return get_permission_for_model(self.queryset.model, 'change') return get_permission_for_model(self.queryset.model, 'change')
def post(self, request): def post(self, request):
logger = logging.getLogger('netbox.views.BulkRenameView')
if '_preview' in request.POST or '_apply' in request.POST: if '_preview' in request.POST or '_apply' in request.POST:
form = self.form(request.POST, initial={'pk': request.POST.getlist('pk')}) form = self.form(request.POST, initial={'pk': request.POST.getlist('pk')})
selected_objects = self.queryset.filter(pk__in=form.initial['pk']) selected_objects = self.queryset.filter(pk__in=form.initial['pk'])
if form.is_valid(): if form.is_valid():
try:
with transaction.atomic():
renamed_pks = []
for obj in selected_objects: for obj in selected_objects:
find = form.cleaned_data['find'] find = form.cleaned_data['find']
replace = form.cleaned_data['replace'] replace = form.cleaned_data['replace']
@ -1071,17 +1075,28 @@ class BulkRenameView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
obj.new_name = obj.name obj.new_name = obj.name
else: else:
obj.new_name = obj.name.replace(find, replace) obj.new_name = obj.name.replace(find, replace)
renamed_pks.append(obj.pk)
if '_apply' in request.POST: if '_apply' in request.POST:
for obj in selected_objects: for obj in selected_objects:
obj.name = obj.new_name obj.name = obj.new_name
obj.save() obj.save()
# Enforce constrained permissions
if self.queryset.filter(pk__in=renamed_pks).count() != len(selected_objects):
raise ObjectDoesNotExist
messages.success(request, "Renamed {} {}".format( messages.success(request, "Renamed {} {}".format(
len(selected_objects), len(selected_objects),
self.queryset.model._meta.verbose_name_plural self.queryset.model._meta.verbose_name_plural
)) ))
return redirect(self.get_return_url(request)) return redirect(self.get_return_url(request))
except ObjectDoesNotExist:
msg = "Object update failed due to object-level permissions violation"
logger.debug(msg)
form.add_error(None, msg)
else: else:
form = self.form(initial={'pk': request.POST.getlist('pk')}) form = self.form(initial={'pk': request.POST.getlist('pk')})
selected_objects = self.queryset.filter(pk__in=form.initial['pk']) selected_objects = self.queryset.filter(pk__in=form.initial['pk'])