diff options
Diffstat (limited to 'Http/Tests/Firewall')
-rw-r--r-- | Http/Tests/Firewall/AbstractPreAuthenticatedListenerTest.php | 252 | ||||
-rw-r--r-- | Http/Tests/Firewall/AccessListenerTest.php | 208 | ||||
-rw-r--r-- | Http/Tests/Firewall/AnonymousAuthenticationListenerTest.php | 87 | ||||
-rw-r--r-- | Http/Tests/Firewall/BasicAuthenticationListenerTest.php | 249 | ||||
-rw-r--r-- | Http/Tests/Firewall/ChannelListenerTest.php | 180 | ||||
-rw-r--r-- | Http/Tests/Firewall/ContextListenerTest.php | 267 | ||||
-rw-r--r-- | Http/Tests/Firewall/DigestDataTest.php | 181 | ||||
-rw-r--r-- | Http/Tests/Firewall/ExceptionListenerTest.php | 184 | ||||
-rw-r--r-- | Http/Tests/Firewall/LogoutListenerTest.php | 235 | ||||
-rw-r--r-- | Http/Tests/Firewall/RememberMeListenerTest.php | 415 | ||||
-rw-r--r-- | Http/Tests/Firewall/RemoteUserAuthenticationListenerTest.php | 91 | ||||
-rw-r--r-- | Http/Tests/Firewall/SimplePreAuthenticationListenerTest.php | 128 | ||||
-rw-r--r-- | Http/Tests/Firewall/SwitchUserListenerTest.php | 260 | ||||
-rw-r--r-- | Http/Tests/Firewall/X509AuthenticationListenerTest.php | 123 |
14 files changed, 2860 insertions, 0 deletions
diff --git a/Http/Tests/Firewall/AbstractPreAuthenticatedListenerTest.php b/Http/Tests/Firewall/AbstractPreAuthenticatedListenerTest.php new file mode 100644 index 0000000..61f086a --- /dev/null +++ b/Http/Tests/Firewall/AbstractPreAuthenticatedListenerTest.php @@ -0,0 +1,252 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * 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 Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken; +use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; +use Symfony\Component\Security\Core\Exception\AuthenticationException; + +class AbstractPreAuthenticatedListenerTest extends \PHPUnit_Framework_TestCase +{ + public function testHandleWithValidValues() + { + $userCredentials = array('TheUser', 'TheCredentials'); + + $request = new Request(array(), array(), array(), array(), array(), array()); + + $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $tokenStorage + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue(null)) + ; + $tokenStorage + ->expects($this->once()) + ->method('setToken') + ->with($this->equalTo($token)) + ; + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + $authenticationManager + ->expects($this->once()) + ->method('authenticate') + ->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken')) + ->will($this->returnValue($token)) + ; + + $listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array( + $tokenStorage, + $authenticationManager, + 'TheProviderKey', + )); + $listener + ->expects($this->once()) + ->method('getPreAuthenticatedData') + ->will($this->returnValue($userCredentials)); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $listener->handle($event); + } + + public function testHandleWhenAuthenticationFails() + { + $userCredentials = array('TheUser', 'TheCredentials'); + + $request = new Request(array(), array(), array(), array(), array(), array()); + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $tokenStorage + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue(null)) + ; + $tokenStorage + ->expects($this->never()) + ->method('setToken') + ; + + $exception = new AuthenticationException('Authentication failed.'); + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + $authenticationManager + ->expects($this->once()) + ->method('authenticate') + ->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken')) + ->will($this->throwException($exception)) + ; + + $listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array( + $tokenStorage, + $authenticationManager, + 'TheProviderKey', + )); + $listener + ->expects($this->once()) + ->method('getPreAuthenticatedData') + ->will($this->returnValue($userCredentials)); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $listener->handle($event); + } + + public function testHandleWhenAuthenticationFailsWithDifferentToken() + { + $userCredentials = array('TheUser', 'TheCredentials'); + + $token = new UsernamePasswordToken('TheUsername', 'ThePassword', 'TheProviderKey', array('ROLE_FOO')); + + $request = new Request(array(), array(), array(), array(), array(), array()); + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $tokenStorage + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue($token)) + ; + $tokenStorage + ->expects($this->never()) + ->method('setToken') + ; + + $exception = new AuthenticationException('Authentication failed.'); + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + $authenticationManager + ->expects($this->once()) + ->method('authenticate') + ->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken')) + ->will($this->throwException($exception)) + ; + + $listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array( + $tokenStorage, + $authenticationManager, + 'TheProviderKey', + )); + $listener + ->expects($this->once()) + ->method('getPreAuthenticatedData') + ->will($this->returnValue($userCredentials)); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $listener->handle($event); + } + + public function testHandleWithASimilarAuthenticatedToken() + { + $userCredentials = array('TheUser', 'TheCredentials'); + + $request = new Request(array(), array(), array(), array(), array(), array()); + + $token = new PreAuthenticatedToken('TheUser', 'TheCredentials', 'TheProviderKey', array('ROLE_FOO')); + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $tokenStorage + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue($token)) + ; + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + $authenticationManager + ->expects($this->never()) + ->method('authenticate') + ; + + $listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array( + $tokenStorage, + $authenticationManager, + 'TheProviderKey', + )); + $listener + ->expects($this->once()) + ->method('getPreAuthenticatedData') + ->will($this->returnValue($userCredentials)); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $listener->handle($event); + } + + public function testHandleWithAnInvalidSimilarToken() + { + $userCredentials = array('TheUser', 'TheCredentials'); + + $request = new Request(array(), array(), array(), array(), array(), array()); + + $token = new PreAuthenticatedToken('AnotherUser', 'TheCredentials', 'TheProviderKey', array('ROLE_FOO')); + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $tokenStorage + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue($token)) + ; + $tokenStorage + ->expects($this->once()) + ->method('setToken') + ->with($this->equalTo(null)) + ; + + $exception = new AuthenticationException('Authentication failed.'); + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + $authenticationManager + ->expects($this->once()) + ->method('authenticate') + ->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken')) + ->will($this->throwException($exception)) + ; + + $listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array( + $tokenStorage, + $authenticationManager, + 'TheProviderKey', + )); + $listener + ->expects($this->once()) + ->method('getPreAuthenticatedData') + ->will($this->returnValue($userCredentials)); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $listener->handle($event); + } +} diff --git a/Http/Tests/Firewall/AccessListenerTest.php b/Http/Tests/Firewall/AccessListenerTest.php new file mode 100644 index 0000000..af9d565 --- /dev/null +++ b/Http/Tests/Firewall/AccessListenerTest.php @@ -0,0 +1,208 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * 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 Symfony\Component\Security\Http\Firewall\AccessListener; + +class AccessListenerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @expectedException \Symfony\Component\Security\Core\Exception\AccessDeniedException + */ + public function testHandleWhenTheAccessDecisionManagerDecidesToRefuseAccess() + { + $request = $this->getMock('Symfony\Component\HttpFoundation\Request', array(), array(), '', false, false); + + $accessMap = $this->getMock('Symfony\Component\Security\Http\AccessMapInterface'); + $accessMap + ->expects($this->any()) + ->method('getPatterns') + ->with($this->equalTo($request)) + ->will($this->returnValue(array(array('foo' => 'bar'), null))) + ; + + $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + $token + ->expects($this->any()) + ->method('isAuthenticated') + ->will($this->returnValue(true)) + ; + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $tokenStorage + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue($token)) + ; + + $accessDecisionManager = $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface'); + $accessDecisionManager + ->expects($this->once()) + ->method('decide') + ->with($this->equalTo($token), $this->equalTo(array('foo' => 'bar')), $this->equalTo($request)) + ->will($this->returnValue(false)) + ; + + $listener = new AccessListener( + $tokenStorage, + $accessDecisionManager, + $accessMap, + $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface') + ); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $listener->handle($event); + } + + public function testHandleWhenTheTokenIsNotAuthenticated() + { + $request = $this->getMock('Symfony\Component\HttpFoundation\Request', array(), array(), '', false, false); + + $accessMap = $this->getMock('Symfony\Component\Security\Http\AccessMapInterface'); + $accessMap + ->expects($this->any()) + ->method('getPatterns') + ->with($this->equalTo($request)) + ->will($this->returnValue(array(array('foo' => 'bar'), null))) + ; + + $notAuthenticatedToken = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + $notAuthenticatedToken + ->expects($this->any()) + ->method('isAuthenticated') + ->will($this->returnValue(false)) + ; + + $authenticatedToken = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + $authenticatedToken + ->expects($this->any()) + ->method('isAuthenticated') + ->will($this->returnValue(true)) + ; + + $authManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + $authManager + ->expects($this->once()) + ->method('authenticate') + ->with($this->equalTo($notAuthenticatedToken)) + ->will($this->returnValue($authenticatedToken)) + ; + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $tokenStorage + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue($notAuthenticatedToken)) + ; + $tokenStorage + ->expects($this->once()) + ->method('setToken') + ->with($this->equalTo($authenticatedToken)) + ; + + $accessDecisionManager = $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface'); + $accessDecisionManager + ->expects($this->once()) + ->method('decide') + ->with($this->equalTo($authenticatedToken), $this->equalTo(array('foo' => 'bar')), $this->equalTo($request)) + ->will($this->returnValue(true)) + ; + + $listener = new AccessListener( + $tokenStorage, + $accessDecisionManager, + $accessMap, + $authManager + ); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $listener->handle($event); + } + + public function testHandleWhenThereIsNoAccessMapEntryMatchingTheRequest() + { + $request = $this->getMock('Symfony\Component\HttpFoundation\Request', array(), array(), '', false, false); + + $accessMap = $this->getMock('Symfony\Component\Security\Http\AccessMapInterface'); + $accessMap + ->expects($this->any()) + ->method('getPatterns') + ->with($this->equalTo($request)) + ->will($this->returnValue(array(null, null))) + ; + + $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + $token + ->expects($this->never()) + ->method('isAuthenticated') + ; + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $tokenStorage + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue($token)) + ; + + $listener = new AccessListener( + $tokenStorage, + $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface'), + $accessMap, + $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface') + ); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $listener->handle($event); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException + */ + public function testHandleWhenTheSecurityTokenStorageHasNoToken() + { + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $tokenStorage + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue(null)) + ; + + $listener = new AccessListener( + $tokenStorage, + $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface'), + $this->getMock('Symfony\Component\Security\Http\AccessMapInterface'), + $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface') + ); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + + $listener->handle($event); + } +} diff --git a/Http/Tests/Firewall/AnonymousAuthenticationListenerTest.php b/Http/Tests/Firewall/AnonymousAuthenticationListenerTest.php new file mode 100644 index 0000000..3450c1e --- /dev/null +++ b/Http/Tests/Firewall/AnonymousAuthenticationListenerTest.php @@ -0,0 +1,87 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * 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 Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; +use Symfony\Component\Security\Http\Firewall\AnonymousAuthenticationListener; + +class AnonymousAuthenticationListenerTest extends \PHPUnit_Framework_TestCase +{ + public function testHandleWithTokenStorageHavingAToken() + { + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $tokenStorage + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'))) + ; + $tokenStorage + ->expects($this->never()) + ->method('setToken') + ; + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + $authenticationManager + ->expects($this->never()) + ->method('authenticate') + ; + + $listener = new AnonymousAuthenticationListener($tokenStorage, 'TheKey', null, $authenticationManager); + $listener->handle($this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false)); + } + + public function testHandleWithTokenStorageHavingNoToken() + { + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $tokenStorage + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue(null)) + ; + + $anonymousToken = new AnonymousToken('TheKey', 'anon.', array()); + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + $authenticationManager + ->expects($this->once()) + ->method('authenticate') + ->with($this->callback(function ($token) { + return 'TheKey' === $token->getKey(); + })) + ->will($this->returnValue($anonymousToken)) + ; + + $tokenStorage + ->expects($this->once()) + ->method('setToken') + ->with($anonymousToken) + ; + + $listener = new AnonymousAuthenticationListener($tokenStorage, 'TheKey', null, $authenticationManager); + $listener->handle($this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false)); + } + + public function testHandledEventIsLogged() + { + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $logger = $this->getMock('Psr\Log\LoggerInterface'); + $logger->expects($this->once()) + ->method('info') + ->with('Populated the TokenStorage with an anonymous Token.') + ; + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + + $listener = new AnonymousAuthenticationListener($tokenStorage, 'TheKey', $logger, $authenticationManager); + $listener->handle($this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false)); + } +} diff --git a/Http/Tests/Firewall/BasicAuthenticationListenerTest.php b/Http/Tests/Firewall/BasicAuthenticationListenerTest.php new file mode 100644 index 0000000..8901cb2 --- /dev/null +++ b/Http/Tests/Firewall/BasicAuthenticationListenerTest.php @@ -0,0 +1,249 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * 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 Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken; +use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Security\Http\Firewall\BasicAuthenticationListener; +use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager; + +class BasicAuthenticationListenerTest extends \PHPUnit_Framework_TestCase +{ + public function testHandleWithValidUsernameAndPasswordServerParameters() + { + $request = new Request(array(), array(), array(), array(), array(), array( + 'PHP_AUTH_USER' => 'TheUsername', + 'PHP_AUTH_PW' => 'ThePassword', + )); + + $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $tokenStorage + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue(null)) + ; + $tokenStorage + ->expects($this->once()) + ->method('setToken') + ->with($this->equalTo($token)) + ; + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + $authenticationManager + ->expects($this->once()) + ->method('authenticate') + ->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken')) + ->will($this->returnValue($token)) + ; + + $listener = new BasicAuthenticationListener( + $tokenStorage, + $authenticationManager, + 'TheProviderKey', + $this->getMock('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface') + ); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $listener->handle($event); + } + + public function testHandleWhenAuthenticationFails() + { + $request = new Request(array(), array(), array(), array(), array(), array( + 'PHP_AUTH_USER' => 'TheUsername', + 'PHP_AUTH_PW' => 'ThePassword', + )); + + $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $tokenStorage + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue(null)) + ; + $tokenStorage + ->expects($this->never()) + ->method('setToken') + ; + + $response = new Response(); + + $authenticationEntryPoint = $this->getMock('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface'); + $authenticationEntryPoint + ->expects($this->any()) + ->method('start') + ->with($this->equalTo($request), $this->isInstanceOf('Symfony\Component\Security\Core\Exception\AuthenticationException')) + ->will($this->returnValue($response)) + ; + + $listener = new BasicAuthenticationListener( + $tokenStorage, + new AuthenticationProviderManager(array($this->getMock('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface'))), + 'TheProviderKey', + $authenticationEntryPoint + ); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + $event + ->expects($this->once()) + ->method('setResponse') + ->with($this->equalTo($response)) + ; + + $listener->handle($event); + } + + public function testHandleWithNoUsernameServerParameter() + { + $request = new Request(); + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $tokenStorage + ->expects($this->never()) + ->method('getToken') + ; + + $listener = new BasicAuthenticationListener( + $tokenStorage, + $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'), + 'TheProviderKey', + $this->getMock('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface') + ); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $listener->handle($event); + } + + public function testHandleWithASimilarAuthenticatedToken() + { + $request = new Request(array(), array(), array(), array(), array(), array('PHP_AUTH_USER' => 'TheUsername')); + + $token = new UsernamePasswordToken('TheUsername', 'ThePassword', 'TheProviderKey', array('ROLE_FOO')); + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $tokenStorage + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue($token)) + ; + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + $authenticationManager + ->expects($this->never()) + ->method('authenticate') + ; + + $listener = new BasicAuthenticationListener( + $tokenStorage, + $authenticationManager, + 'TheProviderKey', + $this->getMock('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface') + ); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $listener->handle($event); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage $providerKey must not be empty + */ + public function testItRequiresProviderKey() + { + new BasicAuthenticationListener( + $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'), + $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'), + '', + $this->getMock('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface') + ); + } + + public function testHandleWithADifferentAuthenticatedToken() + { + $request = new Request(array(), array(), array(), array(), array(), array( + 'PHP_AUTH_USER' => 'TheUsername', + 'PHP_AUTH_PW' => 'ThePassword', + )); + + $token = new PreAuthenticatedToken('TheUser', 'TheCredentials', 'TheProviderKey', array('ROLE_FOO')); + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $tokenStorage + ->expects($this->any()) + ->method('getToken') + ->will($this->returnValue($token)) + ; + $tokenStorage + ->expects($this->never()) + ->method('setToken') + ; + + $response = new Response(); + + $authenticationEntryPoint = $this->getMock('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface'); + $authenticationEntryPoint + ->expects($this->any()) + ->method('start') + ->with($this->equalTo($request), $this->isInstanceOf('Symfony\Component\Security\Core\Exception\AuthenticationException')) + ->will($this->returnValue($response)) + ; + + $listener = new BasicAuthenticationListener( + $tokenStorage, + new AuthenticationProviderManager(array($this->getMock('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface'))), + 'TheProviderKey', + $authenticationEntryPoint + ); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + $event + ->expects($this->once()) + ->method('setResponse') + ->with($this->equalTo($response)) + ; + + $listener->handle($event); + } +} diff --git a/Http/Tests/Firewall/ChannelListenerTest.php b/Http/Tests/Firewall/ChannelListenerTest.php new file mode 100644 index 0000000..1465224 --- /dev/null +++ b/Http/Tests/Firewall/ChannelListenerTest.php @@ -0,0 +1,180 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * 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 Symfony\Component\Security\Http\Firewall\ChannelListener; +use Symfony\Component\HttpFoundation\Response; + +class ChannelListenerTest extends \PHPUnit_Framework_TestCase +{ + public function testHandleWithNotSecuredRequestAndHttpChannel() + { + $request = $this->getMock('Symfony\Component\HttpFoundation\Request', array(), array(), '', false, false); + $request + ->expects($this->any()) + ->method('isSecure') + ->will($this->returnValue(false)) + ; + + $accessMap = $this->getMock('Symfony\Component\Security\Http\AccessMapInterface'); + $accessMap + ->expects($this->any()) + ->method('getPatterns') + ->with($this->equalTo($request)) + ->will($this->returnValue(array(array(), 'http'))) + ; + + $entryPoint = $this->getMock('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface'); + $entryPoint + ->expects($this->never()) + ->method('start') + ; + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + $event + ->expects($this->never()) + ->method('setResponse') + ; + + $listener = new ChannelListener($accessMap, $entryPoint); + $listener->handle($event); + } + + public function testHandleWithSecuredRequestAndHttpsChannel() + { + $request = $this->getMock('Symfony\Component\HttpFoundation\Request', array(), array(), '', false, false); + $request + ->expects($this->any()) + ->method('isSecure') + ->will($this->returnValue(true)) + ; + + $accessMap = $this->getMock('Symfony\Component\Security\Http\AccessMapInterface'); + $accessMap + ->expects($this->any()) + ->method('getPatterns') + ->with($this->equalTo($request)) + ->will($this->returnValue(array(array(), 'https'))) + ; + + $entryPoint = $this->getMock('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface'); + $entryPoint + ->expects($this->never()) + ->method('start') + ; + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + $event + ->expects($this->never()) + ->method('setResponse') + ; + + $listener = new ChannelListener($accessMap, $entryPoint); + $listener->handle($event); + } + + public function testHandleWithNotSecuredRequestAndHttpsChannel() + { + $request = $this->getMock('Symfony\Component\HttpFoundation\Request', array(), array(), '', false, false); + $request + ->expects($this->any()) + ->method('isSecure') + ->will($this->returnValue(false)) + ; + + $response = new Response(); + + $accessMap = $this->getMock('Symfony\Component\Security\Http\AccessMapInterface'); + $accessMap + ->expects($this->any()) + ->method('getPatterns') + ->with($this->equalTo($request)) + ->will($this->returnValue(array(array(), 'https'))) + ; + + $entryPoint = $this->getMock('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface'); + $entryPoint + ->expects($this->once()) + ->method('start') + ->with($this->equalTo($request)) + ->will($this->returnValue($response)) + ; + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + $event + ->expects($this->once()) + ->method('setResponse') + ->with($this->equalTo($response)) + ; + + $listener = new ChannelListener($accessMap, $entryPoint); + $listener->handle($event); + } + + public function testHandleWithSecuredRequestAndHttpChannel() + { + $request = $this->getMock('Symfony\Component\HttpFoundation\Request', array(), array(), '', false, false); + $request + ->expects($this->any()) + ->method('isSecure') + ->will($this->returnValue(true)) + ; + + $response = new Response(); + + $accessMap = $this->getMock('Symfony\Component\Security\Http\AccessMapInterface'); + $accessMap + ->expects($this->any()) + ->method('getPatterns') + ->with($this->equalTo($request)) + ->will($this->returnValue(array(array(), 'http'))) + ; + + $entryPoint = $this->getMock('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface'); + $entryPoint + ->expects($this->once()) + ->method('start') + ->with($this->equalTo($request)) + ->will($this->returnValue($response)) + ; + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + $event + ->expects($this->once()) + ->method('setResponse') + ->with($this->equalTo($response)) + ; + + $listener = new ChannelListener($accessMap, $entryPoint); + $listener->handle($event); + } +} diff --git a/Http/Tests/Firewall/ContextListenerTest.php b/Http/Tests/Firewall/ContextListenerTest.php new file mode 100644 index 0000000..ae1199a --- /dev/null +++ b/Http/Tests/Firewall/ContextListenerTest.php @@ -0,0 +1,267 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * 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 Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Session\Session; +use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; +use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; +use Symfony\Component\Security\Http\Firewall\ContextListener; +use Symfony\Component\EventDispatcher\EventDispatcher; + +class ContextListenerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage $contextKey must not be empty + */ + public function testItRequiresContextKey() + { + new ContextListener( + $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'), + array(), + '' + ); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage User provider "stdClass" must implement "Symfony\Component\Security\Core\User\UserProviderInterface + */ + public function testUserProvidersNeedToImplementAnInterface() + { + new ContextListener( + $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'), + array(new \stdClass()), + 'key123' + ); + } + + public function testOnKernelResponseWillAddSession() + { + $session = $this->runSessionOnKernelResponse( + new UsernamePasswordToken('test1', 'pass1', 'phpunit'), + null + ); + + $token = unserialize($session->get('_security_session')); + $this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $token); + $this->assertEquals('test1', $token->getUsername()); + } + + public function testOnKernelResponseWillReplaceSession() + { + $session = $this->runSessionOnKernelResponse( + new UsernamePasswordToken('test1', 'pass1', 'phpunit'), + 'C:10:"serialized"' + ); + + $token = unserialize($session->get('_security_session')); + $this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $token); + $this->assertEquals('test1', $token->getUsername()); + } + + public function testOnKernelResponseWillRemoveSession() + { + $session = $this->runSessionOnKernelResponse( + null, + 'C:10:"serialized"' + ); + + $this->assertFalse($session->has('_security_session')); + } + + public function testOnKernelResponseWithoutSession() + { + $tokenStorage = new TokenStorage(); + $tokenStorage->setToken(new UsernamePasswordToken('test1', 'pass1', 'phpunit')); + $request = new Request(); + $session = new Session(new MockArraySessionStorage()); + $request->setSession($session); + + $event = new FilterResponseEvent( + $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'), + $request, + HttpKernelInterface::MASTER_REQUEST, + new Response() + ); + + $listener = new ContextListener($tokenStorage, array(), 'session', null, new EventDispatcher()); + $listener->onKernelResponse($event); + + $this->assertTrue($session->isStarted()); + } + + public function testOnKernelResponseWithoutSessionNorToken() + { + $request = new Request(); + $session = new Session(new MockArraySessionStorage()); + $request->setSession($session); + + $event = new FilterResponseEvent( + $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'), + $request, + HttpKernelInterface::MASTER_REQUEST, + new Response() + ); + + $listener = new ContextListener(new TokenStorage(), array(), 'session', null, new EventDispatcher()); + $listener->onKernelResponse($event); + + $this->assertFalse($session->isStarted()); + } + + /** + * @dataProvider provideInvalidToken + */ + public function testInvalidTokenInSession($token) + { + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent') + ->disableOriginalConstructor() + ->getMock(); + $request = $this->getMock('Symfony\Component\HttpFoundation\Request'); + $session = $this->getMock('Symfony\Component\HttpFoundation\Session\SessionInterface'); + + $event->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)); + $request->expects($this->any()) + ->method('hasPreviousSession') + ->will($this->returnValue(true)); + $request->expects($this->any()) + ->method('getSession') + ->will($this->returnValue($session)); + $session->expects($this->any()) + ->method('get') + ->with('_security_key123') + ->will($this->returnValue($token)); + $tokenStorage->expects($this->once()) + ->method('setToken') + ->with(null); + + $listener = new ContextListener($tokenStorage, array(), 'key123'); + $listener->handle($event); + } + + public function provideInvalidToken() + { + return array( + array(serialize(new \__PHP_Incomplete_Class())), + array(serialize(null)), + array(null), + ); + } + + public function testHandleAddsKernelResponseListener() + { + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent') + ->disableOriginalConstructor() + ->getMock(); + + $listener = new ContextListener($tokenStorage, array(), 'key123', null, $dispatcher); + + $event->expects($this->any()) + ->method('isMasterRequest') + ->will($this->returnValue(true)); + $event->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($this->getMock('Symfony\Component\HttpFoundation\Request'))); + + $dispatcher->expects($this->once()) + ->method('addListener') + ->with(KernelEvents::RESPONSE, array($listener, 'onKernelResponse')); + + $listener->handle($event); + } + + public function testOnKernelResponseListenerRemovesItself() + { + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\FilterResponseEvent') + ->disableOriginalConstructor() + ->getMock(); + + $listener = new ContextListener($tokenStorage, array(), 'key123', null, $dispatcher); + + $request = $this->getMock('Symfony\Component\HttpFoundation\Request'); + $request->expects($this->any()) + ->method('hasSession') + ->will($this->returnValue(true)); + + $event->expects($this->any()) + ->method('isMasterRequest') + ->will($this->returnValue(true)); + $event->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)); + + $dispatcher->expects($this->once()) + ->method('removeListener') + ->with(KernelEvents::RESPONSE, array($listener, 'onKernelResponse')); + + $listener->onKernelResponse($event); + } + + public function testHandleRemovesTokenIfNoPreviousSessionWasFound() + { + $request = $this->getMock('Symfony\Component\HttpFoundation\Request'); + $request->expects($this->any())->method('hasPreviousSession')->will($this->returnValue(false)); + + $event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent') + ->disableOriginalConstructor() + ->getMock(); + $event->expects($this->any())->method('getRequest')->will($this->returnValue($request)); + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $tokenStorage->expects($this->once())->method('setToken')->with(null); + + $listener = new ContextListener($tokenStorage, array(), 'key123'); + $listener->handle($event); + } + + protected function runSessionOnKernelResponse($newToken, $original = null) + { + $session = new Session(new MockArraySessionStorage()); + + if ($original !== null) { + $session->set('_security_session', $original); + } + + $tokenStorage = new TokenStorage(); + $tokenStorage->setToken($newToken); + + $request = new Request(); + $request->setSession($session); + $request->cookies->set('MOCKSESSID', true); + + $event = new FilterResponseEvent( + $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'), + $request, + HttpKernelInterface::MASTER_REQUEST, + new Response() + ); + + $listener = new ContextListener($tokenStorage, array(), 'session', null, new EventDispatcher()); + $listener->onKernelResponse($event); + + return $session; + } +} diff --git a/Http/Tests/Firewall/DigestDataTest.php b/Http/Tests/Firewall/DigestDataTest.php new file mode 100644 index 0000000..a7c8d49 --- /dev/null +++ b/Http/Tests/Firewall/DigestDataTest.php @@ -0,0 +1,181 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * 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 Symfony\Component\Security\Http\Firewall\DigestData; + +class DigestDataTest extends \PHPUnit_Framework_TestCase +{ + public function testGetResponse() + { + $digestAuth = new DigestData( + 'username="user", realm="Welcome, robot!", '. + 'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", '. + 'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", '. + 'response="b52938fc9e6d7c01be7702ece9031b42"' + ); + + $this->assertEquals('b52938fc9e6d7c01be7702ece9031b42', $digestAuth->getResponse()); + } + + public function testGetUsername() + { + $digestAuth = new DigestData( + 'username="user", realm="Welcome, robot!", '. + 'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", '. + 'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", '. + 'response="b52938fc9e6d7c01be7702ece9031b42"' + ); + + $this->assertEquals('user', $digestAuth->getUsername()); + } + + public function testGetUsernameWithQuote() + { + $digestAuth = new DigestData( + 'username="\"user\"", realm="Welcome, robot!", '. + 'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", '. + 'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", '. + 'response="b52938fc9e6d7c01be7702ece9031b42"' + ); + + $this->assertEquals('"user"', $digestAuth->getUsername()); + } + + public function testGetUsernameWithQuoteAndEscape() + { + $digestAuth = new DigestData( + 'username="\"u\\\\\"ser\"", realm="Welcome, robot!", '. + 'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", '. + 'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", '. + 'response="b52938fc9e6d7c01be7702ece9031b42"' + ); + + $this->assertEquals('"u\\"ser"', $digestAuth->getUsername()); + } + + public function testGetUsernameWithSingleQuote() + { + $digestAuth = new DigestData( + 'username="\"u\'ser\"", realm="Welcome, robot!", '. + 'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", '. + 'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", '. + 'response="b52938fc9e6d7c01be7702ece9031b42"' + ); + + $this->assertEquals('"u\'ser"', $digestAuth->getUsername()); + } + + public function testGetUsernameWithSingleQuoteAndEscape() + { + $digestAuth = new DigestData( + 'username="\"u\\\'ser\"", realm="Welcome, robot!", '. + 'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", '. + 'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", '. + 'response="b52938fc9e6d7c01be7702ece9031b42"' + ); + + $this->assertEquals('"u\\\'ser"', $digestAuth->getUsername()); + } + + public function testGetUsernameWithEscape() + { + $digestAuth = new DigestData( + 'username="\"u\\ser\"", realm="Welcome, robot!", '. + 'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", '. + 'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", '. + 'response="b52938fc9e6d7c01be7702ece9031b42"' + ); + + $this->assertEquals('"u\\ser"', $digestAuth->getUsername()); + } + + public function testValidateAndDecode() + { + $time = microtime(true); + $key = 'ThisIsAKey'; + $nonce = base64_encode($time.':'.md5($time.':'.$key)); + + $digestAuth = new DigestData( + 'username="user", realm="Welcome, robot!", nonce="'.$nonce.'", '. + 'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", '. + 'response="b52938fc9e6d7c01be7702ece9031b42"' + ); + + try { + $digestAuth->validateAndDecode($key, 'Welcome, robot!'); + } catch (\Exception $e) { + $this->fail(sprintf('testValidateAndDecode fail with message: %s', $e->getMessage())); + } + } + + public function testCalculateServerDigest() + { + $this->calculateServerDigest('user', 'Welcome, robot!', 'pass,word=password', 'ThisIsAKey', '00000001', 'MDIwODkz', 'auth', 'GET', '/path/info?p1=5&p2=5'); + } + + public function testCalculateServerDigestWithQuote() + { + $this->calculateServerDigest('\"user\"', 'Welcome, \"robot\"!', 'pass,word=password', 'ThisIsAKey', '00000001', 'MDIwODkz', 'auth', 'GET', '/path/info?p1=5&p2=5'); + } + + public function testCalculateServerDigestWithQuoteAndEscape() + { + $this->calculateServerDigest('\"u\\\\\"ser\"', 'Welcome, \"robot\"!', 'pass,word=password', 'ThisIsAKey', '00000001', 'MDIwODkz', 'auth', 'GET', '/path/info?p1=5&p2=5'); + } + + public function testCalculateServerDigestEscape() + { + $this->calculateServerDigest('\"u\\ser\"', 'Welcome, \"robot\"!', 'pass,word=password', 'ThisIsAKey', '00000001', 'MDIwODkz', 'auth', 'GET', '/path/info?p1=5&p2=5'); + $this->calculateServerDigest('\"u\\ser\\\\\"', 'Welcome, \"robot\"!', 'pass,word=password', 'ThisIsAKey', '00000001', 'MDIwODkz', 'auth', 'GET', '/path/info?p1=5&p2=5'); + } + + public function testIsNonceExpired() + { + $time = microtime(true) + 10; + $key = 'ThisIsAKey'; + $nonce = base64_encode($time.':'.md5($time.':'.$key)); + + $digestAuth = new DigestData( + 'username="user", realm="Welcome, robot!", nonce="'.$nonce.'", '. + 'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", '. + 'response="b52938fc9e6d7c01be7702ece9031b42"' + ); + + $digestAuth->validateAndDecode($key, 'Welcome, robot!'); + + $this->assertFalse($digestAuth->isNonceExpired()); + } + + protected function setUp() + { + class_exists('Symfony\Component\Security\Http\Firewall\DigestAuthenticationListener', true); + } + + private function calculateServerDigest($username, $realm, $password, $key, $nc, $cnonce, $qop, $method, $uri) + { + $time = microtime(true); + $nonce = base64_encode($time.':'.md5($time.':'.$key)); + + $response = md5( + md5($username.':'.$realm.':'.$password).':'.$nonce.':'.$nc.':'.$cnonce.':'.$qop.':'.md5($method.':'.$uri) + ); + + $digest = sprintf('username="%s", realm="%s", nonce="%s", uri="%s", cnonce="%s", nc=%s, qop="%s", response="%s"', + $username, $realm, $nonce, $uri, $cnonce, $nc, $qop, $response + ); + + $digestAuth = new DigestData($digest); + + $this->assertEquals($digestAuth->getResponse(), $digestAuth->calculateServerDigest($password, $method)); + } +} diff --git a/Http/Tests/Firewall/ExceptionListenerTest.php b/Http/Tests/Firewall/ExceptionListenerTest.php new file mode 100644 index 0000000..3d409e5 --- /dev/null +++ b/Http/Tests/Firewall/ExceptionListenerTest.php @@ -0,0 +1,184 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * 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 Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Symfony\Component\Security\Core\Exception\AccessDeniedException; +use Symfony\Component\Security\Core\Exception\AuthenticationException; +use Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface; +use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface; +use Symfony\Component\Security\Http\Firewall\ExceptionListener; +use Symfony\Component\Security\Http\HttpUtils; + +class ExceptionListenerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getAuthenticationExceptionProvider + */ + public function testAuthenticationExceptionWithoutEntryPoint(\Exception $exception, \Exception $eventException = null) + { + $event = $this->createEvent($exception); + + $listener = $this->createExceptionListener(); + $listener->onKernelException($event); + + $this->assertNull($event->getResponse()); + $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()); + } + + /** + * @dataProvider getAuthenticationExceptionProvider + */ + public function testAuthenticationExceptionWithEntryPoint(\Exception $exception, \Exception $eventException = null) + { + $event = $this->createEvent($exception = new AuthenticationException()); + + $listener = $this->createExceptionListener(null, null, null, $this->createEntryPoint()); + $listener->onKernelException($event); + + $this->assertEquals('OK', $event->getResponse()->getContent()); + $this->assertSame($exception, $event->getException()); + } + + public function getAuthenticationExceptionProvider() + { + return array( + array(new AuthenticationException()), + array(new \LogicException('random', 0, $e = new AuthenticationException()), $e), + array(new \LogicException('random', 0, $e = new AuthenticationException('embed', 0, new AuthenticationException())), $e), + array(new \LogicException('random', 0, $e = new AuthenticationException('embed', 0, new AccessDeniedException())), $e), + array(new AuthenticationException('random', 0, new \LogicException())), + ); + } + + /** + * @dataProvider getAccessDeniedExceptionProvider + */ + public function testAccessDeniedExceptionFullFledgedAndWithoutAccessDeniedHandlerAndWithoutErrorPage(\Exception $exception, \Exception $eventException = null) + { + $event = $this->createEvent($exception); + + $listener = $this->createExceptionListener(null, $this->createTrustResolver(true)); + $listener->onKernelException($event); + + $this->assertNull($event->getResponse()); + $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious()); + } + + /** + * @dataProvider getAccessDeniedExceptionProvider + */ + public function testAccessDeniedExceptionFullFledgedAndWithoutAccessDeniedHandlerAndWithErrorPage(\Exception $exception, \Exception $eventException = null) + { + $kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'); + $kernel->expects($this->once())->method('handle')->will($this->returnValue(new Response('error'))); + + $event = $this->createEvent($exception, $kernel); + + $httpUtils = $this->getMock('Symfony\Component\Security\Http\HttpUtils'); + $httpUtils->expects($this->once())->method('createRequest')->will($this->returnValue(Request::create('/error'))); + + $listener = $this->createExceptionListener(null, $this->createTrustResolver(true), $httpUtils, null, '/error'); + $listener->onKernelException($event); + + $this->assertEquals('error', $event->getResponse()->getContent()); + $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious()); + } + + /** + * @dataProvider getAccessDeniedExceptionProvider + */ + public function testAccessDeniedExceptionFullFledgedAndWithAccessDeniedHandlerAndWithoutErrorPage(\Exception $exception, \Exception $eventException = null) + { + $event = $this->createEvent($exception); + + $accessDeniedHandler = $this->getMock('Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface'); + $accessDeniedHandler->expects($this->once())->method('handle')->will($this->returnValue(new Response('error'))); + + $listener = $this->createExceptionListener(null, $this->createTrustResolver(true), null, null, null, $accessDeniedHandler); + $listener->onKernelException($event); + + $this->assertEquals('error', $event->getResponse()->getContent()); + $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious()); + } + + /** + * @dataProvider getAccessDeniedExceptionProvider + */ + public function testAccessDeniedExceptionNotFullFledged(\Exception $exception, \Exception $eventException = null) + { + $event = $this->createEvent($exception); + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $tokenStorage->expects($this->once())->method('getToken')->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'))); + + $listener = $this->createExceptionListener($tokenStorage, $this->createTrustResolver(false), null, $this->createEntryPoint()); + $listener->onKernelException($event); + + $this->assertEquals('OK', $event->getResponse()->getContent()); + $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious()); + } + + public function getAccessDeniedExceptionProvider() + { + return array( + array(new AccessDeniedException()), + array(new \LogicException('random', 0, $e = new AccessDeniedException()), $e), + array(new \LogicException('random', 0, $e = new AccessDeniedException('embed', new AccessDeniedException())), $e), + array(new \LogicException('random', 0, $e = new AccessDeniedException('embed', new AuthenticationException())), $e), + array(new AccessDeniedException('random', new \LogicException())), + ); + } + + private function createEntryPoint() + { + $entryPoint = $this->getMock('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface'); + $entryPoint->expects($this->once())->method('start')->will($this->returnValue(new Response('OK'))); + + return $entryPoint; + } + + private function createTrustResolver($fullFledged) + { + $trustResolver = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface'); + $trustResolver->expects($this->once())->method('isFullFledged')->will($this->returnValue($fullFledged)); + + return $trustResolver; + } + + private function createEvent(\Exception $exception, $kernel = null) + { + if (null === $kernel) { + $kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'); + } + + return new GetResponseForExceptionEvent($kernel, Request::create('/'), HttpKernelInterface::MASTER_REQUEST, $exception); + } + + private function createExceptionListener(TokenStorageInterface $tokenStorage = null, AuthenticationTrustResolverInterface $trustResolver = null, HttpUtils $httpUtils = null, AuthenticationEntryPointInterface $authenticationEntryPoint = null, $errorPage = null, AccessDeniedHandlerInterface $accessDeniedHandler = null) + { + return new ExceptionListener( + $tokenStorage ?: $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'), + $trustResolver ?: $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface'), + $httpUtils ?: $this->getMock('Symfony\Component\Security\Http\HttpUtils'), + 'key', + $authenticationEntryPoint, + $errorPage, + $accessDeniedHandler + ); + } +} diff --git a/Http/Tests/Firewall/LogoutListenerTest.php b/Http/Tests/Firewall/LogoutListenerTest.php new file mode 100644 index 0000000..15c996e --- /dev/null +++ b/Http/Tests/Firewall/LogoutListenerTest.php @@ -0,0 +1,235 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * 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 Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Security\Http\Firewall\LogoutListener; + +class LogoutListenerTest extends \PHPUnit_Framework_TestCase +{ + public function testHandleUnmatchedPath() + { + list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener(); + + list($event, $request) = $this->getGetResponseEvent(); + + $event->expects($this->never()) + ->method('setResponse'); + + $httpUtils->expects($this->once()) + ->method('checkRequestPath') + ->with($request, $options['logout_path']) + ->will($this->returnValue(false)); + + $listener->handle($event); + } + + public function testHandleMatchedPathWithSuccessHandlerAndCsrfValidation() + { + $successHandler = $this->getSuccessHandler(); + $tokenManager = $this->getTokenManager(); + + list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener($successHandler, $tokenManager); + + list($event, $request) = $this->getGetResponseEvent(); + + $request->query->set('_csrf_token', 'token'); + + $httpUtils->expects($this->once()) + ->method('checkRequestPath') + ->with($request, $options['logout_path']) + ->will($this->returnValue(true)); + + $tokenManager->expects($this->once()) + ->method('isTokenValid') + ->will($this->returnValue(true)); + + $successHandler->expects($this->once()) + ->method('onLogoutSuccess') + ->with($request) + ->will($this->returnValue($response = new Response())); + + $tokenStorage->expects($this->once()) + ->method('getToken') + ->will($this->returnValue($token = $this->getToken())); + + $handler = $this->getHandler(); + $handler->expects($this->once()) + ->method('logout') + ->with($request, $response, $token); + + $tokenStorage->expects($this->once()) + ->method('setToken') + ->with(null); + + $event->expects($this->once()) + ->method('setResponse') + ->with($response); + + $listener->addHandler($handler); + + $listener->handle($event); + } + + public function testHandleMatchedPathWithoutSuccessHandlerAndCsrfValidation() + { + $successHandler = $this->getSuccessHandler(); + + list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener($successHandler); + + list($event, $request) = $this->getGetResponseEvent(); + + $httpUtils->expects($this->once()) + ->method('checkRequestPath') + ->with($request, $options['logout_path']) + ->will($this->returnValue(true)); + + $successHandler->expects($this->once()) + ->method('onLogoutSuccess') + ->with($request) + ->will($this->returnValue($response = new Response())); + + $tokenStorage->expects($this->once()) + ->method('getToken') + ->will($this->returnValue($token = $this->getToken())); + + $handler = $this->getHandler(); + $handler->expects($this->once()) + ->method('logout') + ->with($request, $response, $token); + + $tokenStorage->expects($this->once()) + ->method('setToken') + ->with(null); + + $event->expects($this->once()) + ->method('setResponse') + ->with($response); + + $listener->addHandler($handler); + + $listener->handle($event); + } + + /** + * @expectedException \RuntimeException + */ + public function testSuccessHandlerReturnsNonResponse() + { + $successHandler = $this->getSuccessHandler(); + + list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener($successHandler); + + list($event, $request) = $this->getGetResponseEvent(); + + $httpUtils->expects($this->once()) + ->method('checkRequestPath') + ->with($request, $options['logout_path']) + ->will($this->returnValue(true)); + + $successHandler->expects($this->once()) + ->method('onLogoutSuccess') + ->with($request) + ->will($this->returnValue(null)); + + $listener->handle($event); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\LogoutException + */ + public function testCsrfValidationFails() + { + $tokenManager = $this->getTokenManager(); + + list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener(null, $tokenManager); + + list($event, $request) = $this->getGetResponseEvent(); + + $request->query->set('_csrf_token', 'token'); + + $httpUtils->expects($this->once()) + ->method('checkRequestPath') + ->with($request, $options['logout_path']) + ->will($this->returnValue(true)); + + $tokenManager->expects($this->once()) + ->method('isTokenValid') + ->will($this->returnValue(false)); + + $listener->handle($event); + } + + private function getTokenManager() + { + return $this->getMock('Symfony\Component\Security\Csrf\CsrfTokenManagerInterface'); + } + + private function getTokenStorage() + { + return $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + } + + private function getGetResponseEvent() + { + $event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent') + ->disableOriginalConstructor() + ->getMock(); + + $event->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request = new Request())); + + return array($event, $request); + } + + private function getHandler() + { + return $this->getMock('Symfony\Component\Security\Http\Logout\LogoutHandlerInterface'); + } + + private function getHttpUtils() + { + return $this->getMockBuilder('Symfony\Component\Security\Http\HttpUtils') + ->disableOriginalConstructor() + ->getMock(); + } + + private function getListener($successHandler = null, $tokenManager = null) + { + $listener = new LogoutListener( + $tokenStorage = $this->getTokenStorage(), + $httpUtils = $this->getHttpUtils(), + $successHandler ?: $this->getSuccessHandler(), + $options = array( + 'csrf_parameter' => '_csrf_token', + 'intention' => 'logout', + 'logout_path' => '/logout', + 'target_url' => '/', + ), + $tokenManager + ); + + return array($listener, $tokenStorage, $httpUtils, $options); + } + + private function getSuccessHandler() + { + return $this->getMock('Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface'); + } + + private function getToken() + { + return $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + } +} diff --git a/Http/Tests/Firewall/RememberMeListenerTest.php b/Http/Tests/Firewall/RememberMeListenerTest.php new file mode 100644 index 0000000..7309042 --- /dev/null +++ b/Http/Tests/Firewall/RememberMeListenerTest.php @@ -0,0 +1,415 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * 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 Symfony\Component\Security\Core\Exception\AuthenticationException; +use Symfony\Component\Security\Http\Firewall\RememberMeListener; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Http\SecurityEvents; + +class RememberMeListenerTest extends \PHPUnit_Framework_TestCase +{ + public function testOnCoreSecurityDoesNotTryToPopulateNonEmptyTokenStorage() + { + list($listener, $tokenStorage) = $this->getListener(); + + $tokenStorage + ->expects($this->once()) + ->method('getToken') + ->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'))) + ; + + $tokenStorage + ->expects($this->never()) + ->method('setToken') + ; + + $this->assertNull($listener->handle($this->getGetResponseEvent())); + } + + public function testOnCoreSecurityDoesNothingWhenNoCookieIsSet() + { + list($listener, $tokenStorage, $service) = $this->getListener(); + + $tokenStorage + ->expects($this->once()) + ->method('getToken') + ->will($this->returnValue(null)) + ; + + $service + ->expects($this->once()) + ->method('autoLogin') + ->will($this->returnValue(null)) + ; + + $event = $this->getGetResponseEvent(); + $event + ->expects($this->once()) + ->method('getRequest') + ->will($this->returnValue(new Request())) + ; + + $this->assertNull($listener->handle($event)); + } + + public function testOnCoreSecurityIgnoresAuthenticationExceptionThrownByAuthenticationManagerImplementation() + { + list($listener, $tokenStorage, $service, $manager) = $this->getListener(); + + $tokenStorage + ->expects($this->once()) + ->method('getToken') + ->will($this->returnValue(null)) + ; + + $service + ->expects($this->once()) + ->method('autoLogin') + ->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'))) + ; + + $service + ->expects($this->once()) + ->method('loginFail') + ; + + $exception = new AuthenticationException('Authentication failed.'); + $manager + ->expects($this->once()) + ->method('authenticate') + ->will($this->throwException($exception)) + ; + + $event = $this->getGetResponseEvent(); + $event + ->expects($this->once()) + ->method('getRequest') + ->will($this->returnValue(new Request())) + ; + + $listener->handle($event); + } + + /** + * @expectedException Symfony\Component\Security\Core\Exception\AuthenticationException + * @expectedExceptionMessage Authentication failed. + */ + public function testOnCoreSecurityIgnoresAuthenticationOptionallyRethrowsExceptionThrownAuthenticationManagerImplementation() + { + list($listener, $tokenStorage, $service, $manager) = $this->getListener(false, false); + + $tokenStorage + ->expects($this->once()) + ->method('getToken') + ->will($this->returnValue(null)) + ; + + $service + ->expects($this->once()) + ->method('autoLogin') + ->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'))) + ; + + $service + ->expects($this->once()) + ->method('loginFail') + ; + + $exception = new AuthenticationException('Authentication failed.'); + $manager + ->expects($this->once()) + ->method('authenticate') + ->will($this->throwException($exception)) + ; + + $event = $this->getGetResponseEvent(); + $event + ->expects($this->once()) + ->method('getRequest') + ->will($this->returnValue(new Request())) + ; + + $listener->handle($event); + } + + public function testOnCoreSecurity() + { + list($listener, $tokenStorage, $service, $manager) = $this->getListener(); + + $tokenStorage + ->expects($this->once()) + ->method('getToken') + ->will($this->returnValue(null)) + ; + + $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + $service + ->expects($this->once()) + ->method('autoLogin') + ->will($this->returnValue($token)) + ; + + $tokenStorage + ->expects($this->once()) + ->method('setToken') + ->with($this->equalTo($token)) + ; + + $manager + ->expects($this->once()) + ->method('authenticate') + ->will($this->returnValue($token)) + ; + + $event = $this->getGetResponseEvent(); + $event + ->expects($this->once()) + ->method('getRequest') + ->will($this->returnValue(new Request())) + ; + + $listener->handle($event); + } + + public function testSessionStrategy() + { + list($listener, $tokenStorage, $service, $manager, , $dispatcher, $sessionStrategy) = $this->getListener(false, true, true); + + $tokenStorage + ->expects($this->once()) + ->method('getToken') + ->will($this->returnValue(null)) + ; + + $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + $service + ->expects($this->once()) + ->method('autoLogin') + ->will($this->returnValue($token)) + ; + + $tokenStorage + ->expects($this->once()) + ->method('setToken') + ->with($this->equalTo($token)) + ; + + $manager + ->expects($this->once()) + ->method('authenticate') + ->will($this->returnValue($token)) + ; + + $session = $this->getMock('\Symfony\Component\HttpFoundation\Session\SessionInterface'); + $session + ->expects($this->once()) + ->method('isStarted') + ->will($this->returnValue(true)) + ; + + $request = $this->getMock('\Symfony\Component\HttpFoundation\Request'); + $request + ->expects($this->once()) + ->method('hasSession') + ->will($this->returnValue(true)) + ; + + $request + ->expects($this->once()) + ->method('getSession') + ->will($this->returnValue($session)) + ; + + $event = $this->getGetResponseEvent(); + $event + ->expects($this->once()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $sessionStrategy + ->expects($this->once()) + ->method('onAuthentication') + ->will($this->returnValue(null)) + ; + + $listener->handle($event); + } + + public function testSessionIsMigratedByDefault() + { + list($listener, $tokenStorage, $service, $manager, , $dispatcher, $sessionStrategy) = $this->getListener(false, true, false); + + $tokenStorage + ->expects($this->once()) + ->method('getToken') + ->will($this->returnValue(null)) + ; + + $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + $service + ->expects($this->once()) + ->method('autoLogin') + ->will($this->returnValue($token)) + ; + + $tokenStorage + ->expects($this->once()) + ->method('setToken') + ->with($this->equalTo($token)) + ; + + $manager + ->expects($this->once()) + ->method('authenticate') + ->will($this->returnValue($token)) + ; + + $session = $this->getMock('\Symfony\Component\HttpFoundation\Session\SessionInterface'); + $session + ->expects($this->once()) + ->method('isStarted') + ->will($this->returnValue(true)) + ; + $session + ->expects($this->once()) + ->method('migrate') + ; + + $request = $this->getMock('\Symfony\Component\HttpFoundation\Request'); + $request + ->expects($this->any()) + ->method('hasSession') + ->will($this->returnValue(true)) + ; + + $request + ->expects($this->any()) + ->method('getSession') + ->will($this->returnValue($session)) + ; + + $event = $this->getGetResponseEvent(); + $event + ->expects($this->once()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $listener->handle($event); + } + + public function testOnCoreSecurityInteractiveLoginEventIsDispatchedIfDispatcherIsPresent() + { + list($listener, $tokenStorage, $service, $manager, , $dispatcher) = $this->getListener(true); + + $tokenStorage + ->expects($this->once()) + ->method('getToken') + ->will($this->returnValue(null)) + ; + + $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + $service + ->expects($this->once()) + ->method('autoLogin') + ->will($this->returnValue($token)) + ; + + $tokenStorage + ->expects($this->once()) + ->method('setToken') + ->with($this->equalTo($token)) + ; + + $manager + ->expects($this->once()) + ->method('authenticate') + ->will($this->returnValue($token)) + ; + + $event = $this->getGetResponseEvent(); + $request = new Request(); + $event + ->expects($this->once()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $dispatcher + ->expects($this->once()) + ->method('dispatch') + ->with( + SecurityEvents::INTERACTIVE_LOGIN, + $this->isInstanceOf('Symfony\Component\Security\Http\Event\InteractiveLoginEvent') + ) + ; + + $listener->handle($event); + } + + protected function getGetResponseEvent() + { + return $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + } + + protected function getFilterResponseEvent() + { + return $this->getMock('Symfony\Component\HttpKernel\Event\FilterResponseEvent', array(), array(), '', false); + } + + protected function getListener($withDispatcher = false, $catchExceptions = true, $withSessionStrategy = false) + { + $listener = new RememberMeListener( + $tokenStorage = $this->getTokenStorage(), + $service = $this->getService(), + $manager = $this->getManager(), + $logger = $this->getLogger(), + $dispatcher = ($withDispatcher ? $this->getDispatcher() : null), + $catchExceptions, + $sessionStrategy = ($withSessionStrategy ? $this->getSessionStrategy() : null) + ); + + return array($listener, $tokenStorage, $service, $manager, $logger, $dispatcher, $sessionStrategy); + } + + protected function getLogger() + { + return $this->getMock('Psr\Log\LoggerInterface'); + } + + protected function getManager() + { + return $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + } + + protected function getService() + { + return $this->getMock('Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface'); + } + + protected function getTokenStorage() + { + return $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + } + + protected function getDispatcher() + { + return $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + } + + private function getSessionStrategy() + { + return $this->getMock('\Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface'); + } +} diff --git a/Http/Tests/Firewall/RemoteUserAuthenticationListenerTest.php b/Http/Tests/Firewall/RemoteUserAuthenticationListenerTest.php new file mode 100644 index 0000000..dad7aad --- /dev/null +++ b/Http/Tests/Firewall/RemoteUserAuthenticationListenerTest.php @@ -0,0 +1,91 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * 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 Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Http\Firewall\RemoteUserAuthenticationListener; + +class RemoteUserAuthenticationListenerTest extends \PHPUnit_Framework_TestCase +{ + public function testGetPreAuthenticatedData() + { + $serverVars = array( + 'REMOTE_USER' => 'TheUser', + ); + + $request = new Request(array(), array(), array(), array(), array(), $serverVars); + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + + $listener = new RemoteUserAuthenticationListener( + $tokenStorage, + $authenticationManager, + 'TheProviderKey' + ); + + $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); + $method->setAccessible(true); + + $result = $method->invokeArgs($listener, array($request)); + $this->assertSame($result, array('TheUser', null)); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + */ + public function testGetPreAuthenticatedDataNoUser() + { + $request = new Request(array(), array(), array(), array(), array(), array()); + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + + $listener = new RemoteUserAuthenticationListener( + $tokenStorage, + $authenticationManager, + 'TheProviderKey' + ); + + $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); + $method->setAccessible(true); + + $result = $method->invokeArgs($listener, array($request)); + } + + public function testGetPreAuthenticatedDataWithDifferentKeys() + { + $userCredentials = array('TheUser', null); + + $request = new Request(array(), array(), array(), array(), array(), array( + 'TheUserKey' => 'TheUser', + )); + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + + $listener = new RemoteUserAuthenticationListener( + $tokenStorage, + $authenticationManager, + 'TheProviderKey', + 'TheUserKey' + ); + + $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); + $method->setAccessible(true); + + $result = $method->invokeArgs($listener, array($request)); + $this->assertSame($result, $userCredentials); + } +} diff --git a/Http/Tests/Firewall/SimplePreAuthenticationListenerTest.php b/Http/Tests/Firewall/SimplePreAuthenticationListenerTest.php new file mode 100644 index 0000000..0a1286c --- /dev/null +++ b/Http/Tests/Firewall/SimplePreAuthenticationListenerTest.php @@ -0,0 +1,128 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * 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 Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Core\Exception\AuthenticationException; +use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; +use Symfony\Component\Security\Http\Firewall\SimplePreAuthenticationListener; +use Symfony\Component\Security\Http\SecurityEvents; + +class SimplePreAuthenticationListenerTest extends \PHPUnit_Framework_TestCase +{ + private $authenticationManager; + private $dispatcher; + private $event; + private $logger; + private $request; + private $tokenStorage; + private $token; + + public function testHandle() + { + $this->tokenStorage + ->expects($this->once()) + ->method('setToken') + ->with($this->equalTo($this->token)) + ; + + $this->authenticationManager + ->expects($this->once()) + ->method('authenticate') + ->with($this->equalTo($this->token)) + ->will($this->returnValue($this->token)) + ; + + $simpleAuthenticator = $this->getMock('Symfony\Component\Security\Core\Authentication\SimplePreAuthenticatorInterface'); + $simpleAuthenticator + ->expects($this->once()) + ->method('createToken') + ->with($this->equalTo($this->request), $this->equalTo('secured_area')) + ->will($this->returnValue($this->token)) + ; + + $loginEvent = new InteractiveLoginEvent($this->request, $this->token); + + $this->dispatcher + ->expects($this->once()) + ->method('dispatch') + ->with($this->equalTo(SecurityEvents::INTERACTIVE_LOGIN), $this->equalTo($loginEvent)) + ; + + $listener = new SimplePreAuthenticationListener($this->tokenStorage, $this->authenticationManager, 'secured_area', $simpleAuthenticator, $this->logger, $this->dispatcher); + + $listener->handle($this->event); + } + + public function testHandlecatchAuthenticationException() + { + $exception = new AuthenticationException('Authentication failed.'); + + $this->authenticationManager + ->expects($this->once()) + ->method('authenticate') + ->with($this->equalTo($this->token)) + ->will($this->throwException($exception)) + ; + + $this->tokenStorage->expects($this->once()) + ->method('setToken') + ->with($this->equalTo(null)) + ; + + $simpleAuthenticator = $this->getMock('Symfony\Component\Security\Core\Authentication\SimplePreAuthenticatorInterface'); + $simpleAuthenticator + ->expects($this->once()) + ->method('createToken') + ->with($this->equalTo($this->request), $this->equalTo('secured_area')) + ->will($this->returnValue($this->token)) + ; + + $listener = new SimplePreAuthenticationListener($this->tokenStorage, $this->authenticationManager, 'secured_area', $simpleAuthenticator, $this->logger, $this->dispatcher); + + $listener->handle($this->event); + } + + protected function setUp() + { + $this->authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager') + ->disableOriginalConstructor() + ->getMock() + ; + + $this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + + $this->request = new Request(array(), array(), array(), array(), array(), array()); + + $this->event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $this->event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($this->request)) + ; + + $this->logger = $this->getMock('Psr\Log\LoggerInterface'); + $this->tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $this->token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + } + + protected function tearDown() + { + $this->authenticationManager = null; + $this->dispatcher = null; + $this->event = null; + $this->logger = null; + $this->request = null; + $this->tokenStorage = null; + $this->token = null; + } +} diff --git a/Http/Tests/Firewall/SwitchUserListenerTest.php b/Http/Tests/Firewall/SwitchUserListenerTest.php new file mode 100644 index 0000000..bcba3c2 --- /dev/null +++ b/Http/Tests/Firewall/SwitchUserListenerTest.php @@ -0,0 +1,260 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * 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 Symfony\Component\Security\Http\Event\SwitchUserEvent; +use Symfony\Component\Security\Http\Firewall\SwitchUserListener; +use Symfony\Component\Security\Http\SecurityEvents; + +class SwitchUserListenerTest extends \PHPUnit_Framework_TestCase +{ + private $tokenStorage; + + private $userProvider; + + private $userChecker; + + private $accessDecisionManager; + + private $request; + + private $event; + + protected function setUp() + { + $this->tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + $this->userProvider = $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface'); + $this->userChecker = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface'); + $this->accessDecisionManager = $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface'); + $this->request = $this->getMock('Symfony\Component\HttpFoundation\Request'); + $this->request->query = $this->getMock('Symfony\Component\HttpFoundation\ParameterBag'); + $this->request->server = $this->getMock('Symfony\Component\HttpFoundation\ServerBag'); + $this->event = $this->getEvent($this->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() + { + $this->request->expects($this->any())->method('get')->with('_switch_user')->will($this->returnValue(null)); + + $this->event->expects($this->never())->method('setResponse'); + $this->securityContext->expects($this->never())->method('setToken'); + + $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 = $this->getToken(array($this->getMock('Symfony\Component\Security\Core\Role\RoleInterface'))); + + $this->tokenStorage->expects($this->any())->method('getToken')->will($this->returnValue($token)); + $this->request->expects($this->any())->method('get')->with('_switch_user')->will($this->returnValue('_exit')); + + $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager); + $listener->handle($this->event); + } + + public function testExitUserUpdatesToken() + { + $originalToken = $this->getToken(); + $role = $this->getMockBuilder('Symfony\Component\Security\Core\Role\SwitchUserRole') + ->disableOriginalConstructor() + ->getMock(); + $role->expects($this->any())->method('getSource')->will($this->returnValue($originalToken)); + + $this->tokenStorage->expects($this->any()) + ->method('getToken') + ->will($this->returnValue($this->getToken(array($role)))); + + $this->request->expects($this->any())->method('get')->with('_switch_user')->will($this->returnValue('_exit')); + $this->request->expects($this->any())->method('getUri')->will($this->returnValue('/')); + $this->request->query->expects($this->once())->method('remove', '_switch_user'); + $this->request->query->expects($this->any())->method('all')->will($this->returnValue(array())); + $this->request->server->expects($this->once())->method('set')->with('QUERY_STRING', ''); + + $this->tokenStorage->expects($this->once()) + ->method('setToken')->with($originalToken); + $this->event->expects($this->once()) + ->method('setResponse')->with($this->isInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse')); + + $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager); + $listener->handle($this->event); + } + + public function testExitUserDispatchesEventWithRefreshedUser() + { + $originalUser = $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); + $refreshedUser = $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); + $this + ->userProvider + ->expects($this->any()) + ->method('refreshUser') + ->with($originalUser) + ->willReturn($refreshedUser); + $originalToken = $this->getToken(); + $originalToken + ->expects($this->any()) + ->method('getUser') + ->willReturn($originalUser); + $role = $this + ->getMockBuilder('Symfony\Component\Security\Core\Role\SwitchUserRole') + ->disableOriginalConstructor() + ->getMock(); + $role->expects($this->any())->method('getSource')->willReturn($originalToken); + $this + ->tokenStorage + ->expects($this->any()) + ->method('getToken') + ->willReturn($this->getToken(array($role))); + $this + ->request + ->expects($this->any()) + ->method('get') + ->with('_switch_user') + ->willReturn('_exit'); + $this + ->request + ->expects($this->any()) + ->method('getUri') + ->willReturn('/'); + $this + ->request + ->query + ->expects($this->any()) + ->method('all') + ->will($this->returnValue(array())); + + $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $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); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\AccessDeniedException + */ + public function testSwitchUserIsDisallowed() + { + $token = $this->getToken(array($this->getMock('Symfony\Component\Security\Core\Role\RoleInterface'))); + + $this->tokenStorage->expects($this->any())->method('getToken')->will($this->returnValue($token)); + $this->request->expects($this->any())->method('get')->with('_switch_user')->will($this->returnValue('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 = $this->getToken(array($this->getMock('Symfony\Component\Security\Core\Role\RoleInterface'))); + $user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); + $user->expects($this->any())->method('getRoles')->will($this->returnValue(array())); + + $this->tokenStorage->expects($this->any())->method('getToken')->will($this->returnValue($token)); + $this->request->expects($this->any())->method('get')->with('_switch_user')->will($this->returnValue('kuba')); + $this->request->query->expects($this->once())->method('remove', '_switch_user'); + $this->request->query->expects($this->any())->method('all')->will($this->returnValue(array())); + + $this->request->expects($this->any())->method('getUri')->will($this->returnValue('/')); + $this->request->server->expects($this->once())->method('set')->with('QUERY_STRING', ''); + + $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); + $this->tokenStorage->expects($this->once()) + ->method('setToken')->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken')); + + $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager); + $listener->handle($this->event); + } + + public function testSwitchUserKeepsOtherQueryStringParameters() + { + $token = $this->getToken(array($this->getMock('Symfony\Component\Security\Core\Role\RoleInterface'))); + $user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); + $user->expects($this->any())->method('getRoles')->will($this->returnValue(array())); + + $this->tokenStorage->expects($this->any())->method('getToken')->will($this->returnValue($token)); + $this->request->expects($this->any())->method('get')->with('_switch_user')->will($this->returnValue('kuba')); + $this->request->query->expects($this->once())->method('remove', '_switch_user'); + $this->request->query->expects($this->any())->method('all')->will($this->returnValue(array('page' => 3, 'section' => 2))); + $this->request->expects($this->any())->method('getUri')->will($this->returnValue('/')); + $this->request->server->expects($this->once())->method('set')->with('QUERY_STRING', 'page=3§ion=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); + $this->tokenStorage->expects($this->once()) + ->method('setToken')->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken')); + + $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager); + $listener->handle($this->event); + } + + private function getEvent($request) + { + $event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent') + ->disableOriginalConstructor() + ->getMock(); + + $event->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)); + + return $event; + } + + private function getToken(array $roles = array()) + { + $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + $token->expects($this->any()) + ->method('getRoles') + ->will($this->returnValue($roles)); + + return $token; + } +} diff --git a/Http/Tests/Firewall/X509AuthenticationListenerTest.php b/Http/Tests/Firewall/X509AuthenticationListenerTest.php new file mode 100644 index 0000000..66690d9 --- /dev/null +++ b/Http/Tests/Firewall/X509AuthenticationListenerTest.php @@ -0,0 +1,123 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * 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 Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Http\Firewall\X509AuthenticationListener; + +class X509AuthenticationListenerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider dataProviderGetPreAuthenticatedData + */ + public function testGetPreAuthenticatedData($user, $credentials) + { + $serverVars = array(); + if ('' !== $user) { + $serverVars['SSL_CLIENT_S_DN_Email'] = $user; + } + if ('' !== $credentials) { + $serverVars['SSL_CLIENT_S_DN'] = $credentials; + } + + $request = new Request(array(), array(), array(), array(), array(), $serverVars); + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + + $listener = new X509AuthenticationListener($tokenStorage, $authenticationManager, 'TheProviderKey'); + + $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); + $method->setAccessible(true); + + $result = $method->invokeArgs($listener, array($request)); + $this->assertSame($result, array($user, $credentials)); + } + + public static function dataProviderGetPreAuthenticatedData() + { + return array( + 'validValues' => array('TheUser', 'TheCredentials'), + 'noCredentials' => array('TheUser', ''), + ); + } + + /** + * @dataProvider dataProviderGetPreAuthenticatedDataNoUser + */ + public function testGetPreAuthenticatedDataNoUser($emailAddress) + { + $credentials = 'CN=Sample certificate DN/emailAddress='.$emailAddress; + $request = new Request(array(), array(), array(), array(), array(), array('SSL_CLIENT_S_DN' => $credentials)); + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + + $listener = new X509AuthenticationListener($tokenStorage, $authenticationManager, 'TheProviderKey'); + + $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); + $method->setAccessible(true); + + $result = $method->invokeArgs($listener, array($request)); + $this->assertSame($result, array($emailAddress, $credentials)); + } + + public static function dataProviderGetPreAuthenticatedDataNoUser() + { + return array( + 'basicEmailAddress' => array('cert@example.com'), + 'emailAddressWithPlusSign' => array('cert+something@example.com'), + ); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + */ + public function testGetPreAuthenticatedDataNoData() + { + $request = new Request(array(), array(), array(), array(), array(), array()); + + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + + $listener = new X509AuthenticationListener($tokenStorage, $authenticationManager, 'TheProviderKey'); + + $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); + $method->setAccessible(true); + + $result = $method->invokeArgs($listener, array($request)); + } + + public function testGetPreAuthenticatedDataWithDifferentKeys() + { + $userCredentials = array('TheUser', 'TheCredentials'); + + $request = new Request(array(), array(), array(), array(), array(), array( + 'TheUserKey' => 'TheUser', + 'TheCredentialsKey' => 'TheCredentials', + )); + $tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'); + + $authenticationManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + + $listener = new X509AuthenticationListener($tokenStorage, $authenticationManager, 'TheProviderKey', 'TheUserKey', 'TheCredentialsKey'); + + $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); + $method->setAccessible(true); + + $result = $method->invokeArgs($listener, array($request)); + $this->assertSame($result, $userCredentials); + } +} |