AddSecurityCallsPass.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. <?php
  2. /*
  3. * This file is part of the Sonata project.
  4. *
  5. * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
  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 Sonata\AdminBundle\DependencyInjection;
  11. use Symfony\Component\DependencyInjection\Definition;
  12. use Symfony\Component\DependencyInjection\ContainerBuilder;
  13. use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
  14. use Symfony\Component\DependencyInjection\Reference;
  15. use Symfony\Component\DependencyInjection\ContainerInterface;
  16. /**
  17. * This code append Admin security roles
  18. *
  19. * @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
  20. * @author Fabien Potencier <fabien@symfony.com>
  21. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  22. */
  23. class AddSecurityCallsPass implements CompilerPassInterface
  24. {
  25. /**
  26. * {@inheritDoc}
  27. */
  28. public function process(ContainerBuilder $container)
  29. {
  30. $definition = $container->getDefinition('sonata_dummy_security');
  31. $container->removeDefinition('sonata_dummy_security');
  32. $config = $definition->getArguments();
  33. $this->createAuthorization($config, $container);
  34. $this->createRoleHierarchy($config, $container);
  35. }
  36. private function createRoleHierarchy($config, ContainerBuilder $container)
  37. {
  38. if (!isset($config['role_hierarchy'])) {
  39. $container->removeDefinition('security.access.role_hierarchy_voter');
  40. return;
  41. }
  42. $parameters = (array) $container->getParameter('security.role_hierarchy.roles');
  43. $container->setParameter('security.role_hierarchy.roles', array_merge($parameters, $config['role_hierarchy']));
  44. $container->removeDefinition('security.access.simple_role_voter');
  45. }
  46. private function createAuthorization($config, ContainerBuilder $container)
  47. {
  48. if (!$config['access_control']) {
  49. return;
  50. }
  51. foreach ($config['access_control'] as $access) {
  52. $matcher = $this->createRequestMatcher(
  53. $container,
  54. $access['path'],
  55. $access['host'],
  56. count($access['methods']) === 0 ? null : $access['methods'],
  57. $access['ip']
  58. );
  59. $container->getDefinition('security.access_map')
  60. ->addMethodCall('add', array($matcher, $access['roles'], $access['requires_channel']));
  61. }
  62. }
  63. private function createRequestMatcher($container, $path = null, $host = null, $methods = null, $ip = null, array $attributes = array())
  64. {
  65. $serialized = serialize(array($path, $host, $methods, $ip, $attributes));
  66. $id = 'security.request_matcher.'.md5($serialized).sha1($serialized);
  67. if (isset($this->requestMatchers[$id])) {
  68. return $this->requestMatchers[$id];
  69. }
  70. // only add arguments that are necessary
  71. $arguments = array($path, $host, $methods, $ip, $attributes);
  72. while (count($arguments) > 0 && !end($arguments)) {
  73. array_pop($arguments);
  74. }
  75. $container
  76. ->register($id, '%security.matcher.class%')
  77. ->setPublic(false)
  78. ->setArguments($arguments)
  79. ;
  80. return $this->requestMatchers[$id] = new Reference($id);
  81. }
  82. }