def __check_perms_for_each(user: DCFAbstractUser, queryset: QuerySet, *,
                            field_name: str, perms: str) -> None:
     """For each object in the queryset, check whether the user has write
     permission on the field."""
     has_perm = p.filter_queryset_by_perms_shortcut(perms, user, queryset,
                                                    field_name)
     no_perm = queryset.difference(has_perm).first()
     if no_perm:
         raise APIPermissionDenied(no_perm, perms, field_name)
Example #2
0
 def test_recipients(self):
     login = self.client.login(username='******',
                               password='******')
     resp = self.client.get(
         reverse('tcsystem:order-detail', kwargs={'pk': self.order_1.pk}))
     self.assertEqual(resp.status_code, 200)
     self.assertTrue('is_recipient' in resp.context)
     self.assertTrue(resp.context['is_recipient'])
     self.assertTrue('recipient_list' in resp.context)
     qs = QuerySet.difference(resp.context['recipient_list'],
                              self.order_1.userorder_set.all())
     self.assertTrue(qs.count() == 0)
    def check_3way_permissions(
        cls,
        user: DCFAbstractUser,
        model_object: Model,
        field_name: str,
        new_vals: QuerySet,
        perms: str,
    ) -> None:
        """Check user's permission on three things:

        1. The object's field (field_name)
        2. Each old related object (field on the reverse side)
        3. Each new related object (field on the reverse side)
        """

        field = cls._get_field(model_object._meta.model, field_name)
        assert isinstance(
            field,
            (
                ManyToManyRel,
                ManyToManyField,
                ManyToOneRel,
                ForeignKey,
            ),
        )

        if not p.has_perms_shortcut(
                user,
                model_object,
                perms,
                field_name=field_name,
        ):
            raise APIPermissionDenied(model_object, perms, field=field_name)

        old_vals = cls._get_field_as_queryset(model_object, field_name)
        diff_remove = old_vals.difference(new_vals)
        diff_add = new_vals.difference(old_vals)
        # Django doesn't support calling .filter() after .union() and
        # .difference()
        symmetric_diff_pks = diff_add.union(diff_remove).values_list("pk")
        diff_queryset: QuerySet = QuerySet(model=field.related_model).filter(
            pk__in=symmetric_diff_pks)

        cls.__check_perms_for_each(
            user,
            diff_queryset,
            field_name=field.remote_field.name,
            perms=perms,
        )