Skip to content

Commit 5a07c29

Browse files
[Security] Make stateful firewalls turn responses private only when needed
1 parent 62f60fc commit 5a07c29

File tree

3 files changed

+131
-1
lines changed

3 files changed

+131
-1
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Security\Core\Authentication\Token\Storage;
13+
14+
use Psr\Container\ContainerInterface;
15+
use Symfony\Component\HttpFoundation\Session\SessionInterface;
16+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
17+
use Symfony\Contracts\Service\ServiceSubscriberInterface;
18+
19+
/**
20+
* A token storage that increments the session usage index when the token is accessed.
21+
*
22+
* @author Nicolas Grekas <[email protected]>
23+
*/
24+
final class UsageTrackingTokenStorage implements TokenStorageInterface, ServiceSubscriberInterface
25+
{
26+
private $storage;
27+
private $sessionLocator;
28+
private $enableUsageTracking = false;
29+
30+
public function __construct(TokenStorageInterface $storage, ContainerInterface $sessionLocator)
31+
{
32+
$this->storage = $storage;
33+
$this->sessionLocator = $sessionLocator;
34+
}
35+
36+
/**
37+
* {@inheritdoc}
38+
*/
39+
public function getToken(): ?TokenInterface
40+
{
41+
if ($this->enableUsageTracking) {
42+
// increments the internal session usage index
43+
$this->sessionLocator->get('session')->getMetadataBag();
44+
}
45+
46+
return $this->storage->getToken();
47+
}
48+
49+
/**
50+
* {@inheritdoc}
51+
*/
52+
public function setToken(TokenInterface $token = null): void
53+
{
54+
$this->storage->setToken($token);
55+
}
56+
57+
public function enableUsageTracking(): void
58+
{
59+
$this->enableUsageTracking = true;
60+
}
61+
62+
public function disableUsageTracking(): void
63+
{
64+
$this->enableUsageTracking = false;
65+
}
66+
67+
public static function getSubscribedServices(): array
68+
{
69+
return [
70+
'session' => SessionInterface::class,
71+
];
72+
}
73+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Security\Core\Tests\Authentication\Token\Storage;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Psr\Container\ContainerInterface;
16+
use Symfony\Component\HttpFoundation\Session\SessionInterface;
17+
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
18+
use Symfony\Component\Security\Core\Authentication\Token\Storage\UsageTrackingTokenStorage;
19+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
20+
use Symfony\Contracts\Service\ServiceLocatorTrait;
21+
22+
class UsageTrackingTokenStorageTest extends TestCase
23+
{
24+
public function testGetSetToken()
25+
{
26+
$sessionAccess = 0;
27+
$sessionLocator = new class(['session' => function () use (&$sessionAccess) {
28+
++$sessionAccess;
29+
30+
$session = $this->createMock(SessionInterface::class);
31+
$session->expects($this->once())
32+
->method('getMetadataBag');
33+
34+
return $session;
35+
}]) implements ContainerInterface {
36+
use ServiceLocatorTrait;
37+
};
38+
$tokenStorage = new TokenStorage();
39+
$trackingStorage = new UsageTrackingTokenStorage($tokenStorage, $sessionLocator);
40+
41+
$this->assertNull($trackingStorage->getToken());
42+
$token = $this->getMockBuilder(TokenInterface::class)->getMock();
43+
44+
$trackingStorage->setToken($token);
45+
$this->assertSame($token, $trackingStorage->getToken());
46+
$this->assertSame($token, $tokenStorage->getToken());
47+
$this->assertSame(0, $sessionAccess);
48+
49+
$trackingStorage->enableUsageTracking();
50+
$this->assertSame($token, $trackingStorage->getToken());
51+
$this->assertSame(1, $sessionAccess);
52+
53+
$trackingStorage->disableUsageTracking();
54+
$this->assertSame($token, $trackingStorage->getToken());
55+
$this->assertSame(1, $sessionAccess);
56+
}
57+
}

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"require": {
1919
"php": "^7.1.3",
2020
"symfony/event-dispatcher-contracts": "^1.1|^2",
21-
"symfony/service-contracts": "^1.1|^2"
21+
"symfony/service-contracts": "^1.1.6|^2"
2222
},
2323
"require-dev": {
2424
"psr/container": "^1.0",

0 commit comments

Comments
 (0)