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

时间:2017-01-10 10:18:04

标签: php symfony workflow symfony-workflows

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

我的应用程序需要一些工作流程管理系统,因此我想尝试使用Symfony的新Workflow Component。我们以Pull Request工作流程为例。

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

  • 只有管理员可以接受提款请求
  • 用户只能重新打开自己的Pull Request
  • 用户无法重新开启超过1年的PR

虽然在这种情况下您可以使用Events,但我认为这不是处理它的最佳方法,因为事件是在$workflow->apply()之后触发的。我想事先知道是否允许用户更改状态,因此我可以隐藏或禁用该按钮。 (不是like this)。

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

添加自定义实体约束的最佳方法是什么(' 1年以上的PR无法重新开启')和安全限制(' 只有管理员可以接受公关的',也许可以通过使用Symfony的安全选民进行转换?

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

1 个答案:

答案 0 :(得分:3)

我发现的最佳方法是在工作流 GuardListener 中实施 AuthorizationChecker

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',
        ];
    }