Symfony 工作流组件和安全选民?
Symfony Workflow Component and Security Voters?
TL;DR:如何向转换添加自定义约束(即安全选民)?
我的应用程序需要一些工作流管理系统,所以我想以 Symfony 的新 Workflow Component. Let's take a Pull Request 工作流为例。
在此示例中,仅描述状态及其转换。但是,如果我想向该工作流程添加其他约束怎么办?我可以想象一些限制:
- 只有管理员可以接受 Pull Request
- 用户只能重新打开自己的 Pull Request
- 用户不能重新打开超过 1 年的 PR
虽然您可以使用 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.
中实施 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',
];
}
TL;DR:如何向转换添加自定义约束(即安全选民)?
我的应用程序需要一些工作流管理系统,所以我想以 Symfony 的新 Workflow Component. Let's take a Pull Request 工作流为例。
在此示例中,仅描述状态及其转换。但是,如果我想向该工作流程添加其他约束怎么办?我可以想象一些限制:
- 只有管理员可以接受 Pull Request
- 用户只能重新打开自己的 Pull Request
- 用户不能重新打开超过 1 年的 PR
虽然您可以使用 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.
中实施 AuthorizationCheckerdemo 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',
];
}