1
votes

I want check access_control from a subresource but it's not working.

My first entity has a OneToMany relationship with second.

src/Entity/Course.php

/**
 * @ApiResource(
 *     collectionOperations={
 *         "get"={"access_control"="object.userCompanyRoles.user == user"}
 *     }
 * )
 *
 * @ORM\Table(name="course")
 * @ORM\Entity(repositoryClass="App\Repository\CourseRepository")
 */
class Course
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\OneToMany(targetEntity="UserCompanyRole", mappedBy="course")
     * @ApiSubresource()
     */
    private $userCompanyRoles;
}

src/Entity/UserCompanyRole.php

/**
 * @ApiResource()
 * @ORM\Table(name="user_company_role")
 * @ORM\Entity(repositoryClass="App\Repository\UserCompanyRoleRepository")
 */
class UserCompanyRole
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Course", inversedBy="userCompanyRoles", cascade={"all"})
     */
    private $course;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="userCompanyRoles", cascade={"all"})
     * @ORM\JoinColumn(nullable=false)
     */
    private $user;
}

But when i send request I have this :

"hydra:description": "Notice: Undefined property: ApiPlatform\Core\Bridge\Doctrine\Orm\Paginator::$userCompanyRoles",

I can't simplify my relation because many User can have many roles on courses.

Does anyone have a suggestion about my problem? Thanks.

2
You maybe hitted a bug. Can you fill a report on GitHub and paste the full stack trace of the error? - Kévin Dunglas

2 Answers

0
votes

You are in a collectionOperations so it means you are going to retrieve an array. Well, that won't be exactly an array but a Paginator so object.userCompanyRoles is going to be a Paginator because it's what you are retrieving.

Your object.userCompanyRoles on access_control should work if you were in a n itemOperations.

So how to add access control on your /courses ? First of all you won't need an ApiSubresource. This annotation means you are able to list userCompanyRoles which belong to a course item id on the request /courses/{id}/user_company_roles

What I understand is, you want to be able to list courses only if your user is listed in the userCompanyRoles.user. This doesn't sound like an access control to me but more like an override operation or event a filter because when you request /courses it should be filtered relative to your connected user, right ?

https://api-platform.com/docs/core/operations https://api-platform.com/docs/core/filters

Let me know if you are still in trouble.

0
votes

A collection does not have the object variable available in its security expression. You might want to write an Extension. Here is an example which filters a collection by current user, exactly like you are trying to:

https://api-platform.com/docs/core/extensions/