From 05f8268ae26d4205a97e1113c0b3c0e2954e95ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Sat, 17 Oct 2015 21:53:58 +0200 Subject: [PATCH] api: expose formdata retrieval api under /api/ (#8678) --- help/fr/api-get.page | 2 +- tests/test_api.py | 17 ++++++++++++++++- wcs/api.py | 24 ++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/help/fr/api-get.page b/help/fr/api-get.page index bf42606f4..5dacf22cf 100644 --- a/help/fr/api-get.page +++ b/help/fr/api-get.page @@ -31,7 +31,7 @@ newsletter. $ curl -H "Accept: application/json" \ - https://www.example.net/inscriptions/newsletter/16/ + https://www.example.net/api/forms/newsletter/16/

diff --git a/tests/test_api.py b/tests/test_api.py index ba6a75f66..736c9f7dc 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -391,6 +391,9 @@ def test_categories_formdefs(): def test_formdata(local_user): + Role.wipe() + role = Role(name='test') + role.store() FormDef.wipe() formdef = FormDef() formdef.name = 'test' @@ -399,6 +402,7 @@ def test_formdata(local_user): fields.StringField(id='1', label='foobar2'), fields.DateField(id='2', label='foobar3', varname='date'), fields.FileField(id='3', label='foobar4', varname='file'),] + formdef.workflow_roles = {'_receiver': role.id} formdef.store() formdata = formdef.data_class()() @@ -410,7 +414,18 @@ def test_formdata(local_user): formdata.just_created() formdata.store() - resp = get_app(pub).get(sign_uri('/test/%s/' % formdata.id, user=local_user)) + resp = get_app(pub).get( + sign_uri('/api/forms/test/%s/' % formdata.id, user=local_user), + status=403) + + local_user.roles = [role.id] + local_user.store() + resp = get_app(pub).get( + sign_uri('/api/forms/test/%s/' % formdata.id, user=local_user), + status=200) + + resp2 = get_app(pub).get(sign_uri('/test/%s/' % formdata.id, user=local_user)) + assert resp.json == resp2.json assert 'last_update_time' in resp.json assert len(resp.json['fields']) == 3 # foobar2 has no varname, not in json assert resp.json['user']['name'] == local_user.name diff --git a/wcs/api.py b/wcs/api.py index 50082562f..47da685c5 100644 --- a/wcs/api.py +++ b/wcs/api.py @@ -35,6 +35,7 @@ from qommon.errors import (AccessForbiddenError, QueryError, TraversalError, from wcs.categories import Category from wcs.formdef import FormDef from wcs.roles import Role, logged_users_role +from wcs.forms.common import FormStatusPage from wcs.forms.root import RootDirectory import wcs.qommon.storage as st @@ -136,6 +137,22 @@ def sign_string(s, key, algo='sha256', timedelta=30): from backoffice.management import FormPage as BackofficeFormPage +class ApiFormdataPage(FormStatusPage): + _q_exports = ['', 'download'] + + def _q_index(self): + return self.json() + + def check_receiver(self): + api_user = get_user_from_api_query_string() + if not api_user: + if get_request().user and get_request().user.is_admin: + return # grant access to admins, to ease debug + raise AccessForbiddenError() + if not self.formdef.is_user_allowed_read_status_and_history(api_user, self.filled): + raise AccessForbiddenError() + + class ApiFormPage(BackofficeFormPage): _q_exports = [('list', 'json')] # same as backoffice but restricted to json export @@ -153,6 +170,13 @@ class ApiFormPage(BackofficeFormPage): if not self.formdef.is_of_concern_for_user(api_user): raise AccessForbiddenError() + def _q_lookup(self, component): + try: + formdata = self.formdef.data_class().get(component) + except KeyError: + raise TraversalError() + return ApiFormdataPage(self.formdef, formdata) + class ApiFormsDirectory(Directory): def _q_lookup(self, component):