From 4aafc474d8a30fb99ead36e2ddc2c2c6a19c4f09 Mon Sep 17 00:00:00 2001 From: Tomas Date: Tue, 18 Jun 2024 12:55:24 +0300 Subject: [PATCH] Wire clock for totp factories Not passing the clock is deprecated --- .../config/two_factor_provider_google.php | 2 ++ .../config/two_factor_provider_totp.php | 2 ++ .../Provider/Google/GoogleTotpFactory.php | 12 ++++++-- .../TwoFactor/Provider/Totp/TotpFactory.php | 28 ++++++++++++++----- 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/bundle/Resources/config/two_factor_provider_google.php b/src/bundle/Resources/config/two_factor_provider_google.php index 84fad478..c1c9bfd2 100644 --- a/src/bundle/Resources/config/two_factor_provider_google.php +++ b/src/bundle/Resources/config/two_factor_provider_google.php @@ -8,6 +8,7 @@ use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Google\GoogleAuthenticatorTwoFactorProvider; use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Google\GoogleTotpFactory; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; +use Symfony\Component\DependencyInjection\Loader\Configurator\ReferenceConfigurator; use function Symfony\Component\DependencyInjection\Loader\Configurator\service; return static function (ContainerConfigurator $container): void { @@ -18,6 +19,7 @@ '%scheb_two_factor.google.server_name%', '%scheb_two_factor.google.issuer%', '%scheb_two_factor.google.digits%', + (new ReferenceConfigurator('clock'))->nullOnInvalid(), ]) ->set('scheb_two_factor.security.google_authenticator', GoogleAuthenticator::class) diff --git a/src/bundle/Resources/config/two_factor_provider_totp.php b/src/bundle/Resources/config/two_factor_provider_totp.php index febf34d6..44d2801d 100644 --- a/src/bundle/Resources/config/two_factor_provider_totp.php +++ b/src/bundle/Resources/config/two_factor_provider_totp.php @@ -8,6 +8,7 @@ use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Totp\TotpAuthenticatorTwoFactorProvider; use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Totp\TotpFactory; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; +use Symfony\Component\DependencyInjection\Loader\Configurator\ReferenceConfigurator; use function Symfony\Component\DependencyInjection\Loader\Configurator\service; return static function (ContainerConfigurator $container): void { @@ -19,6 +20,7 @@ '%scheb_two_factor.totp.server_name%', '%scheb_two_factor.totp.issuer%', '%scheb_two_factor.totp.parameters%', + (new ReferenceConfigurator('clock'))->nullOnInvalid(), ]) ->set('scheb_two_factor.security.totp_authenticator', TotpAuthenticator::class) diff --git a/src/google-authenticator/Security/TwoFactor/Provider/Google/GoogleTotpFactory.php b/src/google-authenticator/Security/TwoFactor/Provider/Google/GoogleTotpFactory.php index b998fa65..4c6ba6f2 100644 --- a/src/google-authenticator/Security/TwoFactor/Provider/Google/GoogleTotpFactory.php +++ b/src/google-authenticator/Security/TwoFactor/Provider/Google/GoogleTotpFactory.php @@ -6,6 +6,8 @@ use OTPHP\TOTP; use OTPHP\TOTPInterface; +use Psr\Clock\ClockInterface; +use ReflectionClass; use Scheb\TwoFactorBundle\Model\Google\TwoFactorInterface; use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Exception\TwoFactorProviderLogicException; use function strlen; @@ -19,6 +21,7 @@ public function __construct( private readonly string|null $server, private readonly string|null $issuer, private readonly int $digits, + private readonly ClockInterface|null $clock = null, ) { } @@ -29,8 +32,13 @@ public function createTotpForUser(TwoFactorInterface $user): TOTPInterface throw new TwoFactorProviderLogicException('Cannot initialize TOTP, no secret code provided.'); } - /** @psalm-suppress ArgumentTypeCoercion */ - $totp = TOTP::create($secret, 30, 'sha1', $this->digits); + if ((new ReflectionClass(TOTP::class))->hasProperty('clock')) { + /** @psalm-suppress ArgumentTypeCoercion */ + $totp = TOTP::create($secret, 30, 'sha1', $this->digits, clock: $this->clock); + } else { + /** @psalm-suppress ArgumentTypeCoercion */ + $totp = TOTP::create($secret, 30, 'sha1', $this->digits); + } $userAndHost = $user->getGoogleAuthenticatorUsername().(null !== $this->server && $this->server ? '@'.$this->server : ''); $totp->setLabel($userAndHost); diff --git a/src/totp/Security/TwoFactor/Provider/Totp/TotpFactory.php b/src/totp/Security/TwoFactor/Provider/Totp/TotpFactory.php index 252247f0..bbd1ab3a 100644 --- a/src/totp/Security/TwoFactor/Provider/Totp/TotpFactory.php +++ b/src/totp/Security/TwoFactor/Provider/Totp/TotpFactory.php @@ -6,6 +6,8 @@ use OTPHP\TOTP; use OTPHP\TOTPInterface; +use Psr\Clock\ClockInterface; +use ReflectionClass; use Scheb\TwoFactorBundle\Model\Totp\TwoFactorInterface; use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Exception\TwoFactorProviderLogicException; use function strlen; @@ -22,6 +24,7 @@ public function __construct( private readonly string|null $server, private readonly string|null $issuer, private readonly array $customParameters, + private readonly ClockInterface|null $clock = null, ) { } @@ -37,13 +40,24 @@ public function createTotpForUser(TwoFactorInterface $user): TOTPInterface throw new TwoFactorProviderLogicException('Cannot initialize TOTP, no secret code provided.'); } - /** @psalm-suppress ArgumentTypeCoercion */ - $totp = TOTP::create( - $secret, - $totpConfiguration->getPeriod(), - $totpConfiguration->getAlgorithm(), - $totpConfiguration->getDigits(), - ); + if ((new ReflectionClass(TOTP::class))->hasProperty('clock')) { + /** @psalm-suppress ArgumentTypeCoercion */ + $totp = TOTP::create( + $secret, + $totpConfiguration->getPeriod(), + $totpConfiguration->getAlgorithm(), + $totpConfiguration->getDigits(), + clock: $this->clock, + ); + } else { + /** @psalm-suppress ArgumentTypeCoercion */ + $totp = TOTP::create( + $secret, + $totpConfiguration->getPeriod(), + $totpConfiguration->getAlgorithm(), + $totpConfiguration->getDigits(), + ); + } $userAndHost = $user->getTotpAuthenticationUsername().(null !== $this->server && $this->server ? '@'.$this->server : ''); $totp->setLabel($userAndHost);