Projet

Général

Profil

0001-api-filter-user-forms-when-requested-by-another-user.patch

Frédéric Péters, 08 décembre 2018 14:11

Télécharger (5,61 ko)

Voir les différences:

Subject: [PATCH] api: filter user forms when requested by another user
 (#28732)

 tests/test_api.py | 52 +++++++++++++++++++++++++++++++++++++++++++++++
 wcs/api.py        | 32 +++++++++++++++++++++++++----
 wcs/sql.py        |  1 +
 3 files changed, 81 insertions(+), 4 deletions(-)
tests/test_api.py
1321 1321
    draft_formdata = [x for x in resp.json['data'] if x['status'] == 'Draft'][0]
1322 1322
    assert draft_formdata.get('url')[-1] != '/'
1323 1323

  
1324
def test_user_forms_from_agent(pub, local_user):
1325
    Role.wipe()
1326
    role = Role(name='Foo bar')
1327
    role.store()
1328

  
1329
    agent_user = get_publisher().user_class()
1330
    agent_user.name = 'Agent'
1331
    agent_user.email = 'agent@example.com'
1332
    agent_user.name_identifiers = ['ABCDE']
1333
    agent_user.roles = [role.id]
1334
    agent_user.store()
1335

  
1336
    FormDef.wipe()
1337
    formdef = FormDef()
1338
    formdef.name = 'test'
1339
    formdef.fields = [
1340
        fields.StringField(id='0', label='foobar', varname='foobar'),
1341
        fields.StringField(id='1', label='foobar2'),]
1342
    formdef.store()
1343
    formdef.data_class().wipe()
1344

  
1345
    formdata = formdef.data_class()()
1346
    formdata.data = {'0': 'foo@localhost', '1': 'xxx'}
1347
    formdata.user_id = local_user.id
1348
    formdata.just_created()
1349
    formdata.jump_status('new')
1350
    formdata.store()
1351

  
1352
    resp = get_app(pub).get(sign_uri('/api/users/%s/forms' % local_user.id, user=agent_user))
1353
    assert resp.json['err'] == 0
1354
    assert len(resp.json['data']) == 1
1355
    assert resp.json['data'][0]['form_name'] == 'test'
1356
    assert resp.json['data'][0]['form_slug'] == 'test'
1357
    assert resp.json['data'][0]['form_status'] == 'New'
1358
    assert resp.json['data'][0]['readable'] is False
1359

  
1360
    formdef.skip_from_360_view = True
1361
    formdef.store()
1362

  
1363
    resp = get_app(pub).get(sign_uri('/api/users/%s/forms' % local_user.id, user=agent_user))
1364
    assert len(resp.json['data']) == 0
1365

  
1366
    formdef.workflow_roles = {'_receiver': str(role.id)}
1367
    formdef.store()
1368
    formdef.data_class().rebuild_security()
1369
    resp = get_app(pub).get(sign_uri('/api/users/%s/forms' % local_user.id, user=agent_user))
1370
    assert len(resp.json['data']) == 1
1371

  
1372
    agent_user.roles = []
1373
    agent_user.store()
1374
    get_app(pub).get(sign_uri('/api/users/%s/forms' % local_user.id, user=agent_user), status=403)
1375

  
1324 1376
def test_user_drafts(pub, local_user):
1325 1377
    FormDef.wipe()
1326 1378
    formdef = FormDef()
wcs/api.py
613 613
            return json.dumps({'err': 1, 'err_desc': 'unknown NameID', 'data': []})
614 614
        if not user:
615 615
            return json.dumps({'err': 1, 'err_desc': 'no user specified', 'data': []})
616
        forms = []
616

  
617
        forms = self.get_user_forms(user)
618

  
619
        if self.user:
620
            query_user = get_user_from_api_query_string() or get_request().user
621
            if query_user and query_user.id != self.user.id:
622
                if not query_user.can_go_in_backoffice():
623
                    raise AccessForbiddenError('user not allowed to query data from others')
624
                # mark forms that are readable by querying user
625
                user_roles = set(query_user.roles or [])
626
                if get_publisher().is_using_postgresql():
627
                    # use concerned_roles_array attribute that was saved in the
628
                    # table.
629
                    for form in forms:
630
                        form.readable = bool(set(form.concerned_roles_array).intersection(user_roles))
631
                else:
632
                    # recomputed concerned roles.
633
                    for form in forms:
634
                        concerned_roles_array = [str(x) for x in form.concerned_roles if x]
635
                        form.readable = bool(set(concerned_roles_array).intersection(user_roles))
636
                # ignore confidential forms
637
                forms = [x for x in forms if x.readable or not x.formdef.skip_from_360_view]
638

  
617 639
        include_drafts = include_drafts or get_request().form.get('include-drafts') == 'true'
618
        for form in self.get_user_forms(user):
640
        result = []
641
        for form in forms:
619 642
            if form.is_draft():
620 643
                if not include_drafts:
621 644
                    continue
......
628 651
            if not formdata_dict:
629 652
                # skip hidden forms
630 653
                continue
631
            forms.append(formdata_dict)
654
            formdata_dict['readable'] = getattr(form, 'readable', True)
655
            result.append(formdata_dict)
632 656

  
633
        return json.dumps({'err': 0, 'data': forms},
657
        return json.dumps({'err': 0, 'data': result},
634 658
                cls=misc.JSONEncoder,
635 659
                encoding=get_publisher().site_charset)
636 660

  
wcs/sql.py
1960 1960
        cls.__table_static_fields.append(('criticality_level', 'criticality_level'))
1961 1961
        cls.__table_static_fields.append(('geoloc_base_x', 'geoloc_base_x'))
1962 1962
        cls.__table_static_fields.append(('geoloc_base_y', 'geoloc_base_y'))
1963
        cls.__table_static_fields.append(('concerned_roles_array', 'concerned_roles_array'))
1963 1964
        return cls.__table_static_fields
1964 1965

  
1965 1966
    @classmethod
1966
-