From 490e640582d55f32d10d472fa536297adff4a166 Mon Sep 17 00:00:00 2001 From: ntrncic Date: Thu, 11 May 2023 09:20:08 +0200 Subject: [PATCH 1/5] Update azure-pipelines.yml for Azure Pipelines --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 813bbe75..57fa5430 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -26,7 +26,7 @@ variables: - name: appName value: "uni-hope-ukr-sr" - ${{ elseif eq(variables['Build.SourceBranchName'], 'staging') }}: - - group: flex-registration-dev + - group: flex-registration-stg - name: Docker.registry value: "unihopeukrsrdev" - name: azureSubscription From abb8e0a34d90eb8cabc248d2d208cc32b719be13 Mon Sep 17 00:00:00 2001 From: sax Date: Thu, 25 May 2023 14:38:19 +0200 Subject: [PATCH 2/5] CSP settings --- src/aurora/api/viewsets/registration.py | 187 ++++++++++++------------ src/aurora/config/settings.py | 46 ++++-- 2 files changed, 127 insertions(+), 106 deletions(-) diff --git a/src/aurora/api/viewsets/registration.py b/src/aurora/api/viewsets/registration.py index fd6ad290..b6d3751b 100644 --- a/src/aurora/api/viewsets/registration.py +++ b/src/aurora/api/viewsets/registration.py @@ -1,5 +1,6 @@ import csv import io +import logging import os from collections import OrderedDict from urllib import parse @@ -22,6 +23,8 @@ from ..serializers.record import DataTableRecordSerializer from .base import SmartViewSet +logger = logging.getLogger(__name__) + class RecordPageNumberPagination(PageNumberPagination): def get_paginated_response(self, data): @@ -162,101 +165,105 @@ def csv(self, request: HttpRequest, pk): from aurora.core.forms import CSVOptionsForm from aurora.core.forms import DateFormatsForm - form = RegistrationExportForm(request.GET, initial=RegistrationExportForm.defaults) - opts_form = CSVOptionsForm(request.GET, prefix="csv", initial=CSVOptionsForm.defaults) - fmt_form = DateFormatsForm(request.GET, prefix="fmt", initial=DateFormatsForm.defaults) - if form.is_valid() and opts_form.is_valid() and fmt_form.is_valid(): - for frm in [form, fmt_form, opts_form]: - for k, f in frm.defaults.items(): - if not frm.cleaned_data.get(k): - frm.cleaned_data[k] = frm.defaults[k] - filters, exclude = form.cleaned_data["filters"] - include_fields = form.cleaned_data["include"] - exclude_fields = form.cleaned_data["exclude"] - qs = ( - Record.objects.filter(registration__pk=pk) - .defer( - "storage", - "counters", - "files", + try: + form = RegistrationExportForm(request.GET, initial=RegistrationExportForm.defaults) + opts_form = CSVOptionsForm(request.GET, prefix="csv", initial=CSVOptionsForm.defaults) + fmt_form = DateFormatsForm(request.GET, prefix="fmt", initial=DateFormatsForm.defaults) + if form.is_valid() and opts_form.is_valid() and fmt_form.is_valid(): + for frm in [form, fmt_form, opts_form]: + for k, f in frm.defaults.items(): + if not frm.cleaned_data.get(k): + frm.cleaned_data[k] = frm.defaults[k] + filters, exclude = form.cleaned_data["filters"] + include_fields = form.cleaned_data["include"] + exclude_fields = form.cleaned_data["exclude"] + qs = ( + Record.objects.filter(registration__pk=pk) + .defer( + "storage", + "counters", + "files", + ) + .filter(**filters) + .exclude(**exclude) + .values("fields", "id", "ignored", "timestamp", "registration_id") ) - .filter(**filters) - .exclude(**exclude) - .values("fields", "id", "ignored", "timestamp", "registration_id") - ) - if qs.count() >= 5000: - raise Exception("Too many records please change your filters. (max 5000)") - skipped = [] - all_fields = [] - records = [build_dict(r, **fmt_form.cleaned_data) for r in qs] - for r in records: - for field_name in r.keys(): - if field_name not in skipped and field_name in exclude_fields: - skipped.append(field_name) - elif field_name not in all_fields and field_name in include_fields: - all_fields.append(field_name) - csv_options = opts_form.cleaned_data - add_header = csv_options.pop("header") - date_format = csv_options.pop("date_format") # noqa - datetime_format = csv_options.pop("datetime_format") # noqa - time_format = csv_options.pop("time_format") # noqa - if "download" in request.GET or "preview" in request.GET: - filename = f"Registration_{reg.slug}.csv" - if "preview" in request.GET: - headers = {} + if qs.count() >= 5000: + raise Exception("Too many records please change your filters. (max 5000)") + skipped = [] + all_fields = [] + records = [build_dict(r, **fmt_form.cleaned_data) for r in qs] + for r in records: + for field_name in r.keys(): + if field_name not in skipped and field_name in exclude_fields: + skipped.append(field_name) + elif field_name not in all_fields and field_name in include_fields: + all_fields.append(field_name) + csv_options = opts_form.cleaned_data + add_header = csv_options.pop("header") + date_format = csv_options.pop("date_format") # noqa + datetime_format = csv_options.pop("datetime_format") # noqa + time_format = csv_options.pop("time_format") # noqa + if "download" in request.GET or "preview" in request.GET: + filename = f"Registration_{reg.slug}.csv" + if "preview" in request.GET: + headers = {} + else: + headers = {"Content-Disposition": 'attachment;filename="%s"' % filename} + + out = io.StringIO() + writer = csv.DictWriter( + out, + fieldnames=all_fields, + restval="-", + extrasaction="ignore", + **csv_options, + ) + if add_header: + writer.writeheader() + writer.writerows(records) + out.seek(0) + content = out.read() + return HttpResponse( + content, + headers=headers, + content_type="text/plain", + ) else: - headers = {"Content-Disposition": 'attachment;filename="%s"' % filename} - out = io.StringIO() - writer = csv.DictWriter( - out, - fieldnames=all_fields, - restval="-", - extrasaction="ignore", - **csv_options, - ) - if add_header: - writer.writeheader() - writer.writerows(records) - out.seek(0) - content = out.read() - return HttpResponse( - content, - headers=headers, - content_type="text/plain", - ) + return Response( + { + "reg": { + "name": reg.name, + "slug": reg.slug, + }, + "data": { + "download": request.build_absolute_uri( + "?download=1&" + parse.urlencode(request.GET.dict(), doseq=False) + ), + "preview": request.build_absolute_uri( + "?preview=1&" + parse.urlencode(request.GET.dict(), doseq=False) + ), + "count": qs.count(), + "filters": filters, + "exclude": exclude, + "include_fields": [r.pattern for r in include_fields], + "fieldnames": all_fields, + "skipped": skipped, + }, + "form": {k: str(v) for k, v in form.cleaned_data.items()}, + "fmt": {k: str(v) for k, v in fmt_form.cleaned_data.items()}, + "csv": {k: str(v) for k, v in opts_form.cleaned_data.items()}, + } + ) else: - return Response( { - "reg": { - "name": reg.name, - "slug": reg.slug, - }, - "data": { - "download": request.build_absolute_uri( - "?download=1&" + parse.urlencode(request.GET.dict(), doseq=False) - ), - "preview": request.build_absolute_uri( - "?preview=1&" + parse.urlencode(request.GET.dict(), doseq=False) - ), - "count": qs.count(), - "filters": filters, - "exclude": exclude, - "include_fields": [r.pattern for r in include_fields], - "fieldnames": all_fields, - "skipped": skipped, - }, - "form": {k: str(v) for k, v in form.cleaned_data.items()}, - "fmt": {k: str(v) for k, v in fmt_form.cleaned_data.items()}, - "csv": {k: str(v) for k, v in opts_form.cleaned_data.items()}, + "form": form.errors, + "fmt": fmt_form.errors, + "csv": opts_form.errors, } ) - else: - return Response( - { - "form": form.errors, - "fmt": fmt_form.errors, - "csv": opts_form.errors, - } - ) + except Exception as e: + logger.exception(e) + return Response({"message": "Error"}, status=500) diff --git a/src/aurora/config/settings.py b/src/aurora/config/settings.py index 5e0fbef4..8731b892 100644 --- a/src/aurora/config/settings.py +++ b/src/aurora/config/settings.py @@ -627,26 +627,37 @@ def show_ddt(request): # pragma: no-cover HTTP2_SERVER_PUSH = False # CSP SOURCES = ( - "self", + "'self'", "inline", "unsafe-inline", - "http://localhost:8000", - "https://unpkg.com", - "https://browser.sentry-cdn.com", - "https://cdnjs.cloudflare.com", - "data", - "unsafe-inline", + "data:", + "blob:", + "'unsafe-inline'", + "localhost:8000", + "unpkg.com", + "browser.sentry-cdn.com", + "cdnjs.cloudflare.com", + "register.unicef.org", + "uni-hope-ukr-sr.azurefd.net", + "uni-hope-ukr-sr-dev.azurefd.net", + "uni-hope-ukr-sr-dev.unitst.org", ) -# MIDDLEWARE += ["csp.middleware.CSPMiddleware", ] +MIDDLEWARE += [ + "csp.middleware.CSPMiddleware", +] CSP_DEFAULT_SRC = SOURCES -# CSP_SCRIPT_SRC = ("self",) -CSP_STYLE_SRC = ( - "self", - "unsafe-inline", - "https://unpkg.com", - "http://localhost:8000", - "https://cdnjs.cloudflare.com", -) +CSP_FRAME_SRC = [] +# CSP_SCRIPT_SRC = SOURCES +# CSP_STYLE_SRC = ( +# "'self'", +# "'data'", +# "'unsafe-inline'", +# "https://unpkg.com", +# "http://localhost:8000", +# "https://cdnjs.cloudflare.com", +# "http://cdnjs.cloudflare.com", +# +# ) # CSP_OBJECT_SRC = ("self",) # CSP_BASE_URI = ("self", "http://localhost:8000",) # CSP_CONNECT_SRC = ("self",) @@ -677,6 +688,9 @@ def show_ddt(request): # pragma: no-cover # CSP_DEFAULT_SRC = env("CSP_DEFAULT_SRC") # CSP_SCRIPT_SRC = env("CSP_SCRIPT_SRC") +SECURE_HSTS_SECONDS = 60 +SECURE_HSTS_INCLUDE_SUBDOMAINS = True + # Add reversion models to admin interface: ADD_REVERSION_ADMIN = True # optional settings: From d2b424963cd05679d2b11987ed6ee07bb3b77496 Mon Sep 17 00:00:00 2001 From: Domenico DiNicola Date: Wed, 5 Jul 2023 15:19:56 +0200 Subject: [PATCH 3/5] color admin --- src/aurora/core/templates/admin/base.html | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/aurora/core/templates/admin/base.html diff --git a/src/aurora/core/templates/admin/base.html b/src/aurora/core/templates/admin/base.html new file mode 100644 index 00000000..bbae6dad --- /dev/null +++ b/src/aurora/core/templates/admin/base.html @@ -0,0 +1,22 @@ +{% extends "admin/base.html" %} + +{% block extrahead %} + +{% endblock %} From b6538201854007482ef5d1b145f61ebc56b66632 Mon Sep 17 00:00:00 2001 From: Domenico DiNicola Date: Wed, 5 Jul 2023 15:31:49 +0200 Subject: [PATCH 4/5] ad flag --- src/aurora/web/templates/base_lean.html | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/aurora/web/templates/base_lean.html b/src/aurora/web/templates/base_lean.html index be30800b..743a8d9f 100644 --- a/src/aurora/web/templates/base_lean.html +++ b/src/aurora/web/templates/base_lean.html @@ -1,2 +1,23 @@ {% extends "base.html" %} {% block header %}{% endblock %} + +{% block extrahead %} + +{% endblock %} From c7aaeab0465202a55ed56bc7de27b5d7c6db6d76 Mon Sep 17 00:00:00 2001 From: Domenico DiNicola Date: Wed, 5 Jul 2023 16:46:39 +0200 Subject: [PATCH 5/5] header --- src/aurora/web/templates/base.html | 28 ++++++++++++++++++++++++- src/aurora/web/templates/base_lean.html | 21 ------------------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/aurora/web/templates/base.html b/src/aurora/web/templates/base.html index 47f2fb06..608600e0 100644 --- a/src/aurora/web/templates/base.html +++ b/src/aurora/web/templates/base.html @@ -23,8 +23,34 @@ + {% block header %} -
+