bug #38869 [SecurityBundle] inject only compatible token storage implementations for usage tracking (xabbuh)

This PR was merged into the 4.4 branch.

Discussion
----------

[SecurityBundle] inject only compatible token storage implementations for usage tracking

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #36720
| License       | MIT
| Doc PR        |

Commits
-------

d915e44dd0 inject only compatible token storage implementations for usage tracking
This commit is contained in:
Wouter de Jong 2020-10-31 13:26:36 +01:00
commit d71c404a9f
2 changed files with 95 additions and 2 deletions

View File

@ -45,8 +45,12 @@ class RegisterTokenUsageTrackingPass implements CompilerPassInterface
$container->setAlias('security.token_storage', 'security.untracked_token_storage')->setPublic(true);
$container->getDefinition('security.untracked_token_storage')->addTag('kernel.reset', ['method' => 'reset']);
} elseif ($container->hasDefinition('security.context_listener')) {
$container->getDefinition('security.context_listener')
->setArgument(6, [new Reference('security.token_storage'), 'enableUsageTracking']);
$tokenStorageClass = $container->getParameterBag()->resolveValue($container->findDefinition('security.token_storage')->getClass());
if (method_exists($tokenStorageClass, 'enableUsageTracking')) {
$container->getDefinition('security.context_listener')
->setArgument(6, [new Reference('security.token_storage'), 'enableUsageTracking']);
}
}
}
}

View File

@ -0,0 +1,89 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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\RegisterTokenUsageTrackingPass;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authentication\Token\Storage\UsageTrackingTokenStorage;
use Symfony\Component\Security\Http\Firewall\ContextListener;
class RegisterTokenUsageTrackingPassTest extends TestCase
{
public function testTokenStorageIsUntrackedIfSessionIsMissing()
{
$container = new ContainerBuilder();
$container->register('security.untracked_token_storage', TokenStorage::class);
$compilerPass = new RegisterTokenUsageTrackingPass();
$compilerPass->process($container);
$this->assertTrue($container->hasAlias('security.token_storage'));
$this->assertEquals(new Alias('security.untracked_token_storage', true), $container->getAlias('security.token_storage'));
}
public function testContextListenerIsNotModifiedIfTokenStorageDoesNotSupportUsageTracking()
{
$container = new ContainerBuilder();
$container->setParameter('security.token_storage.class', TokenStorage::class);
$container->register('session', Session::class);
$container->register('security.context_listener', ContextListener::class)
->setArguments([
new Reference('security.untracked_token_storage'),
[],
'main',
new Reference('logger', ContainerInterface::NULL_ON_INVALID_REFERENCE),
new Reference('event_dispatcher', ContainerInterface::NULL_ON_INVALID_REFERENCE),
new Reference('security.authentication.trust_resolver'),
]);
$container->register('security.token_storage', '%security.token_storage.class%');
$container->register('security.untracked_token_storage', TokenStorage::class);
$compilerPass = new RegisterTokenUsageTrackingPass();
$compilerPass->process($container);
$this->assertCount(6, $container->getDefinition('security.context_listener')->getArguments());
}
public function testContextListenerEnablesUsageTrackingIfSupportedByTokenStorage()
{
$container = new ContainerBuilder();
$container->setParameter('security.token_storage.class', UsageTrackingTokenStorage::class);
$container->register('session', Session::class);
$container->register('security.context_listener', ContextListener::class)
->setArguments([
new Reference('security.untracked_token_storage'),
[],
'main',
new Reference('logger', ContainerInterface::NULL_ON_INVALID_REFERENCE),
new Reference('event_dispatcher', ContainerInterface::NULL_ON_INVALID_REFERENCE),
new Reference('security.authentication.trust_resolver'),
]);
$container->register('security.token_storage', '%security.token_storage.class%');
$container->register('security.untracked_token_storage', TokenStorage::class);
$compilerPass = new RegisterTokenUsageTrackingPass();
$compilerPass->process($container);
$contextListener = $container->getDefinition('security.context_listener');
$this->assertCount(7, $container->getDefinition('security.context_listener')->getArguments());
$this->assertEquals([new Reference('security.token_storage'), 'enableUsageTracking'], $contextListener->getArgument(6));
}
}