diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig b/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig
index 46804a4d2ed2e..eb40758489d02 100644
--- a/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig
+++ b/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig
@@ -16,47 +16,63 @@
{% endset %}
{% set text %}
- {% if collector.enabled %}
- {% if collector.token %}
+ {% if collector.impersonated %}
+
+ {% endif %}
-
- Authenticated
- {{ is_authenticated ? 'Yes' : 'No' }}
-
+
{% endset %}
{{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: profiler_url, status: color_code }) }}
diff --git a/src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php b/src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php
index 3cfb11404ccf8..62317f625c271 100644
--- a/src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php
+++ b/src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php
@@ -27,6 +27,7 @@ final class FirewallConfig
private $accessDeniedHandler;
private $accessDeniedUrl;
private $listeners;
+ private $switchUser;
/**
* @param string $name
@@ -40,8 +41,9 @@ final class FirewallConfig
* @param string|null $accessDeniedHandler
* @param string|null $accessDeniedUrl
* @param string[] $listeners
+ * @param array|null $switchUser
*/
- public function __construct($name, $userChecker, $requestMatcher = null, $securityEnabled = true, $stateless = false, $provider = null, $context = null, $entryPoint = null, $accessDeniedHandler = null, $accessDeniedUrl = null, $listeners = array())
+ public function __construct($name, $userChecker, $requestMatcher = null, $securityEnabled = true, $stateless = false, $provider = null, $context = null, $entryPoint = null, $accessDeniedHandler = null, $accessDeniedUrl = null, $listeners = array(), $switchUser = null)
{
$this->name = $name;
$this->userChecker = $userChecker;
@@ -54,6 +56,7 @@ public function __construct($name, $userChecker, $requestMatcher = null, $securi
$this->accessDeniedHandler = $accessDeniedHandler;
$this->accessDeniedUrl = $accessDeniedUrl;
$this->listeners = $listeners;
+ $this->switchUser = $switchUser;
}
public function getName()
@@ -140,4 +143,12 @@ public function getListeners()
{
return $this->listeners;
}
+
+ /**
+ * @return array|null The switch_user parameters if configured, null otherwise
+ */
+ public function getSwitchUser()
+ {
+ return $this->switchUser;
+ }
}
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php
index 1c75641daf697..58809ef56f8da 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php
@@ -24,6 +24,7 @@
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Security\Core\Role\RoleHierarchy;
use Symfony\Component\Security\Http\Firewall\ListenerInterface;
+use Symfony\Component\Security\Core\Role\SwitchUserRole;
use Symfony\Component\Security\Http\FirewallMapInterface;
use Symfony\Component\Security\Http\Logout\LogoutUrlGenerator;
@@ -37,6 +38,9 @@ public function testCollectWhenSecurityIsDisabled()
$this->assertSame('security', $collector->getName());
$this->assertFalse($collector->isEnabled());
$this->assertFalse($collector->isAuthenticated());
+ $this->assertFalse($collector->isImpersonated());
+ $this->assertNull($collector->getImpersonatorUser());
+ $this->assertNull($collector->getImpersonationExitPath());
$this->assertNull($collector->getTokenClass());
$this->assertFalse($collector->supportsRoleHierarchy());
$this->assertCount(0, $collector->getRoles());
@@ -53,6 +57,9 @@ public function testCollectWhenAuthenticationTokenIsNull()
$this->assertTrue($collector->isEnabled());
$this->assertFalse($collector->isAuthenticated());
+ $this->assertFalse($collector->isImpersonated());
+ $this->assertNull($collector->getImpersonatorUser());
+ $this->assertNull($collector->getImpersonationExitPath());
$this->assertNull($collector->getTokenClass());
$this->assertTrue($collector->supportsRoleHierarchy());
$this->assertCount(0, $collector->getRoles());
@@ -73,6 +80,9 @@ public function testCollectAuthenticationTokenAndRoles(array $roles, array $norm
$this->assertTrue($collector->isEnabled());
$this->assertTrue($collector->isAuthenticated());
+ $this->assertFalse($collector->isImpersonated());
+ $this->assertNull($collector->getImpersonatorUser());
+ $this->assertNull($collector->getImpersonationExitPath());
$this->assertSame('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $collector->getTokenClass()->getValue());
$this->assertTrue($collector->supportsRoleHierarchy());
$this->assertSame($normalizedRoles, $collector->getRoles()->getValue(true));
@@ -80,6 +90,33 @@ public function testCollectAuthenticationTokenAndRoles(array $roles, array $norm
$this->assertSame('hhamon', $collector->getUser());
}
+ public function testCollectImpersonatedToken()
+ {
+ $adminToken = new UsernamePasswordToken('yceruto', 'P4$$w0rD', 'provider', array('ROLE_ADMIN'));
+
+ $userRoles = array(
+ 'ROLE_USER',
+ new SwitchUserRole('ROLE_PREVIOUS_ADMIN', $adminToken),
+ );
+
+ $tokenStorage = new TokenStorage();
+ $tokenStorage->setToken(new UsernamePasswordToken('hhamon', 'P4$$w0rD', 'provider', $userRoles));
+
+ $collector = new SecurityDataCollector($tokenStorage, $this->getRoleHierarchy());
+ $collector->collect($this->getRequest(), $this->getResponse());
+ $collector->lateCollect();
+
+ $this->assertTrue($collector->isEnabled());
+ $this->assertTrue($collector->isAuthenticated());
+ $this->assertTrue($collector->isImpersonated());
+ $this->assertSame('yceruto', $collector->getImpersonatorUser());
+ $this->assertSame('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $collector->getTokenClass()->getValue());
+ $this->assertTrue($collector->supportsRoleHierarchy());
+ $this->assertSame(array('ROLE_USER', 'ROLE_PREVIOUS_ADMIN'), $collector->getRoles()->getValue(true));
+ $this->assertSame(array(), $collector->getInheritedRoles()->getValue(true));
+ $this->assertSame('hhamon', $collector->getUser());
+ }
+
public function testGetFirewall()
{
$firewallConfig = new FirewallConfig('dummy', 'security.request_matcher.dummy', 'security.user_checker.dummy');
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php
index 220e39b09a723..c2598b51ff927 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php
@@ -107,6 +107,10 @@ public function testFirewalls()
'remember_me',
'anonymous',
),
+ array(
+ 'parameter' => '_switch_user',
+ 'role' => 'ROLE_ALLOWED_TO_SWITCH',
+ ),
),
array(
'host',
@@ -123,6 +127,7 @@ public function testFirewalls()
'http_basic',
'anonymous',
),
+ null,
),
array(
'with_user_checker',
@@ -139,6 +144,7 @@ public function testFirewalls()
'http_basic',
'anonymous',
),
+ null,
),
), $configs);
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SwitchUserTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SwitchUserTest.php
index f12e95671be2c..697829b1cb75a 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SwitchUserTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SwitchUserTest.php
@@ -11,6 +11,8 @@
namespace Symfony\Bundle\SecurityBundle\Tests\Functional;
+use Symfony\Component\Security\Http\Firewall\SwitchUserListener;
+
class SwitchUserTest extends WebTestCase
{
/**
@@ -42,7 +44,7 @@ public function testSwitchedUserExit()
$client = $this->createAuthenticatedClient('user_can_switch');
$client->request('GET', '/profile?_switch_user=user_cannot_switch_1');
- $client->request('GET', '/profile?_switch_user=_exit');
+ $client->request('GET', '/profile?_switch_user='.SwitchUserListener::EXIT_VALUE);
$this->assertEquals(200, $client->getResponse()->getStatusCode());
$this->assertEquals('user_can_switch', $client->getProfile()->getCollector('security')->getUser());
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallConfigTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallConfigTest.php
index a0b4a79c50cdc..4abf33e276694 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallConfigTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallConfigTest.php
@@ -29,6 +29,7 @@ public function testGetters()
'access_denied_url' => 'foo_access_denied_url',
'access_denied_handler' => 'foo_access_denied_handler',
'user_checker' => 'foo_user_checker',
+ 'switch_user' => array('provider' => null, 'parameter' => '_switch_user', 'role' => 'ROLE_ALLOWED_TO_SWITCH'),
);
$config = new FirewallConfig(
@@ -42,7 +43,8 @@ public function testGetters()
$options['entry_point'],
$options['access_denied_handler'],
$options['access_denied_url'],
- $listeners
+ $listeners,
+ $options['switch_user']
);
$this->assertSame('foo_firewall', $config->getName());
@@ -57,5 +59,6 @@ public function testGetters()
$this->assertSame($options['user_checker'], $config->getUserChecker());
$this->assertTrue($config->allowsAnonymous());
$this->assertSame($listeners, $config->getListeners());
+ $this->assertSame($options['switch_user'], $config->getSwitchUser());
}
}
diff --git a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php
index e9c3e4068d530..b4f9b3e0782c0 100644
--- a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php
+++ b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php
@@ -38,6 +38,8 @@
*/
class SwitchUserListener implements ListenerInterface
{
+ const EXIT_VALUE = '_exit';
+
private $tokenStorage;
private $provider;
private $userChecker;
@@ -80,7 +82,7 @@ public function handle(GetResponseEvent $event)
return;
}
- if ('_exit' === $request->get($this->usernameParameter)) {
+ if (self::EXIT_VALUE === $request->get($this->usernameParameter)) {
$this->tokenStorage->setToken($this->attemptExitUser($request));
} else {
try {
diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php
index 43013520c36ba..3174265c08d08 100644
--- a/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php
+++ b/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php
@@ -73,7 +73,7 @@ public function testExitUserThrowsAuthenticationExceptionIfOriginalTokenCannotBe
$token = new UsernamePasswordToken('username', '', 'key', array('ROLE_FOO'));
$this->tokenStorage->setToken($token);
- $this->request->query->set('_switch_user', '_exit');
+ $this->request->query->set('_switch_user', SwitchUserListener::EXIT_VALUE);
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
@@ -84,7 +84,7 @@ public function testExitUserUpdatesToken()
$originalToken = new UsernamePasswordToken('username', '', 'key', array());
$this->tokenStorage->setToken(new UsernamePasswordToken('username', '', 'key', array(new SwitchUserRole('ROLE_PREVIOUS', $originalToken))));
- $this->request->query->set('_switch_user', '_exit');
+ $this->request->query->set('_switch_user', SwitchUserListener::EXIT_VALUE);
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
@@ -108,7 +108,7 @@ public function testExitUserDispatchesEventWithRefreshedUser()
->willReturn($refreshedUser);
$originalToken = new UsernamePasswordToken($originalUser, '', 'key');
$this->tokenStorage->setToken(new UsernamePasswordToken('username', '', 'key', array(new SwitchUserRole('ROLE_PREVIOUS', $originalToken))));
- $this->request->query->set('_switch_user', '_exit');
+ $this->request->query->set('_switch_user', SwitchUserListener::EXIT_VALUE);
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$dispatcher
@@ -132,7 +132,7 @@ public function testExitUserDoesNotDispatchEventWithStringUser()
->method('refreshUser');
$originalToken = new UsernamePasswordToken($originalUser, '', 'key');
$this->tokenStorage->setToken(new UsernamePasswordToken('username', '', 'key', array(new SwitchUserRole('ROLE_PREVIOUS', $originalToken))));
- $this->request->query->set('_switch_user', '_exit');
+ $this->request->query->set('_switch_user', SwitchUserListener::EXIT_VALUE);
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$dispatcher