我正在尝试通过根据the documentation装饰graphql阶段,将当前用户添加到create
突变中。
此功能允许用户阻止邮件系统fyi中的其他用户。
它应满足以下访问控制:
"access_control"="is_granted('IS_AUTHENTICATED_FULLY') and object.getBlocker() == user"
表示被阻止的用户是当前经过身份验证的用户。
如果我将以上内容修改为:
"access_control"="is_granted('IS_AUTHENTICATED_FULLY')"
通过像这样装饰deserialize stage
:
App / Stage / DeserializeStage
/**
* @param object|null $objectToPopulate
*
* @return object|null
*/
public function __invoke($objectToPopulate, string $resourceClass, string $operationName, array $context)
{
// Call the decorated serialized stage (this syntax calls the __invoke method).
$deserializeObject = ($this->deserializeStage)($objectToPopulate, $resourceClass, $operationName, $context);
if ($resourceClass === 'App\Entity\BlockedUser' && $operationName === 'create') {
$user = $this->tokenStorage->getToken()->getUser();
$deserializeObject->setBlocker($user);
}
return $deserializeObject;
}
据我了解,为了使其能够完全满足访问控制的要求,我需要装饰read stage
之前的security stage
并将当前经过身份验证的用户插入到宾语。
这样,它将满足访问控制的第二部分,即
and object.getBlocker() == user
我尝试如下进行操作,但是得到了NULL
对象:
App / Stage / ReadStage
/**
* @return object|iterable|null
*/
public function __invoke(?string $resourceClass, ?string $rootClass, string $operationName, array $context)
{
$readObject = ($this->readStage)($resourceClass, $rootClass, $operationName, $context);
var_dump($readObject->getBlocked()->getUsername()); // throws error 'method getBlocked on NULL
if ($resourceClass === 'App\Entity\BlockedUser' && $operationName === 'create') {
$userId = $this->tokenStorage->getToken()->getUser();
$readObject->setBlocker($user);
}
return $readObject;
}
答案 0 :(得分:0)
好吧,重新启动应用程序后,它似乎在deserialize
阶段正常运行。可能是缓存问题或其他问题。
我仍然不确定为什么它可以在deserialize
阶段工作,还是不确定修改对象的正确位置。
无论如何,它都按原样工作,所以...
因此,我将发布完整的代码以供参考。
App / Stage / DeserializeStage
<?php
namespace App\Stage;
use ApiPlatform\Core\GraphQl\Resolver\Stage\DeserializeStageInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
final class DeserializeStage implements DeserializeStageInterface
{
private $deserializeStage;
/**
* @var TokenStorageInterface
*/
private $tokenStorage;
public function __construct(
DeserializeStageInterface $deserializeStage,
TokenStorageInterface $tokenStorage)
{
$this->deserializeStage = $deserializeStage;
$this->tokenStorage = $tokenStorage;
}
/**
* @param object|null $objectToPopulate
*
* @return object|null
*/
public function __invoke($objectToPopulate, string $resourceClass, string $operationName, array $context)
{
// Call the decorated serialized stage (this syntax calls the __invoke method).
$deserializeObject = ($this->deserializeStage)($objectToPopulate, $resourceClass, $operationName, $context);
if ($resourceClass === 'App\Entity\BlockedUser' && $operationName === 'create') {
$user = $this->tokenStorage->getToken()->getUser();
$deserializeObject->setBlocker($user);
}
return $deserializeObject;
}
}
您需要将此添加到config/services.yaml
App\Stage\DeserializeStage:
decorates: api_platform.graphql.resolver.stage.deserialize