diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index fde20aaaba6e0..5fc271c0512d0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -6,6 +6,7 @@ CHANGELOG * Allowed configuring taggable cache pools via a new `framework.cache.pools.tags` option (bool|service-id) * Deprecated auto-injection of the container in AbstractController instances, register them as service subscribers instead + * Deprecated processing of services tagged `security.expression_language_provider` in favor of a new `AddExpressionLanguageProvidersPass` in SecurityBundle. 4.1.0 ----- diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddExpressionLanguageProvidersPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddExpressionLanguageProvidersPass.php index bceacd21ea91b..5a1bc8ad1e58b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddExpressionLanguageProvidersPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddExpressionLanguageProvidersPass.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\AddExpressionLanguageProvidersPass as SecurityExpressionLanguageProvidersPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Reference; @@ -22,6 +23,17 @@ */ class AddExpressionLanguageProvidersPass implements CompilerPassInterface { + private $handleSecurityLanguageProviders; + + public function __construct(bool $handleSecurityLanguageProviders = true) + { + if ($handleSecurityLanguageProviders) { + @trigger_error(sprintf('Registering services tagged "security.expression_language_provider" with "%s" is deprecated since Symfony 4.2, use the "%s" instead.', __CLASS__, SecurityExpressionLanguageProvidersPass::class), E_USER_DEPRECATED); + } + + $this->handleSecurityLanguageProviders = $handleSecurityLanguageProviders; + } + /** * {@inheritdoc} */ @@ -36,7 +48,7 @@ public function process(ContainerBuilder $container) } // security - if ($container->has('security.expression_language')) { + if ($this->handleSecurityLanguageProviders && $container->has('security.expression_language')) { $definition = $container->findDefinition('security.expression_language'); foreach ($container->findTaggedServiceIds('security.expression_language_provider', true) as $id => $attributes) { $definition->addMethodCall('registerProvider', array(new Reference($id))); diff --git a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php index e9143ba56d0e5..eeba01220aa28 100644 --- a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php +++ b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php @@ -101,7 +101,7 @@ public function build(ContainerBuilder $container) $this->addCompilerPassIfExists($container, AddConsoleCommandPass::class, PassConfig::TYPE_BEFORE_REMOVING); $this->addCompilerPassIfExists($container, TranslatorPass::class); $container->addCompilerPass(new LoggingTranslatorPass()); - $container->addCompilerPass(new AddExpressionLanguageProvidersPass()); + $container->addCompilerPass(new AddExpressionLanguageProvidersPass(false)); $this->addCompilerPassIfExists($container, TranslationExtractorPass::class); $this->addCompilerPassIfExists($container, TranslationDumperPass::class); $container->addCompilerPass(new FragmentRendererPass()); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddExpressionLanguageProvidersPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddExpressionLanguageProvidersPassTest.php index 89ba5ff73076a..d8b4c11f510a5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddExpressionLanguageProvidersPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddExpressionLanguageProvidersPassTest.php @@ -22,7 +22,7 @@ class AddExpressionLanguageProvidersPassTest extends TestCase public function testProcessForRouter() { $container = new ContainerBuilder(); - $container->addCompilerPass(new AddExpressionLanguageProvidersPass()); + $container->addCompilerPass(new AddExpressionLanguageProvidersPass(false)); $definition = new Definition('\stdClass'); $definition->addTag('routing.expression_language_provider'); @@ -41,7 +41,7 @@ public function testProcessForRouter() public function testProcessForRouterAlias() { $container = new ContainerBuilder(); - $container->addCompilerPass(new AddExpressionLanguageProvidersPass()); + $container->addCompilerPass(new AddExpressionLanguageProvidersPass(false)); $definition = new Definition('\stdClass'); $definition->addTag('routing.expression_language_provider'); @@ -58,6 +58,10 @@ public function testProcessForRouterAlias() $this->assertEquals(new Reference('some_routing_provider'), $calls[0][1][0]); } + /** + * @group legacy + * @expectedDeprecation Registering services tagged with "security.expression_language_provider" with "Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddExpressionLanguageProvidersPass" is deprecated since Symfony 4.2, use the "Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\AddExpressionLanguageProvidersPass" instead. + */ public function testProcessForSecurity() { $container = new ContainerBuilder(); @@ -76,6 +80,10 @@ public function testProcessForSecurity() $this->assertEquals(new Reference('some_security_provider'), $calls[0][1][0]); } + /** + * @group legacy + * @expectedDeprecation Registering services tagged with "security.expression_language_provider" with "Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddExpressionLanguageProvidersPass" is deprecated since Symfony 4.2, use the "Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\AddExpressionLanguageProvidersPass" instead. + */ public function testProcessForSecurityAlias() { $container = new ContainerBuilder(); @@ -94,4 +102,43 @@ public function testProcessForSecurityAlias() $this->assertEquals('registerProvider', $calls[0][0]); $this->assertEquals(new Reference('some_security_provider'), $calls[0][1][0]); } + + /** + * @group legacy + */ + public function testProcessIgnoreSecurity() + { + $container = new ContainerBuilder(); + $container->addCompilerPass(new AddExpressionLanguageProvidersPass(false)); + + $definition = new Definition('\stdClass'); + $definition->addTag('security.expression_language_provider'); + $container->setDefinition('some_security_provider', $definition->setPublic(true)); + + $container->register('security.expression_language', '\stdClass')->setPublic(true); + $container->compile(); + + $calls = $container->getDefinition('security.expression_language')->getMethodCalls(); + $this->assertCount(0, $calls); + } + + /** + * @group legacy + */ + public function testProcessIgnoreSecurityAlias() + { + $container = new ContainerBuilder(); + $container->addCompilerPass(new AddExpressionLanguageProvidersPass(false)); + + $definition = new Definition('\stdClass'); + $definition->addTag('security.expression_language_provider'); + $container->setDefinition('some_security_provider', $definition->setPublic(true)); + + $container->register('my_security.expression_language', '\stdClass')->setPublic(true); + $container->setAlias('security.expression_language', 'my_security.expression_language'); + $container->compile(); + + $calls = $container->getDefinition('my_security.expression_language')->getMethodCalls(); + $this->assertCount(0, $calls); + } } diff --git a/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md b/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md index 32b9f618adafd..555b802df510c 100644 --- a/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/SecurityBundle/CHANGELOG.md @@ -9,6 +9,7 @@ CHANGELOG the token classes is deprecated. To use custom tokens extend the existing `Symfony\Component\Security\Core\Authentication\Token\AnonymousToken` or `Symfony\Component\Security\Core\Authentication\Token\RememberMeToken`. + * Added `Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\AddExpressionLanguageProvidersPass` 4.1.0 ----- diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddExpressionLanguageProvidersPass.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddExpressionLanguageProvidersPass.php new file mode 100644 index 0000000000000..8d9d7577ef780 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddExpressionLanguageProvidersPass.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Registers the expression language providers. + * + * @author Fabien Potencier + */ +class AddExpressionLanguageProvidersPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + if ($container->has('security.expression_language')) { + $definition = $container->findDefinition('security.expression_language'); + foreach ($container->findTaggedServiceIds('security.expression_language_provider', true) as $id => $attributes) { + $definition->addMethodCall('registerProvider', array(new Reference($id))); + } + } + } +} diff --git a/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php b/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php index 89d7a7f98e99b..a50a5f4884091 100644 --- a/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php +++ b/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\SecurityBundle; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\AddExpressionLanguageProvidersPass; use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\RegisterCsrfTokenClearingLogoutHandlerPass; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\JsonLoginFactory; use Symfony\Component\HttpKernel\Bundle\Bundle; @@ -57,6 +58,7 @@ public function build(ContainerBuilder $container) $extension->addUserProviderFactory(new InMemoryFactory()); $extension->addUserProviderFactory(new LdapFactory()); + $container->addCompilerPass(new AddExpressionLanguageProvidersPass()); $container->addCompilerPass(new AddSecurityVotersPass()); $container->addCompilerPass(new AddSessionDomainConstraintPass(), PassConfig::TYPE_BEFORE_REMOVING); $container->addCompilerPass(new RegisterCsrfTokenClearingLogoutHandlerPass()); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/AddExpressionLanguageProvidersPassTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/AddExpressionLanguageProvidersPassTest.php new file mode 100644 index 0000000000000..6e79f8fc644d1 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/AddExpressionLanguageProvidersPassTest.php @@ -0,0 +1,58 @@ + + * + * 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\AddExpressionLanguageProvidersPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +class AddExpressionLanguageProvidersPassTest extends TestCase +{ + public function testProcessForSecurity() + { + $container = new ContainerBuilder(); + $container->addCompilerPass(new AddExpressionLanguageProvidersPass()); + + $definition = new Definition('\stdClass'); + $definition->addTag('security.expression_language_provider'); + $container->setDefinition('some_security_provider', $definition->setPublic(true)); + + $container->register('security.expression_language', '\stdClass')->setPublic(true); + $container->compile(); + + $calls = $container->getDefinition('security.expression_language')->getMethodCalls(); + $this->assertCount(1, $calls); + $this->assertEquals('registerProvider', $calls[0][0]); + $this->assertEquals(new Reference('some_security_provider'), $calls[0][1][0]); + } + + public function testProcessForSecurityAlias() + { + $container = new ContainerBuilder(); + $container->addCompilerPass(new AddExpressionLanguageProvidersPass()); + + $definition = new Definition('\stdClass'); + $definition->addTag('security.expression_language_provider'); + $container->setDefinition('some_security_provider', $definition->setPublic(true)); + + $container->register('my_security.expression_language', '\stdClass')->setPublic(true); + $container->setAlias('security.expression_language', 'my_security.expression_language'); + $container->compile(); + + $calls = $container->getDefinition('my_security.expression_language')->getMethodCalls(); + $this->assertCount(1, $calls); + $this->assertEquals('registerProvider', $calls[0][0]); + $this->assertEquals(new Reference('some_security_provider'), $calls[0][1][0]); + } +} diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index c58aed2207d65..fa2f9810303f6 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -30,7 +30,7 @@ "symfony/dom-crawler": "~3.4|~4.0", "symfony/event-dispatcher": "~3.4|~4.0", "symfony/form": "~3.4|~4.0", - "symfony/framework-bundle": "~4.1", + "symfony/framework-bundle": "~4.2", "symfony/http-foundation": "~3.4|~4.0", "symfony/translation": "~3.4|~4.0", "symfony/twig-bundle": "~3.4|~4.0", @@ -46,7 +46,7 @@ "conflict": { "symfony/var-dumper": "<3.4", "symfony/event-dispatcher": "<3.4", - "symfony/framework-bundle": "<4.1.1", + "symfony/framework-bundle": "<4.2", "symfony/console": "<3.4" }, "autoload": {