Операции с элементами ManyToMany "access_control"

это код из документа

// 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;

    // ...
}

Я думаю, что это может быть что-то вроде «и пользователь в object.users» или «и в object.users есть пользователь»

Arleigh Hix 10.06.2019 00:20

Вы пробовали так: "get" = {"access_control" = "is_granted('ROLE_USER') or object == user"}?

Alexis 10.06.2019 09:48

@ArleighHix Обратите внимание: свойство Undefined: Proxies\__CG__\\App\\Entity\\Book::$users даже не распознает переменную $users

Daniel 10.06.2019 10:15

@ Алексис, я не думаю, что это работает, «объект» - это сам класс, поэтому объект книги не может быть объектом пользователя. («Доступ запрещен». bdw.)

Daniel 10.06.2019 10:18

Да, извините, и что-то вроде этого может быть: "get" = { * "access_control" = " is_granted('ROLE_USER')) and object.getOwner() == user"} при условии, что у вас есть getOwner() функция в вашем Book классе, которая возвращает пользователя с отношением ManyToOne, которое у вас есть в поле пользователей

Alexis 10.06.2019 10:25

У меня есть отношение ManyToMany, сэр, и у меня есть функция getUsers(). and user in object.users работает, но не распознает переменную $users. см. 3-й комментарий выше этого

Daniel 10.06.2019 10:35
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
6
182
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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», есть небольшая опечатка :-)

Daniel 10.06.2019 11:31

в следующий раз предложите исправление, чтобы я одобрил его, и вы получили несколько баллов: P

AythaNzt 10.06.2019 12:40

Другие вопросы по теме