From b9cf37ac492b6cb5e16c3729d7b3f25f71db8f55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Wed, 18 Jul 2018 11:45:02 +0200 Subject: [PATCH] forms: redirect manager to backoffice view of formdatas (#25330) --- tests/test_backoffice_pages.py | 4 +- tests/test_form_pages.py | 73 ++++++++++++++++++++++++++++++++++ wcs/forms/common.py | 6 +++ 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/tests/test_backoffice_pages.py b/tests/test_backoffice_pages.py index 3cf142c5..0116c6cc 100644 --- a/tests/test_backoffice_pages.py +++ b/tests/test_backoffice_pages.py @@ -2271,7 +2271,7 @@ def test_backoffice_submission_no_manual_channel_with_welco(pub, welco_url): assert 'submission_channel' not in resp.form.fields def test_backoffice_wscall_failure_display(http_requests, pub): - create_user(pub) + user = create_user(pub) create_environment(pub) formdef = FormDef.get_by_urlname('form-title') form_class = formdef.data_class() @@ -2313,6 +2313,8 @@ def test_backoffice_wscall_failure_display(http_requests, pub): resp = resp.follow() assert 'Error during webservice call' in resp.body + number31.user_id = user.id # change ownership to stay in frontoffice + number31.store() # the failure message shouldn't be displayed in the frontoffice resp = app.get('/form-title/%s/' % number31.id) assert (' with the number %s.' % number31.get_display_id()) in resp.body diff --git a/tests/test_form_pages.py b/tests/test_form_pages.py index cdb95c35..1a8145b8 100644 --- a/tests/test_form_pages.py +++ b/tests/test_form_pages.py @@ -4105,6 +4105,7 @@ def test_form_worklow_multiple_identical_status(pub): Role.wipe() role = Role(name='xxx') + role.allows_backoffice_access = False role.store() jump.by = [role.id] @@ -4919,3 +4920,75 @@ def test_condition_on_action(pub, emails): resp = resp.form.submit('submit') resp = resp.form.submit('submit') assert emails.get('New form2 (test condition on action)') + +def test_manager_public_access(pub): + user, manager = create_user_and_admin(pub) + + Role.wipe() + role = Role(name='xxx') + role.store() + + manager.is_admin = False + manager.roles = [role.id] + manager.store() + assert manager.can_go_in_backoffice() + + formdef = create_formdef() + formdef.workflow_roles = {'_receiver': role.id} + formdef.store() + + formdata = formdef.data_class()() + formdata.user_id = user.id + formdata.data = {} + formdata.just_created() + formdata.store() + + # user access to own formdata + app = login(get_app(pub), username='foo', password='foo') + resp = app.get(formdata.get_url()) + assert 'The form has been recorded' in resp.body + + # agent access to formdata + app = login(get_app(pub), username='admin', password='admin') + resp = app.get(formdata.get_url()) + assert resp.location == formdata.get_url(backoffice=True) + resp = resp.follow() + assert 'The form has been recorded' in resp.body + + # agent access to an unauthorized formdata + formdef.workflow_roles = {'_receiver': None} + formdef.store() + resp = app.get(formdata.get_url(), status=403) + + # agent access via a tracking code (stays in frontoffice) + formdef.workflow_roles = {'_receiver': role.id} + formdef.enable_tracking_codes = True + formdef.store() + + code = pub.tracking_code_class() + code.formdata = formdata + code.store() + + resp = app.get('/code/%s/load' % code.id) + resp = resp.follow() # -> /test/1 + assert not 'backoffice' in resp.location + resp = resp.follow() # -> /test/1/ + assert 'The form has been recorded' in resp.body + + # authorized access but not backoffice access + app = login(get_app(pub), username='admin', password='admin') # reset session + resp = app.get(formdata.get_url()) + assert resp.location == formdata.get_url(backoffice=True) # check tracking code is no longer effective + role.allows_backoffice_access = False + role.store() + resp = app.get(formdata.get_url()) + assert 'The form has been recorded' in resp.body + + # agent access to own formdata (stays in frontoffice) + formdata = formdef.data_class()() + formdata.user_id = manager.id + formdata.data = {} + formdata.just_created() + formdata.store() + resp = app.get(formdata.get_url()) + assert 'The form has been recorded' in resp.body diff --git a/wcs/forms/common.py b/wcs/forms/common.py index 368af029..a7ce3585 100644 --- a/wcs/forms/common.py +++ b/wcs/forms/common.py @@ -227,6 +227,12 @@ class FormStatusPage(Directory, FormTemplateMixin): def _q_index(self): mine = self.check_auth() + if not mine and not get_request().is_in_backoffice(): + # access authorized but the form doesn't belong to the user; if the + # user has access to the backoffice, redirect. + if get_request().user.can_go_in_backoffice(): + return redirect(self.filled.get_url(backoffice=True)) + get_logger().info('form %s - id: %s - view' % (self.formdef.name, self.filled.id)) user = get_request().user -- 2.18.0