Skip to content

Commit

Permalink
FRW-5940 Symfony Security 6 Support (#10579)
Browse files Browse the repository at this point in the history
FRW-5940 Symfony Security 6 Support
  • Loading branch information
olhalivitchuk authored Dec 21, 2023
1 parent 6413096 commit 5133e31
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 11 deletions.
5 changes: 3 additions & 2 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ parameters:
reportUnmatchedIgnoredErrors: false
ignoreErrors:
- '#Instantiated class .+NativePasswordEncoder not found.#'
- '#Instantiated class .+BCryptPasswordEncoder not found.#'
- '#Method .+Customer::getPasswordEncoder\(\) should return .+PasswordEncoderInterface but returns .+NativePasswordEncoder.#'
- '#Method .+Customer::getPasswordEncoder\(\) should return .+PasswordEncoderInterface but returns .+BCryptPasswordEncoder.#'
- '#Cannot call method format\(\) on DateTime\|string.#'
- { message: '#Call to method encodePassword\(\) on an unknown class Symfony\\Component\\Security\\Core\\Encoder\\PasswordEncoderInterface.#', path: '%rootDir%/../../../vendor/spryker/spryker/Bundles/Customer/src/Spryker/Zed/Customer/Business/Customer/Customer.php' }
- { message: '#Call to method isPasswordValid\(\) on an unknown class Symfony\\Component\\Security\\Core\\Encoder\\PasswordEncoderInterface.#', path: '%rootDir%/../../../vendor/spryker/spryker/Bundles/Customer/src/Spryker/Zed/Customer/Business/Customer/Customer.php' }
- { message: '#Method .+Customer::getPasswordEncoder\(\) has invalid return type Symfony\\Component\\Security\\Core\\Encoder\\PasswordEncoderInterface.#', path: '%rootDir%/../../../vendor/spryker/spryker/Bundles/Customer/src/Spryker/Zed/Customer/Business/Customer/Customer.php' }
33 changes: 31 additions & 2 deletions src/Spryker/Zed/Customer/Business/Customer/Customer.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
use Spryker\Zed\Customer\Dependency\Facade\CustomerToMailInterface;
use Spryker\Zed\Customer\Persistence\CustomerQueryContainerInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\PasswordHasher\Hasher\NativePasswordHasher;
use Symfony\Component\PasswordHasher\PasswordHasherInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager;
use Symfony\Component\Security\Core\Encoder\NativePasswordEncoder;
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;

Expand Down Expand Up @@ -893,7 +896,11 @@ protected function getEncodedPassword($currentPassword)
return $currentPassword;
}

return $this->getPasswordEncoder()->encodePassword($currentPassword, static::BCRYPT_SALT);
if ($this->isSymfonyVersion5() === true) {
return $this->getPasswordEncoder()->encodePassword($currentPassword, static::BCRYPT_SALT);
}

return $this->createPasswordHasher()->hash($currentPassword);
}

/**
Expand All @@ -904,6 +911,14 @@ protected function getPasswordEncoder(): PasswordEncoderInterface
return new NativePasswordEncoder(null, null, static::BCRYPT_FACTOR);
}

/**
* @return \Symfony\Component\PasswordHasher\PasswordHasherInterface
*/
public function createPasswordHasher(): PasswordHasherInterface
{
return new NativePasswordHasher(null, null, static::BCRYPT_FACTOR);
}

/**
* @param string $hash
* @param string $rawPassword
Expand All @@ -912,7 +927,11 @@ protected function getPasswordEncoder(): PasswordEncoderInterface
*/
protected function isValidPassword($hash, $rawPassword)
{
return $this->getPasswordEncoder()->isPasswordValid($hash, $rawPassword, static::BCRYPT_SALT);
if ($this->isSymfonyVersion5() === true) {
return $this->getPasswordEncoder()->isPasswordValid($hash, $rawPassword, static::BCRYPT_SALT);
}

return $this->createPasswordHasher()->verify($hash, $rawPassword);
}

/**
Expand Down Expand Up @@ -1035,4 +1054,14 @@ public function sendPasswordRestoreMailForCustomerCollection(
));
}
}

/**
* @deprecated Shim for Symfony Security Core 5.x, to be removed when Symfony Security Core dependency becomes 6.x+.
*
* @return bool
*/
protected function isSymfonyVersion5(): bool
{
return class_exists(AuthenticationProviderManager::class);
}
}
55 changes: 48 additions & 7 deletions tests/SprykerTest/Zed/Customer/_support/CustomerBusinessTester.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@

use Codeception\Actor;
use Generated\Shared\Transfer\CustomerTransfer;
use Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder;
use Symfony\Component\PasswordHasher\Hasher\NativePasswordHasher;
use Symfony\Component\PasswordHasher\PasswordHasherInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager;
use Symfony\Component\Security\Core\Encoder\NativePasswordEncoder;
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;

Expand Down Expand Up @@ -43,6 +45,11 @@ class CustomerBusinessTester extends Actor
*/
public const TESTER_PASSWORD = '$2tester';

/**
* @var int
*/
protected const BCRYPT_FACTOR = 12;

/**
* @param string $hash
* @param string $rawPassword
Expand All @@ -52,9 +59,15 @@ class CustomerBusinessTester extends Actor
*/
public function assertPasswordsEqual(string $hash, string $rawPassword, string $salt = ''): void
{
$passwordEncoder = $this->getPasswordEncoder();
if ($this->isSymfonyVersion5() === true) {
$this->assertPasswordIsEncoded($hash, $rawPassword, $salt);

$this->assertTrue($passwordEncoder->isPasswordValid($hash, $rawPassword, $salt), 'Passwords are not equal.');
return;
}

$passwordHasher = $this->createPasswordHasher();

$this->assertTrue($passwordHasher->verify($hash, $rawPassword), 'Passwords are not equal.');
}

/**
Expand All @@ -81,15 +94,43 @@ public function createTestCustomer(): CustomerTransfer
return $customerTransfer;
}

/**
* @param string $hash
* @param string $rawPassword
* @param string $salt
*
* @return void
*/
protected function assertPasswordIsEncoded(string $hash, string $rawPassword, string $salt = ''): void
{
$passwordEncoder = $this->getPasswordEncoder();

$this->assertTrue($passwordEncoder->isPasswordValid($hash, $rawPassword, $salt), 'Passwords are not equal.');
}

/**
* @return \Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface
*/
protected function getPasswordEncoder(): PasswordEncoderInterface
{
if (class_exists(BCryptPasswordEncoder::class)) {
return new BCryptPasswordEncoder(12);
}
return new NativePasswordEncoder(null, null, static::BCRYPT_FACTOR);
}

/**
* @return \Symfony\Component\PasswordHasher\PasswordHasherInterface
*/
protected function createPasswordHasher(): PasswordHasherInterface
{
return new NativePasswordHasher(null, null, static::BCRYPT_FACTOR);
}

return new NativePasswordEncoder(null, null, 12);
/**
* @deprecated Shim for Symfony Security Core 5.x, to be removed when Symfony Security Core dependency becomes 6.x+.
*
* @return bool
*/
protected function isSymfonyVersion5(): bool
{
return class_exists(AuthenticationProviderManager::class);
}
}

0 comments on commit 5133e31

Please sign in to comment.