diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php index c2bcb7d0e3..6b23e29958 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php @@ -59,6 +59,26 @@ class MainConfiguration implements ConfigurationInterface $rootNode = $tb->root('security'); $rootNode + ->beforeNormalization() + ->ifTrue(function ($v) { + if (!isset($v['access_decision_manager'])) { + return true; + } + + if (!isset($v['access_decision_manager']['strategy']) && !isset($v['access_decision_manager']['service'])) { + return true; + } + + return false; + }) + ->then(function ($v) { + $v['access_decision_manager'] = array( + 'strategy' => AccessDecisionManager::STRATEGY_AFFIRMATIVE, + ); + + return $v; + }) + ->end() ->children() ->scalarNode('access_denied_url')->defaultNull()->example('/foo/error403')->end() ->enumNode('session_fixation_strategy') @@ -73,11 +93,15 @@ class MainConfiguration implements ConfigurationInterface ->children() ->enumNode('strategy') ->values(array(AccessDecisionManager::STRATEGY_AFFIRMATIVE, AccessDecisionManager::STRATEGY_CONSENSUS, AccessDecisionManager::STRATEGY_UNANIMOUS)) - ->defaultValue(AccessDecisionManager::STRATEGY_AFFIRMATIVE) ->end() + ->scalarNode('service')->end() ->booleanNode('allow_if_all_abstain')->defaultFalse()->end() ->booleanNode('allow_if_equal_granted_denied')->defaultTrue()->end() ->end() + ->validate() + ->ifTrue(function ($v) { return isset($v['strategy']) && isset($v['service']); }) + ->thenInvalid('"strategy" and "service" cannot be used together.') + ->end() ->end() ->end() ; diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index 82aa222a75..95c2d07d9d 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -83,12 +83,17 @@ class SecurityExtension extends Extension $container->setParameter('security.access.denied_url', $config['access_denied_url']); $container->setParameter('security.authentication.manager.erase_credentials', $config['erase_credentials']); $container->setParameter('security.authentication.session_strategy.strategy', $config['session_fixation_strategy']); - $container - ->getDefinition('security.access.decision_manager') - ->addArgument($config['access_decision_manager']['strategy']) - ->addArgument($config['access_decision_manager']['allow_if_all_abstain']) - ->addArgument($config['access_decision_manager']['allow_if_equal_granted_denied']) - ; + + if (isset($config['access_decision_manager']['service'])) { + $container->setAlias('security.access.decision_manager', $config['access_decision_manager']['service']); + } else { + $container + ->getDefinition('security.access.decision_manager') + ->addArgument($config['access_decision_manager']['strategy']) + ->addArgument($config['access_decision_manager']['allow_if_all_abstain']) + ->addArgument($config['access_decision_manager']['allow_if_equal_granted_denied']); + } + $container->setParameter('security.access.always_authenticate_before_granting', $config['always_authenticate_before_granting']); $container->setParameter('security.authentication.hide_user_not_found', $config['hide_user_not_found']); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php index c2598b51ff..4034e1c3c3 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php @@ -16,6 +16,7 @@ use Symfony\Component\DependencyInjection\Reference; use Symfony\Bundle\SecurityBundle\SecurityBundle; use Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Security\Core\Authorization\AccessDecisionManager; abstract class CompleteConfigurationTest extends TestCase { @@ -356,6 +357,29 @@ abstract class CompleteConfigurationTest extends TestCase $this->assertTrue($this->getContainer('remember_me_options')->has('security.console.user_password_encoder_command')); } + public function testDefaultAccessDecisionManagerStrategyIsAffirmative() + { + $container = $this->getContainer('access_decision_manager_default_strategy'); + + $this->assertSame(AccessDecisionManager::STRATEGY_AFFIRMATIVE, $container->getDefinition('security.access.decision_manager')->getArgument(1), 'Default vote strategy is affirmative'); + } + + public function testCustomAccessDecisionManagerService() + { + $container = $this->getContainer('access_decision_manager_service'); + + $this->assertSame('app.access_decision_manager', (string) $container->getAlias('security.access.decision_manager'), 'The custom access decision manager service is aliased'); + } + + /** + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + * @expectedExceptionMessage "strategy" and "service" cannot be used together. + */ + public function testAccessDecisionManagerServiceAndStrategyCannotBeUsedAtTheSameTime() + { + $container = $this->getContainer('access_decision_manager_service_and_strategy'); + } + protected function getContainer($file) { $file = $file.'.'.$this->getFileExtension(); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/access_decision_manager_default_strategy.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/access_decision_manager_default_strategy.php new file mode 100644 index 0000000000..d06fc3e686 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/access_decision_manager_default_strategy.php @@ -0,0 +1,16 @@ +loadFromExtension('security', array( + 'providers' => array( + 'default' => array( + 'memory' => array( + 'users' => array( + 'foo' => array('password' => 'foo', 'roles' => 'ROLE_USER'), + ), + ), + ), + ), + 'firewalls' => array( + 'simple' => array('pattern' => '/login', 'security' => false), + ), +)); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/access_decision_manager_service.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/access_decision_manager_service.php new file mode 100644 index 0000000000..29db539362 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/access_decision_manager_service.php @@ -0,0 +1,19 @@ +loadFromExtension('security', array( + 'access_decision_manager' => array( + 'service' => 'app.access_decision_manager', + ), + 'providers' => array( + 'default' => array( + 'memory' => array( + 'users' => array( + 'foo' => array('password' => 'foo', 'roles' => 'ROLE_USER'), + ), + ), + ), + ), + 'firewalls' => array( + 'simple' => array('pattern' => '/login', 'security' => false), + ), +)); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/access_decision_manager_service_and_strategy.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/access_decision_manager_service_and_strategy.php new file mode 100644 index 0000000000..f7175e21f6 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/access_decision_manager_service_and_strategy.php @@ -0,0 +1,20 @@ +loadFromExtension('security', array( + 'access_decision_manager' => array( + 'service' => 'app.access_decision_manager', + 'strategy' => 'affirmative', + ), + 'providers' => array( + 'default' => array( + 'memory' => array( + 'users' => array( + 'foo' => array('password' => 'foo', 'roles' => 'ROLE_USER'), + ), + ), + ), + ), + 'firewalls' => array( + 'simple' => array('pattern' => '/login', 'security' => false), + ), +)); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/access_decision_manager_default_strategy.xml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/access_decision_manager_default_strategy.xml new file mode 100644 index 0000000000..6c267a2e77 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/access_decision_manager_default_strategy.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/access_decision_manager_service.xml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/access_decision_manager_service.xml new file mode 100644 index 0000000000..4e67e168c8 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/access_decision_manager_service.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/access_decision_manager_service_and_strategy.xml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/access_decision_manager_service_and_strategy.xml new file mode 100644 index 0000000000..dbadce4fa7 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/access_decision_manager_service_and_strategy.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/access_decision_manager_default_strategy.yml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/access_decision_manager_default_strategy.yml new file mode 100644 index 0000000000..f7fb5adc2c --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/access_decision_manager_default_strategy.yml @@ -0,0 +1,8 @@ +security: + providers: + default: + memory: + users: + foo: { password: foo, roles: ROLE_USER } + firewalls: + simple: { pattern: /login, security: false } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/access_decision_manager_service.yml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/access_decision_manager_service.yml new file mode 100644 index 0000000000..7ef3d8d93c --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/access_decision_manager_service.yml @@ -0,0 +1,10 @@ +security: + access_decision_manager: + service: app.access_decision_manager + providers: + default: + memory: + users: + foo: { password: foo, roles: ROLE_USER } + firewalls: + simple: { pattern: /login, security: false } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/access_decision_manager_service_and_strategy.yml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/access_decision_manager_service_and_strategy.yml new file mode 100644 index 0000000000..bd38b21ef3 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/access_decision_manager_service_and_strategy.yml @@ -0,0 +1,11 @@ +security: + access_decision_manager: + service: app.access_decision_manager + strategy: affirmative + providers: + default: + memory: + users: + foo: { password: foo, roles: ROLE_USER } + firewalls: + simple: { pattern: /login, security: false }