Skip to content

Commit

Permalink
[PasswordHasher] Improved BC layer
Browse files Browse the repository at this point in the history
  • Loading branch information
derrabus committed May 2, 2021
1 parent 9c0ca75 commit fd127dd
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
13 changes: 12 additions & 1 deletion Hasher/PasswordHasherFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -25,6 +27,9 @@ class PasswordHasherFactory implements PasswordHasherFactoryInterface
{
private $passwordHashers;

/**
* @param array<string, PasswordHasherInterface|array> $passwordHashers
*/
public function __construct(array $passwordHashers)
{
$this->passwordHashers = $passwordHashers;
Expand Down Expand Up @@ -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];
Expand All @@ -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;
Expand Down
19 changes: 19 additions & 0 deletions Tests/Hasher/PasswordHasherFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand Down

0 comments on commit fd127dd

Please sign in to comment.