diff options
18 files changed, 418 insertions, 82 deletions
diff --git a/Acl/Dbal/MutableAclProvider.php b/Acl/Dbal/MutableAclProvider.php index 5f93845..4e634de 100644 --- a/Acl/Dbal/MutableAclProvider.php +++ b/Acl/Dbal/MutableAclProvider.php @@ -865,10 +865,10 @@ QUERY; } /** - * This process old entries changes on an ACE related property (classFieldAces, or objectFieldAces). + * This processes old entries changes on an ACE related property (classFieldAces, or objectFieldAces). * * @param string $name - * @param array $changes + * @param array $changes */ private function updateOldFieldAceProperty($name, array $changes) { diff --git a/Core/Authentication/Provider/UserAuthenticationProvider.php b/Core/Authentication/Provider/UserAuthenticationProvider.php index 3728c01..4371abf 100644 --- a/Core/Authentication/Provider/UserAuthenticationProvider.php +++ b/Core/Authentication/Provider/UserAuthenticationProvider.php @@ -70,7 +70,7 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter $user = $this->retrieveUser($username, $token); } catch (UsernameNotFoundException $notFound) { if ($this->hideUserNotFoundExceptions) { - throw new BadCredentialsException('Bad credentials', 0, $notFound); + throw new BadCredentialsException('Bad credentials.', 0, $notFound); } $notFound->setUsername($username); @@ -87,7 +87,7 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter $this->userChecker->checkPostAuth($user); } catch (BadCredentialsException $e) { if ($this->hideUserNotFoundExceptions) { - throw new BadCredentialsException('Bad credentials', 0, $e); + throw new BadCredentialsException('Bad credentials.', 0, $e); } throw $e; diff --git a/Core/Authorization/Voter/VoterInterface.php b/Core/Authorization/Voter/VoterInterface.php index abc18b4..79fa69f 100644 --- a/Core/Authorization/Voter/VoterInterface.php +++ b/Core/Authorization/Voter/VoterInterface.php @@ -49,7 +49,7 @@ interface VoterInterface * ACCESS_GRANTED, ACCESS_DENIED, or ACCESS_ABSTAIN. * * @param TokenInterface $token A TokenInterface instance - * @param object $object The object to secure + * @param object|null $object The object to secure * @param array $attributes An array of attributes associated with the method being invoked * * @return int either ACCESS_GRANTED, ACCESS_ABSTAIN, or ACCESS_DENIED diff --git a/Core/Encoder/BCryptPasswordEncoder.php b/Core/Encoder/BCryptPasswordEncoder.php index 1dcf3a6..27a7334 100644 --- a/Core/Encoder/BCryptPasswordEncoder.php +++ b/Core/Encoder/BCryptPasswordEncoder.php @@ -61,6 +61,8 @@ class BCryptPasswordEncoder extends BasePasswordEncoder * * @return string The encoded password * + * @throws BadCredentialsException when the given password is too long + * * @link http://lxr.php.net/xref/PHP_5_5/ext/standard/password.c#111 */ public function encodePassword($raw, $salt) diff --git a/Core/Encoder/BasePasswordEncoder.php b/Core/Encoder/BasePasswordEncoder.php index 97d707b..0d29631 100644 --- a/Core/Encoder/BasePasswordEncoder.php +++ b/Core/Encoder/BasePasswordEncoder.php @@ -89,7 +89,7 @@ abstract class BasePasswordEncoder implements PasswordEncoderInterface /** * Checks if the password is too long. * - * @param string $password The password + * @param string $password The password to check * * @return bool true if the password is too long, false otherwise */ diff --git a/Core/Encoder/UserPasswordEncoder.php b/Core/Encoder/UserPasswordEncoder.php new file mode 100644 index 0000000..13ee835 --- /dev/null +++ b/Core/Encoder/UserPasswordEncoder.php @@ -0,0 +1,55 @@ +<?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\Encoder; + +use Symfony\Component\Security\Core\User\UserInterface; + +/** + * A generic password encoder + * + * @author Ariel Ferrandini <arielferrandini@gmail.com> + */ +class UserPasswordEncoder implements UserPasswordEncoderInterface +{ + /** + * @var EncoderFactoryInterface + */ + private $encoderFactory; + + /** + * @param EncoderFactoryInterface $encoderFactory The encoder factory + */ + public function __construct(EncoderFactoryInterface $encoderFactory) + { + $this->encoderFactory = $encoderFactory; + } + + /** + * {@inheritdoc} + */ + public function encodePassword(UserInterface $user, $plainPassword) + { + $encoder = $this->encoderFactory->getEncoder($user); + + return $encoder->encodePassword($plainPassword, $user->getSalt()); + } + + /** + * {@inheritdoc} + */ + public function isPasswordValid(UserInterface $user, $raw) + { + $encoder = $this->encoderFactory->getEncoder($user); + + return $encoder->isPasswordValid($user->getPassword(), $raw, $user->getSalt()); + } +} diff --git a/Core/Encoder/UserPasswordEncoderInterface.php b/Core/Encoder/UserPasswordEncoderInterface.php new file mode 100644 index 0000000..39e906a --- /dev/null +++ b/Core/Encoder/UserPasswordEncoderInterface.php @@ -0,0 +1,41 @@ +<?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\Encoder; + +use Symfony\Component\Security\Core\User\UserInterface; + +/** + * UserPasswordEncoderInterface is the interface for the password encoder service. + * + * @author Ariel Ferrandini <arielferrandini@gmail.com> + */ +interface UserPasswordEncoderInterface +{ + /** + * + * Encodes the plain password. + * + * @param UserInterface $user The user + * @param string $plainPassword The password to encode + * + * @return string The encoded password + */ + public function encodePassword(UserInterface $user, $plainPassword); + + /** + * @param UserInterface $user The user + * @param string $raw A raw password + * + * @return bool true if the password is valid, false otherwise + */ + public function isPasswordValid(UserInterface $user, $raw); +} diff --git a/Core/Exception/UsernameNotFoundException.php b/Core/Exception/UsernameNotFoundException.php index 8b72dc2..6979389 100644 --- a/Core/Exception/UsernameNotFoundException.php +++ b/Core/Exception/UsernameNotFoundException.php @@ -71,7 +71,7 @@ class UsernameNotFoundException extends AuthenticationException } /** - * {@inheritDoc} + * {@inheritdoc} */ public function getMessageData() { diff --git a/Core/Tests/Encoder/UserPasswordEncoderTest.php b/Core/Tests/Encoder/UserPasswordEncoderTest.php new file mode 100644 index 0000000..590652d --- /dev/null +++ b/Core/Tests/Encoder/UserPasswordEncoderTest.php @@ -0,0 +1,70 @@ +<?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\UserPasswordEncoder; + +class UserPasswordEncoderTest extends \PHPUnit_Framework_TestCase +{ + public function testEncodePassword() + { + $userMock = $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); + $userMock->expects($this->any()) + ->method('getSalt') + ->will($this->returnValue('userSalt')); + + $mockEncoder = $this->getMock('Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface'); + $mockEncoder->expects($this->any()) + ->method('encodePassword') + ->with($this->equalTo('plainPassword'), $this->equalTo('userSalt')) + ->will($this->returnValue('encodedPassword')); + + $mockEncoderFactory = $this->getMock('Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface'); + $mockEncoderFactory->expects($this->any()) + ->method('getEncoder') + ->with($this->equalTo($userMock)) + ->will($this->returnValue($mockEncoder)); + + $passwordEncoder = new UserPasswordEncoder($mockEncoderFactory); + + $encoded = $passwordEncoder->encodePassword($userMock, 'plainPassword'); + $this->assertEquals('encodedPassword', $encoded); + } + + public function testIsPasswordValid() + { + $userMock = $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); + $userMock->expects($this->any()) + ->method('getSalt') + ->will($this->returnValue('userSalt')); + $userMock->expects($this->any()) + ->method('getPassword') + ->will($this->returnValue('encodedPassword')); + + $mockEncoder = $this->getMock('Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface'); + $mockEncoder->expects($this->any()) + ->method('isPasswordValid') + ->with($this->equalTo('encodedPassword'), $this->equalTo('plainPassword'), $this->equalTo('userSalt')) + ->will($this->returnValue(true)); + + $mockEncoderFactory = $this->getMock('Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface'); + $mockEncoderFactory->expects($this->any()) + ->method('getEncoder') + ->with($this->equalTo($userMock)) + ->will($this->returnValue($mockEncoder)); + + $passwordEncoder = new UserPasswordEncoder($mockEncoderFactory); + + $isValid = $passwordEncoder->isPasswordValid($userMock, 'plainPassword'); + $this->assertTrue($isValid); + } +} diff --git a/Core/Tests/Exception/UsernameNotFoundExceptionTest.php b/Core/Tests/Exception/UsernameNotFoundExceptionTest.php index b460229..98ea374 100644 --- a/Core/Tests/Exception/UsernameNotFoundExceptionTest.php +++ b/Core/Tests/Exception/UsernameNotFoundExceptionTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\Security\Tests\Core\Exception; +namespace Symfony\Component\Security\Core\Tests\Exception; use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; diff --git a/Core/Tests/Validator/Constraints/LegacyUserPasswordValidator2Dot4ApiTest.php b/Core/Tests/Validator/Constraints/LegacyUserPasswordValidator2Dot4ApiTest.php new file mode 100644 index 0000000..4cba363 --- /dev/null +++ b/Core/Tests/Validator/Constraints/LegacyUserPasswordValidator2Dot4ApiTest.php @@ -0,0 +1,26 @@ +<?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\Validator\Validation; + +/** + * @since 2.5.4 + * @author Bernhard Schussek <bschussek@gmail.com> + */ +class LegacyUserPasswordValidator2Dot4ApiTest extends UserPasswordValidatorTest +{ + protected function getApiVersion() + { + return Validation::API_VERSION_2_4; + } +} diff --git a/Core/Tests/Validator/Constraints/LegacyUserPasswordValidatorLegacyApiTest.php b/Core/Tests/Validator/Constraints/LegacyUserPasswordValidatorLegacyApiTest.php new file mode 100644 index 0000000..5092a79 --- /dev/null +++ b/Core/Tests/Validator/Constraints/LegacyUserPasswordValidatorLegacyApiTest.php @@ -0,0 +1,26 @@ +<?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\Validator\Validation; + +/** + * @since 2.5.4 + * @author Bernhard Schussek <bschussek@gmail.com> + */ +class LegacyUserPasswordValidatorLegacyApiTest extends UserPasswordValidatorTest +{ + protected function getApiVersion() + { + return Validation::API_VERSION_2_5_BC; + } +} diff --git a/Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php b/Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php index 53eeb5f..10f692c 100644 --- a/Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php +++ b/Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php @@ -11,77 +11,102 @@ namespace Symfony\Component\Security\Core\Tests\Validator\Constraints; +use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; +use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface; +use Symfony\Component\Security\Core\SecurityContextInterface; use Symfony\Component\Security\Core\Validator\Constraints\UserPassword; use Symfony\Component\Security\Core\Validator\Constraints\UserPasswordValidator; +use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest; +use Symfony\Component\Validator\Validation; -class UserPasswordValidatorTest extends \PHPUnit_Framework_TestCase +/** + * @author Bernhard Schussek <bschussek@gmail.com> + */ +class UserPasswordValidatorTest extends AbstractConstraintValidatorTest { - const PASSWORD_VALID = true; - const PASSWORD_INVALID = false; + const PASSWORD = 's3Cr3t'; - protected $context; + const SALT = '^S4lt$'; - protected function setUp() + /** + * @var SecurityContextInterface + */ + protected $securityContext; + + /** + * @var PasswordEncoderInterface + */ + protected $encoder; + + /** + * @var EncoderFactoryInterface + */ + protected $encoderFactory; + + protected function getApiVersion() { - $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); + return Validation::API_VERSION_2_5; } - protected function tearDown() + protected function createValidator() { - $this->context = null; + return new UserPasswordValidator($this->securityContext, $this->encoderFactory); } - public function testPasswordIsValid() + protected function setUp() { $user = $this->createUser(); - $securityContext = $this->createSecurityContext($user); + $this->securityContext = $this->createSecurityContext($user); + $this->encoder = $this->createPasswordEncoder(); + $this->encoderFactory = $this->createEncoderFactory($this->encoder); - $encoder = $this->createPasswordEncoder(static::PASSWORD_VALID); - $encoderFactory = $this->createEncoderFactory($encoder); + parent::setUp(); + } + + public function testPasswordIsValid() + { + $constraint = new UserPassword(array( + 'message' => 'myMessage', + )); - $validator = new UserPasswordValidator($securityContext, $encoderFactory); - $validator->initialize($this->context); + $this->encoder->expects($this->once()) + ->method('isPasswordValid') + ->with(static::PASSWORD, 'secret', static::SALT) + ->will($this->returnValue(true)); - $this - ->context - ->expects($this->never()) - ->method('addViolation') - ; + $this->validator->validate('secret', $constraint); - $validator->validate('secret', new UserPassword()); + $this->assertNoViolation(); } public function testPasswordIsNotValid() { - $user = $this->createUser(); - $securityContext = $this->createSecurityContext($user); - - $encoder = $this->createPasswordEncoder(static::PASSWORD_INVALID); - $encoderFactory = $this->createEncoderFactory($encoder); + $constraint = new UserPassword(array( + 'message' => 'myMessage', + )); - $validator = new UserPasswordValidator($securityContext, $encoderFactory); - $validator->initialize($this->context); + $this->encoder->expects($this->once()) + ->method('isPasswordValid') + ->with(static::PASSWORD, 'secret', static::SALT) + ->will($this->returnValue(false)); - $this - ->context - ->expects($this->once()) - ->method('addViolation') - ; + $this->validator->validate('secret', $constraint); - $validator->validate('secret', new UserPassword()); + $this->assertViolation('myMessage'); } + /** + * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException + */ 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()); + $this->securityContext = $this->createSecurityContext($user); + $this->validator = $this->createValidator(); + $this->validator->initialize($this->context); + + $this->validator->validate('secret', new UserPassword()); } protected function createUser() @@ -89,15 +114,15 @@ class UserPasswordValidatorTest extends \PHPUnit_Framework_TestCase $mock = $this->getMock('Symfony\Component\Security\Core\User\UserInterface'); $mock - ->expects($this->once()) + ->expects($this->any()) ->method('getPassword') - ->will($this->returnValue('s3Cr3t')) + ->will($this->returnValue(static::PASSWORD)) ; $mock - ->expects($this->once()) + ->expects($this->any()) ->method('getSalt') - ->will($this->returnValue('^S4lt$')) + ->will($this->returnValue(static::SALT)) ; return $mock; @@ -105,15 +130,7 @@ class UserPasswordValidatorTest extends \PHPUnit_Framework_TestCase 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; + return $this->getMock('Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface'); } protected function createEncoderFactory($encoder = null) @@ -121,7 +138,7 @@ class UserPasswordValidatorTest extends \PHPUnit_Framework_TestCase $mock = $this->getMock('Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface'); $mock - ->expects($this->once()) + ->expects($this->any()) ->method('getEncoder') ->will($this->returnValue($encoder)) ; @@ -135,7 +152,7 @@ class UserPasswordValidatorTest extends \PHPUnit_Framework_TestCase $mock = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'); $mock - ->expects($this->once()) + ->expects($this->any()) ->method('getToken') ->will($this->returnValue($token)) ; @@ -147,7 +164,7 @@ class UserPasswordValidatorTest extends \PHPUnit_Framework_TestCase { $mock = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); $mock - ->expects($this->once()) + ->expects($this->any()) ->method('getUser') ->will($this->returnValue($user)) ; diff --git a/Core/Validator/Constraints/UserPassword.php b/Core/Validator/Constraints/UserPassword.php index aee4cda..35537b3 100644 --- a/Core/Validator/Constraints/UserPassword.php +++ b/Core/Validator/Constraints/UserPassword.php @@ -19,7 +19,7 @@ use Symfony\Component\Validator\Constraint; */ class UserPassword extends Constraint { - public $message = 'This value should be the user current password.'; + public $message = 'This value should be the user\'s current password.'; public $service = 'security.validator.user_password'; /** diff --git a/Http/Firewall/RememberMeListener.php b/Http/Firewall/RememberMeListener.php index 6ca3842..44000d3 100644 --- a/Http/Firewall/RememberMeListener.php +++ b/Http/Firewall/RememberMeListener.php @@ -33,6 +33,7 @@ class RememberMeListener implements ListenerInterface private $authenticationManager; private $logger; private $dispatcher; + private $catchExceptions = true; /** * Constructor. @@ -42,14 +43,16 @@ class RememberMeListener implements ListenerInterface * @param AuthenticationManagerInterface $authenticationManager * @param LoggerInterface $logger * @param EventDispatcherInterface $dispatcher + * @param bool $catchExceptions */ - public function __construct(SecurityContextInterface $securityContext, RememberMeServicesInterface $rememberMeServices, AuthenticationManagerInterface $authenticationManager, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null) + public function __construct(SecurityContextInterface $securityContext, RememberMeServicesInterface $rememberMeServices, AuthenticationManagerInterface $authenticationManager, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, $catchExceptions = true) { $this->securityContext = $securityContext; $this->rememberMeServices = $rememberMeServices; $this->authenticationManager = $authenticationManager; $this->logger = $logger; $this->dispatcher = $dispatcher; + $this->catchExceptions = $catchExceptions; } /** @@ -90,6 +93,10 @@ class RememberMeListener implements ListenerInterface } $this->rememberMeServices->loginFail($request); + + if (!$this->catchExceptions) { + throw $failed; + } } } } diff --git a/Http/RememberMe/AbstractRememberMeServices.php b/Http/RememberMe/AbstractRememberMeServices.php index be84208..b868dae 100644 --- a/Http/RememberMe/AbstractRememberMeServices.php +++ b/Http/RememberMe/AbstractRememberMeServices.php @@ -303,7 +303,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface $parameter = $request->get($this->options['remember_me_parameter'], null, true); - if ($parameter === null && null !== $this->logger) { + if (null === $parameter && null !== $this->logger) { $this->logger->debug(sprintf('Did not send remember-me cookie (remember-me parameter "%s" was not sent).', $this->options['remember_me_parameter'])); } diff --git a/Http/Tests/Firewall/RememberMeListenerTest.php b/Http/Tests/Firewall/RememberMeListenerTest.php index 9506692..68dfc14 100644 --- a/Http/Tests/Firewall/RememberMeListenerTest.php +++ b/Http/Tests/Firewall/RememberMeListenerTest.php @@ -14,12 +14,13 @@ namespace Symfony\Component\Security\Http\Tests\Firewall; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Http\Firewall\RememberMeListener; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Http\SecurityEvents; class RememberMeListenerTest extends \PHPUnit_Framework_TestCase { public function testOnCoreSecurityDoesNotTryToPopulateNonEmptySecurityContext() { - list($listener, $context, $service,,) = $this->getListener(); + list($listener, $context,,,,) = $this->getListener(); $context ->expects($this->once()) @@ -99,6 +100,48 @@ class RememberMeListenerTest extends \PHPUnit_Framework_TestCase $listener->handle($event); } + /** + * @expectedException Symfony\Component\Security\Core\Exception\AuthenticationException + * @expectedExceptionMessage Authentication failed. + */ + public function testOnCoreSecurityIgnoresAuthenticationOptionallyRethrowsExceptionThrownAuthenticationManagerImplementation() + { + list($listener, $context, $service, $manager,) = $this->getListener(false, false); + + $context + ->expects($this->once()) + ->method('getToken') + ->will($this->returnValue(null)) + ; + + $service + ->expects($this->once()) + ->method('autoLogin') + ->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'))) + ; + + $service + ->expects($this->once()) + ->method('loginFail') + ; + + $exception = new AuthenticationException('Authentication failed.'); + $manager + ->expects($this->once()) + ->method('authenticate') + ->will($this->throwException($exception)) + ; + + $event = $this->getGetResponseEvent(); + $event + ->expects($this->once()) + ->method('getRequest') + ->will($this->returnValue(new Request())) + ; + + $listener->handle($event); + } + public function testOnCoreSecurity() { list($listener, $context, $service, $manager,) = $this->getListener(); @@ -138,6 +181,55 @@ class RememberMeListenerTest extends \PHPUnit_Framework_TestCase $listener->handle($event); } + public function testOnCoreSecurityInteractiveLoginEventIsDispatchedIfDispatcherIsPresent() + { + list($listener, $context, $service, $manager,, $dispatcher) = $this->getListener(true); + + $context + ->expects($this->once()) + ->method('getToken') + ->will($this->returnValue(null)) + ; + + $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'); + $service + ->expects($this->once()) + ->method('autoLogin') + ->will($this->returnValue($token)) + ; + + $context + ->expects($this->once()) + ->method('setToken') + ->with($this->equalTo($token)) + ; + + $manager + ->expects($this->once()) + ->method('authenticate') + ->will($this->returnValue($token)) + ; + + $event = $this->getGetResponseEvent(); + $request = new Request(); + $event + ->expects($this->once()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $dispatcher + ->expects($this->once()) + ->method('dispatch') + ->with( + SecurityEvents::INTERACTIVE_LOGIN, + $this->isInstanceOf('Symfony\Component\Security\Http\Event\InteractiveLoginEvent') + ) + ; + + $listener->handle($event); + } + protected function getGetResponseEvent() { return $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); @@ -148,16 +240,18 @@ class RememberMeListenerTest extends \PHPUnit_Framework_TestCase return $this->getMock('Symfony\Component\HttpKernel\Event\FilterResponseEvent', array(), array(), '', false); } - protected function getListener() + protected function getListener($withDispatcher = false, $catchExceptions = true) { $listener = new RememberMeListener( $context = $this->getContext(), $service = $this->getService(), $manager = $this->getManager(), - $logger = $this->getLogger() + $logger = $this->getLogger(), + $dispatcher = ($withDispatcher ? $this->getDispatcher() : null), + $catchExceptions ); - return array($listener, $context, $service, $manager, $logger); + return array($listener, $context, $service, $manager, $logger, $dispatcher); } protected function getLogger() @@ -177,8 +271,11 @@ class RememberMeListenerTest extends \PHPUnit_Framework_TestCase protected function getContext() { - return $this->getMockBuilder('Symfony\Component\Security\Core\SecurityContext') - ->disableOriginalConstructor() - ->getMock(); + return $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'); + } + + protected function getDispatcher() + { + return $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 65cc186..4d167b7 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,14 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> -<phpunit backupGlobals="false" - backupStaticAttributes="false" +<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd" + backupGlobals="false" colors="true" - convertErrorsToExceptions="true" - convertNoticesToExceptions="true" - convertWarningsToExceptions="true" - processIsolation="false" - stopOnFailure="false" - syntaxCheck="false" bootstrap="vendor/autoload.php" > <testsuites> |