vendor/scheb/2fa-bundle/Security/Http/EventListener/AbstractCheckCodeListener.php line 29

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Scheb\TwoFactorBundle\Security\Http\EventListener;
  4. use Scheb\TwoFactorBundle\Security\Http\Authenticator\Passport\Credentials\TwoFactorCodeCredentials;
  5. use Scheb\TwoFactorBundle\Security\Http\Authenticator\Passport\TwoFactorPassport;
  6. use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\PreparationRecorderInterface;
  7. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  8. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  9. use Symfony\Component\Security\Http\Event\CheckPassportEvent;
  10. /**
  11.  * @internal
  12.  */
  13. abstract class AbstractCheckCodeListener implements EventSubscriberInterface
  14. {
  15.     /**
  16.      * @var PreparationRecorderInterface
  17.      */
  18.     private $preparationRecorder;
  19.     public function __construct(PreparationRecorderInterface $preparationRecorder)
  20.     {
  21.         $this->preparationRecorder $preparationRecorder;
  22.     }
  23.     public function checkPassport(CheckPassportEvent $event): void
  24.     {
  25.         $passport $event->getPassport();
  26.         if (!($passport instanceof TwoFactorPassport && $passport->hasBadge(TwoFactorCodeCredentials::class))) {
  27.             return;
  28.         }
  29.         /** @var TwoFactorCodeCredentials $credentialsBadge */
  30.         $credentialsBadge $passport->getBadge(TwoFactorCodeCredentials::class);
  31.         if ($credentialsBadge->isResolved()) {
  32.             return;
  33.         }
  34.         $token $passport->getTwoFactorToken();
  35.         $providerName $token->getCurrentTwoFactorProvider();
  36.         if (!$providerName) {
  37.             throw new AuthenticationException('There is no active two-factor provider.');
  38.         }
  39.         if (!$this->preparationRecorder->isTwoFactorProviderPrepared($token->getProviderKey(true), $providerName)) {
  40.             throw new AuthenticationException(sprintf('The two-factor provider "%s" has not been prepared.'$providerName));
  41.         }
  42.         $user $token->getUser();
  43.         if (null === $user) {
  44.             throw new \RuntimeException('Security token must provide a user.');
  45.         }
  46.         if ($this->isValidCode($providerName$user$credentialsBadge->getCode())) {
  47.             $token->setTwoFactorProviderComplete($providerName);
  48.             $credentialsBadge->markResolved();
  49.         }
  50.     }
  51.     /**
  52.      * @param object|string $user
  53.      */
  54.     abstract protected function isValidCode(string $providerName$userstring $code): bool;
  55. }