diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
index d90f3206dba0..6b754838bef1 100644
--- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
+++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
@@ -10,6 +10,7 @@
Symfony\Component\Security\Core\User\UserChecker
Symfony\Component\Security\Core\Encoder\EncoderFactory
+ Symfony\Component\Security\Core\Encoder\UserPasswordEncoder
Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder
Symfony\Component\Security\Core\Encoder\PlaintextPasswordEncoder
Symfony\Component\Security\Core\Encoder\Pbkdf2PasswordEncoder
@@ -80,6 +81,12 @@
+
+
+
+
+
+
diff --git a/src/Symfony/Component/Security/Core/Encoder/UserPasswordEncoder.php b/src/Symfony/Component/Security/Core/Encoder/UserPasswordEncoder.php
new file mode 100644
index 000000000000..13ee835d4ad1
--- /dev/null
+++ b/src/Symfony/Component/Security/Core/Encoder/UserPasswordEncoder.php
@@ -0,0 +1,55 @@
+
+ *
+ * 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
+ */
+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/src/Symfony/Component/Security/Core/Encoder/UserPasswordEncoderInterface.php b/src/Symfony/Component/Security/Core/Encoder/UserPasswordEncoderInterface.php
new file mode 100644
index 000000000000..39e906ac69a8
--- /dev/null
+++ b/src/Symfony/Component/Security/Core/Encoder/UserPasswordEncoderInterface.php
@@ -0,0 +1,41 @@
+
+ *
+ * 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
+ */
+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/src/Symfony/Component/Security/Core/Tests/Encoder/UserPasswordEncoderTest.php b/src/Symfony/Component/Security/Core/Tests/Encoder/UserPasswordEncoderTest.php
new file mode 100644
index 000000000000..590652da0420
--- /dev/null
+++ b/src/Symfony/Component/Security/Core/Tests/Encoder/UserPasswordEncoderTest.php
@@ -0,0 +1,70 @@
+
+ *
+ * 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);
+ }
+}