diff --git a/Hasher/PasswordHasherFactory.php b/Hasher/PasswordHasherFactory.php index b75573f..62c5e37 100644 --- a/Hasher/PasswordHasherFactory.php +++ b/Hasher/PasswordHasherFactory.php @@ -14,6 +14,8 @@ use Symfony\Component\PasswordHasher\Exception\LogicException; use Symfony\Component\PasswordHasher\PasswordHasherInterface; use Symfony\Component\Security\Core\Encoder\EncoderAwareInterface; +use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface; +use Symfony\Component\Security\Core\Encoder\PasswordHasherAdapter; /** * A generic hasher factory implementation. @@ -25,6 +27,9 @@ class PasswordHasherFactory implements PasswordHasherFactoryInterface { private $passwordHashers; + /** + * @param array $passwordHashers + */ public function __construct(array $passwordHashers) { $this->passwordHashers = $passwordHashers; @@ -57,7 +62,10 @@ public function getPasswordHasher($user): PasswordHasherInterface } if (!$this->passwordHashers[$hasherKey] instanceof PasswordHasherInterface) { - $this->passwordHashers[$hasherKey] = $this->createHasher($this->passwordHashers[$hasherKey]); + $this->passwordHashers[$hasherKey] = $this->passwordHashers[$hasherKey] instanceof PasswordEncoderInterface + ? new PasswordHasherAdapter($this->passwordHashers[$hasherKey]) + : $this->createHasher($this->passwordHashers[$hasherKey]) + ; } return $this->passwordHashers[$hasherKey]; @@ -82,6 +90,9 @@ private function createHasher(array $config, bool $isExtra = false): PasswordHas } $hasher = new $config['class'](...$config['arguments']); + if (!$hasher instanceof PasswordHasherInterface && $hasher instanceof PasswordEncoderInterface) { + $hasher = new PasswordHasherAdapter($hasher); + } if ($isExtra || !\in_array($config['class'], [NativePasswordHasher::class, SodiumPasswordHasher::class], true)) { return $hasher; diff --git a/Tests/Hasher/PasswordHasherFactoryTest.php b/Tests/Hasher/PasswordHasherFactoryTest.php index 633e38e..bebd95b 100644 --- a/Tests/Hasher/PasswordHasherFactoryTest.php +++ b/Tests/Hasher/PasswordHasherFactoryTest.php @@ -18,6 +18,7 @@ use Symfony\Component\PasswordHasher\Hasher\PasswordHasherAwareInterface; use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactory; use Symfony\Component\PasswordHasher\Hasher\SodiumPasswordHasher; +use Symfony\Component\Security\Core\Encoder\PlaintextPasswordEncoder; use Symfony\Component\Security\Core\User\InMemoryUser; use Symfony\Component\Security\Core\User\UserInterface; @@ -176,6 +177,24 @@ public function testDefaultMigratingHashers() (new PasswordHasherFactory([SomeUser::class => ['class' => SodiumPasswordHasher::class, 'arguments' => []]]))->getPasswordHasher(SomeUser::class) ); } + + /** + * @group legacy + */ + public function testLegacyEncoderObject() + { + $factory = new PasswordHasherFactory([SomeUser::class => new PlaintextPasswordEncoder()]); + self::assertSame('foo{bar}', $factory->getPasswordHasher(SomeUser::class)->hash('foo', 'bar')); + } + + /** + * @group legacy + */ + public function testLegacyEncoderClass() + { + $factory = new PasswordHasherFactory([SomeUser::class => ['class' => PlaintextPasswordEncoder::class, 'arguments' => []]]); + self::assertSame('foo{bar}', $factory->getPasswordHasher(SomeUser::class)->hash('foo', 'bar')); + } } class SomeUser implements UserInterface diff --git a/composer.json b/composer.json index 2ed22ee..0098950 100644 --- a/composer.json +++ b/composer.json @@ -23,6 +23,9 @@ "symfony/security-core": "^5.3", "symfony/console": "^5" }, + "conflict": { + "symfony/security-core": "<5.3" + }, "autoload": { "psr-4": { "Symfony\\Component\\PasswordHasher\\": "" }, "exclude-from-classmap": [