Projet

Général

Profil

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

Lauréline Guérin, 09 août 2022 15:33

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
1007 1007

  
1008 1008
        populate_cache()
1009 1009

  
1010
    def is_visible(self, request, **kwargs):
1011
        user = getattr(request, 'user', None)
1012
        if self.only_for_user and (not user or user.is_anonymous):
1013
            return False
1014
        return super().is_visible(request, **kwargs)
1015

  
1010 1016
    def check_validity(self):
1011 1017
        if self.related_card_path:
1012 1018
            relations = [r[0] for r in self.get_related_card_paths()]
......
1028 1034
    def get_repeat_template(self, context):
1029 1035
        return len(context.get(self.global_context_key) or [])
1030 1036

  
1031
    def get_card_data_from_ids(self, card_id, context):
1032
        card_ids = context.get(self.global_context_key)
1033
        if not card_ids:
1034
            return None
1035

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

  
1068 1071
        if response.status_code == 200:
1069
            data = response.json()
1070
            for card_data in data.get('data') or []:
1071
                if str(card_data.get('id')) == str(card_id):
1072
                    return card_data
1072
            return response.json().get('data') or []
1073
        return []
1074

  
1075
    def filter_card_ids(self, card_ids, context):
1076
        # check that all ids in context are available for user
1077
        cards = self.get_cards_from_ids(card_ids, context, synchronous=True)
1078
        return [c['id'] for c in cards if str(c['id']) in [str(i) for i in card_ids]]
1079

  
1080
    def get_card_data_from_ids(self, card_id, context):
1081
        # get the correct card from all known cards for ids in context
1082
        card_ids = context.get(self.global_context_key)
1083
        if not card_ids:
1084
            return None
1085
        cards = self.get_cards_from_ids(card_ids, context)
1086
        for card_data in cards:
1087
            if str(card_data.get('id')) == str(card_id):
1088
                return card_data
1073 1089
        return None
1074 1090

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

  
1109 1121
        if response.status_code == 200:
......
1259 1271
                return []
1260 1272
            # and data
1261 1273
            next_card_data = self.get_card_data(
1262
                card_slug, None, card_data['fields']['%s_raw' % varname], context, synchronous=True
1274
                card_slug=card_slug,
1275
                card_custom_view=None,
1276
                card_id=card_data['fields']['%s_raw' % varname],
1277
                only_for_user=False,
1278
                without_user=False,
1279
                context=context,
1280
                synchronous=True,
1263 1281
            )
1264 1282
            if not next_card_data:
1265 1283
                # card data not found
......
1289 1307
            # no card id found
1290 1308
            return []
1291 1309
        card_data = self.get_card_data(
1292
            first_cell.card_slug, first_cell.card_custom_view, card_id, context, synchronous=True
1310
            card_slug=first_cell.card_slug,
1311
            card_custom_view=first_cell.card_custom_view,
1312
            card_id=card_id,
1313
            only_for_user=first_cell.only_for_user,
1314
            without_user=first_cell.without_user,
1315
            context=context,
1316
            synchronous=True,
1293 1317
        )
1294 1318
        if not card_data:
1295 1319
            # card data not found
......
1318 1342

  
1319 1343
        if self.related_card_path:
1320 1344
            # look at other cells to get related ids
1321
            return self.get_card_ids_from_related(original_context, request)
1345
            card_ids = self.get_card_ids_from_related(original_context, request)
1346
            if card_ids == []:
1347
                return []
1348
            elif card_ids:
1349
                # check that ids from related are available for user
1350
                # (use only_for_user and without_user flags)
1351
                return self.filter_card_ids(card_ids, original_context)
1322 1352

  
1323 1353
        if self.card_ids:
1324 1354
            # card ids template is defined
tests/test_wcs.py
3437 3437
            # get first cell data
3438 3438
            '/api/cards/card_a/1/',
3439 3439
            # and follow cardb relation
3440
            ('/api/cards/card_b/list', '&filter-internal-id=1&'),
3440
            ('/api/cards/card_b/list', '&filter-internal-id=1&'),  # check user access
3441
            ('/api/cards/card_b/list', '&filter-internal-id=1&'),  # get card
3441 3442
        ]
3442 3443
    )
3443 3444
    cell3.delete()  # reset
......
3453 3454
            # follow cardc relation
3454 3455
            '/api/cards/card_c/6/',
3455 3456
            # and follow cardb relation
3456
            ('/api/cards/card_b/list', '&filter-internal-id=7&'),
3457
            ('/api/cards/card_b/list', '&filter-internal-id=7&'),  # check user access
3458
            ('/api/cards/card_b/list', '&filter-internal-id=7&'),  # get card
3457 3459
        ]
3458 3460
    )
3459 3461

  
......
3473 3475
        # follow cardc relation
3474 3476
        '/api/cards/card_c/6/',
3475 3477
        # and follow cardb relation
3476
        ('/api/cards/card_b/list', '&filter-internal-id=7&'),
3478
        ('/api/cards/card_b/list', '&filter-internal-id=7&'),  # check user access
3479
        ('/api/cards/card_b/list', '&filter-internal-id=7&'),  # get card
3477 3480
    ]
3478 3481
    resp = app.get(page.get_online_url())
3479 3482
    assert len(resp.context['cells']) == 2
......
3509 3512
            # follow cardc relation
3510 3513
            '/api/cards/card_c/6/',
3511 3514
            # and follow cardb relation
3512
            ('/api/cards/card_b/list/a-custom-view', '&filter-internal-id=7&'),
3515
            ('/api/cards/card_b/list/a-custom-view', '&filter-internal-id=7&'),  # check user access
3516
            ('/api/cards/card_b/list/a-custom-view', '&filter-internal-id=7&'),  # get card
3513 3517
        ]
3514 3518
    )
3515 3519

  
......
3522 3526
            # get first cell data
3523 3527
            '/api/cards/card_a/1/',
3524 3528
            # and follow cardb relation
3525
            ('/api/cards/card_b/list', '&filter-internal-id=2&filter-internal-id=3&'),
3529
            ('/api/cards/card_b/list', '&filter-internal-id=2&filter-internal-id=3&'),  # check user access
3530
            ('/api/cards/card_b/list', '&filter-internal-id=2&filter-internal-id=3&'),  # get card
3526 3531
        ]
3527 3532
    )
3528 3533

  
......
3537 3542
            # follow cardc relation
3538 3543
            '/api/cards/card_c/6/',
3539 3544
            # and follow cardb relation
3540
            ('/api/cards/card_b/list', '&filter-internal-id=8&filter-internal-id=9&'),
3545
            ('/api/cards/card_b/list', '&filter-internal-id=8&filter-internal-id=9&'),  # check user access
3546
            ('/api/cards/card_b/list', '&filter-internal-id=8&filter-internal-id=9&'),  # get card
3541 3547
        ]
3542 3548
    )
3543 3549

  
......
3549 3555
            # get first cell data
3550 3556
            '/api/cards/card_a/1/',
3551 3557
            # and follow cardb relation
3552
            ('/api/cards/card_b/list', '&filter-internal-id=4&filter-internal-id=5&'),
3558
            ('/api/cards/card_b/list', '&filter-internal-id=4&filter-internal-id=5&'),  # check user access
3559
            ('/api/cards/card_b/list', '&filter-internal-id=4&filter-internal-id=5&'),  # get card
3553 3560
        ]
3554 3561
    )
3555 3562

  
......
3564 3571
            # follow cardc relation
3565 3572
            '/api/cards/card_c/6/',
3566 3573
            # and follow cardb relation
3567
            ('/api/cards/card_b/list', '&filter-internal-id=10&filter-internal-id=11&'),
3574
            ('/api/cards/card_b/list', '&filter-internal-id=10&filter-internal-id=11&'),  # check user access
3575
            ('/api/cards/card_b/list', '&filter-internal-id=10&filter-internal-id=11&'),  # get card
3568 3576
        ]
3569 3577
    )
3570 3578

  
......
3726 3734
            # get list of card_a with cardb=1
3727 3735
            '/api/cards/card_a/list?orig=combo&filter-cardb=1',
3728 3736
            # and follow carda reverse relation
3737
            # check user access
3738
            (
3739
                '/api/cards/card_a/list',
3740
                '&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&',
3741
            ),
3742
            # get card
3729 3743
            (
3730 3744
                '/api/cards/card_a/list',
3731 3745
                '&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&',
......
3743 3757
            # get list of card_a with cardsb=1
3744 3758
            '/api/cards/card_a/list?orig=combo&filter-cardsb=1',
3745 3759
            # and follow carda reverse relation
3760
            # check user access
3761
            (
3762
                '/api/cards/card_a/list',
3763
                '&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&',
3764
            ),
3765
            # get card
3746 3766
            (
3747 3767
                '/api/cards/card_a/list',
3748 3768
                '&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&',
......
3760 3780
            # get list of card_a with cardsb=1
3761 3781
            '/api/cards/card_a/list?orig=combo&filter-blockb_cardb=1',
3762 3782
            # and follow carda reverse relation
3783
            # check user access
3784
            (
3785
                '/api/cards/card_a/list',
3786
                '&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&',
3787
            ),
3788
            # get card
3763 3789
            (
3764 3790
                '/api/cards/card_a/list',
3765 3791
                '&filter-internal-id=1&filter-internal-id=2&filter-internal-id=3&filter-internal-id=4&',
......
3805 3831
            # get list of card_f with cardf=42
3806 3832
            '/api/cards/card_f/list?orig=combo&filter-cardh=42',
3807 3833
            # and follow cardf reverse relation
3808
            ('/api/cards/card_f/list', '&filter-internal-id=41&'),
3834
            ('/api/cards/card_f/list', '&filter-internal-id=41&'),  # check user access
3835
            ('/api/cards/card_f/list', '&filter-internal-id=41&'),  # get card
3809 3836
        ]
3810 3837
    )
3811 3838

  
......
3824 3851
            # get list of card_g with cardf=44
3825 3852
            '/api/cards/card_g/list?orig=combo&filter-cardh=44',
3826 3853
            # and follow cardf reverse relation
3827
            ('/api/cards/card_g/list', '&filter-internal-id=43&'),
3854
            ('/api/cards/card_g/list', '&filter-internal-id=43&'),  # check user access
3855
            ('/api/cards/card_g/list', '&filter-internal-id=43&'),  # get card
3828 3856
        ]
3829 3857
    )
3830 3858

  
3831 3859

  
3860
@pytest.mark.parametrize('carddef_reference', ['default:card_model_1', 'default:card_model_1:foo'])
3861
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
3862
def test_card_cell_only_for_user(mock_send, context, carddef_reference):
3863
    page = Page.objects.create(title='xxx', template_name='standard')
3864
    cell = WcsCardInfosCell(page=page, placeholder='content', order=0)
3865
    cell.carddef_reference = carddef_reference
3866
    cell.only_for_user = False
3867
    cell.save()
3868

  
3869
    context['card_model_1_id'] = 11
3870
    request = RequestFactory().get('/')
3871
    cell.modify_global_context(context, request)
3872
    cell.repeat_index = 0
3873

  
3874
    assert cell.is_visible(request=context['request']) is True
3875
    context['request'].user = MockUserWithNameId()
3876
    assert cell.is_visible(request=context['request']) is True
3877

  
3878
    cell.only_for_user = True
3879
    cell.save()
3880
    context['request'].user = None
3881
    assert cell.is_visible(request=context['request']) is False
3882
    context['request'].user = MockUserWithNameId()
3883
    assert cell.is_visible(request=context['request']) is True
3884

  
3885
    cache.clear()
3886
    context['synchronous'] = True  # to get fresh content
3887
    context['request'].user = None
3888

  
3889
    mock_send.reset_mock()
3890
    cell.render(context)
3891
    assert 'filter-user-uuid' not in mock_send.call_args_list[0][0][0].url
3892

  
3893
    context['request'].user = MockUser()
3894
    mock_send.reset_mock()
3895
    cell.render(context)
3896
    assert 'filter-user-uuid' not in mock_send.call_args_list[0][0][0].url
3897

  
3898
    context['request'].user = MockUserWithNameId()
3899
    mock_send.reset_mock()
3900
    cell.render(context)
3901
    assert 'filter-user-uuid=xyz' in mock_send.call_args_list[0][0][0].url
3902

  
3903

  
3832 3904
@pytest.mark.parametrize('carddef_reference', ['default:card_model_1', 'default:card_model_1:foo'])
3833 3905
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
3834 3906
def test_card_cell_render_user(mock_send, context, nocache, carddef_reference):
3835
-