Projet

Général

Profil

0002-wcs-use-only_for_user-without_user-flags-68037.patch

Lauréline Guérin, 29 août 2022 14:35

Télécharger (17,5 ko)

Voir les différences:

Subject: [PATCH 2/5] wcs: use only_for_user & without_user flags (#68037)

 combo/apps/wcs/forms.py  |  1 +
 combo/apps/wcs/models.py | 92 ++++++++++++++++++++++++++--------------
 tests/test_wcs.py        | 92 +++++++++++++++++++++++++++++++++++-----
 3 files changed, 144 insertions(+), 41 deletions(-)
combo/apps/wcs/forms.py
86 86
            'carddef_reference',
87 87
            'related_card_path',
88 88
            'card_ids',
89
            'only_for_user',
89 90
            'custom_schema',
90 91
        )
91 92
        widgets = {
combo/apps/wcs/models.py
1012 1012

  
1013 1013
        populate_cache()
1014 1014

  
1015
    def is_visible(self, request, **kwargs):
1016
        user = getattr(request, 'user', None)
1017
        if self.only_for_user and (not user or user.is_anonymous):
1018
            return False
1019
        return super().is_visible(request, **kwargs)
1020

  
1015 1021
    def check_validity(self):
1016 1022
        if self.related_card_path:
1017 1023
            relations = [r[0] for r in self.get_related_card_paths()]
......
1033 1039
    def get_repeat_template(self, context):
1034 1040
        return len(context.get(self.global_context_key) or [])
1035 1041

  
1036
    def get_card_data_from_ids(self, card_id, context):
1037
        card_ids = context.get(self.global_context_key)
1038
        if not card_ids:
1039
            return None
1040

  
1042
    def get_cards_from_ids(self, card_ids, context, synchronous=False):
1043
        # if check_user, get all cards from ids in context, with correct filter-user-uuid and without_user value
1044
        # use custom view if requested
1041 1045
        api_url = '/api/cards/%s/list?full=on' % (self.card_slug)
1042 1046
        if self.card_custom_view:
1043 1047
            api_url = '/api/cards/%s/list/%s?full=on' % (
1044 1048
                self.card_slug,
1045 1049
                self.card_custom_view,
1046 1050
            )
1047
            user = self.get_concerned_user(context)
1048
            if user and not user.is_anonymous:
1049
                user_name_id = user.get_name_id()
1050
                if user_name_id:
1051
                    api_url += '&filter-user-uuid=%s' % user_name_id
1051
        user = self.get_concerned_user(context)
1052
        if self.only_for_user and user and not user.is_anonymous and user.get_name_id():
1053
            api_url += '&filter-user-uuid=%s' % user.get_name_id()
1052 1054
        api_url += '&%s' % '&'.join(['filter-internal-id=%s' % cid for cid in card_ids])
1053
        synchronous = bool(context.get('synchronous'))
1055
        if not synchronous:
1056
            synchronous = bool(context.get('synchronous'))
1054 1057
        wcs_site = get_wcs_services().get(self.wcs_site)
1055 1058
        try:
1056 1059
            response = requests.get(
......
1068 1071
                # if there's a custom view consider the error is a 404 because
1069 1072
                # the card was not found in that view, and mark it so.
1070 1073
                context['card_not_found'] = True
1071
            return None
1074
            return []
1072 1075

  
1073 1076
        if response.status_code == 200:
1074
            data = response.json()
1075
            for card_data in data.get('data') or []:
1076
                if str(card_data.get('id')) == str(card_id):
1077
                    return card_data
1077
            return response.json().get('data') or []
1078
        return []
1079

  
1080
    def filter_card_ids(self, card_ids, context):
1081
        # check that all ids in context are available for user
1082
        cards = self.get_cards_from_ids(card_ids, context, synchronous=True)
1083
        return [c['id'] for c in cards if str(c['id']) in [str(i) for i in card_ids]]
1084

  
1085
    def get_card_data_from_ids(self, card_id, context):
1086
        # get the correct card from all known cards for ids in context
1087
        card_ids = context.get(self.global_context_key)
1088
        if not card_ids:
1089
            return None
1090
        cards = self.get_cards_from_ids(card_ids, context)
1091
        for card_data in cards:
1092
            if str(card_data.get('id')) == str(card_id):
1093
                return card_data
1078 1094
        return None
1079 1095

  
1080
    def get_card_data(self, card_slug, card_custom_view, card_id, context, synchronous=False):
1096
    def get_card_data(
1097
        self, card_slug, card_custom_view, card_id, only_for_user, without_user, context, synchronous=False
1098
    ):
1081 1099
        api_url = '/api/cards/%s/%s/?include-files-content=off' % (card_slug, card_id)
1082 1100
        if card_custom_view:
1083 1101
            api_url = '/api/cards/%s/%s/%s/?include-files-content=off' % (
......
1085 1103
                card_custom_view,
1086 1104
                card_id,
1087 1105
            )
1088
            user = self.get_concerned_user(context)
1089
            if user and not user.is_anonymous:
1090
                user_name_id = user.get_name_id()
1091
                if user_name_id:
1092
                    api_url += '&filter-user-uuid=%s' % user_name_id
1106
        user = self.get_concerned_user(context)
1107
        if only_for_user and user and not user.is_anonymous and user.get_name_id():
1108
            api_url += '&filter-user-uuid=%s' % user.get_name_id()
1093 1109
        if not synchronous:
1094 1110
            synchronous = bool(context.get('synchronous'))
1095 1111
        wcs_site = get_wcs_services().get(self.wcs_site)
......
1097 1113
            response = requests.get(
1098 1114
                api_url,
1099 1115
                remote_service=wcs_site,
1100
                user=None if self.without_user else getattr(context.get('request'), 'user', None),
1101
                without_user=self.without_user,
1116
                user=None if without_user else getattr(context.get('request'), 'user', None),
1117
                without_user=without_user,
1102 1118
                cache_duration=5,
1103 1119
                raise_if_not_cached=not synchronous,
1104 1120
                log_errors=False,
1105 1121
            )
1106 1122
            response.raise_for_status()
1107 1123
        except RequestException:
1108
            if self.card_custom_view:
1109
                # if there's a custom view consider the error is a 404 because
1110
                # the card was not found in that view, and mark it so.
1111
                context['card_not_found'] = True
1112 1124
            return {}
1113 1125

  
1114 1126
        if response.status_code == 200:
......
1264 1276
                return []
1265 1277
            # and data
1266 1278
            next_card_data = self.get_card_data(
1267
                card_slug, None, card_data['fields']['%s_raw' % varname], context, synchronous=True
1279
                card_slug=card_slug,
1280
                card_custom_view=None,
1281
                card_id=card_data['fields']['%s_raw' % varname],
1282
                only_for_user=False,
1283
                without_user=False,
1284
                context=context,
1285
                synchronous=True,
1268 1286
            )
1269 1287
            if not next_card_data:
1270 1288
                # card data not found
......
1294 1312
            # no card id found
1295 1313
            return []
1296 1314
        card_data = self.get_card_data(
1297
            first_cell.card_slug, first_cell.card_custom_view, card_id, context, synchronous=True
1315
            card_slug=first_cell.card_slug,
1316
            card_custom_view=first_cell.card_custom_view,
1317
            card_id=card_id,
1318
            only_for_user=first_cell.only_for_user,
1319
            without_user=first_cell.without_user,
1320
            context=context,
1321
            synchronous=True,
1298 1322
        )
1299 1323
        if not card_data:
1300 1324
            # card data not found
......
1323 1347

  
1324 1348
        if self.related_card_path:
1325 1349
            # look at other cells to get related ids
1326
            return self.get_card_ids_from_related(original_context, request)
1350
            card_ids = self.get_card_ids_from_related(original_context, request)
1351
            if card_ids == []:
1352
                return []
1353
            elif card_ids:
1354
                # check that ids from related are available for user
1355
                # (use only_for_user and without_user flags)
1356
                return self.filter_card_ids(card_ids, original_context)
1327 1357

  
1328 1358
        if self.card_ids:
1329 1359
            # card ids template is defined
tests/test_wcs.py
3474 3474
            # get first cell data
3475 3475
            '/api/cards/card_a/1/',
3476 3476
            # and follow cardb relation
3477
            ('/api/cards/card_b/list', '&filter-internal-id=1&'),
3477
            ('/api/cards/card_b/list', '&filter-internal-id=1&'),  # check user access
3478
            ('/api/cards/card_b/list', '&filter-internal-id=1&'),  # get card
3478 3479
        ]
3479 3480
    )
3480 3481
    cell3.delete()  # reset
......
3490 3491
            # follow cardc relation
3491 3492
            '/api/cards/card_c/6/',
3492 3493
            # and follow cardb relation
3493
            ('/api/cards/card_b/list', '&filter-internal-id=7&'),
3494
            ('/api/cards/card_b/list', '&filter-internal-id=7&'),  # check user access
3495
            ('/api/cards/card_b/list', '&filter-internal-id=7&'),  # get card
3494 3496
        ]
3495 3497
    )
3496 3498

  
......
3510 3512
        # follow cardc relation
3511 3513
        '/api/cards/card_c/6/',
3512 3514
        # and follow cardb relation
3513
        ('/api/cards/card_b/list', '&filter-internal-id=7&'),
3515
        ('/api/cards/card_b/list', '&filter-internal-id=7&'),  # check user access
3516
        ('/api/cards/card_b/list', '&filter-internal-id=7&'),  # get card
3514 3517
    ]
3515 3518
    resp = app.get(page.get_online_url())
3516 3519
    assert len(resp.context['cells']) == 2
......
3546 3549
            # follow cardc relation
3547 3550
            '/api/cards/card_c/6/',
3548 3551
            # and follow cardb relation
3549
            ('/api/cards/card_b/list/a-custom-view', '&filter-internal-id=7&'),
3552
            ('/api/cards/card_b/list/a-custom-view', '&filter-internal-id=7&'),  # check user access
3553
            ('/api/cards/card_b/list/a-custom-view', '&filter-internal-id=7&'),  # get card
3550 3554
        ]
3551 3555
    )
3552 3556

  
......
3559 3563
            # get first cell data
3560 3564
            '/api/cards/card_a/1/',
3561 3565
            # and follow cardb relation
3562
            ('/api/cards/card_b/list', '&filter-internal-id=2&filter-internal-id=3&'),
3566
            ('/api/cards/card_b/list', '&filter-internal-id=2&filter-internal-id=3&'),  # check user access
3567
            ('/api/cards/card_b/list', '&filter-internal-id=2&filter-internal-id=3&'),  # get card
3563 3568
        ]
3564 3569
    )
3565 3570

  
......
3574 3579
            # follow cardc relation
3575 3580
            '/api/cards/card_c/6/',
3576 3581
            # and follow cardb relation
3577
            ('/api/cards/card_b/list', '&filter-internal-id=8&filter-internal-id=9&'),
3582
            ('/api/cards/card_b/list', '&filter-internal-id=8&filter-internal-id=9&'),  # check user access
3583
            ('/api/cards/card_b/list', '&filter-internal-id=8&filter-internal-id=9&'),  # get card
3578 3584
        ]
3579 3585
    )
3580 3586

  
......
3586 3592
            # get first cell data
3587 3593
            '/api/cards/card_a/1/',
3588 3594
            # and follow cardb relation
3589
            ('/api/cards/card_b/list', '&filter-internal-id=4&filter-internal-id=5&'),
3595
            ('/api/cards/card_b/list', '&filter-internal-id=4&filter-internal-id=5&'),  # check user access
3596
            ('/api/cards/card_b/list', '&filter-internal-id=4&filter-internal-id=5&'),  # get card
3590 3597
        ]
3591 3598
    )
3592 3599

  
......
3601 3608
            # follow cardc relation
3602 3609
            '/api/cards/card_c/6/',
3603 3610
            # and follow cardb relation
3604
            ('/api/cards/card_b/list', '&filter-internal-id=10&filter-internal-id=11&'),
3611
            ('/api/cards/card_b/list', '&filter-internal-id=10&filter-internal-id=11&'),  # check user access
3612
            ('/api/cards/card_b/list', '&filter-internal-id=10&filter-internal-id=11&'),  # get card
3605 3613
        ]
3606 3614
    )
3607 3615

  
......
3763 3771
            # get list of card_a with cardb=1
3764 3772
            '/api/cards/card_a/list?orig=combo&filter-cardb=1',
3765 3773
            # and follow carda reverse relation
3774
            # check user access
3775
            (
3776
                '/api/cards/card_a/list',
3777
                '&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&',
3778
            ),
3779
            # get card
3766 3780
            (
3767 3781
                '/api/cards/card_a/list',
3768 3782
                '&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&',
......
3780 3794
            # get list of card_a with cardsb=1
3781 3795
            '/api/cards/card_a/list?orig=combo&filter-cardsb=1',
3782 3796
            # and follow carda reverse relation
3797
            # check user access
3798
            (
3799
                '/api/cards/card_a/list',
3800
                '&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&',
3801
            ),
3802
            # get card
3783 3803
            (
3784 3804
                '/api/cards/card_a/list',
3785 3805
                '&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&',
......
3797 3817
            # get list of card_a with cardsb=1
3798 3818
            '/api/cards/card_a/list?orig=combo&filter-blockb_cardb=1',
3799 3819
            # and follow carda reverse relation
3820
            # check user access
3821
            (
3822
                '/api/cards/card_a/list',
3823
                '&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&',
3824
            ),
3825
            # get card
3800 3826
            (
3801 3827
                '/api/cards/card_a/list',
3802 3828
                '&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&',
......
3842 3868
            # get list of card_f with cardf=42
3843 3869
            '/api/cards/card_f/list?orig=combo&filter-cardh=42',
3844 3870
            # and follow cardf reverse relation
3845
            ('/api/cards/card_f/list', '&filter-internal-id=41&'),
3871
            ('/api/cards/card_f/list', '&filter-internal-id=41&'),  # check user access
3872
            ('/api/cards/card_f/list', '&filter-internal-id=41&'),  # get card
3846 3873
        ]
3847 3874
    )
3848 3875

  
......
3861 3888
            # get list of card_g with cardf=44
3862 3889
            '/api/cards/card_g/list?orig=combo&filter-cardh=44',
3863 3890
            # and follow cardf reverse relation
3864
            ('/api/cards/card_g/list', '&filter-internal-id=43&'),
3891
            ('/api/cards/card_g/list', '&filter-internal-id=43&'),  # check user access
3892
            ('/api/cards/card_g/list', '&filter-internal-id=43&'),  # get card
3865 3893
        ]
3866 3894
    )
3867 3895

  
3868 3896

  
3897
@pytest.mark.parametrize('carddef_reference', ['default:card_model_1', 'default:card_model_1:foo'])
3898
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
3899
def test_card_cell_only_for_user(mock_send, context, carddef_reference):
3900
    page = Page.objects.create(title='xxx', template_name='standard')
3901
    cell = WcsCardInfosCell(page=page, placeholder='content', order=0)
3902
    cell.carddef_reference = carddef_reference
3903
    cell.only_for_user = False
3904
    cell.save()
3905

  
3906
    context['card_model_1_id'] = 11
3907
    request = RequestFactory().get('/')
3908
    cell.modify_global_context(context, request)
3909
    cell.repeat_index = 0
3910

  
3911
    assert cell.is_visible(request=context['request']) is True
3912
    context['request'].user = MockUserWithNameId()
3913
    assert cell.is_visible(request=context['request']) is True
3914

  
3915
    cell.only_for_user = True
3916
    cell.save()
3917
    context['request'].user = None
3918
    assert cell.is_visible(request=context['request']) is False
3919
    context['request'].user = MockUserWithNameId()
3920
    assert cell.is_visible(request=context['request']) is True
3921

  
3922
    cache.clear()
3923
    context['synchronous'] = True  # to get fresh content
3924
    context['request'].user = None
3925

  
3926
    mock_send.reset_mock()
3927
    cell.render(context)
3928
    assert 'filter-user-uuid' not in mock_send.call_args_list[0][0][0].url
3929

  
3930
    context['request'].user = MockUser()
3931
    mock_send.reset_mock()
3932
    cell.render(context)
3933
    assert 'filter-user-uuid' not in mock_send.call_args_list[0][0][0].url
3934

  
3935
    context['request'].user = MockUserWithNameId()
3936
    mock_send.reset_mock()
3937
    cell.render(context)
3938
    assert 'filter-user-uuid=xyz' in mock_send.call_args_list[0][0][0].url
3939

  
3940

  
3869 3941
@pytest.mark.parametrize('carddef_reference', ['default:card_model_1', 'default:card_model_1:foo'])
3870 3942
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
3871 3943
def test_card_cell_render_user(mock_send, context, nocache, carddef_reference):
3872
-