From 413756c103dec9cd640db569cc678357995a3cd1 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Thu, 17 Nov 2011 20:16:17 +0100 Subject: [PATCH] [BC break][SecurityBundle] Changed the way to register factories --- CHANGELOG-2.1.md | 3 + .../FactoryConfiguration.php | 53 -------------- .../DependencyInjection/MainConfiguration.php | 5 -- .../DependencyInjection/SecurityExtension.php | 69 +++++-------------- .../Bundle/SecurityBundle/SecurityBundle.php | 14 +++- .../DependencyInjection/ConfigurationTest.php | 19 ----- .../SecurityExtensionTest.php | 6 +- 7 files changed, 37 insertions(+), 132 deletions(-) delete mode 100644 src/Symfony/Bundle/SecurityBundle/DependencyInjection/FactoryConfiguration.php diff --git a/CHANGELOG-2.1.md b/CHANGELOG-2.1.md index 1e5978a18e..eed96a0c95 100644 --- a/CHANGELOG-2.1.md +++ b/CHANGELOG-2.1.md @@ -36,6 +36,9 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c ### SecurityBundle + * [BC BREAK] The custom factories for the firewall configuration are now registered during the build method of + bundles instead of being registered by the end-user. + * [BC BREAK] The Firewall listener is now registered after the Router one. It means that specific Firewall URLs (like /login_check and /logout must now have proper route defined in your routing configuration) diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/FactoryConfiguration.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/FactoryConfiguration.php deleted file mode 100644 index 599c178dfa..0000000000 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/FactoryConfiguration.php +++ /dev/null @@ -1,53 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace Symfony\Bundle\SecurityBundle\DependencyInjection; - -use Symfony\Component\Config\Definition\Builder\TreeBuilder; -use Symfony\Component\Config\Definition\ConfigurationInterface; - -/** - * This class contains the configuration information for the following tags: - * - * * security.config - * * security.acl - * - * This information is solely responsible for how the different configuration - * sections are normalized, and merged. - * - * @author Johannes M. Schmitt - */ -class FactoryConfiguration implements ConfigurationInterface -{ - /** - * Generates the configuration tree builder. - * - * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder - */ - public function getConfigTreeBuilder() - { - $tb = new TreeBuilder(); - - $tb - ->root('security') - ->ignoreExtraKeys() - ->fixXmlConfig('factory', 'factories') - ->children() - ->arrayNode('factories') - ->prototype('scalar')->end() - ->end() - ->end() - ->end() - ; - - return $tb; - } -} diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php index ecb8a3d061..e11f0c1999 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php @@ -70,11 +70,6 @@ class MainConfiguration implements ConfigurationInterface ->end() ->end() ->end() - // add a faux-entry for factories, so that no validation error is thrown - ->fixXmlConfig('factory', 'factories') - ->children() - ->arrayNode('factories')->ignoreExtraKeys()->end() - ->end() ; $this->addAclSection($rootNode); diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index 7bed1e65d0..70a7b7fca8 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\SecurityBundle\DependencyInjection; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\UserProviderFactoryInterface; use Symfony\Component\DependencyInjection\DefinitionDecorator; use Symfony\Component\DependencyInjection\Alias; @@ -36,22 +37,24 @@ class SecurityExtension extends Extension private $requestMatchers = array(); private $contextListeners = array(); private $listenerPositions = array('pre_auth', 'form', 'http', 'remember_me'); - private $factories; + private $factories = array(); private $userProviderFactories = array(); + public function __construct() + { + foreach ($this->listenerPositions as $position) { + $this->factories[$position] = array(); + } + } + public function load(array $configs, ContainerBuilder $container) { if (!array_filter($configs)) { return; } - // first assemble the factories - $factoriesConfig = new FactoryConfiguration(); - $config = $this->processConfiguration($factoriesConfig, $configs); - $factories = $this->createListenerFactories($container, $config); - // normalize and merge the actual configuration - $mainConfig = new MainConfiguration($factories, $this->userProviderFactories); + $mainConfig = new MainConfiguration($this->factories, $this->userProviderFactories); $config = $this->processConfiguration($mainConfig, $configs); // load services @@ -207,14 +210,11 @@ class SecurityExtension extends Extension $arguments[1] = $userProviders; $definition->setArguments($arguments); - // create security listener factories - $factories = $this->createListenerFactories($container, $config); - // load firewall map $mapDef = $container->getDefinition('security.firewall.map'); $map = $authenticationProviders = array(); foreach ($firewalls as $name => $firewall) { - list($matcher, $listeners, $exceptionListener) = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds, $factories); + list($matcher, $listeners, $exceptionListener) = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds); $contextId = 'security.firewall.map.context.'.$name; $context = $container->setDefinition($contextId, new DefinitionDecorator('security.firewall.context')); @@ -236,7 +236,7 @@ class SecurityExtension extends Extension ; } - private function createFirewall(ContainerBuilder $container, $id, $firewall, &$authenticationProviders, $providerIds, array $factories) + private function createFirewall(ContainerBuilder $container, $id, $firewall, &$authenticationProviders, $providerIds) { // Matcher $i = 0; @@ -309,7 +309,7 @@ class SecurityExtension extends Extension } // Authentication listeners - list($authListeners, $defaultEntryPoint) = $this->createAuthenticationListeners($container, $id, $firewall, $authenticationProviders, $defaultProvider, $factories); + list($authListeners, $defaultEntryPoint) = $this->createAuthenticationListeners($container, $id, $firewall, $authenticationProviders, $defaultProvider); $listeners = array_merge($listeners, $authListeners); @@ -345,14 +345,14 @@ class SecurityExtension extends Extension return $this->contextListeners[$contextKey] = $listenerId; } - private function createAuthenticationListeners($container, $id, $firewall, &$authenticationProviders, $defaultProvider, array $factories) + private function createAuthenticationListeners($container, $id, $firewall, &$authenticationProviders, $defaultProvider) { $listeners = array(); $hasListeners = false; $defaultEntryPoint = null; foreach ($this->listenerPositions as $position) { - foreach ($factories[$position] as $factory) { + foreach ($this->factories[$position] as $factory) { $key = str_replace('-', '_', $factory->getKey()); if (isset($firewall[$key])) { @@ -548,44 +548,9 @@ class SecurityExtension extends Extension return $this->requestMatchers[$id] = new Reference($id); } - private function createListenerFactories(ContainerBuilder $container, $config) + public function addSecurityListenerFactory(SecurityFactoryInterface $factory) { - if (null !== $this->factories) { - return $this->factories; - } - - // load service templates - $c = new ContainerBuilder(); - $parameterBag = $container->getParameterBag(); - - $locator = new FileLocator(__DIR__.'/../Resources/config'); - $resolver = new LoaderResolver(array( - new XmlFileLoader($c, $locator), - new YamlFileLoader($c, $locator), - new PhpFileLoader($c, $locator), - )); - $loader = new DelegatingLoader($resolver); - - $loader->load('security_factories.xml'); - - // load user-created listener factories - foreach ($config['factories'] as $factory) { - $loader->load($parameterBag->resolveValue($factory)); - } - - $tags = $c->findTaggedServiceIds('security.listener.factory'); - - $factories = array(); - foreach ($this->listenerPositions as $position) { - $factories[$position] = array(); - } - - foreach (array_keys($tags) as $tag) { - $factory = $c->get($tag); - $factories[$factory->getPosition()][] = $factory; - } - - return $this->factories = $factories; + $this->factories[$factory->getPosition()][] = $factory; } public function addUserProviderFactory(UserProviderFactoryInterface $factory) diff --git a/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php b/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php index 38c38760d5..7d810fde38 100644 --- a/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php +++ b/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php @@ -14,6 +14,11 @@ namespace Symfony\Bundle\SecurityBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\AddSecurityVotersPass; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\FormLoginFactory; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\HttpBasicFactory; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\HttpDigestFactory; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\RememberMeFactory; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\X509Factory; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\InMemoryFactory; /** @@ -27,7 +32,14 @@ class SecurityBundle extends Bundle { parent::build($container); - $container->getExtension('security')->addUserProviderFactory(new InMemoryFactory()); + $extension = $container->getExtension('security'); + $extension->addSecurityListenerFactory(new FormLoginFactory()); + $extension->addSecurityListenerFactory(new HttpBasicFactory()); + $extension->addSecurityListenerFactory(new HttpDigestFactory()); + $extension->addSecurityListenerFactory(new RememberMeFactory()); + $extension->addSecurityListenerFactory(new X509Factory()); + + $extension->addUserProviderFactory(new InMemoryFactory()); $container->addCompilerPass(new AddSecurityVotersPass()); } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/ConfigurationTest.php index 88ca9938cc..c859cfffed 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -33,25 +33,6 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase ), ); - /** - * Test that the main tree is OK to be passed a factory or factories - * key, without throwing any validation errors. - */ - public function testMainConfigTreeWithFactories() - { - $config = array_merge(self::$minimalConfig, array( - 'factory' => array('foo' => 'bar'), - 'factories' => array('lorem' => 'ipsum'), - )); - - $processor = new Processor(); - $configuration = new MainConfiguration(array(), array()); - $config = $processor->processConfiguration($configuration, array($config)); - - $this->assertFalse(array_key_exists('factory', $config), 'The factory key is silently removed without an exception'); - $this->assertEquals(array(), $config['factories'], 'The factories key is just an empty array'); - } - /** * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException */ diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php index b3c2a2a4db..9abb596cb3 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php @@ -14,7 +14,7 @@ namespace Symfony\Bundle\SecurityBundle\Tests\DependencyInjection; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Parameter; - +use Symfony\Bundle\SecurityBundle\SecurityBundle; use Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\InMemoryFactory; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -169,8 +169,10 @@ abstract class SecurityExtensionTest extends \PHPUnit_Framework_TestCase { $container = new ContainerBuilder(); $security = new SecurityExtension(); - $security->addUserProviderFactory(new InMemoryFactory()); $container->registerExtension($security); + + $bundle = new SecurityBundle(); + $bundle->build($container); // Attach all default factories $this->loadFromFile($container, $file); $container->getCompilerPassConfig()->setOptimizationPasses(array());