Skip to content

Commit

Permalink
Automatically upgrade new password hashes (see #1027)
Browse files Browse the repository at this point in the history
Description
-----------

This will automatically upgrade bcrypt passwords to argon2 passwords when users log in (or whatever we will have in the future). Symfony FTW :)

Implements #538.

Commits
-------

729ae5d Automatically upgrade new password hashes
0a0b575 Add the is_a() check and fix the unit tests
  • Loading branch information
Toflar authored and leofeyer committed Nov 27, 2019
1 parent 4dd809e commit 1a0bfef
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 1 deletion.
16 changes: 15 additions & 1 deletion core-bundle/src/Security/User/ContaoUserProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;

class ContaoUserProvider implements UserProviderInterface
class ContaoUserProvider implements UserProviderInterface, PasswordUpgraderInterface
{
/**
* @var ContaoFramework
Expand Down Expand Up @@ -106,6 +107,19 @@ public function supportsClass($class): bool
return $this->userClass === $class;
}

/**
* @param User $user
*/
public function upgradePassword(UserInterface $user, string $newEncodedPassword): void
{
if (!is_a($user, $this->userClass)) {
throw new UnsupportedUserException(sprintf('Unsupported class "%s".', \get_class($user)));
}

$user->password = $newEncodedPassword;
$user->save();
}

/**
* Validates the session lifetime and logs the user out if the session has expired.
*
Expand Down
29 changes: 29 additions & 0 deletions core-bundle/tests/Security/User/ContaoUserProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,35 @@ public function testDoesNotHandleUnknownUserClasses(): void
$this->getProvider(null, 'LdapUser');
}

public function testUpgradesPasswords(): void
{
/** @var BackendUser&MockObject $user */
$user = $this->mockClassWithProperties(BackendUser::class);
$user->username = 'foobar';
$user->password = 'superhash';

$user
->expects($this->once())
->method('save')
;

$userProvider = $this->getProvider(null, BackendUser::class);
$userProvider->upgradePassword($user, 'newsuperhash');

$this->assertSame('newsuperhash', $user->password);
}

public function testFailsToUpgradePasswordsOfUnsupportedUsers(): void
{
$user = $this->createMock(UserInterface::class);
$provider = $this->getProvider();

$this->expectException(UnsupportedUserException::class);
$this->expectExceptionMessage(sprintf('Unsupported class "%s".', \get_class($user)));

$provider->upgradePassword($user, 'newsuperhash');
}

/**
* @group legacy
*
Expand Down

0 comments on commit 1a0bfef

Please sign in to comment.