diff options
author | Alexandru DAMIAN <alexandru.damian@intel.com> | 2014-11-11 17:01:09 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2014-11-12 17:04:50 +0000 |
commit | c5d19aae55be158676eb0914bd5d0701f7d3fd3a (patch) | |
tree | b549631196198eaa89a922c1088243b25c74ecd9 | |
parent | 326d5b1a284ca4d29f986d3d6a1cee838b841301 (diff) | |
download | poky-c5d19aae55be158676eb0914bd5d0701f7d3fd3a.tar.gz |
bitbake: toastergui: fix XSS injection points in projects page
We close XSS injection points in Projects page.
* modify the json filter to properly escape HTML tags in strings
* enable $sanitize to automatically sanitize dangerous HTML in
user-supplied input
* clean dangerous characters in targets field, as that field contents
will be directly passed to a shell command
Based on the vulnerability discovered and the patch provided by Michael Wood.
(Bitbake rev: 23c440db9c076ca37e651bdbbdbefee54998e1dc)
Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
4 files changed, 43 insertions, 34 deletions
diff --git a/bitbake/lib/toaster/toastergui/static/js/projectapp.js b/bitbake/lib/toaster/toastergui/static/js/projectapp.js index f0569de04d..9f9a06476a 100644 --- a/bitbake/lib/toaster/toastergui/static/js/projectapp.js +++ b/bitbake/lib/toaster/toastergui/static/js/projectapp.js | |||
@@ -101,7 +101,7 @@ function _diffArrays(existingArray, newArray, compareElements, onAdded, onDelete | |||
101 | } | 101 | } |
102 | 102 | ||
103 | 103 | ||
104 | var projectApp = angular.module('project', ['ngCookies', 'ngAnimate', 'ui.bootstrap' ], angular_formpost); | 104 | var projectApp = angular.module('project', ['ngCookies', 'ngAnimate', 'ui.bootstrap', 'ngRoute', 'ngSanitize'], angular_formpost); |
105 | 105 | ||
106 | // modify the template tag markers to prevent conflicts with Django | 106 | // modify the template tag markers to prevent conflicts with Django |
107 | projectApp.config(function($interpolateProvider) { | 107 | projectApp.config(function($interpolateProvider) { |
@@ -128,7 +128,7 @@ projectApp.filter('timediff', function() { | |||
128 | 128 | ||
129 | 129 | ||
130 | // main controller for the project page | 130 | // main controller for the project page |
131 | projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $location, $cookies, $q, $sce, $anchorScroll, $animate) { | 131 | projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $location, $cookies, $q, $sce, $anchorScroll, $animate, $sanitize) { |
132 | 132 | ||
133 | $scope.getSuggestions = function(type, currentValue) { | 133 | $scope.getSuggestions = function(type, currentValue) { |
134 | var deffered = $q.defer(); | 134 | var deffered = $q.defer(); |
@@ -475,6 +475,7 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc | |||
475 | var alertText = undefined; | 475 | var alertText = undefined; |
476 | var alertZone = undefined; | 476 | var alertZone = undefined; |
477 | var oldLayers = []; | 477 | var oldLayers = []; |
478 | |||
478 | switch(elementid) { | 479 | switch(elementid) { |
479 | case '#select-machine': | 480 | case '#select-machine': |
480 | alertText = "You have changed the machine to: <strong>" + $scope.machineName + "</strong>"; | 481 | alertText = "You have changed the machine to: <strong>" + $scope.machineName + "</strong>"; |
@@ -594,7 +595,7 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc | |||
594 | var crtid = zone.maxid ++; | 595 | var crtid = zone.maxid ++; |
595 | angular.forEach(zone, function (o) { o.close() }); | 596 | angular.forEach(zone, function (o) { o.close() }); |
596 | o = { | 597 | o = { |
597 | id: crtid, text: $sce.trustAsHtml(text), type: type, | 598 | id: crtid, text: text, type: type, |
598 | close: function() { | 599 | close: function() { |
599 | zone.splice((function(id){ for (var i = 0; i < zone.length; i++) if (id == zone[i].id) { return i}; return undefined;})(crtid), 1); | 600 | zone.splice((function(id){ for (var i = 0; i < zone.length; i++) if (id == zone[i].id) { return i}; return undefined;})(crtid), 1); |
600 | }, | 601 | }, |
diff --git a/bitbake/lib/toaster/toastergui/templates/project.html b/bitbake/lib/toaster/toastergui/templates/project.html index 38863a3ac6..4e8a7e29aa 100644 --- a/bitbake/lib/toaster/toastergui/templates/project.html +++ b/bitbake/lib/toaster/toastergui/templates/project.html | |||
@@ -11,6 +11,8 @@ vim: expandtab tabstop=2 | |||
11 | <script src="{% static "js/angular.min.js" %}"></script> | 11 | <script src="{% static "js/angular.min.js" %}"></script> |
12 | <script src="{% static "js/angular-animate.min.js" %}"></script> | 12 | <script src="{% static "js/angular-animate.min.js" %}"></script> |
13 | <script src="{% static "js/angular-cookies.min.js" %}"></script> | 13 | <script src="{% static "js/angular-cookies.min.js" %}"></script> |
14 | <script src="{% static "js/angular-route.min.js" %}"></script> | ||
15 | <script src="{% static "js/angular-sanitize.min.js" %}"></script> | ||
14 | <script src="{% static "js/ui-bootstrap-tpls-0.11.0.js" %}"></script> | 16 | <script src="{% static "js/ui-bootstrap-tpls-0.11.0.js" %}"></script> |
15 | 17 | ||
16 | 18 | ||
@@ -365,13 +367,13 @@ angular.element(document).ready(function() { | |||
365 | scope.urls.layers = "{% url 'layers' %}"; | 367 | scope.urls.layers = "{% url 'layers' %}"; |
366 | scope.urls.targets = "{% url 'targets' %}"; | 368 | scope.urls.targets = "{% url 'targets' %}"; |
367 | scope.urls.importlayer = "{% url 'importlayer'%}" | 369 | scope.urls.importlayer = "{% url 'importlayer'%}" |
368 | scope.project = {{prj|safe}}; | 370 | scope.project = {{prj|json}}; |
369 | scope.builds = {{builds|safe}}; | 371 | scope.builds = {{builds|json}}; |
370 | scope.layers = {{layers|safe}}; | 372 | scope.layers = {{layers|json}}; |
371 | scope.targets = {{targets|safe}}; | 373 | scope.targets = {{targets|json}}; |
372 | scope.frequenttargets = {{freqtargets|safe}}; | 374 | scope.frequenttargets = {{freqtargets|json}}; |
373 | scope.machine = {{machine|safe}}; | 375 | scope.machine = {{machine|json}}; |
374 | scope.releases = {{releases|safe}}; | 376 | scope.releases = {{releases|json}}; |
375 | 377 | ||
376 | var now = (new Date()).getTime(); | 378 | var now = (new Date()).getTime(); |
377 | scope.todaydate = now - (now % 86400000); | 379 | scope.todaydate = now - (now % 86400000); |
diff --git a/bitbake/lib/toaster/toastergui/templatetags/projecttags.py b/bitbake/lib/toaster/toastergui/templatetags/projecttags.py index 4a97eb7ac4..99fd4cf287 100644 --- a/bitbake/lib/toaster/toastergui/templatetags/projecttags.py +++ b/bitbake/lib/toaster/toastergui/templatetags/projecttags.py | |||
@@ -25,6 +25,7 @@ from django import template | |||
25 | from django.utils import timezone | 25 | from django.utils import timezone |
26 | from django.template.defaultfilters import filesizeformat | 26 | from django.template.defaultfilters import filesizeformat |
27 | import json as JsonLib | 27 | import json as JsonLib |
28 | from django.utils.safestring import mark_safe | ||
28 | 29 | ||
29 | register = template.Library() | 30 | register = template.Library() |
30 | 31 | ||
@@ -49,7 +50,10 @@ def mapselect(value, argument): | |||
49 | 50 | ||
50 | @register.filter(name = "json") | 51 | @register.filter(name = "json") |
51 | def json(value): | 52 | def json(value): |
52 | return JsonLib.dumps(value) | 53 | # JSON spec says that "\/" is functionally identical to "/" to allow for HTML-tag embedding in JSON strings |
54 | # unfortunately, I can't find any option in the json module to turn on forward-slash escaping, so we do | ||
55 | # it manually here | ||
56 | return mark_safe(JsonLib.dumps(value, ensure_ascii=False).replace('</', '<\\/')) | ||
53 | 57 | ||
54 | @register.assignment_tag | 58 | @register.assignment_tag |
55 | def query(qs, **kwargs): | 59 | def query(qs, **kwargs): |
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py index 3b29dbcfb2..5e92c24a8d 100755 --- a/bitbake/lib/toaster/toastergui/views.py +++ b/bitbake/lib/toaster/toastergui/views.py | |||
@@ -36,6 +36,7 @@ from django.utils import timezone | |||
36 | from django.utils.html import escape | 36 | from django.utils.html import escape |
37 | from datetime import timedelta | 37 | from datetime import timedelta |
38 | from django.utils import formats | 38 | from django.utils import formats |
39 | from toastergui.templatetags.projecttags import json as jsonfilter | ||
39 | import json | 40 | import json |
40 | 41 | ||
41 | 42 | ||
@@ -871,7 +872,7 @@ def _get_dir_entries(build_id, target_id, start): | |||
871 | # sort by directories first, then by name | 872 | # sort by directories first, then by name |
872 | rsorted = sorted(response, key=lambda entry : entry['name']) | 873 | rsorted = sorted(response, key=lambda entry : entry['name']) |
873 | rsorted = sorted(rsorted, key=lambda entry : entry['isdir'], reverse=True) | 874 | rsorted = sorted(rsorted, key=lambda entry : entry['isdir'], reverse=True) |
874 | return json.dumps(rsorted, cls=LazyEncoder) | 875 | return json.dumps(rsorted, cls=LazyEncoder).replace('</', '<\\/') |
875 | 876 | ||
876 | def dirinfo(request, build_id, target_id, file_path=None): | 877 | def dirinfo(request, build_id, target_id, file_path=None): |
877 | template = "dirinfo.html" | 878 | template = "dirinfo.html" |
@@ -1981,25 +1982,25 @@ if toastermain.settings.MANAGED: | |||
1981 | context = { | 1982 | context = { |
1982 | "project" : prj, | 1983 | "project" : prj, |
1983 | "completedbuilds": Build.objects.filter(project = prj).exclude(outcome = Build.IN_PROGRESS), | 1984 | "completedbuilds": Build.objects.filter(project = prj).exclude(outcome = Build.IN_PROGRESS), |
1984 | "prj" : json.dumps({"name": prj.name, "release": { "id": prj.release.pk, "name": prj.release.name, "desc": prj.release.description}}), | 1985 | "prj" : {"name": prj.name, "release": { "id": prj.release.pk, "name": prj.release.name, "desc": prj.release.description}}, |
1985 | #"buildrequests" : prj.buildrequest_set.filter(state=BuildRequest.REQ_QUEUED), | 1986 | #"buildrequests" : prj.buildrequest_set.filter(state=BuildRequest.REQ_QUEUED), |
1986 | "builds" : json.dumps(_project_recent_build_list(prj)), | 1987 | "builds" : _project_recent_build_list(prj), |
1987 | "layers" : json.dumps(map(lambda x: { | 1988 | "layers" : map(lambda x: { |
1988 | "id": x.layercommit.pk, | 1989 | "id": x.layercommit.pk, |
1989 | "orderid": x.pk, | 1990 | "orderid": x.pk, |
1990 | "name" : x.layercommit.layer.name, | 1991 | "name" : x.layercommit.layer.name, |
1991 | "url": x.layercommit.layer.layer_index_url, | 1992 | "url": x.layercommit.layer.layer_index_url, |
1992 | "layerdetailurl": reverse("layerdetails", args=(x.layercommit.layer.pk,)), | 1993 | "layerdetailurl": reverse("layerdetails", args=(x.layercommit.layer.pk,)), |
1993 | "branch" : { "name" : x.layercommit.up_branch.name, "layersource" : x.layercommit.up_branch.layer_source.name}}, | 1994 | "branch" : { "name" : x.layercommit.up_branch.name, "layersource" : x.layercommit.up_branch.layer_source.name}}, |
1994 | prj.projectlayer_set.all().order_by("id"))), | 1995 | prj.projectlayer_set.all().order_by("id")), |
1995 | "targets" : json.dumps(map(lambda x: {"target" : x.target, "task" : x.task, "pk": x.pk}, prj.projecttarget_set.all())), | 1996 | "targets" : map(lambda x: {"target" : x.target, "task" : x.task, "pk": x.pk}, prj.projecttarget_set.all()), |
1996 | "freqtargets": json.dumps(freqtargets), | 1997 | "freqtargets": freqtargets, |
1997 | "releases": json.dumps(map(lambda x: {"id": x.pk, "name": x.name}, Release.objects.all())), | 1998 | "releases": map(lambda x: {"id": x.pk, "name": x.name}, Release.objects.all()), |
1998 | } | 1999 | } |
1999 | try: | 2000 | try: |
2000 | context["machine"] = json.dumps({"name": prj.projectvariable_set.get(name="MACHINE").value}) | 2001 | context["machine"] = {"name": prj.projectvariable_set.get(name="MACHINE").value} |
2001 | except ProjectVariable.DoesNotExist: | 2002 | except ProjectVariable.DoesNotExist: |
2002 | context["machine"] = json.dumps(None) | 2003 | context["machine"] = None |
2003 | try: | 2004 | try: |
2004 | context["distro"] = prj.projectvariable_set.get(name="DISTRO").value | 2005 | context["distro"] = prj.projectvariable_set.get(name="DISTRO").value |
2005 | except ProjectVariable.DoesNotExist: | 2006 | except ProjectVariable.DoesNotExist: |
@@ -2035,7 +2036,8 @@ if toastermain.settings.MANAGED: | |||
2035 | 2036 | ||
2036 | if 'targets' in request.POST: | 2037 | if 'targets' in request.POST: |
2037 | ProjectTarget.objects.filter(project = prj).delete() | 2038 | ProjectTarget.objects.filter(project = prj).delete() |
2038 | for t in request.POST['targets'].strip().split(" "): | 2039 | s = str(request.POST['targets']) |
2040 | for t in s.translate(None, ";%|\"").split(" "): | ||
2039 | if ":" in t: | 2041 | if ":" in t: |
2040 | target, task = t.split(":") | 2042 | target, task = t.split(":") |
2041 | else: | 2043 | else: |
@@ -2045,11 +2047,11 @@ if toastermain.settings.MANAGED: | |||
2045 | 2047 | ||
2046 | br = prj.schedule_build() | 2048 | br = prj.schedule_build() |
2047 | 2049 | ||
2048 | return HttpResponse(json.dumps({"error":"ok", | 2050 | return HttpResponse(jsonfilter({"error":"ok", |
2049 | "builds" : _project_recent_build_list(prj), | 2051 | "builds" : _project_recent_build_list(prj), |
2050 | }), content_type = "application/json") | 2052 | }), content_type = "application/json") |
2051 | except Exception as e: | 2053 | except Exception as e: |
2052 | return HttpResponse(json.dumps({"error":str(e) + "\n" + traceback.format_exc()}), content_type = "application/json") | 2054 | return HttpResponse(jsonfilter({"error":str(e) + "\n" + traceback.format_exc()}), content_type = "application/json") |
2053 | 2055 | ||
2054 | def xhr_projectedit(request, pid): | 2056 | def xhr_projectedit(request, pid): |
2055 | try: | 2057 | try: |
@@ -2088,7 +2090,7 @@ if toastermain.settings.MANAGED: | |||
2088 | machinevar.save() | 2090 | machinevar.save() |
2089 | 2091 | ||
2090 | # return all project settings | 2092 | # return all project settings |
2091 | return HttpResponse(json.dumps( { | 2093 | return HttpResponse(jsonfilter( { |
2092 | "error": "ok", | 2094 | "error": "ok", |
2093 | "layers" : map(lambda x: {"id": x.layercommit.pk, "orderid" : x.pk, "name" : x.layercommit.layer.name, "url": x.layercommit.layer.layer_index_url, "layerdetailurl": reverse("layerdetails", args=(x.layercommit.layer.pk,)), "branch" : { "name" : x.layercommit.up_branch.name, "layersource" : x.layercommit.up_branch.layer_source.name}}, prj.projectlayer_set.all().order_by("id")), | 2095 | "layers" : map(lambda x: {"id": x.layercommit.pk, "orderid" : x.pk, "name" : x.layercommit.layer.name, "url": x.layercommit.layer.layer_index_url, "layerdetailurl": reverse("layerdetails", args=(x.layercommit.layer.pk,)), "branch" : { "name" : x.layercommit.up_branch.name, "layersource" : x.layercommit.up_branch.layer_source.name}}, prj.projectlayer_set.all().order_by("id")), |
2094 | "builds" : _project_recent_build_list(prj), | 2096 | "builds" : _project_recent_build_list(prj), |
@@ -2098,7 +2100,7 @@ if toastermain.settings.MANAGED: | |||
2098 | }), content_type = "application/json") | 2100 | }), content_type = "application/json") |
2099 | 2101 | ||
2100 | except Exception as e: | 2102 | except Exception as e: |
2101 | return HttpResponse(json.dumps({"error":str(e) + "\n" + traceback.format_exc()}), content_type = "application/json") | 2103 | return HttpResponse(jsonfilter({"error":str(e) + "\n" + traceback.format_exc()}), content_type = "application/json") |
2102 | 2104 | ||
2103 | 2105 | ||
2104 | from django.views.decorators.csrf import csrf_exempt | 2106 | from django.views.decorators.csrf import csrf_exempt |
@@ -2112,7 +2114,7 @@ if toastermain.settings.MANAGED: | |||
2112 | prj = Project.objects.get(pk = request.session['project_id']) | 2114 | prj = Project.objects.get(pk = request.session['project_id']) |
2113 | queryset_all = queryset_all.filter(up_branch__release = prj.release).exclude(pk__in = map(lambda x: x.layercommit_id, prj.projectlayer_set.all())) | 2115 | queryset_all = queryset_all.filter(up_branch__release = prj.release).exclude(pk__in = map(lambda x: x.layercommit_id, prj.projectlayer_set.all())) |
2114 | queryset_all = queryset_all.filter(layer__name__icontains=request.GET.get('value','')) | 2116 | queryset_all = queryset_all.filter(layer__name__icontains=request.GET.get('value','')) |
2115 | return HttpResponse(json.dumps( { "error":"ok", | 2117 | return HttpResponse(jsonfilter( { "error":"ok", |
2116 | "list" : map( lambda x: {"id": x.pk, "name": x.layer.name, "detail": "(" + x.layer.layer_source.name + (")" if x.up_branch == None else " | "+x.up_branch.name+")")}, | 2118 | "list" : map( lambda x: {"id": x.pk, "name": x.layer.name, "detail": "(" + x.layer.layer_source.name + (")" if x.up_branch == None else " | "+x.up_branch.name+")")}, |
2117 | queryset_all[:8]) | 2119 | queryset_all[:8]) |
2118 | }), content_type = "application/json") | 2120 | }), content_type = "application/json") |
@@ -2127,7 +2129,7 @@ if toastermain.settings.MANAGED: | |||
2127 | 2129 | ||
2128 | queryset_all.order_by("-up_id"); | 2130 | queryset_all.order_by("-up_id"); |
2129 | 2131 | ||
2130 | return HttpResponse(json.dumps( { "error":"ok", | 2132 | return HttpResponse(jsonfilter( { "error":"ok", |
2131 | "list" : map( | 2133 | "list" : map( |
2132 | lambda x: {"id": x.pk, "name": x.layer.name, "detail": "(" + x.layer.layer_source.name + (")" if x.up_branch == None else " | "+x.up_branch.name+")"), | 2134 | lambda x: {"id": x.pk, "name": x.layer.name, "detail": "(" + x.layer.layer_source.name + (")" if x.up_branch == None else " | "+x.up_branch.name+")"), |
2133 | "layerdetailurl" : reverse('layerdetails', args=(x.pk,))}, | 2135 | "layerdetailurl" : reverse('layerdetails', args=(x.pk,))}, |
@@ -2146,7 +2148,7 @@ if toastermain.settings.MANAGED: | |||
2146 | if lv.count() != 1: # there is no layer_version with the new release id, and the same name | 2148 | if lv.count() != 1: # there is no layer_version with the new release id, and the same name |
2147 | retval.append(i) | 2149 | retval.append(i) |
2148 | 2150 | ||
2149 | return HttpResponse(json.dumps( {"error":"ok", | 2151 | return HttpResponse(jsonfilter( {"error":"ok", |
2150 | "list": map( | 2152 | "list": map( |
2151 | lambda x: {"id": x.layercommit.pk, "name": x.layercommit.layer.name, "detail": "(" + x.layercommit.layer.layer_source.name + (")" if x.layercommit.up_branch == None else " | "+x.layercommit.up_branch.name+")")}, | 2153 | lambda x: {"id": x.layercommit.pk, "name": x.layercommit.layer.name, "detail": "(" + x.layercommit.layer.layer_source.name + (")" if x.layercommit.up_branch == None else " | "+x.layercommit.up_branch.name+")")}, |
2152 | retval) }), content_type = "application/json") | 2154 | retval) }), content_type = "application/json") |
@@ -2156,7 +2158,7 @@ if toastermain.settings.MANAGED: | |||
2156 | queryset_all = Recipe.objects.all() | 2158 | queryset_all = Recipe.objects.all() |
2157 | if 'project_id' in request.session: | 2159 | if 'project_id' in request.session: |
2158 | queryset_all = queryset_all.filter(layer_version__layer__in = map(lambda x: x.layercommit.layer, ProjectLayer.objects.filter(project_id=request.session['project_id']))) | 2160 | queryset_all = queryset_all.filter(layer_version__layer__in = map(lambda x: x.layercommit.layer, ProjectLayer.objects.filter(project_id=request.session['project_id']))) |
2159 | return HttpResponse(json.dumps({ "error":"ok", | 2161 | return HttpResponse(jsonfilter({ "error":"ok", |
2160 | "list" : map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name+ (" | " + x.layer_version.up_branch.name + "]" if x.layer_version.up_branch is not None else "]")}, | 2162 | "list" : map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name+ (" | " + x.layer_version.up_branch.name + "]" if x.layer_version.up_branch is not None else "]")}, |
2161 | queryset_all.filter(name__icontains=request.GET.get('value',''))[:8]), | 2163 | queryset_all.filter(name__icontains=request.GET.get('value',''))[:8]), |
2162 | 2164 | ||
@@ -2166,7 +2168,7 @@ if toastermain.settings.MANAGED: | |||
2166 | queryset_all = Machine.objects.all() | 2168 | queryset_all = Machine.objects.all() |
2167 | if 'project_id' in request.session: | 2169 | if 'project_id' in request.session: |
2168 | queryset_all = queryset_all.filter(layer_version__layer__in = map(lambda x: x.layercommit.layer, ProjectLayer.objects.filter(project_id=request.session['project_id']))) | 2170 | queryset_all = queryset_all.filter(layer_version__layer__in = map(lambda x: x.layercommit.layer, ProjectLayer.objects.filter(project_id=request.session['project_id']))) |
2169 | return HttpResponse(json.dumps({ "error":"ok", | 2171 | return HttpResponse(jsonfilter({ "error":"ok", |
2170 | "list" : map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name+ (" | " + x.layer_version.up_branch.name + "]" if x.layer_version.up_branch is not None else "]")}, | 2172 | "list" : map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name+ (" | " + x.layer_version.up_branch.name + "]" if x.layer_version.up_branch is not None else "]")}, |
2171 | queryset_all.filter(name__icontains=request.GET.get('value',''))[:8]), | 2173 | queryset_all.filter(name__icontains=request.GET.get('value',''))[:8]), |
2172 | 2174 | ||
@@ -2174,7 +2176,7 @@ if toastermain.settings.MANAGED: | |||
2174 | 2176 | ||
2175 | raise Exception("Unknown request! " + request.GET.get('type', "No parameter supplied")) | 2177 | raise Exception("Unknown request! " + request.GET.get('type', "No parameter supplied")) |
2176 | except Exception as e: | 2178 | except Exception as e: |
2177 | return HttpResponse(json.dumps({"error":str(e) + "\n" + traceback.format_exc()}), content_type = "application/json") | 2179 | return HttpResponse(jsonfilter({"error":str(e) + "\n" + traceback.format_exc()}), content_type = "application/json") |
2178 | 2180 | ||
2179 | 2181 | ||
2180 | 2182 | ||
@@ -2216,7 +2218,7 @@ if toastermain.settings.MANAGED: | |||
2216 | 2218 | ||
2217 | 2219 | ||
2218 | context = { | 2220 | context = { |
2219 | 'projectlayerset' : json.dumps(map(lambda x: x.layercommit.id, prj.projectlayer_set.all())), | 2221 | 'projectlayerset' : jsonfilter(map(lambda x: x.layercommit.id, prj.projectlayer_set.all())), |
2220 | 'objects' : layer_info, | 2222 | 'objects' : layer_info, |
2221 | 'objectname' : "layers", | 2223 | 'objectname' : "layers", |
2222 | 'default_orderby' : 'layer__name:+', | 2224 | 'default_orderby' : 'layer__name:+', |
@@ -2309,7 +2311,7 @@ if toastermain.settings.MANAGED: | |||
2309 | 2311 | ||
2310 | 2312 | ||
2311 | context = { | 2313 | context = { |
2312 | 'projectlayerset' : json.dumps(map(lambda x: x.layercommit.id, prj.projectlayer_set.all())), | 2314 | 'projectlayerset' : jsonfilter(map(lambda x: x.layercommit.id, prj.projectlayer_set.all())), |
2313 | 'objects' : target_info, | 2315 | 'objects' : target_info, |
2314 | 'objectname' : "targets", | 2316 | 'objectname' : "targets", |
2315 | 'default_orderby' : 'name:+', | 2317 | 'default_orderby' : 'name:+', |