* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Security\Http\Tests\Firewall; use PHPUnit\Framework\TestCase; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Symfony\Component\Security\Core\Role\SwitchUserRole; use Symfony\Component\Security\Core\User\User; use Symfony\Component\Security\Http\Event\SwitchUserEvent; use Symfony\Component\Security\Http\Firewall\SwitchUserListener; use Symfony\Component\Security\Http\SecurityEvents; class SwitchUserListenerTest extends TestCase { private $tokenStorage; private $userProvider; private $userChecker; private $accessDecisionManager; private $request; private $event; protected function setUp() { $this->tokenStorage = new TokenStorage(); $this->userProvider = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserProviderInterface')->getMock(); $this->userChecker = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserCheckerInterface')->getMock(); $this->accessDecisionManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface')->getMock(); $this->request = new Request(); $this->event = new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $this->request, HttpKernelInterface::MASTER_REQUEST); } /** * @expectedException \InvalidArgumentException * @expectedExceptionMessage $providerKey must not be empty */ public function testProviderKeyIsRequired() { new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, '', $this->accessDecisionManager); } public function testEventIsIgnoredIfUsernameIsNotPassedWithTheRequest() { $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager); $listener->handle($this->event); $this->assertNull($this->event->getResponse()); $this->assertNull($this->tokenStorage->getToken()); } /** * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException */ public function testExitUserThrowsAuthenticationExceptionIfNoCurrentToken() { $this->tokenStorage->setToken(null); $this->request->query->set('_switch_user', '_exit'); $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager); $listener->handle($this->event); } /** * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException */ public function testExitUserThrowsAuthenticationExceptionIfOriginalTokenCannotBeFound() { $token = new UsernamePasswordToken('username', '', 'key', array('ROLE_FOO')); $this->tokenStorage->setToken($token); $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); } 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', SwitchUserListener::EXIT_VALUE); $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager); $listener->handle($this->event); $this->assertSame(array(), $this->request->query->all()); $this->assertSame('', $this->request->server->get('QUERY_STRING')); $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $this->event->getResponse()); $this->assertSame($this->request->getUri(), $this->event->getResponse()->getTargetUrl()); $this->assertSame($originalToken, $this->tokenStorage->getToken()); } public function testExitUserDispatchesEventWithRefreshedUser() { $originalUser = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock(); $refreshedUser = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock(); $this ->userProvider ->expects($this->any()) ->method('refreshUser') ->with($originalUser) ->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', SwitchUserListener::EXIT_VALUE); $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock(); $dispatcher ->expects($this->once()) ->method('dispatch') ->with(SecurityEvents::SWITCH_USER, $this->callback(function (SwitchUserEvent $event) use ($refreshedUser) { return $event->getTargetUser() === $refreshedUser; })) ; $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager, null, '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', $dispatcher); $listener->handle($this->event); } public function testExitUserDoesNotDispatchEventWithStringUser() { $originalUser = 'anon.'; $this ->userProvider ->expects($this->never()) ->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', SwitchUserListener::EXIT_VALUE); $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock(); $dispatcher ->expects($this->never()) ->method('dispatch') ; $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager, null, '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', $dispatcher); $listener->handle($this->event); } /** * @expectedException \Symfony\Component\Security\Core\Exception\AccessDeniedException */ public function testSwitchUserIsDisallowed() { $token = new UsernamePasswordToken('username', '', 'key', array('ROLE_FOO')); $this->tokenStorage->setToken($token); $this->request->query->set('_switch_user', 'kuba'); $this->accessDecisionManager->expects($this->once()) ->method('decide')->with($token, array('ROLE_ALLOWED_TO_SWITCH')) ->will($this->returnValue(false)); $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager); $listener->handle($this->event); } public function testSwitchUser() { $token = new UsernamePasswordToken('username', '', 'key', array('ROLE_FOO')); $user = new User('username', 'password', array()); $this->tokenStorage->setToken($token); $this->request->query->set('_switch_user', 'kuba'); $this->accessDecisionManager->expects($this->once()) ->method('decide')->with($token, array('ROLE_ALLOWED_TO_SWITCH')) ->will($this->returnValue(true)); $this->userProvider->expects($this->once()) ->method('loadUserByUsername')->with('kuba') ->will($this->returnValue($user)); $this->userChecker->expects($this->once()) ->method('checkPostAuth')->with($user); $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager); $listener->handle($this->event); $this->assertSame(array(), $this->request->query->all()); $this->assertSame('', $this->request->server->get('QUERY_STRING')); $this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $this->tokenStorage->getToken()); } public function testSwitchUserKeepsOtherQueryStringParameters() { $token = new UsernamePasswordToken('username', '', 'key', array('ROLE_FOO')); $user = new User('username', 'password', array()); $this->tokenStorage->setToken($token); $this->request->query->replace(array( '_switch_user' => 'kuba', 'page' => 3, 'section' => 2, )); $this->accessDecisionManager->expects($this->once()) ->method('decide')->with($token, array('ROLE_ALLOWED_TO_SWITCH')) ->will($this->returnValue(true)); $this->userProvider->expects($this->once()) ->method('loadUserByUsername')->with('kuba') ->will($this->returnValue($user)); $this->userChecker->expects($this->once()) ->method('checkPostAuth')->with($user); $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager); $listener->handle($this->event); $this->assertSame('page=3§ion=2', $this->request->server->get('QUERY_STRING')); $this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $this->tokenStorage->getToken()); } public function testSwitchUserWithReplacedToken() { $user = new User('username', 'password', array()); $token = new UsernamePasswordToken($user, '', 'provider123', array('ROLE_FOO')); $user = new User('replaced', 'password', array()); $replacedToken = new UsernamePasswordToken($user, '', 'provider123', array('ROLE_BAR')); $this->tokenStorage->setToken($token); $this->request->query->set('_switch_user', 'kuba'); $this->accessDecisionManager->expects($this->any()) ->method('decide')->with($token, array('ROLE_ALLOWED_TO_SWITCH')) ->will($this->returnValue(true)); $this->userProvider->expects($this->any()) ->method('loadUserByUsername')->with('kuba') ->will($this->returnValue($user)); $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock(); $dispatcher ->expects($this->once()) ->method('dispatch') ->with(SecurityEvents::SWITCH_USER, $this->callback(function (SwitchUserEvent $event) use ($replacedToken, $user) { if ($user !== $event->getTargetUser()) { return false; } $event->setToken($replacedToken); return true; })); $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager, null, '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', $dispatcher); $listener->handle($this->event); $this->assertSame($replacedToken, $this->tokenStorage->getToken()); } public function testSwitchUserStateless() { $token = new UsernamePasswordToken('username', '', 'key', array('ROLE_FOO')); $user = new User('username', 'password', array()); $this->tokenStorage->setToken($token); $this->request->query->set('_switch_user', 'kuba'); $this->accessDecisionManager->expects($this->once()) ->method('decide')->with($token, array('ROLE_ALLOWED_TO_SWITCH')) ->will($this->returnValue(true)); $this->userProvider->expects($this->once()) ->method('loadUserByUsername')->with('kuba') ->will($this->returnValue($user)); $this->userChecker->expects($this->once()) ->method('checkPostAuth')->with($user); $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager, null, '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', null, true); $listener->handle($this->event); $this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $this->tokenStorage->getToken()); $this->assertFalse($this->event->hasResponse()); } } __halt_compiler();----SIGNATURE:----dDdWzDP04IM1Dgr90k0SA6XZOj6ywaztnUNoya7RX++07fLsSvXZqlomo+EvMQ6brTomn0opoVbKmARN1Jowe6MCgUS6OVV0lL0fd5juhpYixRfvB8hrpXrUQEc9lGgZqUPikfhjz4kUPZWgn68oyGX6ukEzeQu35uUplpgv4r5Y6tTKJahVCDP6Q8PX0+g2xMt8jClswcVnBSTFRVz8zXuVIpzHf8f0aRRbmvKt+yrJy3U8EdZ3E9B2JX44Bd7+evkkv3a4y+cG7gxqfkTSiwR+/YXzQpB+ME6aBQUEY+f9UDDiPxBZiVGOxzBImnWO53DnKq3Z2ciqYDJIj6xyFC9gncf9Ph87GKqkCviR66i16/WHEQ28sV3RjX0a7U9QKFnZDG8/+GU7Rkxph8PdSz+TQ5qu9Mxn/x223w7K2vGHCe2oZ8W3iMB08AGJKhE/APjkO2JktTGdFXpVQs16GNNbwzfzw2MkHQWd6LMsZr/VIBfD3uyYsP1lDtZ4BTS2C2KDmXIhif8izuCcxwyqoLBQ1Dg5hD6ey0IGJzYe5gN3HZtRSDpAu/LEnTksKopSmHOsEB7bdobupSIWBhxU/J1Vjctic82g2LZnwIct69ZigrKrlr/RnhdqRW1IRJWls6+uV4h/PXz6FF4ttYPaUknxiQ0IpbfrcgVlKEQDFYY=----ATTACHMENT:----NTA4OTc1NzYwMTE1OTQzOCA0NzQ1MDMxNDYyMTc2MTc2IDcwMDI3MzcwMTUyNzg2Njk=