From 0fb795e9dbfe3b313e9faa924f5acecfc5872681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Wed, 25 May 2016 09:32:03 +0200 Subject: [PATCH] api: respect only_allow_one in form submit API (#10580) --- tests/test_api.py | 34 ++++++++++++++++++++++++++++++++++ wcs/api.py | 6 ++++++ 2 files changed, 40 insertions(+) diff --git a/tests/test_api.py b/tests/test_api.py index 8ea17b2..0f28c64 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -438,6 +438,40 @@ def test_formdef_submit(pub, local_user): data_class.wipe() +def test_formdef_submit_only_one(pub, local_user): + Role.wipe() + role = Role(name='test') + role.store() + local_user.roles = [role.id] + local_user.store() + + FormDef.wipe() + formdef = FormDef() + formdef.name = 'test' + formdef.only_allow_one = True + formdef.fields = [fields.StringField(id='0', label='foobar')] + formdef.store() + data_class = formdef.data_class() + + signed_url = sign_url('http://example.net/api/formdefs/test/submit' + + '?format=json&orig=coucou&email=%s' % urllib.quote(local_user.email), '1234') + url = signed_url[len('http://example.net'):] + resp = get_app(pub).post_json(url, {'data': {}}) + assert data_class.get(resp.json['data']['id']).user_id == str(local_user.id) + + assert data_class.count() == 1 + + resp = get_app(pub).post_json(url, {'data': {}}, status=403) + assert resp.json['err'] == 1 + assert resp.json['err_desc'] == 'only one formdata by user is allowed' + + formdata = data_class.select()[0] + formdata.user_id = '1000' # change owner + formdata.store() + + resp = get_app(pub).post_json(url, {'data': {}}, status=200) + assert data_class.get(resp.json['data']['id']).user_id == str(local_user.id) + assert data_class.count() == 2 def test_formdef_submit_with_varname(pub, local_user): NamedDataSource.wipe() diff --git a/wcs/api.py b/wcs/api.py index 7fee087..8948c97 100644 --- a/wcs/api.py +++ b/wcs/api.py @@ -219,6 +219,12 @@ class ApiFormdefDirectory(Directory): formdata.submission_channel = formdata.submission_context.pop('channel', None) formdata.user_id = formdata.submission_context.pop('user_id', None) + if self.formdef.only_allow_one and formdata.user_id: + user_id = formdata.user_id + user_forms = self.formdef.data_class().get_with_indexed_value('user_id', user_id) + if user_forms: + raise AccessForbiddenError('only one formdata by user is allowed') + if meta.get('backoffice-submission'): # keep track of the agent that did the submit if not formdata.submission_context: -- 2.8.1