это код из документа
// https://api-platform.com/docs/core/security/#security
itemOperations = {
"get" = {"access_control" = "is_granted('ROLE_USER') and object.owner == user"}
}
как я могу реализовать это со многими ко многим, я пробовал много разных выражений, но каждый раз получаю сообщение об ошибке.
<?php
// api/src/Entity/Book.php
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Secured resource.
*
* @ApiResource(
* itemOperations = {
* "get" = {"access_control" = "is_granted('ROLE_USER') and object.users == user"}
* }
* )
* @ORM\Entity
*/
class Book
{
// ...
/**
* @var User The owner
*
* @ORM\ManyToMany(targetEntity = "App\Entity\User", mappedBy = "book", cascade = {"persist"})
*/
public $users;
// ...
}
Вы пробовали так: "get" = {"access_control" = "is_granted('ROLE_USER') or object == user"}?
@ArleighHix Обратите внимание: свойство Undefined: Proxies\__CG__\\App\\Entity\\Book::$users даже не распознает переменную $users
@ Алексис, я не думаю, что это работает, «объект» - это сам класс, поэтому объект книги не может быть объектом пользователя. («Доступ запрещен». bdw.)
Да, извините, и что-то вроде этого может быть: "get" = { * "access_control" = " is_granted('ROLE_USER')) and object.getOwner() == user"} при условии, что у вас есть getOwner() функция в вашем Book классе, которая возвращает пользователя с отношением ManyToOne, которое у вас есть в поле пользователей
У меня есть отношение ManyToMany, сэр, и у меня есть функция getUsers(). and user in object.users работает, но не распознает переменную $users. см. 3-й комментарий выше этого






nВы не можете в тех случаях, когда целевое отношение является коллекцией. В этом случае сбор пользователей.
Для этих случаев вы должны создать подписчика с событием PRE_SERIALIZE и бросить туда исключение Access Denied.
Вы должны сделать что-то вроде этого. Поскольку вы говорите, что у вас есть отношение ManyToMany, я предполагаю, что у вас есть промежуточный объект между книгой и пользователем, поэтому вы должны использовать этот репозиторий для поиска пользователя <-> книги.
<?php
namespace App\EventSubscriber;
use ApiPlatform\Core\EventListener\EventPriorities;
use App\Entity\User;
use App\Entity\Book;
use App\Repository\UserRepository;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
class ChatMessagePreSerializeSubscriber implements EventSubscriberInterface
{
private $tokenStorage;
private $userRepository;
private $authorizationChecker;
public function __construct(
TokenStorageInterface $tokenStorage,
UserRepository $userRepository,
AuthorizationCheckerInterface $authorizationChecker
) {
$this->tokenStorage = $tokenStorage;
$this->userRepository = $userRepository;
$this->authorizationChecker = $authorizationChecker;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['bookPreSerialize', EventPriorities::PRE_SERIALIZE],
];
}
public function bookPreSerialize(GetResponseForControllerResultEvent $event)
{
$book = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if (!$book instanceof Book || (Request::METHOD_GET !== $method)) {
return;
}
$currentUser = $this->tokenStorage->getToken()->getUser();
if (!$currentUser instanceof User)
return;
$user = $this->userRepository->findOneBy(['id' => $currentUser->getId(), 'book' => $book]);
if (!$user instanceof User)
throw new AccessDeniedHttpException();
}
}
Спасибо! это сработало! вам нужно назвать «instaceof» на «instanceof», есть небольшая опечатка :-)
в следующий раз предложите исправление, чтобы я одобрил его, и вы получили несколько баллов: P
Я думаю, что это может быть что-то вроде «и пользователь в object.users» или «и в object.users есть пользователь»