From dcd19f3cf9e439c2c590f6cd9bccca7b303c9386 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 20 Feb 2017 08:38:24 +0100 Subject: [PATCH] fix priority ordering of security voters --- .../Compiler/AddSecurityVotersPass.php | 10 ++-- .../Compiler/AddSecurityVotersPassTest.php | 57 +++++++++++++++++++ 2 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/AddSecurityVotersPassTest.php diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddSecurityVotersPass.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddSecurityVotersPass.php index 497807174d..f8cc92c6c7 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddSecurityVotersPass.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddSecurityVotersPass.php @@ -31,15 +31,15 @@ class AddSecurityVotersPass implements CompilerPassInterface return; } - $voters = new \SplPriorityQueue(); + $voters = array(); foreach ($container->findTaggedServiceIds('security.voter') as $id => $attributes) { $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0; - $voters->insert(new Reference($id), $priority); + $voters[$priority][] = new Reference($id); } - $voters = iterator_to_array($voters); - ksort($voters); + krsort($voters); + $voters = call_user_func_array('array_merge', $voters); - $container->getDefinition('security.access.decision_manager')->replaceArgument(0, array_values($voters)); + $container->getDefinition('security.access.decision_manager')->replaceArgument(0, $voters); } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/AddSecurityVotersPassTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/AddSecurityVotersPassTest.php new file mode 100644 index 0000000000..c57207b13f --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/AddSecurityVotersPassTest.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SecurityBundle\Tests\DependencyInjection\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\AddSecurityVotersPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +class AddSecurityVotersPassTest extends TestCase +{ + public function testThatSecurityVotersAreProcessedInPriorityOrder() + { + $container = new ContainerBuilder(); + $container + ->register('security.access.decision_manager', 'Symfony\Component\Security\Core\Authorization\AccessDecisionManager') + ->addArgument(array()) + ; + $container + ->register('no_prio_service') + ->addTag('security.voter') + ; + $container + ->register('lowest_prio_service') + ->addTag('security.voter', array('priority' => 100)) + ; + $container + ->register('highest_prio_service') + ->addTag('security.voter', array('priority' => 200)) + ; + $container + ->register('zero_prio_service') + ->addTag('security.voter', array('priority' => 0)) + ; + $compilerPass = new AddSecurityVotersPass(); + $compilerPass->process($container); + + $this->assertEquals( + array( + new Reference('highest_prio_service'), + new Reference('lowest_prio_service'), + new Reference('no_prio_service'), + new Reference('zero_prio_service'), + ), + $container->getDefinition('security.access.decision_manager')->getArgument(0) + ); + } +}