diff options
Diffstat (limited to 'Core')
41 files changed, 3519 insertions, 0 deletions
diff --git a/Core/.gitignore b/Core/.gitignore new file mode 100644 index 0000000..c49a5d8 --- /dev/null +++ b/Core/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +phpunit.xml diff --git a/Core/LICENSE b/Core/LICENSE new file mode 100644 index 0000000..88a57f8 --- /dev/null +++ b/Core/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2013 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Core/README.md b/Core/README.md new file mode 100644 index 0000000..673b161 --- /dev/null +++ b/Core/README.md @@ -0,0 +1,23 @@ +Security Component - Core +========================= + +Security provides an infrastructure for sophisticated authorization systems, +which makes it possible to easily separate the actual authorization logic from +so called user providers that hold the users credentials. It is inspired by +the Java Spring framework. + +Resources +--------- + +Documentation: + +http://symfony.com/doc/2.4/book/security.html + +Resources +--------- + +You can run the unit tests with the following command: + + $ cd path/to/Symfony/Component/Security/Core/ + $ composer.phar install --dev + $ phpunit diff --git a/Core/Tests/Authentication/AuthenticationProviderManagerTest.php b/Core/Tests/Authentication/AuthenticationProviderManagerTest.php new file mode 100644 index 0000000..f3aaa85 --- /dev/null +++ b/Core/Tests/Authentication/AuthenticationProviderManagerTest.php @@ -0,0 +1,138 @@ +<?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\Core\Tests\Authentication; + +use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager; +use Symfony\Component\Security\Core\Exception\ProviderNotFoundException; +use Symfony\Component\Security\Core\Exception\AuthenticationException; +use Symfony\Component\Security\Core\Exception\AccountStatusException; +use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; + +class AuthenticationProviderManagerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @expectedException InvalidArgumentException + */ + public function testAuthenticateWithoutProviders() + { + new AuthenticationProviderManager(array()); + } + + public function testAuthenticateWhenNoProviderSupportsToken() + { + $manager = new AuthenticationProviderManager(array( + $this->getAuthenticationProvider(false), + )); + + try { + $manager->authenticate($token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')); + $this->fail(); + } catch (ProviderNotFoundException $e) { + $this->assertSame($token, $e->getToken()); + } + } + + public function testAuthenticateWhenProviderReturnsAccountStatusException() + { + $manager = new AuthenticationProviderManager(array( + $this->getAuthenticationProvider(true, null, 'Symfony\Component\Security\Core\Exception\AccountStatusException'), + )); + + try { + $manager->authenticate($token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')); + $this->fail(); + } catch (AccountStatusException $e) { + $this->assertSame($token, $e->getToken()); + } + } + + public function testAuthenticateWhenProviderReturnsAuthenticationException() + { + $manager = new AuthenticationProviderManager(array( + $this->getAuthenticationProvider(true, null, 'Symfony\Component\Security\Core\Exception\AuthenticationException'), + )); + + try { + $manager->authenticate($token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')); + $this->fail(); + } catch (AuthenticationException $e) { + $this->assertSame($token, $e->getToken()); + } + } + + public function testAuthenticateWhenOneReturnsAuthenticationExceptionButNotAll() + { + $manager = new AuthenticationProviderManager(array( + $this->getAuthenticationProvider(true, null, 'Symfony\Component\Security\Core\Exception\AuthenticationException'), + $this->getAuthenticationProvider(true, $expected = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')), + )); + + $token = $manager->authenticate($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')); + $this->assertSame($expected, $token); + } + + public function testAuthenticateReturnsTokenOfTheFirstMatchingProvider() + { + $second = $this->getMock('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface'); + $second + ->expects($this->never()) + ->method('supports') + ; + $manager = new AuthenticationProviderManager(array( + $this->getAuthenticationProvider(true, $expected = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')), + $second, + )); + + $token = $manager->authenticate($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')); + $this->assertSame($expected, $token); + } + + public function testEraseCredentialFlag() + { + $manager = new AuthenticationProviderManager(array( + $this->getAuthenticationProvider(true, $token = new UsernamePasswordToken('foo', 'bar', 'key')), + )); + + $token = $manager->authenticate($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')); + $this->assertEquals('', $token->getCredentials()); + + $manager = new AuthenticationProviderManager(array( + $this->getAuthenticationProvider(true, $token = new UsernamePasswordToken('foo', 'bar', 'key')), + ), false); + + $token = $manager->authenticate($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')); + $this->assertEquals('bar', $token->getCredentials()); + } + + protected function getAuthenticationProvider($supports, $token = null, $exception = null) + { + $provider = $this->getMock('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface'); + $provider->expects($this->once()) + ->method('supports') + ->will($this->returnValue($supports)) + ; + + if (null !== $token) { + $provider->expects($this->once()) + ->method('authenticate') + ->will($this->returnValue($token)) + ; + } elseif (null !== $exception) { + $provider->expects($this->once()) + ->method('authenticate') + ->will($this->throwException($this->getMock($exception, null, array(), '', false))) + ; + } + + return $provider; + } +} diff --git a/Core/Tests/Authentication/AuthenticationTrustResolverTest.php b/Core/Tests/Authentication/AuthenticationTrustResolverTest.php new file mode 100644 index 0000000..07ce08b --- /dev/null +++ b/Core/Tests/Authentication/AuthenticationTrustResolverTest.php @@ -0,0 +1,72 @@ +<?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\Core\Tests\Authentication; + +use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; +use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; +use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver; + +class AuthenticationTrustResolverTest extends \PHPUnit_Framework_TestCase +{ + public function testIsAnonymous() + { + $resolver = $this->getResolver(); + + $this->assertFalse($resolver->isAnonymous(null)); + $this->assertFalse($resolver->isAnonymous($this->getToken())); + $this->assertFalse($resolver->isAnonymous($this->getRememberMeToken())); + $this->assertTrue($resolver->isAnonymous($this->getAnonymousToken())); + } + + public function testIsRememberMe() + { + $resolver = $this->getResolver(); + + $this->assertFalse($resolver->isRememberMe(null)); + $this->assertFalse($resolver->isRememberMe($this->getToken())); + $this->assertFalse($resolver->isRememberMe($this->getAnonymousToken())); + $this->assertTrue($resolver->isRememberMe($this->getRememberMeToken())); + } + + public function testisFullFledged() + { + $resolver = $this->getResolver(); + + $this->assertFalse($resolver->isFullFledged(null)); + $this->assertFalse($resolver->isFullFledged($this->getAnonymousToken())); + $this->assertFalse($resolver->isFullFledged($this->getRememberMeToken())); + $this->assertTrue($resolver->isFullFledged($this->getToken())); + } + + protected function getToken() + { + return $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + } + + protected function getAnonymousToken() + { + return $this->getMock('Symfony\Component\Security\Core\Authentication\Token\AnonymousToken', null, array('', '')); + } + + protected function getRememberMeToken() + { + return $this->getMock('Symfony\Component\Security\Core\Authentication\Token\RememberMeToken', array('setPersistent'), array(), '', false); + } + + protected function getResolver() + { + return new AuthenticationTrustResolver( + 'Symfony\\Component\\Security\\Core\\Authentication\\Token\\AnonymousToken', + 'Symfony\\Component\\Security\\Core\\Authentication\\Token\\RememberMeToken' + ); + } +} diff --git a/Core/Tests/Authentication/Provider/AnonymousAuthenticationProviderTest.php b/Core/Tests/Authentication/Provider/AnonymousAuthenticationProviderTest.php new file mode 100644 index 0000000..5a189b0 --- /dev/null +++ b/Core/Tests/Authentication/Provider/AnonymousAuthenticationProviderTest.php @@ -0,0 +1,66 @@ +<?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\Core\Tests\Authentication\Provider; + +use Symfony\Component\Security\Core\Authentication\Provider\AnonymousAuthenticationProvider; + +class AnonymousAuthenticationProviderTest extends \PHPUnit_Framework_TestCase +{ + public function testSupports() + { + $provider = $this->getProvider('foo'); + + $this->assertTrue($provider->supports($this->getSupportedToken('foo'))); + $this->assertFalse($provider->supports($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'))); + } + + public function testAuthenticateWhenTokenIsNotSupported() + { + $provider = $this->getProvider('foo'); + + $this->assertNull($provider->authenticate($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'))); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + */ + public function testAuthenticateWhenKeyIsNotValid() + { + $provider = $this->getProvider('foo'); + + $this->assertNull($provider->authenticate($this->getSupportedToken('bar'))); + } + + public function testAuthenticate() + { + $provider = $this->getProvider('foo'); + $token = $this->getSupportedToken('foo'); + + $this->assertSame($token, $provider->authenticate($token)); + } + + protected function getSupportedToken($key) + { + $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\AnonymousToken', array('getKey'), array(), '', false); + $token->expects($this->any()) + ->method('getKey') + ->will($this->returnValue($key)) + ; + + return $token; + } + + protected function getProvider($key) + { + return new AnonymousAuthenticationProvider($key); + } +} diff --git a/Core/Tests/Authentication/Provider/DaoAuthenticationProviderTest.php b/Core/Tests/Authentication/Provider/DaoAuthenticationProviderTest.php new file mode 100644 index 0000000..ed4fe10 --- /dev/null +++ b/Core/Tests/Authentication/Provider/DaoAuthenticationProviderTest.php @@ -0,0 +1,300 @@ +<?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\Core\Tests\Authentication\Provider; + +use Symfony\Component\Security\Core\Encoder\PlaintextPasswordEncoder; + +use Symfony\Component\Security\Core\Authentication\Provider\DaoAuthenticationProvider; + +class DaoAuthenticationProviderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationServiceException + */ + public function testRetrieveUserWhenProviderDoesNotReturnAnUserInterface() + { + $provider = $this->getProvider('fabien'); + $method = new \ReflectionMethod($provider, 'retrieveUser'); + $method->setAccessible(true); + + $method->invoke($provider, 'fabien', $this->getSupportedToken()); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\UsernameNotFoundException + */ + public function testRetrieveUserWhenUsernameIsNotFound() + { + $userProvider = $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserProviderInterface'); + $userProvider->expects($this->once()) + ->method('loadUserByUsername') + ->will($this->throwException($this->getMock('Symfony\\Component\\Security\\Core\\Exception\\UsernameNotFoundException', null, array(), '', false))) + ; + + $provider = new DaoAuthenticationProvider($userProvider, $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserCheckerInterface'), 'key', $this->getMock('Symfony\\Component\\Security\\Core\\Encoder\\EncoderFactoryInterface')); + $method = new \ReflectionMethod($provider, 'retrieveUser'); + $method->setAccessible(true); + + $method->invoke($provider, 'fabien', $this->getSupportedToken()); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationServiceException + */ + public function testRetrieveUserWhenAnExceptionOccurs() + { + $userProvider = $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserProviderInterface'); + $userProvider->expects($this->once()) + ->method('loadUserByUsername') + ->will($this->throwException($this->getMock('RuntimeException', null, array(), '', false))) + ; + + $provider = new DaoAuthenticationProvider($userProvider, $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserCheckerInterface'), 'key', $this->getMock('Symfony\\Component\\Security\\Core\\Encoder\\EncoderFactoryInterface')); + $method = new \ReflectionMethod($provider, 'retrieveUser'); + $method->setAccessible(true); + + $method->invoke($provider, 'fabien', $this->getSupportedToken()); + } + + public function testRetrieveUserReturnsUserFromTokenOnReauthentication() + { + $userProvider = $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserProviderInterface'); + $userProvider->expects($this->never()) + ->method('loadUserByUsername') + ; + + $user = $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserInterface'); + $token = $this->getSupportedToken(); + $token->expects($this->once()) + ->method('getUser') + ->will($this->returnValue($user)) + ; + + $provider = new DaoAuthenticationProvider($userProvider, $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserCheckerInterface'), 'key', $this->getMock('Symfony\\Component\\Security\\Core\\Encoder\\EncoderFactoryInterface')); + $reflection = new \ReflectionMethod($provider, 'retrieveUser'); + $reflection->setAccessible(true); + $result = $reflection->invoke($provider, null, $token); + + $this->assertSame($user, $result); + } + + public function testRetrieveUser() + { + $user = $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserInterface'); + + $userProvider = $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserProviderInterface'); + $userProvider->expects($this->once()) + ->method('loadUserByUsername') + ->will($this->returnValue($user)) + ; + + $provider = new DaoAuthenticationProvider($userProvider, $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserCheckerInterface'), 'key', $this->getMock('Symfony\\Component\\Security\\Core\\Encoder\\EncoderFactoryInterface')); + $method = new \ReflectionMethod($provider, 'retrieveUser'); + $method->setAccessible(true); + + $this->assertSame($user, $method->invoke($provider, 'fabien', $this->getSupportedToken())); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + */ + public function testCheckAuthenticationWhenCredentialsAreEmpty() + { + $encoder = $this->getMock('Symfony\\Component\\Security\\Core\\Encoder\\PasswordEncoderInterface'); + $encoder + ->expects($this->never()) + ->method('isPasswordValid') + ; + + $provider = $this->getProvider(false, false, $encoder); + $method = new \ReflectionMethod($provider, 'checkAuthentication'); + $method->setAccessible(true); + + $token = $this->getSupportedToken(); + $token + ->expects($this->once()) + ->method('getCredentials') + ->will($this->returnValue('')) + ; + + $method->invoke( + $provider, + $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserInterface'), + $token + ); + } + + public function testCheckAuthenticationWhenCredentialsAre0() + { + $encoder = $this->getMock('Symfony\\Component\\Security\\Core\\Encoder\\PasswordEncoderInterface'); + $encoder + ->expects($this->once()) + ->method('isPasswordValid') + ->will($this->returnValue(true)) + ; + + $provider = $this->getProvider(false, false, $encoder); + $method = new \ReflectionMethod($provider, 'checkAuthentication'); + $method->setAccessible(true); + + $token = $this->getSupportedToken(); + $token + ->expects($this->once()) + ->method('getCredentials') + ->will($this->returnValue('0')) + ; + + $method->invoke( + $provider, + $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserInterface'), + $token + ); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + */ + public function testCheckAuthenticationWhenCredentialsAreNotValid() + { + $encoder = $this->getMock('Symfony\\Component\\Security\\Core\\Encoder\\PasswordEncoderInterface'); + $encoder->expects($this->once()) + ->method('isPasswordValid') + ->will($this->returnValue(false)) + ; + + $provider = $this->getProvider(false, false, $encoder); + $method = new \ReflectionMethod($provider, 'checkAuthentication'); + $method->setAccessible(true); + + $token = $this->getSupportedToken(); + $token->expects($this->once()) + ->method('getCredentials') + ->will($this->returnValue('foo')) + ; + + $method->invoke($provider, $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserInterface'), $token); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + */ + public function testCheckAuthenticationDoesNotReauthenticateWhenPasswordHasChanged() + { + $user = $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserInterface'); + $user->expects($this->once()) + ->method('getPassword') + ->will($this->returnValue('foo')) + ; + + $token = $this->getSupportedToken(); + $token->expects($this->once()) + ->method('getUser') + ->will($this->returnValue($user)); + + $dbUser = $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserInterface'); + $dbUser->expects($this->once()) + ->method('getPassword') + ->will($this->returnValue('newFoo')) + ; + + $provider = $this->getProvider(false, false, null); + $reflection = new \ReflectionMethod($provider, 'checkAuthentication'); + $reflection->setAccessible(true); + $reflection->invoke($provider, $dbUser, $token); + } + + public function testCheckAuthenticationWhenTokenNeedsReauthenticationWorksWithoutOriginalCredentials() + { + $user = $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserInterface'); + $user->expects($this->once()) + ->method('getPassword') + ->will($this->returnValue('foo')) + ; + + $token = $this->getSupportedToken(); + $token->expects($this->once()) + ->method('getUser') + ->will($this->returnValue($user)); + + $dbUser = $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserInterface'); + $dbUser->expects($this->once()) + ->method('getPassword') + ->will($this->returnValue('foo')) + ; + + $provider = $this->getProvider(false, false, null); + $reflection = new \ReflectionMethod($provider, 'checkAuthentication'); + $reflection->setAccessible(true); + $reflection->invoke($provider, $dbUser, $token); + } + + public function testCheckAuthentication() + { + $encoder = $this->getMock('Symfony\\Component\\Security\\Core\\Encoder\\PasswordEncoderInterface'); + $encoder->expects($this->once()) + ->method('isPasswordValid') + ->will($this->returnValue(true)) + ; + + $provider = $this->getProvider(false, false, $encoder); + $method = new \ReflectionMethod($provider, 'checkAuthentication'); + $method->setAccessible(true); + + $token = $this->getSupportedToken(); + $token->expects($this->once()) + ->method('getCredentials') + ->will($this->returnValue('foo')) + ; + + $method->invoke($provider, $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserInterface'), $token); + } + + protected function getSupportedToken() + { + $mock = $this->getMock('Symfony\\Component\\Security\\Core\\Authentication\\Token\\UsernamePasswordToken', array('getCredentials', 'getUser', 'getProviderKey'), array(), '', false); + $mock + ->expects($this->any()) + ->method('getProviderKey') + ->will($this->returnValue('key')) + ; + + return $mock; + } + + protected function getProvider($user = false, $userChecker = false, $passwordEncoder = null) + { + $userProvider = $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserProviderInterface'); + if (false !== $user) { + $userProvider->expects($this->once()) + ->method('loadUserByUsername') + ->will($this->returnValue($user)) + ; + } + + if (false === $userChecker) { + $userChecker = $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserCheckerInterface'); + } + + if (null === $passwordEncoder) { + $passwordEncoder = new PlaintextPasswordEncoder(); + } + + $encoderFactory = $this->getMock('Symfony\\Component\\Security\\Core\\Encoder\\EncoderFactoryInterface'); + $encoderFactory + ->expects($this->any()) + ->method('getEncoder') + ->will($this->returnValue($passwordEncoder)) + ; + + return new DaoAuthenticationProvider($userProvider, $userChecker, 'key', $encoderFactory); + } +} diff --git a/Core/Tests/Authentication/Provider/PreAuthenticatedAuthenticationProviderTest.php b/Core/Tests/Authentication/Provider/PreAuthenticatedAuthenticationProviderTest.php new file mode 100644 index 0000000..522edb4 --- /dev/null +++ b/Core/Tests/Authentication/Provider/PreAuthenticatedAuthenticationProviderTest.php @@ -0,0 +1,133 @@ +<?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\Core\Tests\Authentication\Provider; + +use Symfony\Component\Security\Core\Authentication\Provider\PreAuthenticatedAuthenticationProvider; + +class PreAuthenticatedAuthenticationProviderTest extends \PHPUnit_Framework_TestCase +{ + public function testSupports() + { + $provider = $this->getProvider(); + + $this->assertTrue($provider->supports($this->getSupportedToken())); + $this->assertFalse($provider->supports($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'))); + + $token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken') + ->disableOriginalConstructor() + ->getMock() + ; + $token + ->expects($this->once()) + ->method('getProviderKey') + ->will($this->returnValue('foo')) + ; + $this->assertFalse($provider->supports($token)); + } + + public function testAuthenticateWhenTokenIsNotSupported() + { + $provider = $this->getProvider(); + + $this->assertNull($provider->authenticate($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'))); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + */ + public function testAuthenticateWhenNoUserIsSet() + { + $provider = $this->getProvider(); + $provider->authenticate($this->getSupportedToken('')); + } + + public function testAuthenticate() + { + $user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); + $user + ->expects($this->once()) + ->method('getRoles') + ->will($this->returnValue(array())) + ; + $provider = $this->getProvider($user); + + $token = $provider->authenticate($this->getSupportedToken('fabien', 'pass')); + $this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken', $token); + $this->assertEquals('pass', $token->getCredentials()); + $this->assertEquals('key', $token->getProviderKey()); + $this->assertEquals(array(), $token->getRoles()); + $this->assertEquals(array('foo' => 'bar'), $token->getAttributes(), '->authenticate() copies token attributes'); + $this->assertSame($user, $token->getUser()); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\LockedException + */ + public function testAuthenticateWhenUserCheckerThrowsException() + { + $user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); + + $userChecker = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface'); + $userChecker->expects($this->once()) + ->method('checkPostAuth') + ->will($this->throwException($this->getMock('Symfony\Component\Security\Core\Exception\LockedException', null, array(), '', false))) + ; + + $provider = $this->getProvider($user, $userChecker); + + $provider->authenticate($this->getSupportedToken('fabien')); + } + + protected function getSupportedToken($user = false, $credentials = false) + { + $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken', array('getUser', 'getCredentials', 'getProviderKey'), array(), '', false); + if (false !== $user) { + $token->expects($this->once()) + ->method('getUser') + ->will($this->returnValue($user)) + ; + } + if (false !== $credentials) { + $token->expects($this->once()) + ->method('getCredentials') + ->will($this->returnValue($credentials)) + ; + } + + $token + ->expects($this->any()) + ->method('getProviderKey') + ->will($this->returnValue('key')) + ; + + $token->setAttributes(array('foo' => 'bar')); + + return $token; + } + + protected function getProvider($user = false, $userChecker = false) + { + $userProvider = $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface'); + if (false !== $user) { + $userProvider->expects($this->once()) + ->method('loadUserByUsername') + ->will($this->returnValue($user)) + ; + } + + if (false === $userChecker) { + $userChecker = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface'); + } + + return new PreAuthenticatedAuthenticationProvider($userProvider, $userChecker, 'key'); + } +} diff --git a/Core/Tests/Authentication/Provider/RememberMeAuthenticationProviderTest.php b/Core/Tests/Authentication/Provider/RememberMeAuthenticationProviderTest.php new file mode 100644 index 0000000..43da274 --- /dev/null +++ b/Core/Tests/Authentication/Provider/RememberMeAuthenticationProviderTest.php @@ -0,0 +1,111 @@ +<?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\Core\Tests\Authentication\Provider; + +use Symfony\Component\Security\Core\Authentication\Provider\RememberMeAuthenticationProvider; +use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; +use Symfony\Component\Security\Core\Role\Role; + +class RememberMeAuthenticationProviderTest extends \PHPUnit_Framework_TestCase +{ + public function testSupports() + { + $provider = $this->getProvider(); + + $this->assertTrue($provider->supports($this->getSupportedToken())); + $this->assertFalse($provider->supports($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'))); + } + + public function testAuthenticateWhenTokenIsNotSupported() + { + $provider = $this->getProvider(); + + $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + $this->assertNull($provider->authenticate($token)); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + */ + public function testAuthenticateWhenKeysDoNotMatch() + { + $provider = $this->getProvider(null, 'key1'); + $token = $this->getSupportedToken(null, 'key2'); + + $provider->authenticate($token); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\AccountExpiredException + */ + public function testAuthenticateWhenPostChecksFails() + { + $userChecker = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface'); + $userChecker->expects($this->once()) + ->method('checkPostAuth') + ->will($this->throwException($this->getMock('Symfony\Component\Security\Core\Exception\AccountExpiredException', null, array(), '', false))) + ; + + $provider = $this->getProvider($userChecker); + + $provider->authenticate($this->getSupportedToken()); + } + + public function testAuthenticate() + { + $user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); + $user->expects($this->exactly(2)) + ->method('getRoles') + ->will($this->returnValue(array('ROLE_FOO'))) + ; + + $provider = $this->getProvider(); + + $token = $this->getSupportedToken($user); + $authToken = $provider->authenticate($token); + + $this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\RememberMeToken', $authToken); + $this->assertSame($user, $authToken->getUser()); + $this->assertEquals(array(new Role('ROLE_FOO')), $authToken->getRoles()); + $this->assertEquals('', $authToken->getCredentials()); + } + + protected function getSupportedToken($user = null, $key = 'test') + { + if (null === $user) { + $user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); + $user + ->expects($this->any()) + ->method('getRoles') + ->will($this->returnValue(array())) + ; + } + + $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\RememberMeToken', array('getProviderKey'), array($user, 'foo', $key)); + $token + ->expects($this->once()) + ->method('getProviderKey') + ->will($this->returnValue('foo')) + ; + + return $token; + } + + protected function getProvider($userChecker = null, $key = 'test') + { + if (null === $userChecker) { + $userChecker = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface'); + } + + return new RememberMeAuthenticationProvider($userChecker, $key, 'foo'); + } +} diff --git a/Core/Tests/Authentication/Provider/UserAuthenticationProviderTest.php b/Core/Tests/Authentication/Provider/UserAuthenticationProviderTest.php new file mode 100644 index 0000000..c2b5781 --- /dev/null +++ b/Core/Tests/Authentication/Provider/UserAuthenticationProviderTest.php @@ -0,0 +1,206 @@ +<?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\Core\Tests\Authentication\Provider; + +use Symfony\Component\Security\Core\Authentication\Provider\UserAuthenticationProvider; +use Symfony\Component\Security\Core\Role\Role; +use Symfony\Component\Security\Core\Exception\BadCredentialsException; + +class UserAuthenticationProviderTest extends \PHPUnit_Framework_TestCase +{ + public function testSupports() + { + $provider = $this->getProvider(); + + $this->assertTrue($provider->supports($this->getSupportedToken())); + $this->assertFalse($provider->supports($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'))); + } + + public function testAuthenticateWhenTokenIsNotSupported() + { + $provider = $this->getProvider(); + + $this->assertNull($provider->authenticate($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'))); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\UsernameNotFoundException + */ + public function testAuthenticateWhenUsernameIsNotFound() + { + $provider = $this->getProvider(false, false); + $provider->expects($this->once()) + ->method('retrieveUser') + ->will($this->throwException($this->getMock('Symfony\Component\Security\Core\Exception\UsernameNotFoundException', null, array(), '', false))) + ; + + $provider->authenticate($this->getSupportedToken()); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + */ + public function testAuthenticateWhenUsernameIsNotFoundAndHideIsTrue() + { + $provider = $this->getProvider(false, true); + $provider->expects($this->once()) + ->method('retrieveUser') + ->will($this->throwException($this->getMock('Symfony\Component\Security\Core\Exception\UsernameNotFoundException', null, array(), '', false))) + ; + + $provider->authenticate($this->getSupportedToken()); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationServiceException + */ + public function testAuthenticateWhenProviderDoesNotReturnAnUserInterface() + { + $provider = $this->getProvider(false, true); + $provider->expects($this->once()) + ->method('retrieveUser') + ->will($this->returnValue(null)) + ; + + $provider->authenticate($this->getSupportedToken()); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\CredentialsExpiredException + */ + public function testAuthenticateWhenPreChecksFails() + { + $userChecker = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface'); + $userChecker->expects($this->once()) + ->method('checkPreAuth') + ->will($this->throwException($this->getMock('Symfony\Component\Security\Core\Exception\CredentialsExpiredException', null, array(), '', false))) + ; + + $provider = $this->getProvider($userChecker); + $provider->expects($this->once()) + ->method('retrieveUser') + ->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\User\UserInterface'))) + ; + + $provider->authenticate($this->getSupportedToken()); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\AccountExpiredException + */ + public function testAuthenticateWhenPostChecksFails() + { + $userChecker = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface'); + $userChecker->expects($this->once()) + ->method('checkPostAuth') + ->will($this->throwException($this->getMock('Symfony\Component\Security\Core\Exception\AccountExpiredException', null, array(), '', false))) + ; + + $provider = $this->getProvider($userChecker); + $provider->expects($this->once()) + ->method('retrieveUser') + ->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\User\UserInterface'))) + ; + + $provider->authenticate($this->getSupportedToken()); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + * @expectedExceptionMessage Bad credentials + */ + public function testAuthenticateWhenPostCheckAuthenticationFails() + { + $provider = $this->getProvider(); + $provider->expects($this->once()) + ->method('retrieveUser') + ->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\User\UserInterface'))) + ; + $provider->expects($this->once()) + ->method('checkAuthentication') + ->will($this->throwException($this->getMock('Symfony\Component\Security\Core\Exception\BadCredentialsException', null, array(), '', false))) + ; + + $provider->authenticate($this->getSupportedToken()); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + * @expectedExceptionMessage Foo + */ + public function testAuthenticateWhenPostCheckAuthenticationFailsWithHideFalse() + { + $provider = $this->getProvider(false, false); + $provider->expects($this->once()) + ->method('retrieveUser') + ->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\User\UserInterface'))) + ; + $provider->expects($this->once()) + ->method('checkAuthentication') + ->will($this->throwException(new BadCredentialsException('Foo'))) + ; + + $provider->authenticate($this->getSupportedToken()); + } + + public function testAuthenticate() + { + $user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); + $user->expects($this->once()) + ->method('getRoles') + ->will($this->returnValue(array('ROLE_FOO'))) + ; + + $provider = $this->getProvider(); + $provider->expects($this->once()) + ->method('retrieveUser') + ->will($this->returnValue($user)) + ; + + $token = $this->getSupportedToken(); + $token->expects($this->once()) + ->method('getCredentials') + ->will($this->returnValue('foo')) + ; + + $authToken = $provider->authenticate($token); + + $this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $authToken); + $this->assertSame($user, $authToken->getUser()); + $this->assertEquals(array(new Role('ROLE_FOO')), $authToken->getRoles()); + $this->assertEquals('foo', $authToken->getCredentials()); + $this->assertEquals(array('foo' => 'bar'), $authToken->getAttributes(), '->authenticate() copies token attributes'); + } + + protected function getSupportedToken() + { + $mock = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', array('getCredentials', 'getProviderKey'), array(), '', false); + $mock + ->expects($this->any()) + ->method('getProviderKey') + ->will($this->returnValue('key')) + ; + + $mock->setAttributes(array('foo' => 'bar')); + + return $mock; + } + + protected function getProvider($userChecker = false, $hide = true) + { + if (false === $userChecker) { + $userChecker = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface'); + } + + return $this->getMockForAbstractClass('Symfony\Component\Security\Core\Authentication\Provider\UserAuthenticationProvider', array($userChecker, 'key', $hide)); + } +} diff --git a/Core/Tests/Authentication/RememberMe/InMemoryTokenProviderTest.php b/Core/Tests/Authentication/RememberMe/InMemoryTokenProviderTest.php new file mode 100644 index 0000000..3bdf38c --- /dev/null +++ b/Core/Tests/Authentication/RememberMe/InMemoryTokenProviderTest.php @@ -0,0 +1,63 @@ +<?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\Core\Tests\Authentication\RememberMe; + +use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken; +use Symfony\Component\Security\Core\Authentication\RememberMe\InMemoryTokenProvider; + +class InMemoryTokenProviderTest extends \PHPUnit_Framework_TestCase +{ + public function testCreateNewToken() + { + $provider = new InMemoryTokenProvider(); + + $token = new PersistentToken('foo', 'foo', 'foo', 'foo', new \DateTime()); + $provider->createNewToken($token); + + $this->assertSame($provider->loadTokenBySeries('foo'), $token); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\TokenNotFoundException + */ + public function testLoadTokenBySeriesThrowsNotFoundException() + { + $provider = new InMemoryTokenProvider(); + $provider->loadTokenBySeries('foo'); + } + + public function testUpdateToken() + { + $provider = new InMemoryTokenProvider(); + + $token = new PersistentToken('foo', 'foo', 'foo', 'foo', new \DateTime()); + $provider->createNewToken($token); + $provider->updateToken('foo', 'newFoo', $lastUsed = new \DateTime()); + $token = $provider->loadTokenBySeries('foo'); + + $this->assertEquals('newFoo', $token->getTokenValue()); + $this->assertSame($token->getLastUsed(), $lastUsed); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\TokenNotFoundException + */ + public function testDeleteToken() + { + $provider = new InMemoryTokenProvider(); + + $token = new PersistentToken('foo', 'foo', 'foo', 'foo', new \DateTime()); + $provider->createNewToken($token); + $provider->deleteTokenBySeries('foo'); + $provider->loadTokenBySeries('foo'); + } +} diff --git a/Core/Tests/Authentication/RememberMe/PersistentTokenTest.php b/Core/Tests/Authentication/RememberMe/PersistentTokenTest.php new file mode 100644 index 0000000..903c030 --- /dev/null +++ b/Core/Tests/Authentication/RememberMe/PersistentTokenTest.php @@ -0,0 +1,29 @@ +<?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\Core\Tests\Authentication\RememberMe; + +use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken; + +class PersistentTokenTest extends \PHPUnit_Framework_TestCase +{ + public function testConstructor() + { + $lastUsed = new \DateTime(); + $token = new PersistentToken('fooclass', 'fooname', 'fooseries', 'footokenvalue', $lastUsed); + + $this->assertEquals('fooclass', $token->getClass()); + $this->assertEquals('fooname', $token->getUsername()); + $this->assertEquals('fooseries', $token->getSeries()); + $this->assertEquals('footokenvalue', $token->getTokenValue()); + $this->assertSame($lastUsed, $token->getLastUsed()); + } +} diff --git a/Core/Tests/Authentication/Token/AbstractTokenTest.php b/Core/Tests/Authentication/Token/AbstractTokenTest.php new file mode 100644 index 0000000..928ee40 --- /dev/null +++ b/Core/Tests/Authentication/Token/AbstractTokenTest.php @@ -0,0 +1,244 @@ +<?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\Core\Tests\Authentication\Token; + +use Symfony\Component\Security\Core\Role\Role; + +class TestUser +{ + protected $name; + + public function __construct($name) + { + $this->name = $name; + } + + public function __toString() + { + return $this->name; + } +} + +class AbstractTokenTest extends \PHPUnit_Framework_TestCase +{ + public function testGetUsername() + { + $token = $this->getToken(array('ROLE_FOO')); + $token->setUser('fabien'); + $this->assertEquals('fabien', $token->getUsername()); + + $token->setUser(new TestUser('fabien')); + $this->assertEquals('fabien', $token->getUsername()); + + $user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); + $user->expects($this->once())->method('getUsername')->will($this->returnValue('fabien')); + $token->setUser($user); + $this->assertEquals('fabien', $token->getUsername()); + } + + public function testEraseCredentials() + { + $token = $this->getToken(array('ROLE_FOO')); + + $user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); + $user->expects($this->once())->method('eraseCredentials'); + $token->setUser($user); + + $token->eraseCredentials(); + } + + /** + * @covers Symfony\Component\Security\Core\Authentication\Token\AbstractToken::serialize + * @covers Symfony\Component\Security\Core\Authentication\Token\AbstractToken::unserialize + */ + public function testSerialize() + { + $token = $this->getToken(array('ROLE_FOO')); + $token->setAttributes(array('foo' => 'bar')); + + $uToken = unserialize(serialize($token)); + + $this->assertEquals($token->getRoles(), $uToken->getRoles()); + $this->assertEquals($token->getAttributes(), $uToken->getAttributes()); + } + + /** + * @covers Symfony\Component\Security\Core\Authentication\Token\AbstractToken::__construct + */ + public function testConstructor() + { + $token = $this->getToken(array('ROLE_FOO')); + $this->assertEquals(array(new Role('ROLE_FOO')), $token->getRoles()); + + $token = $this->getToken(array(new Role('ROLE_FOO'))); + $this->assertEquals(array(new Role('ROLE_FOO')), $token->getRoles()); + + $token = $this->getToken(array(new Role('ROLE_FOO'), 'ROLE_BAR')); + $this->assertEquals(array(new Role('ROLE_FOO'), new Role('ROLE_BAR')), $token->getRoles()); + } + + /** + * @covers Symfony\Component\Security\Core\Authentication\Token\AbstractToken::isAuthenticated + * @covers Symfony\Component\Security\Core\Authentication\Token\AbstractToken::setAuthenticated + */ + public function testAuthenticatedFlag() + { + $token = $this->getToken(); + $this->assertFalse($token->isAuthenticated()); + + $token->setAuthenticated(true); + $this->assertTrue($token->isAuthenticated()); + + $token->setAuthenticated(false); + $this->assertFalse($token->isAuthenticated()); + } + + /** + * @covers Symfony\Component\Security\Core\Authentication\Token\AbstractToken::getAttributes + * @covers Symfony\Component\Security\Core\Authentication\Token\AbstractToken::setAttributes + * @covers Symfony\Component\Security\Core\Authentication\Token\AbstractToken::hasAttribute + * @covers Symfony\Component\Security\Core\Authentication\Token\AbstractToken::getAttribute + * @covers Symfony\Component\Security\Core\Authentication\Token\AbstractToken::setAttribute + */ + public function testAttributes() + { + $attributes = array('foo' => 'bar'); + $token = $this->getToken(); + $token->setAttributes($attributes); + + $this->assertEquals($attributes, $token->getAttributes(), '->getAttributes() returns the token attributes'); + $this->assertEquals('bar', $token->getAttribute('foo'), '->getAttribute() returns the value of an attribute'); + $token->setAttribute('foo', 'foo'); + $this->assertEquals('foo', $token->getAttribute('foo'), '->setAttribute() changes the value of an attribute'); + $this->assertTrue($token->hasAttribute('foo'), '->hasAttribute() returns true if the attribute is defined'); + $this->assertFalse($token->hasAttribute('oof'), '->hasAttribute() returns false if the attribute is not defined'); + + try { + $token->getAttribute('foobar'); + $this->fail('->getAttribute() throws an \InvalidArgumentException exception when the attribute does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->getAttribute() throws an \InvalidArgumentException exception when the attribute does not exist'); + $this->assertEquals('This token has no "foobar" attribute.', $e->getMessage(), '->getAttribute() throws an \InvalidArgumentException exception when the attribute does not exist'); + } + } + + /** + * @dataProvider getUsers + */ + public function testSetUser($user) + { + $token = $this->getToken(); + $token->setUser($user); + $this->assertSame($user, $token->getUser()); + } + + public function getUsers() + { + $user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); + $advancedUser = $this->getMock('Symfony\Component\Security\Core\User\AdvancedUserInterface'); + + return array( + array($advancedUser), + array($user), + array(new TestUser('foo')), + array('foo'), + ); + } + + /** + * @dataProvider getUserChanges + */ + public function testSetUserSetsAuthenticatedToFalseWhenUserChanges($firstUser, $secondUser) + { + $token = $this->getToken(); + $token->setAuthenticated(true); + $this->assertTrue($token->isAuthenticated()); + + $token->setUser($firstUser); + $this->assertTrue($token->isAuthenticated()); + + $token->setUser($secondUser); + $this->assertFalse($token->isAuthenticated()); + } + + public function getUserChanges() + { + $user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); + $advancedUser = $this->getMock('Symfony\Component\Security\Core\User\AdvancedUserInterface'); + + return array( + array( + 'foo', 'bar', + ), + array( + 'foo', new TestUser('bar'), + ), + array( + 'foo', $user, + ), + array( + 'foo', $advancedUser + ), + array( + $user, 'foo' + ), + array( + $advancedUser, 'foo' + ), + array( + $user, new TestUser('foo'), + ), + array( + $advancedUser, new TestUser('foo'), + ), + array( + new TestUser('foo'), new TestUser('bar'), + ), + array( + new TestUser('foo'), 'bar', + ), + array( + new TestUser('foo'), $user, + ), + array( + new TestUser('foo'), $advancedUser, + ), + array( + $user, $advancedUser + ), + array( + $advancedUser, $user + ), + ); + } + + /** + * @dataProvider getUsers + */ + public function testSetUserDoesNotSetAuthenticatedToFalseWhenUserDoesNotChange($user) + { + $token = $this->getToken(); + $token->setAuthenticated(true); + $this->assertTrue($token->isAuthenticated()); + + $token->setUser($user); + $this->assertTrue($token->isAuthenticated()); + + $token->setUser($user); + $this->assertTrue($token->isAuthenticated()); + } + + protected function getToken(array $roles = array()) + { + return $this->getMockForAbstractClass('Symfony\Component\Security\Core\Authentication\Token\AbstractToken', array($roles)); + } +} diff --git a/Core/Tests/Authentication/Token/AnonymousTokenTest.php b/Core/Tests/Authentication/Token/AnonymousTokenTest.php new file mode 100644 index 0000000..b5cf006 --- /dev/null +++ b/Core/Tests/Authentication/Token/AnonymousTokenTest.php @@ -0,0 +1,45 @@ +<?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\Core\Tests\Authentication\Token; + +use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; +use Symfony\Component\Security\Core\Role\Role; + +class AnonymousTokenTest extends \PHPUnit_Framework_TestCase +{ + public function testConstructor() + { + $token = new AnonymousToken('foo', 'bar'); + $this->assertTrue($token->isAuthenticated()); + + $token = new AnonymousToken('foo', 'bar', array('ROLE_FOO')); + $this->assertEquals(array(new Role('ROLE_FOO')), $token->getRoles()); + } + + public function testGetKey() + { + $token = new AnonymousToken('foo', 'bar'); + $this->assertEquals('foo', $token->getKey()); + } + + public function testGetCredentials() + { + $token = new AnonymousToken('foo', 'bar'); + $this->assertEquals('', $token->getCredentials()); + } + + public function testGetUser() + { + $token = new AnonymousToken('foo', 'bar'); + $this->assertEquals('bar', $token->getUser()); + } +} diff --git a/Core/Tests/Authentication/Token/PreAuthenticatedTokenTest.php b/Core/Tests/Authentication/Token/PreAuthenticatedTokenTest.php new file mode 100644 index 0000000..77d2608 --- /dev/null +++ b/Core/Tests/Authentication/Token/PreAuthenticatedTokenTest.php @@ -0,0 +1,48 @@ +<?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\Core\Tests\Authentication\Token; + +use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken; +use Symfony\Component\Security\Core\Role\Role; + +class PreAuthenticatedTokenTest extends \PHPUnit_Framework_TestCase +{ + public function testConstructor() + { + $token = new PreAuthenticatedToken('foo', 'bar', 'key'); + $this->assertFalse($token->isAuthenticated()); + + $token = new PreAuthenticatedToken('foo', 'bar', 'key', array('ROLE_FOO')); + $this->assertTrue($token->isAuthenticated()); + $this->assertEquals(array(new Role('ROLE_FOO')), $token->getRoles()); + $this->assertEquals('key', $token->getProviderKey()); + } + + public function testGetCredentials() + { + $token = new PreAuthenticatedToken('foo', 'bar', 'key'); + $this->assertEquals('bar', $token->getCredentials()); + } + + public function testGetUser() + { + $token = new PreAuthenticatedToken('foo', 'bar', 'key'); + $this->assertEquals('foo', $token->getUser()); + } + + public function testEraseCredentials() + { + $token = new PreAuthenticatedToken('foo', 'bar', 'key'); + $token->eraseCredentials(); + $this->assertEquals('', $token->getCredentials()); + } +} diff --git a/Core/Tests/Authentication/Token/RememerMeTokenTest.php b/Core/Tests/Authentication/Token/RememerMeTokenTest.php new file mode 100644 index 0000000..60d88c2 --- /dev/null +++ b/Core/Tests/Authentication/Token/RememerMeTokenTest.php @@ -0,0 +1,83 @@ +<?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\Core\Tests\Authentication\Token; + +use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; +use Symfony\Component\Security\Core\Role\Role; + +class RememberMeTokenTest extends \PHPUnit_Framework_TestCase +{ + public function testConstructor() + { + $user = $this->getUser(); + $token = new RememberMeToken($user, 'fookey', 'foo'); + + $this->assertEquals('fookey', $token->getProviderKey()); + $this->assertEquals('foo', $token->getKey()); + $this->assertEquals(array(new Role('ROLE_FOO')), $token->getRoles()); + $this->assertSame($user, $token->getUser()); + $this->assertTrue($token->isAuthenticated()); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testConstructorKeyCannotBeNull() + { + new RememberMeToken( + $this->getUser(), + null, + null + ); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testConstructorKeyCannotBeEmptyString() + { + new RememberMeToken( + $this->getUser(), + '', + '' + ); + } + + /** + * @expectedException PHPUnit_Framework_Error + * @dataProvider getUserArguments + */ + public function testConstructorUserCannotBeNull($user) + { + new RememberMeToken($user, 'foo', 'foo'); + } + + public function getUserArguments() + { + return array( + array(null), + array('foo'), + ); + } + + protected function getUser($roles = array('ROLE_FOO')) + { + $user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); + $user + ->expects($this->once()) + ->method('getRoles') + ->will($this->returnValue($roles)) + ; + + return $user; + } +} diff --git a/Core/Tests/Authentication/Token/UsernamePasswordTokenTest.php b/Core/Tests/Authentication/Token/UsernamePasswordTokenTest.php new file mode 100644 index 0000000..99830c7 --- /dev/null +++ b/Core/Tests/Authentication/Token/UsernamePasswordTokenTest.php @@ -0,0 +1,58 @@ +<?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\Core\Tests\Authentication\Token; + +use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; +use Symfony\Component\Security\Core\Role\Role; + +class UsernamePasswordTokenTest extends \PHPUnit_Framework_TestCase +{ + public function testConstructor() + { + $token = new UsernamePasswordToken('foo', 'bar', 'key'); + $this->assertFalse($token->isAuthenticated()); + + $token = new UsernamePasswordToken('foo', 'bar', 'key', array('ROLE_FOO')); + $this->assertEquals(array(new Role('ROLE_FOO')), $token->getRoles()); + $this->assertTrue($token->isAuthenticated()); + $this->assertEquals('key', $token->getProviderKey()); + } + + /** + * @expectedException LogicException + */ + public function testSetAuthenticatedToTrue() + { + $token = new UsernamePasswordToken('foo', 'bar', 'key'); + $token->setAuthenticated(true); + } + + public function testSetAuthenticatedToFalse() + { + $token = new UsernamePasswordToken('foo', 'bar', 'key'); + $token->setAuthenticated(false); + $this->assertFalse($token->isAuthenticated()); + } + + public function testEraseCredentials() + { + $token = new UsernamePasswordToken('foo', 'bar', 'key'); + $token->eraseCredentials(); + $this->assertEquals('', $token->getCredentials()); + } + + public function testToString() + { + $token = new UsernamePasswordToken('foo', '', 'foo', array('A', 'B')); + $this->assertEquals('UsernamePasswordToken(user="foo", authenticated=true, roles="A, B")', (string) $token); + } +} diff --git a/Core/Tests/Authorization/AccessDecisionManagerTest.php b/Core/Tests/Authorization/AccessDecisionManagerTest.php new file mode 100644 index 0000000..0353f99 --- /dev/null +++ b/Core/Tests/Authorization/AccessDecisionManagerTest.php @@ -0,0 +1,159 @@ +<?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\Core\Tests\Authorization; + +use Symfony\Component\Security\Core\Authorization\AccessDecisionManager; +use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface; + +class AccessDecisionManagerTest extends \PHPUnit_Framework_TestCase +{ + public function testSupportsClass() + { + $manager = new AccessDecisionManager(array( + $this->getVoterSupportsClass(true), + $this->getVoterSupportsClass(false), + )); + $this->assertTrue($manager->supportsClass('FooClass')); + + $manager = new AccessDecisionManager(array( + $this->getVoterSupportsClass(false), + $this->getVoterSupportsClass(false), + )); + $this->assertFalse($manager->supportsClass('FooClass')); + } + + public function testSupportsAttribute() + { + $manager = new AccessDecisionManager(array( + $this->getVoterSupportsAttribute(true), + $this->getVoterSupportsAttribute(false), + )); + $this->assertTrue($manager->supportsAttribute('foo')); + + $manager = new AccessDecisionManager(array( + $this->getVoterSupportsAttribute(false), + $this->getVoterSupportsAttribute(false), + )); + $this->assertFalse($manager->supportsAttribute('foo')); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testSetVotersEmpty() + { + $manager = new AccessDecisionManager(array()); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testSetUnsupportedStrategy() + { + new AccessDecisionManager(array($this->getVoter(VoterInterface::ACCESS_GRANTED)), 'fooBar'); + } + + /** + * @dataProvider getStrategyTests + */ + public function testStrategies($strategy, $voters, $allowIfAllAbstainDecisions, $allowIfEqualGrantedDeniedDecisions, $expected) + { + $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + $manager = new AccessDecisionManager($voters, $strategy, $allowIfAllAbstainDecisions, $allowIfEqualGrantedDeniedDecisions); + + $this->assertSame($expected, $manager->decide($token, array('ROLE_FOO'))); + } + + public function getStrategyTests() + { + return array( + // affirmative + array('affirmative', $this->getVoters(1, 0, 0), false, true, true), + array('affirmative', $this->getVoters(1, 2, 0), false, true, true), + array('affirmative', $this->getVoters(0, 1, 0), false, true, false), + array('affirmative', $this->getVoters(0, 0, 1), false, true, false), + array('affirmative', $this->getVoters(0, 0, 1), true, true, true), + + // consensus + array('consensus', $this->getVoters(1, 0, 0), false, true, true), + array('consensus', $this->getVoters(1, 2, 0), false, true, false), + array('consensus', $this->getVoters(2, 1, 0), false, true, true), + + array('consensus', $this->getVoters(0, 0, 1), false, true, false), + + array('consensus', $this->getVoters(0, 0, 1), true, true, true), + + array('consensus', $this->getVoters(2, 2, 0), false, true, true), + array('consensus', $this->getVoters(2, 2, 1), false, true, true), + + array('consensus', $this->getVoters(2, 2, 0), false, false, false), + array('consensus', $this->getVoters(2, 2, 1), false, false, false), + + // unanimous + array('unanimous', $this->getVoters(1, 0, 0), false, true, true), + array('unanimous', $this->getVoters(1, 0, 1), false, true, true), + array('unanimous', $this->getVoters(1, 1, 0), false, true, false), + + array('unanimous', $this->getVoters(0, 0, 2), false, true, false), + array('unanimous', $this->getVoters(0, 0, 2), true, true, true), + ); + } + + protected function getVoters($grants, $denies, $abstains) + { + $voters = array(); + for ($i = 0; $i < $grants; $i++) { + $voters[] = $this->getVoter(VoterInterface::ACCESS_GRANTED); + } + for ($i = 0; $i < $denies; $i++) { + $voters[] = $this->getVoter(VoterInterface::ACCESS_DENIED); + } + for ($i = 0; $i < $abstains; $i++) { + $voters[] = $this->getVoter(VoterInterface::ACCESS_ABSTAIN); + } + + return $voters; + } + + protected function getVoter($vote) + { + $voter = $this->getMock('Symfony\Component\Security\Core\Authorization\Voter\VoterInterface'); + $voter->expects($this->any()) + ->method('vote') + ->will($this->returnValue($vote)); + ; + + return $voter; + } + + protected function getVoterSupportsClass($ret) + { + $voter = $this->getMock('Symfony\Component\Security\Core\Authorization\Voter\VoterInterface'); + $voter->expects($this->any()) + ->method('supportsClass') + ->will($this->returnValue($ret)); + ; + + return $voter; + } + + protected function getVoterSupportsAttribute($ret) + { + $voter = $this->getMock('Symfony\Component\Security\Core\Authorization\Voter\VoterInterface'); + $voter->expects($this->any()) + ->method('supportsAttribute') + ->will($this->returnValue($ret)); + ; + + return $voter; + } +} diff --git a/Core/Tests/Authorization/Voter/AuthenticatedVoterTest.php b/Core/Tests/Authorization/Voter/AuthenticatedVoterTest.php new file mode 100644 index 0000000..4679c0f --- /dev/null +++ b/Core/Tests/Authorization/Voter/AuthenticatedVoterTest.php @@ -0,0 +1,78 @@ +<?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\Core\Tests\Authorization\Voter; + +use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver; +use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter; +use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface; + +class AuthenticatedVoterTest extends \PHPUnit_Framework_TestCase +{ + public function testSupportsClass() + { + $voter = new AuthenticatedVoter($this->getResolver()); + $this->assertTrue($voter->supportsClass('stdClass')); + } + + /** + * @dataProvider getVoteTests + */ + public function testVote($authenticated, $attributes, $expected) + { + $voter = new AuthenticatedVoter($this->getResolver()); + + $this->assertSame($expected, $voter->vote($this->getToken($authenticated), null, $attributes)); + } + + public function getVoteTests() + { + return array( + array('fully', array(), VoterInterface::ACCESS_ABSTAIN), + array('fully', array('FOO'), VoterInterface::ACCESS_ABSTAIN), + array('remembered', array(), VoterInterface::ACCESS_ABSTAIN), + array('remembered', array('FOO'), VoterInterface::ACCESS_ABSTAIN), + array('anonymously', array(), VoterInterface::ACCESS_ABSTAIN), + array('anonymously', array('FOO'), VoterInterface::ACCESS_ABSTAIN), + + array('fully', array('IS_AUTHENTICATED_ANONYMOUSLY'), VoterInterface::ACCESS_GRANTED), + array('remembered', array('IS_AUTHENTICATED_ANONYMOUSLY'), VoterInterface::ACCESS_GRANTED), + array('anonymously', array('IS_AUTHENTICATED_ANONYMOUSLY'), VoterInterface::ACCESS_GRANTED), + + array('fully', array('IS_AUTHENTICATED_REMEMBERED'), VoterInterface::ACCESS_GRANTED), + array('remembered', array('IS_AUTHENTICATED_REMEMBERED'), VoterInterface::ACCESS_GRANTED), + array('anonymously', array('IS_AUTHENTICATED_REMEMBERED'), VoterInterface::ACCESS_DENIED), + + array('fully', array('IS_AUTHENTICATED_FULLY'), VoterInterface::ACCESS_GRANTED), + array('remembered', array('IS_AUTHENTICATED_FULLY'), VoterInterface::ACCESS_DENIED), + array('anonymously', array('IS_AUTHENTICATED_FULLY'), VoterInterface::ACCESS_DENIED), + ); + } + + protected function getResolver() + { + return new AuthenticationTrustResolver( + 'Symfony\\Component\\Security\\Core\\Authentication\\Token\\AnonymousToken', + 'Symfony\\Component\\Security\\Core\\Authentication\\Token\\RememberMeToken' + ); + } + + protected function getToken($authenticated) + { + if ('fully' === $authenticated) { + return $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + } elseif ('remembered' === $authenticated) { + return $this->getMock('Symfony\Component\Security\Core\Authentication\Token\RememberMeToken', array('setPersistent'), array(), '', false); + } else { + return $this->getMock('Symfony\Component\Security\Core\Authentication\Token\AnonymousToken', null, array('', '')); + } + } +} diff --git a/Core/Tests/Authorization/Voter/RoleHierarchyVoterTest.php b/Core/Tests/Authorization/Voter/RoleHierarchyVoterTest.php new file mode 100644 index 0000000..c50ecf3 --- /dev/null +++ b/Core/Tests/Authorization/Voter/RoleHierarchyVoterTest.php @@ -0,0 +1,36 @@ +<?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\Core\Tests\Authorization\Voter; + +use Symfony\Component\Security\Core\Authorization\Voter\RoleHierarchyVoter; +use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface; +use Symfony\Component\Security\Core\Role\RoleHierarchy; + +class RoleHierarchyVoterTest extends RoleVoterTest +{ + /** + * @dataProvider getVoteTests + */ + public function testVote($roles, $attributes, $expected) + { + $voter = new RoleHierarchyVoter(new RoleHierarchy(array('ROLE_FOO' => array('ROLE_FOOBAR')))); + + $this->assertSame($expected, $voter->vote($this->getToken($roles), null, $attributes)); + } + + public function getVoteTests() + { + return array_merge(parent::getVoteTests(), array( + array(array('ROLE_FOO'), array('ROLE_FOOBAR'), VoterInterface::ACCESS_GRANTED), + )); + } +} diff --git a/Core/Tests/Authorization/Voter/RoleVoterTest.php b/Core/Tests/Authorization/Voter/RoleVoterTest.php new file mode 100644 index 0000000..62e3013 --- /dev/null +++ b/Core/Tests/Authorization/Voter/RoleVoterTest.php @@ -0,0 +1,62 @@ +<?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\Core\Tests\Authorization\Voter; + +use Symfony\Component\Security\Core\Authorization\Voter\RoleVoter; +use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface; +use Symfony\Component\Security\Core\Role\Role; + +class RoleVoterTest extends \PHPUnit_Framework_TestCase +{ + public function testSupportsClass() + { + $voter = new RoleVoter(); + + $this->assertTrue($voter->supportsClass('Foo')); + } + + /** + * @dataProvider getVoteTests + */ + public function testVote($roles, $attributes, $expected) + { + $voter = new RoleVoter(); + + $this->assertSame($expected, $voter->vote($this->getToken($roles), null, $attributes)); + } + + public function getVoteTests() + { + return array( + array(array(), array(), VoterInterface::ACCESS_ABSTAIN), + array(array(), array('FOO'), VoterInterface::ACCESS_ABSTAIN), + array(array(), array('ROLE_FOO'), VoterInterface::ACCESS_DENIED), + array(array('ROLE_FOO'), array('ROLE_FOO'), VoterInterface::ACCESS_GRANTED), + array(array('ROLE_FOO'), array('FOO', 'ROLE_FOO'), VoterInterface::ACCESS_GRANTED), + array(array('ROLE_BAR', 'ROLE_FOO'), array('ROLE_FOO'), VoterInterface::ACCESS_GRANTED), + ); + } + + protected function getToken(array $roles) + { + foreach ($roles as $i => $role) { + $roles[$i] = new Role($role); + } + $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + $token->expects($this->once()) + ->method('getRoles') + ->will($this->returnValue($roles)); + ; + + return $token; + } +} diff --git a/Core/Tests/Encoder/BCryptPasswordEncoderTest.php b/Core/Tests/Encoder/BCryptPasswordEncoderTest.php new file mode 100644 index 0000000..4780411 --- /dev/null +++ b/Core/Tests/Encoder/BCryptPasswordEncoderTest.php @@ -0,0 +1,73 @@ +<?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\Core\Tests\Encoder; + +use Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder; + +/** + * @author Elnur Abdurrakhimov <elnur@elnur.pro> + */ +class BCryptPasswordEncoderTest extends \PHPUnit_Framework_TestCase +{ + const PASSWORD = 'password'; + const BYTES = '0123456789abcdef'; + const VALID_COST = '04'; + + /** + * @expectedException \InvalidArgumentException + */ + public function testCostBelowRange() + { + new BCryptPasswordEncoder(3); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testCostAboveRange() + { + new BCryptPasswordEncoder(32); + } + + public function testCostInRange() + { + for ($cost = 4; $cost <= 31; $cost++) { + new BCryptPasswordEncoder($cost); + } + } + + public function testResultLength() + { + $this->skipIfPhpVersionIsNotSupported(); + + $encoder = new BCryptPasswordEncoder(self::VALID_COST); + $result = $encoder->encodePassword(self::PASSWORD, null); + $this->assertEquals(60, strlen($result)); + } + + public function testValidation() + { + $this->skipIfPhpVersionIsNotSupported(); + + $encoder = new BCryptPasswordEncoder(self::VALID_COST); + $result = $encoder->encodePassword(self::PASSWORD, null); + $this->assertTrue($encoder->isPasswordValid($result, self::PASSWORD, null)); + $this->assertFalse($encoder->isPasswordValid($result, 'anotherPassword', null)); + } + + private function skipIfPhpVersionIsNotSupported() + { + if (version_compare(phpversion(), '5.3.7', '<')) { + $this->markTestSkipped('Requires PHP >= 5.3.7'); + } + } +} diff --git a/Core/Tests/Encoder/BasePasswordEncoderTest.php b/Core/Tests/Encoder/BasePasswordEncoderTest.php new file mode 100644 index 0000000..73fac2e --- /dev/null +++ b/Core/Tests/Encoder/BasePasswordEncoderTest.php @@ -0,0 +1,85 @@ +<?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\Core\Tests\Encoder; + +use Symfony\Component\Security\Core\Encoder\BasePasswordEncoder; + +class PasswordEncoder extends BasePasswordEncoder +{ + public function encodePassword($raw, $salt) + { + } + + public function isPasswordValid($encoded, $raw, $salt) + { + } +} + +class BasePasswordEncoderTest extends \PHPUnit_Framework_TestCase +{ + public function testComparePassword() + { + $this->assertTrue($this->invokeComparePasswords('password', 'password')); + $this->assertFalse($this->invokeComparePasswords('password', 'foo')); + } + + public function testDemergePasswordAndSalt() + { + $this->assertEquals(array('password', 'salt'), $this->invokeDemergePasswordAndSalt('password{salt}')); + $this->assertEquals(array('password', ''), $this->invokeDemergePasswordAndSalt('password')); + $this->assertEquals(array('', ''), $this->invokeDemergePasswordAndSalt('')); + } + + public function testMergePasswordAndSalt() + { + $this->assertEquals('password{salt}', $this->invokeMergePasswordAndSalt('password', 'salt')); + $this->assertEquals('password', $this->invokeMergePasswordAndSalt('password', '')); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testMergePasswordAndSaltWithException() + { + $this->invokeMergePasswordAndSalt('password', '{foo}'); + } + + protected function invokeDemergePasswordAndSalt($password) + { + $encoder = new PasswordEncoder(); + $r = new \ReflectionObject($encoder); + $m = $r->getMethod('demergePasswordAndSalt'); + $m->setAccessible(true); + + return $m->invoke($encoder, $password); + } + + protected function invokeMergePasswordAndSalt($password, $salt) + { + $encoder = new PasswordEncoder(); + $r = new \ReflectionObject($encoder); + $m = $r->getMethod('mergePasswordAndSalt'); + $m->setAccessible(true); + + return $m->invoke($encoder, $password, $salt); + } + + protected function invokeComparePasswords($p1, $p2) + { + $encoder = new PasswordEncoder(); + $r = new \ReflectionObject($encoder); + $m = $r->getMethod('comparePasswords'); + $m->setAccessible(true); + + return $m->invoke($encoder, $p1, $p2); + } +} diff --git a/Core/Tests/Encoder/EncoderFactoryTest.php b/Core/Tests/Encoder/EncoderFactoryTest.php new file mode 100644 index 0000000..18c8c4a --- /dev/null +++ b/Core/Tests/Encoder/EncoderFactoryTest.php @@ -0,0 +1,94 @@ +<?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\Core\Tests\Encoder; + +use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder; +use Symfony\Component\Security\Core\Encoder\EncoderFactory; +use Symfony\Component\Security\Core\User\User; +use Symfony\Component\Security\Core\User\UserInterface; + +class EncoderFactoryTest extends \PHPUnit_Framework_TestCase +{ + public function testGetEncoderWithMessageDigestEncoder() + { + $factory = new EncoderFactory(array('Symfony\Component\Security\Core\User\UserInterface' => array( + 'class' => 'Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder', + 'arguments' => array('sha512', true, 5), + ))); + + $encoder = $factory->getEncoder($this->getMock('Symfony\Component\Security\Core\User\UserInterface')); + $expectedEncoder = new MessageDigestPasswordEncoder('sha512', true, 5); + + $this->assertEquals($expectedEncoder->encodePassword('foo', 'moo'), $encoder->encodePassword('foo', 'moo')); + } + + public function testGetEncoderWithService() + { + $factory = new EncoderFactory(array( + 'Symfony\Component\Security\Core\User\UserInterface' => new MessageDigestPasswordEncoder('sha1'), + )); + + $encoder = $factory->getEncoder($this->getMock('Symfony\Component\Security\Core\User\UserInterface')); + $expectedEncoder = new MessageDigestPasswordEncoder('sha1'); + $this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', '')); + + $encoder = $factory->getEncoder(new User('user', 'pass')); + $expectedEncoder = new MessageDigestPasswordEncoder('sha1'); + $this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', '')); + } + + public function testGetEncoderWithClassName() + { + $factory = new EncoderFactory(array( + 'Symfony\Component\Security\Core\User\UserInterface' => new MessageDigestPasswordEncoder('sha1'), + )); + + $encoder = $factory->getEncoder('Symfony\Component\Security\Core\Tests\Encoder\SomeChildUser'); + $expectedEncoder = new MessageDigestPasswordEncoder('sha1'); + $this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', '')); + } + + public function testGetEncoderConfiguredForConcreteClassWithService() + { + $factory = new EncoderFactory(array( + 'Symfony\Component\Security\Core\User\User' => new MessageDigestPasswordEncoder('sha1'), + )); + + $encoder = $factory->getEncoder(new User('user', 'pass')); + $expectedEncoder = new MessageDigestPasswordEncoder('sha1'); + $this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', '')); + } + + public function testGetEncoderConfiguredForConcreteClassWithClassName() + { + $factory = new EncoderFactory(array( + 'Symfony\Component\Security\Core\Tests\Encoder\SomeUser' => new MessageDigestPasswordEncoder('sha1'), + )); + + $encoder = $factory->getEncoder('Symfony\Component\Security\Core\Tests\Encoder\SomeChildUser'); + $expectedEncoder = new MessageDigestPasswordEncoder('sha1'); + $this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', '')); + } +} + +class SomeUser implements UserInterface +{ + public function getRoles() {} + public function getPassword() {} + public function getSalt() {} + public function getUsername() {} + public function eraseCredentials() {} +} + +class SomeChildUser extends SomeUser +{ +} diff --git a/Core/Tests/Encoder/MessageDigestPasswordEncoderTest.php b/Core/Tests/Encoder/MessageDigestPasswordEncoderTest.php new file mode 100644 index 0000000..550d08e --- /dev/null +++ b/Core/Tests/Encoder/MessageDigestPasswordEncoderTest.php @@ -0,0 +1,45 @@ +<?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\Core\Tests\Encoder; + +use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder; + +class MessageDigestPasswordEncoderTest extends \PHPUnit_Framework_TestCase +{ + public function testIsPasswordValid() + { + $encoder = new MessageDigestPasswordEncoder('sha256', false, 1); + + $this->assertTrue($encoder->isPasswordValid(hash('sha256', 'password'), 'password', '')); + } + + public function testEncodePassword() + { + $encoder = new MessageDigestPasswordEncoder('sha256', false, 1); + $this->assertSame(hash('sha256', 'password'), $encoder->encodePassword('password', '')); + + $encoder = new MessageDigestPasswordEncoder('sha256', true, 1); + $this->assertSame(base64_encode(hash('sha256', 'password', true)), $encoder->encodePassword('password', '')); + + $encoder = new MessageDigestPasswordEncoder('sha256', false, 2); + $this->assertSame(hash('sha256', hash('sha256', 'password', true).'password'), $encoder->encodePassword('password', '')); + } + + /** + * @expectedException LogicException + */ + public function testEncodePasswordAlgorithmDoesNotExist() + { + $encoder = new MessageDigestPasswordEncoder('foobar'); + $encoder->encodePassword('password', ''); + } +} diff --git a/Core/Tests/Encoder/Pbkdf2PasswordEncoderTest.php b/Core/Tests/Encoder/Pbkdf2PasswordEncoderTest.php new file mode 100644 index 0000000..ba5c4d5 --- /dev/null +++ b/Core/Tests/Encoder/Pbkdf2PasswordEncoderTest.php @@ -0,0 +1,45 @@ +<?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\Core\Tests\Encoder; + +use Symfony\Component\Security\Core\Encoder\Pbkdf2PasswordEncoder; + +class Pbkdf2PasswordEncoderTest extends \PHPUnit_Framework_TestCase +{ + public function testIsPasswordValid() + { + $encoder = new Pbkdf2PasswordEncoder('sha256', false, 1, 40); + + $this->assertTrue($encoder->isPasswordValid('c1232f10f62715fda06ae7c0a2037ca19b33cf103b727ba56d870c11f290a2ab106974c75607c8a3', 'password', '')); + } + + public function testEncodePassword() + { + $encoder = new Pbkdf2PasswordEncoder('sha256', false, 1, 40); + $this->assertSame('c1232f10f62715fda06ae7c0a2037ca19b33cf103b727ba56d870c11f290a2ab106974c75607c8a3', $encoder->encodePassword('password', '')); + + $encoder = new Pbkdf2PasswordEncoder('sha256', true, 1, 40); + $this->assertSame('wSMvEPYnFf2gaufAogN8oZszzxA7cnulbYcMEfKQoqsQaXTHVgfIow==', $encoder->encodePassword('password', '')); + + $encoder = new Pbkdf2PasswordEncoder('sha256', false, 2, 40); + $this->assertSame('8bc2f9167a81cdcfad1235cd9047f1136271c1f978fcfcb35e22dbeafa4634f6fd2214218ed63ebb', $encoder->encodePassword('password', '')); + } + + /** + * @expectedException LogicException + */ + public function testEncodePasswordAlgorithmDoesNotExist() + { + $encoder = new Pbkdf2PasswordEncoder('foobar'); + $encoder->encodePassword('password', ''); + } +} diff --git a/Core/Tests/Encoder/PlaintextPasswordEncoderTest.php b/Core/Tests/Encoder/PlaintextPasswordEncoderTest.php new file mode 100644 index 0000000..513a94a --- /dev/null +++ b/Core/Tests/Encoder/PlaintextPasswordEncoderTest.php @@ -0,0 +1,39 @@ +<?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\Core\Tests\Encoder; + +use Symfony\Component\Security\Core\Encoder\PlaintextPasswordEncoder; + +class PlaintextPasswordEncoderTest extends \PHPUnit_Framework_TestCase +{ + public function testIsPasswordValid() + { + $encoder = new PlaintextPasswordEncoder(); + + $this->assertTrue($encoder->isPasswordValid('foo', 'foo', '')); + $this->assertFalse($encoder->isPasswordValid('bar', 'foo', '')); + $this->assertFalse($encoder->isPasswordValid('FOO', 'foo', '')); + + $encoder = new PlaintextPasswordEncoder(true); + + $this->assertTrue($encoder->isPasswordValid('foo', 'foo', '')); + $this->assertFalse($encoder->isPasswordValid('bar', 'foo', '')); + $this->assertTrue($encoder->isPasswordValid('FOO', 'foo', '')); + } + + public function testEncodePassword() + { + $encoder = new PlaintextPasswordEncoder(); + + $this->assertSame('foo', $encoder->encodePassword('foo', '')); + } +} diff --git a/Core/Tests/Role/RoleHierarchyTest.php b/Core/Tests/Role/RoleHierarchyTest.php new file mode 100644 index 0000000..df1b6a3 --- /dev/null +++ b/Core/Tests/Role/RoleHierarchyTest.php @@ -0,0 +1,32 @@ +<?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\Core\Tests\Role; + +use Symfony\Component\Security\Core\Role\RoleHierarchy; +use Symfony\Component\Security\Core\Role\Role; + +class RoleHierarchyTest extends \PHPUnit_Framework_TestCase +{ + public function testGetReachableRoles() + { + $role = new RoleHierarchy(array( + 'ROLE_ADMIN' => array('ROLE_USER'), + 'ROLE_SUPER_ADMIN' => array('ROLE_ADMIN', 'ROLE_FOO'), + )); + + $this->assertEquals(array(new Role('ROLE_USER')), $role->getReachableRoles(array(new Role('ROLE_USER')))); + $this->assertEquals(array(new Role('ROLE_FOO')), $role->getReachableRoles(array(new Role('ROLE_FOO')))); + $this->assertEquals(array(new Role('ROLE_ADMIN'), new Role('ROLE_USER')), $role->getReachableRoles(array(new Role('ROLE_ADMIN')))); + $this->assertEquals(array(new Role('ROLE_FOO'), new Role('ROLE_ADMIN'), new Role('ROLE_USER')), $role->getReachableRoles(array(new Role('ROLE_FOO'), new Role('ROLE_ADMIN')))); + $this->assertEquals(array(new Role('ROLE_SUPER_ADMIN'), new Role('ROLE_ADMIN'), new Role('ROLE_FOO'), new Role('ROLE_USER')), $role->getReachableRoles(array(new Role('ROLE_SUPER_ADMIN')))); + } +} diff --git a/Core/Tests/Role/RoleTest.php b/Core/Tests/Role/RoleTest.php new file mode 100644 index 0000000..02be07b --- /dev/null +++ b/Core/Tests/Role/RoleTest.php @@ -0,0 +1,24 @@ +<?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\Core\Tests\Role; + +use Symfony\Component\Security\Core\Role\Role; + +class RoleTest extends \PHPUnit_Framework_TestCase +{ + public function testGetRole() + { + $role = new Role('FOO'); + + $this->assertEquals('FOO', $role->getRole()); + } +} diff --git a/Core/Tests/Role/SwitchUserRoleTest.php b/Core/Tests/Role/SwitchUserRoleTest.php new file mode 100644 index 0000000..f0ce468 --- /dev/null +++ b/Core/Tests/Role/SwitchUserRoleTest.php @@ -0,0 +1,31 @@ +<?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\Core\Tests\Role; + +use Symfony\Component\Security\Core\Role\SwitchUserRole; + +class SwitchUserRoleTest extends \PHPUnit_Framework_TestCase +{ + public function testGetSource() + { + $role = new SwitchUserRole('FOO', $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')); + + $this->assertSame($token, $role->getSource()); + } + + public function testGetRole() + { + $role = new SwitchUserRole('FOO', $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')); + + $this->assertEquals('FOO', $role->getRole()); + } +} diff --git a/Core/Tests/SecurityContextTest.php b/Core/Tests/SecurityContextTest.php new file mode 100644 index 0000000..dd0e2e3 --- /dev/null +++ b/Core/Tests/SecurityContextTest.php @@ -0,0 +1,92 @@ +<?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\Core\Tests; + +use Symfony\Component\Security\Core\SecurityContext; + +class SecurityContextTest extends \PHPUnit_Framework_TestCase +{ + public function testVoteAuthenticatesTokenIfNecessary() + { + $authManager = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'); + $decisionManager = $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface'); + + $context = new SecurityContext($authManager, $decisionManager); + $context->setToken($token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')); + + $authManager + ->expects($this->once()) + ->method('authenticate') + ->with($this->equalTo($token)) + ->will($this->returnValue($newToken = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'))) + ; + + $decisionManager + ->expects($this->once()) + ->method('decide') + ->will($this->returnValue(true)) + ; + + $this->assertTrue($context->isGranted('foo')); + $this->assertSame($newToken, $context->getToken()); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException + */ + public function testVoteWithoutAuthenticationToken() + { + $context = new SecurityContext( + $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'), + $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface') + ); + + $context->isGranted('ROLE_FOO'); + } + + public function testIsGranted() + { + $manager = $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface'); + $manager->expects($this->once())->method('decide')->will($this->returnValue(false)); + $context = new SecurityContext($this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'), $manager); + $context->setToken($token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')); + $token + ->expects($this->once()) + ->method('isAuthenticated') + ->will($this->returnValue(true)) + ; + $this->assertFalse($context->isGranted('ROLE_FOO')); + + $manager = $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface'); + $manager->expects($this->once())->method('decide')->will($this->returnValue(true)); + $context = new SecurityContext($this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'), $manager); + $context->setToken($token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')); + $token + ->expects($this->once()) + ->method('isAuthenticated') + ->will($this->returnValue(true)) + ; + $this->assertTrue($context->isGranted('ROLE_FOO')); + } + + public function testGetSetToken() + { + $context = new SecurityContext( + $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface'), + $this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface') + ); + $this->assertNull($context->getToken()); + + $context->setToken($token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')); + $this->assertSame($token, $context->getToken()); + } +} diff --git a/Core/Tests/User/AccountCheckerTest.php b/Core/Tests/User/AccountCheckerTest.php new file mode 100644 index 0000000..8d5e203 --- /dev/null +++ b/Core/Tests/User/AccountCheckerTest.php @@ -0,0 +1,108 @@ +<?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\Core\Tests\User; + +use Symfony\Component\Security\Core\User\UserChecker; + +class UserCheckerTest extends \PHPUnit_Framework_TestCase +{ + public function testCheckPreAuthNotAdvancedUserInterface() + { + $checker = new UserChecker(); + + $this->assertNull($checker->checkPreAuth($this->getMock('Symfony\Component\Security\Core\User\UserInterface'))); + } + + public function testCheckPreAuthPass() + { + $checker = new UserChecker(); + + $account = $this->getMock('Symfony\Component\Security\Core\User\AdvancedUserInterface'); + $account->expects($this->once())->method('isCredentialsNonExpired')->will($this->returnValue(true)); + + $this->assertNull($checker->checkPreAuth($account)); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\CredentialsExpiredException + */ + public function testCheckPreAuthCredentialsExpired() + { + $checker = new UserChecker(); + + $account = $this->getMock('Symfony\Component\Security\Core\User\AdvancedUserInterface'); + $account->expects($this->once())->method('isCredentialsNonExpired')->will($this->returnValue(false)); + + $checker->checkPreAuth($account); + } + + public function testCheckPostAuthNotAdvancedUserInterface() + { + $checker = new UserChecker(); + + $this->assertNull($checker->checkPostAuth($this->getMock('Symfony\Component\Security\Core\User\UserInterface'))); + } + + public function testCheckPostAuthPass() + { + $checker = new UserChecker(); + + $account = $this->getMock('Symfony\Component\Security\Core\User\AdvancedUserInterface'); + $account->expects($this->once())->method('isAccountNonLocked')->will($this->returnValue(true)); + $account->expects($this->once())->method('isEnabled')->will($this->returnValue(true)); + $account->expects($this->once())->method('isAccountNonExpired')->will($this->returnValue(true)); + + $this->assertNull($checker->checkPostAuth($account)); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\LockedException + */ + public function testCheckPostAuthAccountLocked() + { + $checker = new UserChecker(); + + $account = $this->getMock('Symfony\Component\Security\Core\User\AdvancedUserInterface'); + $account->expects($this->once())->method('isAccountNonLocked')->will($this->returnValue(false)); + + $checker->checkPostAuth($account); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\DisabledException + */ + public function testCheckPostAuthDisabled() + { + $checker = new UserChecker(); + + $account = $this->getMock('Symfony\Component\Security\Core\User\AdvancedUserInterface'); + $account->expects($this->once())->method('isAccountNonLocked')->will($this->returnValue(true)); + $account->expects($this->once())->method('isEnabled')->will($this->returnValue(false)); + + $checker->checkPostAuth($account); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\AccountExpiredException + */ + public function testCheckPostAuthAccountExpired() + { + $checker = new UserChecker(); + + $account = $this->getMock('Symfony\Component\Security\Core\User\AdvancedUserInterface'); + $account->expects($this->once())->method('isAccountNonLocked')->will($this->returnValue(true)); + $account->expects($this->once())->method('isEnabled')->will($this->returnValue(true)); + $account->expects($this->once())->method('isAccountNonExpired')->will($this->returnValue(false)); + + $checker->checkPostAuth($account); + } +} diff --git a/Core/Tests/User/ChainUserProviderTest.php b/Core/Tests/User/ChainUserProviderTest.php new file mode 100644 index 0000000..57873cf --- /dev/null +++ b/Core/Tests/User/ChainUserProviderTest.php @@ -0,0 +1,185 @@ +<?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\Core\Tests\User; + +use Symfony\Component\Security\Core\Exception\UnsupportedUserException; + +use Symfony\Component\Security\Core\User\ChainUserProvider; + +use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; + +class ChainUserProviderTest extends \PHPUnit_Framework_TestCase +{ + public function testLoadUserByUsername() + { + $provider1 = $this->getProvider(); + $provider1 + ->expects($this->once()) + ->method('loadUserByUsername') + ->with($this->equalTo('foo')) + ->will($this->throwException(new UsernameNotFoundException('not found'))) + ; + + $provider2 = $this->getProvider(); + $provider2 + ->expects($this->once()) + ->method('loadUserByUsername') + ->with($this->equalTo('foo')) + ->will($this->returnValue($account = $this->getAccount())) + ; + + $provider = new ChainUserProvider(array($provider1, $provider2)); + $this->assertSame($account, $provider->loadUserByUsername('foo')); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\UsernameNotFoundException + */ + public function testLoadUserByUsernameThrowsUsernameNotFoundException() + { + $provider1 = $this->getProvider(); + $provider1 + ->expects($this->once()) + ->method('loadUserByUsername') + ->with($this->equalTo('foo')) + ->will($this->throwException(new UsernameNotFoundException('not found'))) + ; + + $provider2 = $this->getProvider(); + $provider2 + ->expects($this->once()) + ->method('loadUserByUsername') + ->with($this->equalTo('foo')) + ->will($this->throwException(new UsernameNotFoundException('not found'))) + ; + + $provider = new ChainUserProvider(array($provider1, $provider2)); + $provider->loadUserByUsername('foo'); + } + + public function testRefreshUser() + { + $provider1 = $this->getProvider(); + $provider1 + ->expects($this->once()) + ->method('refreshUser') + ->will($this->throwException(new UnsupportedUserException('unsupported'))) + ; + + $provider2 = $this->getProvider(); + $provider2 + ->expects($this->once()) + ->method('refreshUser') + ->will($this->returnValue($account = $this->getAccount())) + ; + + $provider = new ChainUserProvider(array($provider1, $provider2)); + $this->assertSame($account, $provider->refreshUser($this->getAccount())); + } + + public function testRefreshUserAgain() + { + $provider1 = $this->getProvider(); + $provider1 + ->expects($this->once()) + ->method('refreshUser') + ->will($this->throwException(new UsernameNotFoundException('not found'))) + ; + + $provider2 = $this->getProvider(); + $provider2 + ->expects($this->once()) + ->method('refreshUser') + ->will($this->returnValue($account = $this->getAccount())) + ; + + $provider = new ChainUserProvider(array($provider1, $provider2)); + $this->assertSame($account, $provider->refreshUser($this->getAccount())); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\UnsupportedUserException + */ + public function testRefreshUserThrowsUnsupportedUserException() + { + $provider1 = $this->getProvider(); + $provider1 + ->expects($this->once()) + ->method('refreshUser') + ->will($this->throwException(new UnsupportedUserException('unsupported'))) + ; + + $provider2 = $this->getProvider(); + $provider2 + ->expects($this->once()) + ->method('refreshUser') + ->will($this->throwException(new UnsupportedUserException('unsupported'))) + ; + + $provider = new ChainUserProvider(array($provider1, $provider2)); + $provider->refreshUser($this->getAccount()); + } + + public function testSupportsClass() + { + $provider1 = $this->getProvider(); + $provider1 + ->expects($this->once()) + ->method('supportsClass') + ->with($this->equalTo('foo')) + ->will($this->returnValue(false)) + ; + + $provider2 = $this->getProvider(); + $provider2 + ->expects($this->once()) + ->method('supportsClass') + ->with($this->equalTo('foo')) + ->will($this->returnValue(true)) + ; + + $provider = new ChainUserProvider(array($provider1, $provider2)); + $this->assertTrue($provider->supportsClass('foo')); + } + + public function testSupportsClassWhenNotSupported() + { + $provider1 = $this->getProvider(); + $provider1 + ->expects($this->once()) + ->method('supportsClass') + ->with($this->equalTo('foo')) + ->will($this->returnValue(false)) + ; + + $provider2 = $this->getProvider(); + $provider2 + ->expects($this->once()) + ->method('supportsClass') + ->with($this->equalTo('foo')) + ->will($this->returnValue(false)) + ; + + $provider = new ChainUserProvider(array($provider1, $provider2)); + $this->assertFalse($provider->supportsClass('foo')); + } + + protected function getAccount() + { + return $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); + } + + protected function getProvider() + { + return $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface'); + } +} diff --git a/Core/Tests/User/InMemoryProviderTest.php b/Core/Tests/User/InMemoryProviderTest.php new file mode 100644 index 0000000..5d6cadc --- /dev/null +++ b/Core/Tests/User/InMemoryProviderTest.php @@ -0,0 +1,62 @@ +<?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\Core\Tests\User; + +use Symfony\Component\Security\Core\User\InMemoryUserProvider; +use Symfony\Component\Security\Core\User\User; + +class InMemoryUserProviderTest extends \PHPUnit_Framework_TestCase +{ + public function testConstructor() + { + $provider = new InMemoryUserProvider(array( + 'fabien' => array( + 'password' => 'foo', + 'enabled' => false, + 'roles' => array('ROLE_USER'), + ), + )); + + $user = $provider->loadUserByUsername('fabien'); + $this->assertEquals('foo', $user->getPassword()); + $this->assertEquals(array('ROLE_USER'), $user->getRoles()); + $this->assertFalse($user->isEnabled()); + } + + public function testCreateUser() + { + $provider = new InMemoryUserProvider(); + $provider->createUser(new User('fabien', 'foo')); + + $user = $provider->loadUserByUsername('fabien'); + $this->assertEquals('foo', $user->getPassword()); + } + + /** + * @expectedException LogicException + */ + public function testCreateUserAlreadyExist() + { + $provider = new InMemoryUserProvider(); + $provider->createUser(new User('fabien', 'foo')); + $provider->createUser(new User('fabien', 'foo')); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\UsernameNotFoundException + */ + public function testLoadUserByUsernameDoesNotExist() + { + $provider = new InMemoryUserProvider(); + $provider->loadUserByUsername('fabien'); + } +} diff --git a/Core/Tests/User/UserTest.php b/Core/Tests/User/UserTest.php new file mode 100644 index 0000000..7d4cf95 --- /dev/null +++ b/Core/Tests/User/UserTest.php @@ -0,0 +1,126 @@ +<?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\Core\Tests\User; + +use Symfony\Component\Security\Core\User\User; + +class UserTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Symfony\Component\Security\Core\User\User::__construct + * @expectedException InvalidArgumentException + */ + public function testConstructorException() + { + new User('', 'superpass'); + } + + /** + * @covers Symfony\Component\Security\Core\User\User::__construct + * @covers Symfony\Component\Security\Core\User\User::getRoles + */ + public function testGetRoles() + { + $user = new User('fabien', 'superpass'); + $this->assertEquals(array(), $user->getRoles()); + + $user = new User('fabien', 'superpass', array('ROLE_ADMIN')); + $this->assertEquals(array('ROLE_ADMIN'), $user->getRoles()); + } + + /** + * @covers Symfony\Component\Security\Core\User\User::__construct + * @covers Symfony\Component\Security\Core\User\User::getPassword + */ + public function testGetPassword() + { + $user = new User('fabien', 'superpass'); + $this->assertEquals('superpass', $user->getPassword()); + } + + /** + * @covers Symfony\Component\Security\Core\User\User::__construct + * @covers Symfony\Component\Security\Core\User\User::getUsername + */ + public function testGetUsername() + { + $user = new User('fabien', 'superpass'); + $this->assertEquals('fabien', $user->getUsername()); + } + + /** + * @covers Symfony\Component\Security\Core\User\User::getSalt + */ + public function testGetSalt() + { + $user = new User('fabien', 'superpass'); + $this->assertEquals('', $user->getSalt()); + } + + /** + * @covers Symfony\Component\Security\Core\User\User::isAccountNonExpired + */ + public function testIsAccountNonExpired() + { + $user = new User('fabien', 'superpass'); + $this->assertTrue($user->isAccountNonExpired()); + + $user = new User('fabien', 'superpass', array(), true, false); + $this->assertFalse($user->isAccountNonExpired()); + } + + /** + * @covers Symfony\Component\Security\Core\User\User::isCredentialsNonExpired + */ + public function testIsCredentialsNonExpired() + { + $user = new User('fabien', 'superpass'); + $this->assertTrue($user->isCredentialsNonExpired()); + + $user = new User('fabien', 'superpass', array(), true, true, false); + $this->assertFalse($user->isCredentialsNonExpired()); + } + + /** + * @covers Symfony\Component\Security\Core\User\User::isAccountNonLocked + */ + public function testIsAccountNonLocked() + { + $user = new User('fabien', 'superpass'); + $this->assertTrue($user->isAccountNonLocked()); + + $user = new User('fabien', 'superpass', array(), true, true, true, false); + $this->assertFalse($user->isAccountNonLocked()); + } + + /** + * @covers Symfony\Component\Security\Core\User\User::isEnabled + */ + public function testIsEnabled() + { + $user = new User('fabien', 'superpass'); + $this->assertTrue($user->isEnabled()); + + $user = new User('fabien', 'superpass', array(), false); + $this->assertFalse($user->isEnabled()); + } + + /** + * @covers Symfony\Component\Security\Core\User\User::eraseCredentials + */ + public function testEraseCredentials() + { + $user = new User('fabien', 'superpass'); + $user->eraseCredentials(); + $this->assertEquals('superpass', $user->getPassword()); + } +} diff --git a/Core/Tests/Util/ClassUtilsTest.php b/Core/Tests/Util/ClassUtilsTest.php new file mode 100644 index 0000000..e8f0143 --- /dev/null +++ b/Core/Tests/Util/ClassUtilsTest.php @@ -0,0 +1,50 @@ +<?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\Core\Tests\Util +{ + use Symfony\Component\Security\Core\Util\ClassUtils; + + class ClassUtilsTest extends \PHPUnit_Framework_TestCase + { + public static function dataGetClass() + { + return array( + array('stdClass', 'stdClass'), + array('Symfony\Component\Security\Core\Util\ClassUtils', 'Symfony\Component\Security\Core\Util\ClassUtils'), + array('MyProject\Proxies\__CG__\stdClass', 'stdClass'), + array('MyProject\Proxies\__CG__\OtherProject\Proxies\__CG__\stdClass', 'stdClass'), + array('MyProject\Proxies\__CG__\Symfony\Component\Security\Core\Tests\Util\ChildObject', 'Symfony\Component\Security\Core\Tests\Util\ChildObject'), + array(new TestObject(), 'Symfony\Component\Security\Core\Tests\Util\TestObject'), + array(new \Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Core\Tests\Util\TestObject(), 'Symfony\Component\Security\Core\Tests\Util\TestObject'), + ); + } + + /** + * @dataProvider dataGetClass + */ + public function testGetRealClass($object, $expectedClassName) + { + $this->assertEquals($expectedClassName, ClassUtils::getRealClass($object)); + } + } + + class TestObject + { + } +} + +namespace Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Core\Tests\Util +{ + class TestObject extends \Symfony\Component\Security\Core\Tests\Util\TestObject + { + } +} diff --git a/Core/Tests/Util/SecureRandomTest.php b/Core/Tests/Util/SecureRandomTest.php new file mode 100644 index 0000000..91d0489 --- /dev/null +++ b/Core/Tests/Util/SecureRandomTest.php @@ -0,0 +1,201 @@ +<?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\Core\Tests\Util; + +use Symfony\Component\Security\Core\Util\SecureRandom; + +class SecureRandomTest extends \PHPUnit_Framework_TestCase +{ + /** + * T1: Monobit test + * + * @dataProvider getSecureRandoms + */ + public function testMonobit($secureRandom) + { + $nbOnBits = substr_count($this->getBitSequence($secureRandom, 20000), '1'); + $this->assertTrue($nbOnBits > 9654 && $nbOnBits < 10346, 'Monobit test failed, number of turned on bits: '.$nbOnBits); + } + + /** + * T2: Chi-square test with 15 degrees of freedom (chi-Quadrat-Anpassungstest) + * + * @dataProvider getSecureRandoms + */ + public function testPoker($secureRandom) + { + $b = $this->getBitSequence($secureRandom, 20000); + $c = array(); + for ($i = 0; $i <= 15; $i++) { + $c[$i] = 0; + } + + for ($j = 1; $j <= 5000; $j++) { + $k = 4 * $j - 1; + $c[8 * $b[$k - 3] + 4 * $b[$k - 2] + 2 * $b[$k - 1] + $b[$k]] += 1; + } + + $f = 0; + for ($i = 0; $i <= 15; $i++) { + $f += $c[$i] * $c[$i]; + } + + $Y = 16/5000 * $f - 5000; + + $this->assertTrue($Y > 1.03 && $Y < 57.4, 'Poker test failed, Y = '.$Y); + } + + /** + * Run test + * + * @dataProvider getSecureRandoms + */ + public function testRun($secureRandom) + { + $b = $this->getBitSequence($secureRandom, 20000); + + $runs = array(); + for ($i = 1; $i <= 6; $i++) { + $runs[$i] = 0; + } + + $addRun = function($run) use (&$runs) { + if ($run > 6) { + $run = 6; + } + + $runs[$run] += 1; + }; + + $currentRun = 0; + $lastBit = null; + for ($i = 0; $i < 20000; $i++) { + if ($lastBit === $b[$i]) { + $currentRun += 1; + } else { + if ($currentRun > 0) { + $addRun($currentRun); + } + + $lastBit = $b[$i]; + $currentRun = 0; + } + } + if ($currentRun > 0) { + $addRun($currentRun); + } + + $this->assertTrue($runs[1] > 2267 && $runs[1] < 2733, 'Runs of length 1 outside of defined interval: '.$runs[1]); + $this->assertTrue($runs[2] > 1079 && $runs[2] < 1421, 'Runs of length 2 outside of defined interval: '.$runs[2]); + $this->assertTrue($runs[3] > 502 && $runs[3] < 748, 'Runs of length 3 outside of defined interval: '.$runs[3]); + $this->assertTrue($runs[4] > 233 && $runs[4] < 402, 'Runs of length 4 outside of defined interval: '.$runs[4]); + $this->assertTrue($runs[5] > 90 && $runs[5] < 223, 'Runs of length 5 outside of defined interval: '.$runs[5]); + $this->assertTrue($runs[6] > 90 && $runs[6] < 233, 'Runs of length 6 outside of defined interval: '.$runs[6]); + } + + /** + * Long-run test + * + * @dataProvider getSecureRandoms + */ + public function testLongRun($secureRandom) + { + $b = $this->getBitSequence($secureRandom, 20000); + + $longestRun = 0; + $currentRun = $lastBit = null; + for ($i = 0; $i < 20000; $i++) { + if ($lastBit === $b[$i]) { + $currentRun += 1; + } else { + if ($currentRun > $longestRun) { + $longestRun = $currentRun; + } + $lastBit = $b[$i]; + $currentRun = 0; + } + } + if ($currentRun > $longestRun) { + $longestRun = $currentRun; + } + + $this->assertTrue($longestRun < 34, 'Failed longest run test: '.$longestRun); + } + + /** + * Serial Correlation (Autokorrelationstest) + * + * @dataProvider getSecureRandoms + */ + public function testSerialCorrelation($secureRandom) + { + $shift = rand(1, 5000); + $b = $this->getBitSequence($secureRandom, 20000); + + $Z = 0; + for ($i = 0; $i < 5000; $i++) { + $Z += $b[$i] === $b[$i + $shift] ? 1 : 0; + } + + $this->assertTrue($Z > 2326 && $Z < 2674, 'Failed serial correlation test: '.$Z); + } + + public function getSecureRandoms() + { + $secureRandoms = array(); + + // only add if openssl is indeed present + $secureRandom = new SecureRandom(); + if ($this->hasOpenSsl($secureRandom)) { + $secureRandoms[] = array($secureRandom); + } + + // no-openssl with custom seed provider + $secureRandom = new SecureRandom(sys_get_temp_dir().'/_sf2.seed'); + $this->disableOpenSsl($secureRandom); + $secureRandoms[] = array($secureRandom); + + return $secureRandoms; + } + + protected function disableOpenSsl($secureRandom) + { + $ref = new \ReflectionProperty($secureRandom, 'useOpenSsl'); + $ref->setAccessible(true); + $ref->setValue($secureRandom, false); + $ref->setAccessible(false); + } + + protected function hasOpenSsl($secureRandom) + { + $ref = new \ReflectionProperty($secureRandom, 'useOpenSsl'); + $ref->setAccessible(true); + + $ret = $ref->getValue($secureRandom); + + $ref->setAccessible(false); + + return $ret; + } + + private function getBitSequence($secureRandom, $length) + { + $bitSequence = ''; + for ($i = 0; $i < $length; $i += 40) { + $value = unpack('H*', $secureRandom->nextBytes(5)); + $value = str_pad(base_convert($value[1], 16, 2), 40, '0', STR_PAD_LEFT); + $bitSequence .= $value; + } + + return substr($bitSequence, 0, $length); + } +} diff --git a/Core/Tests/Util/StringUtilsTest.php b/Core/Tests/Util/StringUtilsTest.php new file mode 100644 index 0000000..89da98d --- /dev/null +++ b/Core/Tests/Util/StringUtilsTest.php @@ -0,0 +1,23 @@ +<?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\Core\Tests\Util; + +use Symfony\Component\Security\Core\Util\StringUtils; + +class StringUtilsTest extends \PHPUnit_Framework_TestCase +{ + public function testEquals() + { + $this->assertTrue(StringUtils::equals('password', 'password')); + $this->assertFalse(StringUtils::equals('password', 'foo')); + } +} diff --git a/Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php b/Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php new file mode 100644 index 0000000..53eeb5f --- /dev/null +++ b/Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php @@ -0,0 +1,157 @@ +<?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\Core\Tests\Validator\Constraints; + +use Symfony\Component\Security\Core\Validator\Constraints\UserPassword; +use Symfony\Component\Security\Core\Validator\Constraints\UserPasswordValidator; + +class UserPasswordValidatorTest extends \PHPUnit_Framework_TestCase +{ + const PASSWORD_VALID = true; + const PASSWORD_INVALID = false; + + protected $context; + + protected function setUp() + { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); + } + + protected function tearDown() + { + $this->context = null; + } + + public function testPasswordIsValid() + { + $user = $this->createUser(); + $securityContext = $this->createSecurityContext($user); + + $encoder = $this->createPasswordEncoder(static::PASSWORD_VALID); + $encoderFactory = $this->createEncoderFactory($encoder); + + $validator = new UserPasswordValidator($securityContext, $encoderFactory); + $validator->initialize($this->context); + + $this + ->context + ->expects($this->never()) + ->method('addViolation') + ; + + $validator->validate('secret', new UserPassword()); + } + + public function testPasswordIsNotValid() + { + $user = $this->createUser(); + $securityContext = $this->createSecurityContext($user); + + $encoder = $this->createPasswordEncoder(static::PASSWORD_INVALID); + $encoderFactory = $this->createEncoderFactory($encoder); + + $validator = new UserPasswordValidator($securityContext, $encoderFactory); + $validator->initialize($this->context); + + $this + ->context + ->expects($this->once()) + ->method('addViolation') + ; + + $validator->validate('secret', new UserPassword()); + } + + public function testUserIsNotValid() + { + $this->setExpectedException('Symfony\Component\Validator\Exception\ConstraintDefinitionException'); + + $user = $this->getMock('Foo\Bar\User'); + $encoderFactory = $this->getMock('Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface'); + $securityContext = $this->createSecurityContext($user); + + $validator = new UserPasswordValidator($securityContext, $encoderFactory); + $validator->initialize($this->context); + $validator->validate('secret', new UserPassword()); + } + + protected function createUser() + { + $mock = $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); + + $mock + ->expects($this->once()) + ->method('getPassword') + ->will($this->returnValue('s3Cr3t')) + ; + + $mock + ->expects($this->once()) + ->method('getSalt') + ->will($this->returnValue('^S4lt$')) + ; + + return $mock; + } + + protected function createPasswordEncoder($isPasswordValid = true) + { + $mock = $this->getMock('Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface'); + + $mock + ->expects($this->once()) + ->method('isPasswordValid') + ->will($this->returnValue($isPasswordValid)) + ; + + return $mock; + } + + protected function createEncoderFactory($encoder = null) + { + $mock = $this->getMock('Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface'); + + $mock + ->expects($this->once()) + ->method('getEncoder') + ->will($this->returnValue($encoder)) + ; + + return $mock; + } + + protected function createSecurityContext($user = null) + { + $token = $this->createAuthenticationToken($user); + + $mock = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'); + $mock + ->expects($this->once()) + ->method('getToken') + ->will($this->returnValue($token)) + ; + + return $mock; + } + + protected function createAuthenticationToken($user = null) + { + $mock = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + $mock + ->expects($this->once()) + ->method('getUser') + ->will($this->returnValue($user)) + ; + + return $mock; + } +} diff --git a/Core/composer.json b/Core/composer.json new file mode 100644 index 0000000..91851a8 --- /dev/null +++ b/Core/composer.json @@ -0,0 +1,42 @@ +{ + "name": "symfony/security-core", + "type": "library", + "description": "Symfony Security Component - Core Library", + "keywords": [], + "homepage": "http://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "require": { + "php": ">=5.3.3", + "symfony/event-dispatcher": "~2.1", + "symfony/http-foundation": "~2.4" + }, + "require-dev": { + "symfony/validator": "~2.2", + "psr/log": "~1.0", + "ircmaxell/password-compat": "1.0.*" + }, + "suggest": { + "symfony/validator": "", + "ircmaxell/password-compat": "" + }, + "autoload": { + "psr-0": { "Symfony\\Component\\Security\\Core\\": "" } + }, + "target-dir": "Symfony/Component/Security/Core", + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + } +} diff --git a/Core/phpunit.xml.dist b/Core/phpunit.xml.dist new file mode 100644 index 0000000..f085b72 --- /dev/null +++ b/Core/phpunit.xml.dist @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<phpunit backupGlobals="false" + backupStaticAttributes="false" + colors="true" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + processIsolation="false" + stopOnFailure="false" + syntaxCheck="false" + bootstrap="vendor/autoload.php" +> + <testsuites> + <testsuite name="Symfony Security Component Core Test Suite"> + <directory>./Tests/</directory> + </testsuite> + </testsuites> + + <filter> + <whitelist> + <directory>./</directory> + <exclude> + <directory>./vendor</directory> + <directory>./Tests</directory> + </exclude> + </whitelist> + </filter> +</phpunit> |