* * 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:----s3o9P6l68wly+tNgycz1nCjgF59+PUWnYbbxJ6aMj0m2NQuq+NPLG0UObDw8Vh3M9peqLwJ3sPx/28FFl4fvA60EWB+WK2Rmf93rpo4Bg2tt9tb+8uWSGmYKvrXY3NtzUyDYPfeinAxOtv/qzIzqRSgilbzknSlkjcMi86Q0Fxtzkg7HWOaRrSXIwF/5VDOaspNDmxx0zpCVVQY6PfdY/4M77Wl7IWYwa0+sSuifiIdf7tIaALfEG3WBkgmI5/zEOoGwNv5jfKE1fN+Y72NLruji6Gaoui5A0cIiF4MlRYV7NWlgxAoWg/lFRmaPnsZF00y5FpzRqlVBMlBWi4hAQ9QXBIxwB6X/xD/3FjAPFhVA5GRa6USVW8fiko2B04oT+FEuHwv35v+ZatGF8q79afAnEAxdakgJfLg/uV/Vh9rsbuxuzN9eUIFbqGXShDG8XIvXnk1zzAsmJ0L+8xxUNSzjrNdxquhzTkAgQ2/YjywV+tLULlmukdTevUGARsKv4W+JxsSAbYPKvn3HaHaMIHnR/XrOX34hXxXF9oqvhhI9G5HsbDKW26udJ/NWcyt5Ju50vgt0TP51InvcgEz45aWfZ9PB/PqD33SFYC7RShbkzNIxG8lweFTBFkbKJ17+rC5D1RFWfO1s/ROWGpxPA27A5pyfQvJIrdSU/JaFd+g=----ATTACHMENT:----NzQ1NDk3NTk5NTM5MDEyMSA2NTQxMjAzOTM4MTgzNTM5IDgzNjMzNDYxMTYxNTMzODQ=