From 3fbb0ec4d10b695581b26d332bbd1271b97e1b5c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Tue, 15 Nov 2022 11:07:25 +0100
Subject: [PATCH 1/3] api: use formdata user on formdata.get_json_export_dict
 (#71303)

and not user calling the api
---
 tests/api/test_carddata.py | 71 ++++++++++++++++++++++++++++++++++++++
 wcs/formdata.py            | 25 ++++++++------
 2 files changed, 85 insertions(+), 11 deletions(-)

diff --git a/tests/api/test_carddata.py b/tests/api/test_carddata.py
index ca9dee50e..c0d0ac9b6 100644
--- a/tests/api/test_carddata.py
+++ b/tests/api/test_carddata.py
@@ -94,6 +94,77 @@ def test_carddata_api_access(pub, local_user):
     )
 
 
+@pytest.mark.parametrize('auth', ['signature', 'http-basic', 'api-admin-user'])
+def test_carddata_include_params(pub, local_user, auth):
+    # signature: SqlUser
+    # http-basic: RestrictedApiUser
+    # api-admin-user: ApiAdminUser
+    pub.role_class.wipe()
+    role = pub.role_class(name='test')
+    role.id = '123'
+    role.store()
+    local_user.roles = [role.id]
+    local_user.store()
+
+    CardDef.wipe()
+    carddef = CardDef()
+    carddef.name = 'test'
+    carddef.workflow_roles = {'_viewer': role.id}
+    carddef.fields = [
+        fields.StringField(id='1', label='foobar', varname='foobar'),
+    ]
+    carddef.store()
+
+    carddef.data_class().wipe()
+    carddata = carddef.data_class()()
+    carddata.data = {'1': 'FOO BAR'}
+    carddata.user_id = local_user.id
+    carddata.just_created()
+    carddata.store()
+
+    ApiAccess.wipe()
+    access = ApiAccess()
+    access.name = 'test'
+    access.access_identifier = 'test'
+    access.access_key = '12345'
+    access.store()
+
+    app = get_app(pub)
+
+    if auth == 'http-basic':
+        # there's not "defaults to admin" permissions in case of basic authentication.
+        access.roles = [role]
+        access.store()
+
+        def get_url(url, **kwargs):
+            app.set_authorization(('Basic', ('test', '12345')))
+            return app.get(url, **kwargs)
+
+    else:
+
+        def get_url(url, **kwargs):
+            return app.get(
+                sign_uri(
+                    url,
+                    user=local_user if auth == 'signature' else None,
+                    orig=access.access_identifier,
+                    key=access.access_key,
+                ),
+                **kwargs,
+            )
+
+    resp = get_url('/api/cards/test/list?include-fields=on')
+    assert 'fields' in resp.json['data'][0]
+    resp = get_url('/api/cards/test/list?include-evolution=on')
+    assert 'evolution' in resp.json['data'][0]
+    resp = get_url('/api/cards/test/list?include-roles=on')
+    assert 'roles' in resp.json['data'][0]
+    resp = get_url('/api/cards/test/list?include-submission=on')
+    assert 'submission' in resp.json['data'][0]
+    resp = get_url('/api/cards/test/list?include-workflow=on')
+    assert 'workflow' in resp.json['data'][0]
+
+
 def test_carddata_user_fields(pub, local_user):
     pub.role_class.wipe()
     role = pub.role_class(name='test')
diff --git a/wcs/formdata.py b/wcs/formdata.py
index 66a891f15..610541abe 100644
--- a/wcs/formdata.py
+++ b/wcs/formdata.py
@@ -1373,22 +1373,25 @@ class FormData(StorableObject):
         data['receipt_time'] = datetime.datetime(*self.receipt_time[:6])
         data['last_update_time'] = datetime.datetime(*self.last_update_time[:6])
 
+        formdata_user = None
+        if include_fields or include_workflow or include_evolution:
+            try:
+                if prefetched_users is not None:
+                    formdata_user = prefetched_users.get(str(self.user_id))
+                else:
+                    formdata_user = get_publisher().user_class.get(self.user_id)
+            except KeyError:
+                pass
+
         if include_fields:
             data['criticality_level'] = self.criticality_level
             data['api_url'] = self.get_api_url()
             data['backoffice_url'] = self.get_backoffice_url()
 
-            try:
-                if prefetched_users is not None:
-                    user = prefetched_users.get(str(self.user_id))
-                else:
-                    user = get_publisher().user_class.get(self.user_id)
-            except KeyError:
-                user = None
-            if not anonymise and user:
+            if not anonymise and formdata_user:
                 from .carddef import CardDef
 
-                data['user'] = user.get_json_export_dict(full=isinstance(self.formdef, CardDef))
+                data['user'] = formdata_user.get_json_export_dict(full=isinstance(self.formdef, CardDef))
 
             data['fields'] = self.get_json_dict(
                 self.formdef.fields,
@@ -1399,7 +1402,7 @@ class FormData(StorableObject):
 
         if include_workflow:
             data['workflow'] = {}
-            wf_status = self.get_visible_status(user)
+            wf_status = self.get_visible_status(formdata_user)
             if wf_status:
                 data['workflow']['status'] = {'id': wf_status.id, 'name': wf_status.name}
             wf_real_status = self.get_status()
@@ -1472,7 +1475,7 @@ class FormData(StorableObject):
             for evo in self.evolution:
                 evolution.append(
                     evo.get_json_export_dict(
-                        user=None if anonymise else user,
+                        user=None if anonymise else formdata_user,
                         anonymise=anonymise,
                         include_files=include_files,
                     )
-- 
2.35.1

