Skip to content

Commit e386fea

Browse files
committed
Merge branch 'onEXHovia-switch-user'
2 parents 2e8f5ec + a0ac504 commit e386fea

File tree

7 files changed

+136
-0
lines changed

7 files changed

+136
-0
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the FOSHttpCacheBundle package.
5+
*
6+
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
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 FOS\HttpCacheBundle\EventListener;
13+
14+
use FOS\HttpCacheBundle\UserContextInvalidator;
15+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
16+
use Symfony\Component\Security\Http\Event\SwitchUserEvent;
17+
use Symfony\Component\Security\Http\SecurityEvents;
18+
19+
class SwitchUserListener implements EventSubscriberInterface
20+
{
21+
private $invalidator;
22+
23+
public function __construct(UserContextInvalidator $invalidator)
24+
{
25+
$this->invalidator = $invalidator;
26+
}
27+
28+
/**
29+
* {@inheritdoc}
30+
*/
31+
public static function getSubscribedEvents(): array
32+
{
33+
return [
34+
SecurityEvents::SWITCH_USER => 'onSwitchUser',
35+
];
36+
}
37+
38+
public function onSwitchUser(SwitchUserEvent $event)
39+
{
40+
$request = $event->getRequest();
41+
$this->invalidator->invalidateContext($request->getSession()->getId());
42+
}
43+
}

src/Resources/config/user_context.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@
3939
<argument type="service" id="fos_http_cache.user_context_invalidator" />
4040
</service>
4141

42+
<service id="fos_http_cache.user_context.switch_user_listener" class="FOS\HttpCacheBundle\EventListener\SwitchUserListener" public="false">
43+
<argument type="service" id="fos_http_cache.user_context_invalidator" />
44+
<tag name="kernel.event_subscriber" />
45+
</service>
46+
4247
<service id="fos_http_cache.user_context.session_listener" class="FOS\HttpCacheBundle\EventListener\SessionListener" decorates="session_listener" public="false">
4348
<argument type="service" id="fos_http_cache.user_context.session_listener.inner" />
4449
<argument /> <!-- set by extension -->
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the FOSHttpCacheBundle package.
5+
*
6+
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
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 FOS\HttpCacheBundle\Tests\Functional\EventListener;
13+
14+
use FOS\HttpCache\ProxyClient\Varnish;
15+
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
16+
use Symfony\Bundle\FrameworkBundle\Client;
17+
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
18+
use Symfony\Component\BrowserKit\Cookie;
19+
use Symfony\Component\HttpFoundation\Session\Session;
20+
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
21+
use Symfony\Component\Security\Core\User\User;
22+
23+
class SwitchUserListenerTest extends WebTestCase
24+
{
25+
use MockeryPHPUnitIntegration;
26+
27+
public function testSwitchUserCompatibility()
28+
{
29+
$client = static::createClient();
30+
$session = $client->getContainer()->get('session');
31+
$this->loginAsAdmin($client, $session);
32+
33+
$client->request('GET', '/secured_area/switch_user?_switch_user=user');
34+
$client->request('GET', '/secured_area/switch_user');
35+
$this->assertSame('user', substr($client->getResponse()->getContent(), 0, 2000));
36+
37+
$client->request('GET', '/secured_area/switch_user?_switch_user=_exit');
38+
$client->request('GET', '/secured_area/switch_user');
39+
$this->assertSame('admin', substr($client->getResponse()->getContent(), 0, 2000));
40+
}
41+
42+
public function testInvalidateContext()
43+
{
44+
$client = static::createClient();
45+
$session = $client->getContainer()->get('session');
46+
$this->loginAsAdmin($client, $session);
47+
48+
$mock = \Mockery::mock(Varnish::class);
49+
$mock->shouldReceive('invalidateTags')
50+
->once()
51+
->with(['fos_http_cache_hashlookup-test']);
52+
53+
$mock->shouldReceive('flush')
54+
->once()
55+
->andReturn(1);
56+
57+
$client->getContainer()->set('fos_http_cache.proxy_client.varnish', $mock);
58+
$client->request('GET', '/secured_area/switch_user?_switch_user=user');
59+
}
60+
61+
private function loginAsAdmin(Client $client, Session $session, $firewallName = 'secured_area', $sessionId = 'test')
62+
{
63+
$token = new UsernamePasswordToken(new User('admin', 'admin'), null, $firewallName, ['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH']);
64+
65+
$session->setId($sessionId);
66+
$session->set(sprintf('_security_%s', $firewallName), serialize($token));
67+
$session->save();
68+
69+
$client->getCookieJar()->set(new Cookie($session->getName(), $session->getId()));
70+
}
71+
}

tests/Functional/Fixtures/Controller/TestController.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,11 @@ public function sessionAction()
3030

3131
return $response;
3232
}
33+
34+
public function switchUserAction()
35+
{
36+
$user = $this->getUser();
37+
38+
return new Response($user->getUsername());
39+
}
3340
}

tests/Functional/Fixtures/app/config/config.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,13 @@ security:
6565
memory:
6666
users:
6767
user: { password: user, roles: 'ROLE_USER' }
68+
admin: { password: admin, roles: ['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH'] }
6869
encoders:
6970
Symfony\Component\Security\Core\User\User: plaintext
7071
firewalls:
7172
secured_area:
7273
pattern: ^/secured_area
7374
anonymous:
75+
switch_user: true
7476
logout:
7577
path: /secured_area/logout

tests/Functional/Fixtures/app/config/routing.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ test_cached_session:
4141
path: /secured_area/cached_session
4242
defaults: { _controller: FOS\HttpCacheBundle\Tests\Functional\Fixtures\Controller\TestController::sessionAction }
4343

44+
test_switch_user:
45+
path: /secured_area/switch_user
46+
defaults: { _controller: FOS\HttpCacheBundle\Tests\Functional\Fixtures\Controller\TestController::switchUserAction }
47+
4448
test_noncached:
4549
path: /noncached
4650
defaults: { _controller: FOS\HttpCacheBundle\Tests\Functional\Fixtures\Controller\TestController::contentAction }

tests/Functional/Fixtures/app/config/routing_41.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ test_cached_session:
4141
path: /secured_area/cached_session
4242
controller: FOS\HttpCacheBundle\Tests\Functional\Fixtures\Controller\TestController::sessionAction
4343

44+
test_switch_user:
45+
path: /secured_area/switch_user
46+
controller: FOS\HttpCacheBundle\Tests\Functional\Fixtures\Controller\TestController::switchUserAction
47+
4448
test_noncached:
4549
path: /noncached
4650
controller: FOS\HttpCacheBundle\Tests\Functional\Fixtures\Controller\TestController::contentAction

0 commit comments

Comments
 (0)