diff --git a/src/Symfony/Component/Security/Core/Encoder/EncoderAwareInterface.php b/src/Symfony/Component/Security/Core/Encoder/EncoderAwareInterface.php new file mode 100644 index 0000000000000..22ae820cce394 --- /dev/null +++ b/src/Symfony/Component/Security/Core/Encoder/EncoderAwareInterface.php @@ -0,0 +1,28 @@ + + * + * 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; + +/** + * @author Christophe Coevoet + */ +interface EncoderAwareInterface +{ + /** + * Gets the name of the encoder used to encode the password. + * + * If the method returns null, the standard way to retrieve the encoder + * will be used instead. + * + * @return string + */ + public function getEncoderName(); +} diff --git a/src/Symfony/Component/Security/Core/Encoder/EncoderFactory.php b/src/Symfony/Component/Security/Core/Encoder/EncoderFactory.php index 8bad61fabfda8..bb5ba912b36d6 100644 --- a/src/Symfony/Component/Security/Core/Encoder/EncoderFactory.php +++ b/src/Symfony/Component/Security/Core/Encoder/EncoderFactory.php @@ -30,19 +30,32 @@ public function __construct(array $encoders) */ public function getEncoder($user) { - foreach ($this->encoders as $class => $encoder) { - if ((is_object($user) && !$user instanceof $class) || (!is_object($user) && !is_subclass_of($user, $class) && $user != $class)) { - continue; + $encoderKey = null; + + if ($user instanceof EncoderAwareInterface && (null !== $encoderName = $user->getEncoderName())) { + if (!array_key_exists($encoderName, $this->encoders)) { + throw new \RuntimeException(sprintf('The encoder "%s" was not configured.', $encoderName)); } - if (!$encoder instanceof PasswordEncoderInterface) { - return $this->encoders[$class] = $this->createEncoder($encoder); + $encoderKey = $encoderName; + } else { + foreach ($this->encoders as $class => $encoder) { + if ((is_object($user) && $user instanceof $class) || (!is_object($user) && (is_subclass_of($user, $class) || $user == $class))) { + $encoderKey = $class; + break; + } } + } + + if (null === $encoderKey) { + throw new \RuntimeException(sprintf('No encoder has been configured for account "%s".', is_object($user) ? get_class($user) : $user)); + } - return $this->encoders[$class]; + if (!$this->encoders[$encoderKey] instanceof PasswordEncoderInterface) { + $this->encoders[$encoderKey] = $this->createEncoder($this->encoders[$encoderKey]); } - throw new \RuntimeException(sprintf('No encoder has been configured for account "%s".', is_object($user) ? get_class($user) : $user)); + return $this->encoders[$encoderKey]; } /** diff --git a/src/Symfony/Component/Security/Core/Tests/Encoder/EncoderFactoryTest.php b/src/Symfony/Component/Security/Core/Tests/Encoder/EncoderFactoryTest.php index 18c8c4a9b00c8..3d34d0468d58d 100644 --- a/src/Symfony/Component/Security/Core/Tests/Encoder/EncoderFactoryTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Encoder/EncoderFactoryTest.php @@ -13,6 +13,7 @@ use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder; use Symfony\Component\Security\Core\Encoder\EncoderFactory; +use Symfony\Component\Security\Core\Encoder\EncoderAwareInterface; use Symfony\Component\Security\Core\User\User; use Symfony\Component\Security\Core\User\UserInterface; @@ -78,6 +79,59 @@ public function testGetEncoderConfiguredForConcreteClassWithClassName() $expectedEncoder = new MessageDigestPasswordEncoder('sha1'); $this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', '')); } + + public function testGetNamedEncoderForEncoderAware() + { + $factory = new EncoderFactory(array( + 'Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser' => new MessageDigestPasswordEncoder('sha256'), + 'encoder_name' => new MessageDigestPasswordEncoder('sha1') + )); + + $encoder = $factory->getEncoder(new EncAwareUser('user', 'pass')); + $expectedEncoder = new MessageDigestPasswordEncoder('sha1'); + $this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', '')); + } + + public function testGetNullNamedEncoderForEncoderAware() + { + $factory = new EncoderFactory(array( + 'Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser' => new MessageDigestPasswordEncoder('sha1'), + 'encoder_name' => new MessageDigestPasswordEncoder('sha256') + )); + + $user = new EncAwareUser('user', 'pass'); + $user->encoderName = null; + $encoder = $factory->getEncoder($user); + $expectedEncoder = new MessageDigestPasswordEncoder('sha1'); + $this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', '')); + } + + /** + * @expectedException RuntimeException + */ + public function testGetInvalidNamedEncoderForEncoderAware() + { + $factory = new EncoderFactory(array( + 'Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser' => new MessageDigestPasswordEncoder('sha1'), + 'encoder_name' => new MessageDigestPasswordEncoder('sha256') + )); + + $user = new EncAwareUser('user', 'pass'); + $user->encoderName = 'invalid_encoder_name'; + $encoder = $factory->getEncoder($user); + } + + public function testGetEncoderForEncoderAwareWithClassName() + { + $factory = new EncoderFactory(array( + 'Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser' => new MessageDigestPasswordEncoder('sha1'), + 'encoder_name' => new MessageDigestPasswordEncoder('sha256') + )); + + $encoder = $factory->getEncoder('Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser'); + $expectedEncoder = new MessageDigestPasswordEncoder('sha1'); + $this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', '')); + } } class SomeUser implements UserInterface @@ -92,3 +146,13 @@ public function eraseCredentials() {} class SomeChildUser extends SomeUser { } + +class EncAwareUser extends SomeUser implements EncoderAwareInterface +{ + public $encoderName = 'encoder_name'; + + public function getEncoderName() + { + return $this->encoderName; + } +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy