From aa14ac99b3b416e96c15977ae544969a1e85a0ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Norman=20J=C3=A4ckel?= Date: Fri, 17 Feb 2017 17:20:13 +0100 Subject: [PATCH 1/2] Added check for hierarchical loops in agenda sort view. See #2972. --- openslides/agenda/views.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/openslides/agenda/views.py b/openslides/agenda/views.py index 75d8d1cbe..b8a8e1c82 100644 --- a/openslides/agenda/views.py +++ b/openslides/agenda/views.py @@ -241,7 +241,8 @@ class ItemViewSet(ListModelMixin, RetrieveModelMixin, UpdateModelMixin, GenericV @list_route(methods=['post']) def sort(self, request): """ - Sort agenda items. + Sort agenda items. Also checks parent field to prevent hierarchical + loops. """ nodes = request.data.get('nodes', []) parent_id = request.data.get('parent_id') @@ -253,5 +254,15 @@ class ItemViewSet(ListModelMixin, RetrieveModelMixin, UpdateModelMixin, GenericV item.weight = index item.save(skip_autoupdate=True) items.append(item) + + # Now check consistency. TODO: Try to use less DB queries. + item = Item.objects.get(pk=node['id']) + ancestor = item.parent + while ancestor is not None: + if ancestor == item: + raise ValidationError({'detail': _( + 'There must not be a hierarchical loop. Please reload the page.')}) + ancestor = ancestor.parent + inform_changed_data(items) return Response({'detail': _('The agenda has been sorted.')}) From 9ae1d7e59a9d9374741a27bdf00da4a159080612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emanuel=20Sch=C3=BCtze?= Date: Fri, 17 Feb 2017 21:59:13 +0100 Subject: [PATCH 2/2] Show allert in sort template if agenda sort request failed. --- openslides/agenda/static/js/agenda/site.js | 11 ++++++++++- .../agenda/static/templates/agenda/item-sort.html | 4 ++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/openslides/agenda/static/js/agenda/site.js b/openslides/agenda/static/js/agenda/site.js index a373d890d..f622bf870 100644 --- a/openslides/agenda/static/js/agenda/site.js +++ b/openslides/agenda/static/js/agenda/site.js @@ -585,6 +585,7 @@ angular.module('OpenSlidesApp.agenda.site', [ $scope.items = AgendaTree.getTree(Agenda.getAll()); }); $scope.showInternalItems = true; + $scope.alert = {}; // save parent and weight of moved agenda item (and all items on same level) $scope.treeOptions = { @@ -594,7 +595,15 @@ angular.module('OpenSlidesApp.agenda.site', [ if (event.dest.nodesScope.item) { parentID = event.dest.nodesScope.item.id; } - $http.post('/rest/agenda/item/sort/', {nodes: event.dest.nodesScope.$modelValue, parent_id: parentID}); + $http.post('/rest/agenda/item/sort/', { + nodes: event.dest.nodesScope.$modelValue, + parent_id: parentID} + ).then( + function(success) {}, + function(error){ + $scope.alert = {type: 'danger', msg: error.data.detail, show: true}; + } + ); } }; } diff --git a/openslides/agenda/static/templates/agenda/item-sort.html b/openslides/agenda/static/templates/agenda/item-sort.html index eebe04d65..d92342624 100644 --- a/openslides/agenda/static/templates/agenda/item-sort.html +++ b/openslides/agenda/static/templates/agenda/item-sort.html @@ -19,6 +19,10 @@ Show internal items +
+ {{ alert.msg }} +
+