diff --git a/src/Symfony/Component/PasswordHasher/Hasher/PasswordHasherFactory.php b/src/Symfony/Component/PasswordHasher/Hasher/PasswordHasherFactory.php index a2f24224744aa..dd7e015c1ecd2 100644 --- a/src/Symfony/Component/PasswordHasher/Hasher/PasswordHasherFactory.php +++ b/src/Symfony/Component/PasswordHasher/Hasher/PasswordHasherFactory.php @@ -61,14 +61,7 @@ public function getPasswordHasher($user): PasswordHasherInterface throw new \RuntimeException(sprintf('No password hasher has been configured for account "%s".', \is_object($user) ? get_debug_type($user) : $user)); } - if (!$this->passwordHashers[$hasherKey] instanceof PasswordHasherInterface) { - $this->passwordHashers[$hasherKey] = $this->passwordHashers[$hasherKey] instanceof PasswordEncoderInterface - ? new PasswordHasherAdapter($this->passwordHashers[$hasherKey]) - : $this->createHasher($this->passwordHashers[$hasherKey]) - ; - } - - return $this->passwordHashers[$hasherKey]; + return $this->createHasherUsingAdapter($hasherKey); } /** @@ -111,6 +104,18 @@ private function createHasher(array $config, bool $isExtra = false): PasswordHas return new MigratingPasswordHasher($hasher, ...$extrapasswordHashers); } + private function createHasherUsingAdapter(string $hasherKey): PasswordHasherInterface + { + if (!$this->passwordHashers[$hasherKey] instanceof PasswordHasherInterface) { + $this->passwordHashers[$hasherKey] = $this->passwordHashers[$hasherKey] instanceof PasswordEncoderInterface + ? new PasswordHasherAdapter($this->passwordHashers[$hasherKey]) + : $this->createHasher($this->passwordHashers[$hasherKey]) + ; + } + + return $this->passwordHashers[$hasherKey]; + } + private function getHasherConfigFromAlgorithm(array $config): array { if ('auto' === $config['algorithm']) { @@ -142,8 +147,8 @@ private function getHasherConfigFromAlgorithm(array $config): array $hasherChain = [$this->createHasher($config, true)]; foreach ($frompasswordHashers as $name) { - if ($hasher = $this->passwordHashers[$name] ?? false) { - $hasher = $hasher instanceof PasswordHasherInterface ? $hasher : $this->createHasher($hasher, true); + if (isset($this->passwordHashers[$name])) { + $hasher = $this->createHasherUsingAdapter($name); } else { $hasher = $this->createHasher(['algorithm' => $name], true); } diff --git a/src/Symfony/Component/PasswordHasher/Tests/Hasher/PasswordHasherFactoryTest.php b/src/Symfony/Component/PasswordHasher/Tests/Hasher/PasswordHasherFactoryTest.php index 1f8fcb3e79531..1f24a0d3cace2 100644 --- a/src/Symfony/Component/PasswordHasher/Tests/Hasher/PasswordHasherFactoryTest.php +++ b/src/Symfony/Component/PasswordHasher/Tests/Hasher/PasswordHasherFactoryTest.php @@ -163,6 +163,29 @@ public function testMigrateFrom() $this->assertStringStartsWith(\SODIUM_CRYPTO_PWHASH_STRPREFIX, $hasher->hash('foo', null)); } + /** + * @group legacy + */ + public function testMigrateFromLegacy() + { + if (!SodiumPasswordHasher::isSupported()) { + $this->markTestSkipped('Sodium is not available'); + } + + $factory = new PasswordHasherFactory([ + 'plaintext_encoder' => $plaintext = new PlaintextPasswordEncoder(), + SomeUser::class => ['algorithm' => 'sodium', 'migrate_from' => ['bcrypt', 'plaintext_encoder']], + ]); + + $hasher = $factory->getPasswordHasher(SomeUser::class); + $this->assertInstanceOf(MigratingPasswordHasher::class, $hasher); + + $this->assertTrue($hasher->verify((new SodiumPasswordHasher())->hash('foo', null), 'foo', null)); + $this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, null, \PASSWORD_BCRYPT))->hash('foo', null), 'foo', null)); + $this->assertTrue($hasher->verify($plaintext->encodePassword('foo', null), 'foo', null)); + $this->assertStringStartsWith(\SODIUM_CRYPTO_PWHASH_STRPREFIX, $hasher->hash('foo', null)); + } + public function testDefaultMigratingHashers() { $this->assertInstanceOf(
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: