From 77fb0eb0a16eaaf7dcf469cf2d039249c12e1286 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Tue, 16 Mar 2021 14:36:31 +0100 Subject: [PATCH] [Security] Add XML support for authenticator manager --- .../Security/Factory/LoginLinkFactory.php | 6 +++- .../Resources/config/schema/security-1.0.xsd | 23 +++++++++++++ .../security_authenticator_login_link.php | 1 - .../CompleteConfigurationTest.php | 34 +++++++++++++++++++ .../Fixtures/php/authenticator_manager.php | 20 +++++++++++ .../Fixtures/xml/authenticator_manager.xml | 24 +++++++++++++ .../Fixtures/yml/authenticator_manager.yml | 13 +++++++ 7 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/authenticator_manager.php create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/authenticator_manager.xml create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/authenticator_manager.yml diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginLinkFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginLinkFactory.php index 3afddb3d35..0b99f281e9 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginLinkFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginLinkFactory.php @@ -31,7 +31,7 @@ class LoginLinkFactory extends AbstractFactory implements AuthenticatorFactoryIn public function addConfiguration(NodeDefinition $node) { /** @var NodeBuilder $builder */ - $builder = $node->children(); + $builder = $node->fixXmlConfig('signature_property', 'signature_properties')->children(); $builder ->scalarNode('check_route') @@ -98,6 +98,10 @@ class LoginLinkFactory extends AbstractFactory implements AuthenticatorFactoryIn if (null !== $config['max_uses'] && !isset($config['used_link_cache'])) { $config['used_link_cache'] = 'security.authenticator.cache.expired_links'; + $defaultCacheDefinition = $container->getDefinition($config['used_link_cache']); + if (!$defaultCacheDefinition->hasTag('cache.pool')) { + $defaultCacheDefinition->addTag('cache.pool'); + } } $expiredStorageId = null; diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/schema/security-1.0.xsd b/src/Symfony/Bundle/SecurityBundle/Resources/config/schema/security-1.0.xsd index 8ff0d5e46d..509ac0b053 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/schema/security-1.0.xsd +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/schema/security-1.0.xsd @@ -23,6 +23,7 @@ + @@ -141,6 +142,7 @@ + @@ -160,6 +162,7 @@ + @@ -231,6 +234,7 @@ + @@ -283,6 +287,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator_login_link.php b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator_login_link.php index 2efb089262..2248b5e8ee 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator_login_link.php +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator_login_link.php @@ -51,7 +51,6 @@ return static function (ContainerConfigurator $container) { ->set('security.authenticator.cache.expired_links') ->parent('cache.app') ->private() - ->tag('cache.pool') ->set('security.authenticator.firewall_aware_login_link_handler', FirewallAwareLoginLinkHandler::class) ->args([ diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php index 072e33aca6..47d3033a25 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php @@ -21,6 +21,7 @@ use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\Security\Core\Authorization\AccessDecisionManager; use Symfony\Component\Security\Core\Encoder\NativePasswordEncoder; use Symfony\Component\Security\Core\Encoder\SodiumPasswordEncoder; +use Symfony\Component\Security\Http\Authentication\AuthenticatorManager; abstract class CompleteConfigurationTest extends TestCase { @@ -28,6 +29,38 @@ abstract class CompleteConfigurationTest extends TestCase abstract protected function getFileExtension(); + public function testAuthenticatorManager() + { + $container = $this->getContainer('authenticator_manager'); + + $this->assertEquals(AuthenticatorManager::class, $container->getDefinition('security.authenticator.manager.main')->getClass()); + + // login link + $expiredStorage = $container->getDefinition($expiredStorageId = 'security.authenticator.expired_login_link_storage.main'); + $this->assertEquals('cache.redis', (string) $expiredStorage->getArgument(0)); + $this->assertEquals(3600, (string) $expiredStorage->getArgument(1)); + + $linker = $container->getDefinition($linkerId = 'security.authenticator.login_link_handler.main'); + $this->assertEquals(['id', 'email'], $linker->getArgument(3)); + $this->assertEquals([ + 'route_name' => 'login_check', + 'lifetime' => 3600, + 'max_uses' => 1, + ], $linker->getArgument(5)); + $this->assertEquals($expiredStorageId, (string) $linker->getArgument(6)); + + $authenticator = $container->getDefinition('security.authenticator.login_link.main'); + $this->assertEquals($linkerId, (string) $authenticator->getArgument(0)); + $this->assertEquals([ + 'check_route' => 'login_check', + 'check_post_only' => true, + ], $authenticator->getArgument(4)); + + // login throttling + $listener = $container->getDefinition('security.listener.login_throttling.main'); + $this->assertEquals('app.rate_limiter', (string) $listener->getArgument(1)); + } + public function testRolesHierarchy() { $container = $this->getContainer('container1'); @@ -648,6 +681,7 @@ abstract class CompleteConfigurationTest extends TestCase $container->setParameter('kernel.debug', false); $container->setParameter('request_listener.http_port', 80); $container->setParameter('request_listener.https_port', 443); + $container->register('cache.app', \stdClass::class); $security = new SecurityExtension(); $container->registerExtension($security); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/authenticator_manager.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/authenticator_manager.php new file mode 100644 index 0000000000..31a37fe210 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/authenticator_manager.php @@ -0,0 +1,20 @@ +loadFromExtension('security', [ + 'enable_authenticator_manager' => true, + 'firewalls' => [ + 'main' => [ + 'login_link' => [ + 'check_route' => 'login_check', + 'check_post_only' => true, + 'signature_properties' => ['id', 'email'], + 'max_uses' => 1, + 'lifetime' => 3600, + 'used_link_cache' => 'cache.redis', + ], + 'login_throttling' => [ + 'limiter' => 'app.rate_limiter', + ], + ], + ], +]); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/authenticator_manager.xml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/authenticator_manager.xml new file mode 100644 index 0000000000..2a3b643a6e --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/authenticator_manager.xml @@ -0,0 +1,24 @@ + + + + + + + id + email + + + + + diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/authenticator_manager.yml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/authenticator_manager.yml new file mode 100644 index 0000000000..8ff11698ae --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/authenticator_manager.yml @@ -0,0 +1,13 @@ +security: + enable_authenticator_manager: true + firewalls: + main: + login_link: + check_route: login_check + check_post_only: true + signature_properties: [id, email] + max_uses: 1 + lifetime: 3600 + used_link_cache: 'cache.redis' + login_throttling: + limiter: 'app.rate_limiter'