From 4468feda27a1e5fa66fc25636dc70d34d14ab503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Tue, 26 May 2020 20:39:58 +0200 Subject: [PATCH] backoffice: redirect on missing user custom view (#42164) --- tests/test_backoffice_pages.py | 16 ++++++++++++++++ wcs/backoffice/management.py | 11 +++++++++++ wcs/forms/common.py | 2 +- wcs/qommon/misc.py | 13 ++++++++++++- 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/tests/test_backoffice_pages.py b/tests/test_backoffice_pages.py index 4b885abd0..71346bb6c 100644 --- a/tests/test_backoffice_pages.py +++ b/tests/test_backoffice_pages.py @@ -6735,6 +6735,22 @@ def test_backoffice_custom_view_visibility(pub): [('custom-test-view', 'owner'), ('shared-view', 'any'), ('shared-view-2', 'any')]) +def test_backoffice_missing_custom_view(pub): + create_superuser(pub) + create_environment(pub, set_receiver=False) + app = login(get_app(pub)) + resp = app.get('/backoffice/management/form-title/user-plop/') + assert resp.location == 'http://example.net/backoffice/management/form-title/' + resp = resp.follow() + assert 'A missing or invalid custom view was referenced' in resp + + resp = app.get('/backoffice/management/form-title/user-plop/1/') + assert resp.location == 'http://example.net/backoffice/management/form-title/1/' + + resp = app.get('/backoffice/management/form-title/user-plop/1/?plop') + assert resp.location == 'http://example.net/backoffice/management/form-title/1/?plop' + + def test_carddata_custom_view(pub, studio): CardDef.wipe() user = create_user(pub) diff --git a/wcs/backoffice/management.py b/wcs/backoffice/management.py index 641e1394b..242c55ff3 100644 --- a/wcs/backoffice/management.py +++ b/wcs/backoffice/management.py @@ -2487,6 +2487,15 @@ class FormPage(Directory): for view in self.get_custom_views(): if view.get_url_slug() == component: return self.__class__(formdef=self.formdef, view=view) + if component.startswith('user-'): + get_session().message = ('warning', + _('A missing or invalid custom view was referenced; ' + 'you have been automatically redirected.')) + # remove custom view reference from path + # (ignore the fact that some form/card could itself be named + # user-whatever) + url = get_request().get_path_query().replace('/%s/' % component, '/') + return misc.QLookupRedirect(url) try: filled = self.formdef.data_class().get(component) @@ -2906,6 +2915,8 @@ class FormBackOfficeStatusPage(FormStatusPage): r += htmltext('') r += htmltext('') + r += get_session().display_message() + r += htmltext('
') r += htmltext('

%s

') % _('Test tools') r += htmltext('
') diff --git a/wcs/forms/common.py b/wcs/forms/common.py index f9a277ce0..7156ccbb0 100644 --- a/wcs/forms/common.py +++ b/wcs/forms/common.py @@ -534,7 +534,7 @@ class FormStatusPage(Directory, FormTemplateMixin): get_response().add_javascript(['jquery.js', 'qommon.forms.js']) self.html_top('%s - %s' % (self.formdef.name, self.filled.id)) r = TemplateIO(html=True) - + r += get_session().display_message() r += htmltext(self.workflow_messages()) r += self.receipt(always_include_user=True, mine=False) r += self.backoffice_fields_section() diff --git a/wcs/qommon/misc.py b/wcs/qommon/misc.py index 98a6d040d..25585905f 100644 --- a/wcs/qommon/misc.py +++ b/wcs/qommon/misc.py @@ -44,7 +44,7 @@ from django.utils.six.moves.html_parser import HTMLParser from django.utils.six.moves.urllib.parse import quote, urlencode from django.utils.six.moves.urllib import parse as urlparse -from quixote import get_publisher, get_response, get_request +from quixote import get_publisher, get_response, get_request, redirect from quixote.html import htmltext from . import _, force_str @@ -815,3 +815,14 @@ def get_order_by_or_400(value): if not re.match(r'-?[a-z0-9_-]+$', value): raise RequestError() return value + + +class QLookupRedirect: + ''' + Class to use to interrupt a _q_lookup method and redirect. + ''' + def __init__(self, url): + self.url = url + + def _q_traverse(self, path): + return redirect(self.url)