Core: Errors when fetching resources related to the current user

Created on 6 Nov 2017  路  6Comments  路  Source: api-platform/core

Hi,

I want to fetch books related to the current user according to this documentation: https://api-platform.com/docs/core/security

Unfortunately, I have an issue.

I have a Book entity where I have $user property and a getter. The resource file looks like that ( I use yaml):

App\Entity\Book:
    attributes:
        normalization_context:
            groups: ['read']
        denormalization_context:
            groups: ['write']
    collectionOperations:
        get:
            method: 'GET'
            access_control: "is_granted('ROLE_USER') and object.getUser() == user"

When I want to fetch books I get an error:

Unable to call method "getUser" of object "ApiPlatform\Core\Bridge\Doctrine\Orm\Paginator"

When I use access_control: "is_granted('ROLE_USER')" it works fine tho, so the file is being read properly.

Any idea what I did wrong and why this Paginator class is being called?

Thanks!

Most helpful comment

Item GET operation is only related to the /items/{id} endpoint, if you need to restrict which books are returned for user see API Platform - Filter upon the current user.

All 6 comments

yes because object is a collection of items (ie an array/Paginator). You may want to do this on an item or you'd have to loop on the collection.

thanks @soyuka for your reply.

I tried:

    itemOperations:
        get:
            method: 'GET'
            access_control: "is_granted('ROLE_USER') and object.getUser() == user"

it doesn't throw an exception now, but all books are returned, even those related to other user.
It looks like itemOperations is not called at all. My user has role ROLE_USER when I change is_granted('ROLE_USER') to is_granted('ROLE_ADMIN') it still shows all books.

Any idea?

Item GET operation is only related to the /items/{id} endpoint, if you need to restrict which books are returned for user see API Platform - Filter upon the current user.

Doesn't work like this according to what you're saying you're still retrieving the collection (ie GET /books) and not an item.
I don't see a way to loop over a collection in the access_control (https://symfony.com/doc/current/security/expressions.html#security-expression-variables). Therefore, I'd advise you to use some other way to make sure the item does belong to the user.

@dunglas not sure but maybe we should loop over the collection in case the object is a \Traversable here?

Thanks @norkunas ! Works like a charm 馃憤 This is what I needed.

@soyuka I dont think so, @norkunas is right the filtering for collection must be done on the SQL side, or the pagination (and many other things) will be wrong.

Was this page helpful?
0 / 5 - 0 ratings