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)
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, )