Symfony 工作流组件和安全选民?

Symfony Workflow Component and Security Voters?

TL;DR:如何向转换添加自定义约束(即安全选民)?

我的应用程序需要一些工作流管理系统,所以我想以 Symfony 的新 Workflow Component. Let's take a Pull Request 工作流为例。

在此示例中,仅描述状态及其转换。但是,如果我想向该工作流程添加其他约束怎么办?我可以想象一些限制:

虽然您可以使用 Events in this case, I don't think that's the best way to handle it, because an event is fired after $workflow->apply(). I want to know beforehand if a user is allowed to change the state, so I can hide or disable the button. (not like this).

LexikWorkflowBundle 通过向步骤(转换)添加角色,部分解决了这个问题。切换到这个包可能是个好主意,但我想弄清楚如何在没有的情况下解决这个问题。

添加自定义实体约束('超过 1 年的 PR 不能重新打开')和安全约束('only管理员可以接受 PR's',也许通过使用 Symfony 的安全选民)来转换?

更新: 澄清一下:我想将权限控制添加到我的工作流中,但这并不一定意味着我想将它与工作流组件紧密耦合。我想坚持良好的做法,所以给定的解决方案应该尊重单一职责原则。

我发现的最佳方法是在工作流的 GuardListener.

中实施 A​​uthorizationChecker

demo application给出了一个很好的例子:

namespace Acme\DemoBundle\Entity\Listener;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
use Symfony\Component\Workflow\Event\GuardEvent;

class GuardListener implements EventSubscriberInterface
{
    public function __construct(AuthorizationCheckerInterface $checker)
    {
        $this->checker = $checker;
    }
    public function onTransition(GuardEvent $event)
    {
        // For all action, user should be logger
        if (!$this->checker->isGranted('IS_AUTHENTICATED_FULLY')) {
            $event->setBlocked(true);
        }
    }
    public function onTransitionJournalist(GuardEvent $event)
    {
        if (!$this->checker->isGranted('ROLE_JOURNALIST')) {
            $event->setBlocked(true);
        }
    }
    public function onTransitionSpellChecker(GuardEvent $event)
    {
        if (!$this->checker->isGranted('ROLE_SPELLCHECKER')) {
            $event->setBlocked(true);
        }
    }
    public static function getSubscribedEvents()
    {
        return [
            'workflow.article.guard' => 'onTransition',
            'workflow.article.guard.journalist_approval' => 'onTransitionJournalist',
            'workflow.article.guard.spellchecker_approval' => 'onTransitionSpellChecker',
        ];
    }