From 02fb27fa5dff8cc6101ee28f9d822678d6ad5f11 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Sun, 10 Apr 2016 17:30:24 +0200 Subject: [PATCH] Externalize more resources, implement Content-Security-Policy headers --- src/pretix/base/middleware.py | 41 +++ .../pretixcontrol/attendees/index.html | 2 +- .../control/templates/pretixcontrol/base.html | 1 + .../help/payment/fee_reverse.html | 4 +- .../templates/pretixcontrol/order/index.html | 2 +- .../templates/pretixcontrol/orders/index.html | 4 +- src/pretix/locale/de/LC_MESSAGES/django.po | 313 ++++++++++-------- src/pretix/locale/de/LC_MESSAGES/djangojs.po | 26 +- .../locale/de_Informal/LC_MESSAGES/django.po | 313 ++++++++++-------- .../de_Informal/LC_MESSAGES/djangojs.po | 26 +- .../banktransfer/import_assign.html | 4 +- .../banktransfer/import_confirm.html | 2 +- .../pretixplugins/statistics/statistics.js | 13 +- .../pretixplugins/statistics/index.html | 7 +- src/pretix/plugins/statistics/views.py | 10 +- .../pretixplugins/stripe/pretix-stripe.js | 6 +- .../pretixplugins/stripe/presale_head.html | 6 +- src/pretix/settings.py | 1 + src/static/pretixcontrol/scss/main.scss | 10 + 19 files changed, 494 insertions(+), 297 deletions(-) diff --git a/src/pretix/base/middleware.py b/src/pretix/base/middleware.py index 580eaeaddc..313ba60361 100644 --- a/src/pretix/base/middleware.py +++ b/src/pretix/base/middleware.py @@ -129,3 +129,44 @@ def get_language_from_request(request: HttpRequest) -> str: or get_language_from_browser(request) or get_default_language() ) + + +class SecurityMiddleware: + + def _parse_csp(self, header): + h = {} + for part in header.split(';'): + k, v = part.split(' ', 1) + h[k] = v + return h + + def _render_csp(self, h): + return "; ".join(k + ' ' + v for k, v in h.items()) + + def process_response(self, request, resp): + resp['X-XSS-Protection'] = '1' + h = { + 'default-src': "{static}", + 'script-src': '{static} https://js.stripe.com', + 'object-src': "'none'", + 'frame-src': "'none'", + 'style-src': "{static}", + 'img-src': "{static} data:", + 'form-action': "{dynamic}", + } + if 'Content-Security-Policy' in resp: + h.update(self._parse_csp(resp['Content-Security-Policy'])) + + staticdomain = "'self'" + dynamicdomain = "'self'" + if settings.STATIC_URL.startswith('http'): + staticdomain += " " + settings.STATIC_URL[:settings.STATIC_URL.find('/', 9)] + if settings.SITE_URL.startswith('http'): + if settings.SITE_URL.find('/', 9) > 0: + staticdomain += " " + settings.SITE_URL[:settings.SITE_URL.find('/', 9)] + dynamicdomain += " " + settings.SITE_URL[:settings.SITE_URL.find('/', 9)] + else: + staticdomain += " " + settings.SITE_URL + dynamicdomain += " " + settings.SITE_URL + resp['Content-Security-Policy'] = self._render_csp(h).format(static=staticdomain, dynamic=dynamicdomain) + return resp diff --git a/src/pretix/control/templates/pretixcontrol/attendees/index.html b/src/pretix/control/templates/pretixcontrol/attendees/index.html index b23ccb771c..93c33fe98f 100644 --- a/src/pretix/control/templates/pretixcontrol/attendees/index.html +++ b/src/pretix/control/templates/pretixcontrol/attendees/index.html @@ -4,7 +4,7 @@ {% block content %}

{% trans "Attendees" %}

-

+ @@ -13,7 +13,7 @@
-
+ -
diff --git a/src/pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js b/src/pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js index a47de0db7f..ad64ce91b6 100644 --- a/src/pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js +++ b/src/pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js @@ -1,11 +1,12 @@ -/*globals $, Morris*/ +/*globals $, Morris, gettext*/ $(function () { + $(".chart").css("height", "250px"); new Morris.Area({ element: 'obd_chart', data: JSON.parse($("#obd-data").html()), xkey: 'date', ykeys: ['ordered', 'paid'], - labels: ['{% trans "Placed orders" %}', '{% trans "Paid orders" %}'], + labels: [gettext('Placed orders'), gettext('Paid orders')], lineColors: ['#000099', '#009900'], smooth: false, resize: true, @@ -17,18 +18,18 @@ $(function () { data: JSON.parse($("#rev-data").html()), xkey: 'date', ykeys: ['revenue'], - labels: ['{% trans "Total revenue" %}'], + labels: [gettext('Total revenue')], smooth: false, resize: true, fillOpacity: 0.3, - preUnits: '{{ request.event.currency }} ' + preUnits: $.trim($("#currency").html()) + ' ' }); new Morris.Bar({ element: 'obp_chart', - data: JSON.parse($("#odp-data").html()), + data: JSON.parse($("#obp-data").html()), xkey: 'item', ykeys: ['ordered', 'paid'], - labels: ['{% trans "Placed orders" %}', '{% trans "Paid orders" %}'], + labels: [gettext('Placed orders'), gettext('Paid orders')], barColors: ['#000099', '#009900'], resize: true }); diff --git a/src/pretix/plugins/statistics/templates/pretixplugins/statistics/index.html b/src/pretix/plugins/statistics/templates/pretixplugins/statistics/index.html index 814492728c..e8dc9fb350 100644 --- a/src/pretix/plugins/statistics/templates/pretixplugins/statistics/index.html +++ b/src/pretix/plugins/statistics/templates/pretixplugins/statistics/index.html @@ -10,7 +10,7 @@

{% trans "Orders by day" %}

-
+
@@ -18,7 +18,7 @@

{% trans "Revenue over time" %}

-
+
@@ -26,12 +26,13 @@

{% trans "Orders by product" %}

-
+
+ {% endblock %} diff --git a/src/pretix/plugins/statistics/views.py b/src/pretix/plugins/statistics/views.py index efc32f181e..6cd4f6ee61 100644 --- a/src/pretix/plugins/statistics/views.py +++ b/src/pretix/plugins/statistics/views.py @@ -15,6 +15,12 @@ class IndexView(EventPermissionRequiredMixin, TemplateView): template_name = 'pretixplugins/statistics/index.html' permission = 'can_view_orders' + def get(self, request, *args, **kwargs): + resp = super().get(request, *args, **kwargs) + # required by raphael.js + resp['Content-Security-Policy'] = "script-src {static} 'unsafe-eval'; style-src {static} 'unsafe-inline'" + return resp + def get_context_data(self, **kwargs): ctx = super().get_context_data(**kwargs) @@ -75,13 +81,13 @@ class IndexView(EventPermissionRequiredMixin, TemplateView): i.id: str(i.name) for i in Item.objects.filter(event=self.request.event) } - ctx['obp_data'] = [ + ctx['obp_data'] = json.dumps([ { 'item': item_names[item], 'ordered': cnt, 'paid': num_paid.get(item, 0) } for item, cnt in num_ordered.items() - ] + ]) cache.set('statistics_obp_data', ctx['obp_data']) ctx['rev_data'] = cache.get('statistics_rev_data') diff --git a/src/pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js b/src/pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js index 1156b34aa9..6ba13535a4 100644 --- a/src/pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js +++ b/src/pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js @@ -1,4 +1,4 @@ -/*global $, stripe_pubkey, stripe_loadingmessage */ +/*global $, stripe_pubkey, stripe_loadingmessage, gettext */ 'use strict'; var Stripe = null; @@ -44,7 +44,7 @@ var pretixstripe = { } }, 'request': function () { - waitingDialog.show(stripe_loading_message); + waitingDialog.show(gettext("Contacting Stripe…")); $(".stripe-errors").hide(); Stripe.card.createToken( { @@ -80,7 +80,7 @@ var pretixstripe = { url: 'https://js.stripe.com/v2/', dataType: 'script', success: function () { - Stripe.setPublishableKey(stripe_pubkey); + Stripe.setPublishableKey($.trim($("#stripe_pubkey").html())); } } ); diff --git a/src/pretix/plugins/stripe/templates/pretixplugins/stripe/presale_head.html b/src/pretix/plugins/stripe/templates/pretixplugins/stripe/presale_head.html index 709ae4830f..57e1f02104 100644 --- a/src/pretix/plugins/stripe/templates/pretixplugins/stripe/presale_head.html +++ b/src/pretix/plugins/stripe/templates/pretixplugins/stripe/presale_head.html @@ -5,7 +5,5 @@ {% compress js %} {% endcompress %} - + + diff --git a/src/pretix/settings.py b/src/pretix/settings.py index f76c8bcd83..dcf2d743d6 100644 --- a/src/pretix/settings.py +++ b/src/pretix/settings.py @@ -179,6 +179,7 @@ MIDDLEWARE_CLASSES = [ 'pretix.control.middleware.PermissionMiddleware', 'pretix.presale.middleware.EventMiddleware', 'pretix.base.middleware.LocaleMiddleware', + 'pretix.base.middleware.SecurityMiddleware', ] try: diff --git a/src/static/pretixcontrol/scss/main.scss b/src/static/pretixcontrol/scss/main.scss index b7b8227298..db75666f55 100644 --- a/src/static/pretixcontrol/scss/main.scss +++ b/src/static/pretixcontrol/scss/main.scss @@ -153,4 +153,14 @@ h1 .btn-sm { padding-bottom: 15px; } +} + +.helper-display-inline { + display: inline !important; +} +.helper-width-auto { + width: auto; +} +.helper-space-below { + margin-bottom: 10px; } \ No newline at end of file