summaryrefslogtreecommitdiffstats
path: root/Core
diff options
context:
space:
mode:
Diffstat (limited to 'Core')
-rw-r--r--Core/Authentication/Provider/UserAuthenticationProvider.php4
-rw-r--r--Core/Authorization/Voter/VoterInterface.php2
-rw-r--r--Core/Encoder/BCryptPasswordEncoder.php2
-rw-r--r--Core/Encoder/BasePasswordEncoder.php2
-rw-r--r--Core/Encoder/UserPasswordEncoder.php55
-rw-r--r--Core/Encoder/UserPasswordEncoderInterface.php41
-rw-r--r--Core/Exception/UsernameNotFoundException.php2
-rw-r--r--Core/Tests/Encoder/UserPasswordEncoderTest.php70
-rw-r--r--Core/Tests/Exception/UsernameNotFoundExceptionTest.php2
-rw-r--r--Core/Tests/Validator/Constraints/LegacyUserPasswordValidator2Dot4ApiTest.php26
-rw-r--r--Core/Tests/Validator/Constraints/LegacyUserPasswordValidatorLegacyApiTest.php26
-rw-r--r--Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php129
-rw-r--r--Core/Validator/Constraints/UserPassword.php2
13 files changed, 300 insertions, 63 deletions
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';
/**