AddSecurityVotersPass.php 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler;
  11. use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
  12. use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
  13. use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
  14. use Symfony\Component\DependencyInjection\ContainerBuilder;
  15. use Symfony\Component\DependencyInjection\Exception\LogicException;
  16. use Symfony\Component\DependencyInjection\Reference;
  17. use Symfony\Component\Security\Core\Authorization\Voter\TraceableVoter;
  18. use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
  19. /**
  20. * Adds all configured security voters to the access decision manager.
  21. *
  22. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  23. */
  24. class AddSecurityVotersPass implements CompilerPassInterface
  25. {
  26. use PriorityTaggedServiceTrait;
  27. /**
  28. * {@inheritdoc}
  29. */
  30. public function process(ContainerBuilder $container)
  31. {
  32. if (!$container->hasDefinition('security.access.decision_manager')) {
  33. return;
  34. }
  35. $voters = $this->findAndSortTaggedServices('security.voter', $container);
  36. if (!$voters) {
  37. throw new LogicException('No security voters found. You need to tag at least one with "security.voter".');
  38. }
  39. $debug = $container->getParameter('kernel.debug');
  40. $voterServices = [];
  41. foreach ($voters as $voter) {
  42. $voterServiceId = (string) $voter;
  43. $definition = $container->getDefinition($voterServiceId);
  44. $class = $container->getParameterBag()->resolveValue($definition->getClass());
  45. if (!is_a($class, VoterInterface::class, true)) {
  46. throw new LogicException(sprintf('"%s" must implement the "%s" when used as a voter.', $class, VoterInterface::class));
  47. }
  48. if ($debug) {
  49. $voterServices[] = new Reference($debugVoterServiceId = 'debug.security.voter.'.$voterServiceId);
  50. $container
  51. ->register($debugVoterServiceId, TraceableVoter::class)
  52. ->addArgument($voter)
  53. ->addArgument(new Reference('event_dispatcher'));
  54. } else {
  55. $voterServices[] = $voter;
  56. }
  57. }
  58. $container->getDefinition('security.access.decision_manager')
  59. ->replaceArgument(0, new IteratorArgument($voterServices));
  60. }
  61. }