app/Plugin/TwoFactorAuthCustomer42/EventListener/CustomerPersonalValidationListener.php line 97

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of EC-CUBE
  4.  *
  5.  * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  6.  *
  7.  * http://www.ec-cube.co.jp/
  8.  *
  9.  * For the full copyright and license information, please view the LICENSE
  10.  * file that was distributed with this source code.
  11.  */
  12. namespace Plugin\TwoFactorAuthCustomer42\EventListener;
  13. use Eccube\Entity\BaseInfo;
  14. use Eccube\Repository\BaseInfoRepository;
  15. use Eccube\Repository\CustomerRepository;
  16. use Eccube\Request\Context;
  17. use Plugin\TwoFactorAuthCustomer42\Repository\TwoFactorAuthTypeRepository;
  18. use Plugin\TwoFactorAuthCustomer42\Service\CustomerTwoFactorAuthService;
  19. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  20. use Symfony\Component\HttpFoundation\RedirectResponse;
  21. use Symfony\Component\HttpFoundation\Session\Session;
  22. use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
  23. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  24. use Symfony\Component\HttpKernel\KernelEvents;
  25. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  26. class CustomerPersonalValidationListener implements EventSubscriberInterface
  27. {
  28.     /**
  29.      * アクティベーション
  30.      */
  31.     public const ACTIVATE_ROUTE 'entry_activate';
  32.     /**
  33.      * @var Context
  34.      */
  35.     protected $requestContext;
  36.     /**
  37.      * @var UrlGeneratorInterface
  38.      */
  39.     protected $router;
  40.     /**
  41.      * @var CustomerTwoFactorAuthService
  42.      */
  43.     protected $customerTwoFactorAuthService;
  44.     /**
  45.      * @var BaseInfoRepository
  46.      */
  47.     protected BaseInfoRepository $baseInfoRepository;
  48.     /**
  49.      * @var CustomerRepository
  50.      */
  51.     protected CustomerRepository $customerRepository;
  52.     /**
  53.      * @var BaseInfo|object|null
  54.      */
  55.     protected $baseInfo;
  56.     /**
  57.      * @param Context $requestContext
  58.      * @param UrlGeneratorInterface $router
  59.      * @param CustomerTwoFactorAuthService $customerTwoFactorAuthService
  60.      * @param BaseInfoRepository $baseInfoRepository
  61.      * @param CustomerRepository $customerRepository
  62.      */
  63.     public function __construct(
  64.         Context $requestContext,
  65.         UrlGeneratorInterface $router,
  66.         CustomerTwoFactorAuthService $customerTwoFactorAuthService,
  67.         BaseInfoRepository $baseInfoRepository,
  68.         CustomerRepository $customerRepository
  69.     ) {
  70.         $this->requestContext $requestContext;
  71.         $this->router $router;
  72.         $this->customerTwoFactorAuthService $customerTwoFactorAuthService;
  73.         $this->baseInfo $baseInfoRepository->find(1);
  74.         $this->customerRepository $customerRepository;
  75.     }
  76.     /**
  77.      * @return array
  78.      */
  79.     public static function getSubscribedEvents(): array
  80.     {
  81.         return [
  82.             KernelEvents::CONTROLLER_ARGUMENTS => ['onKernelController'7],
  83.         ];
  84.     }
  85.     /**
  86.      * リクエスト受信時イベントハンドラ.
  87.      *
  88.      * @param ControllerArgumentsEvent $event
  89.      */
  90.     public function onKernelController(ControllerArgumentsEvent $event)
  91.     {
  92.         if (!$event->isMainRequest()) {
  93.             // サブリクエストの場合、処理なし
  94.             return;
  95.         }
  96.         if ($this->requestContext->isAdmin()) {
  97.             // バックエンドURLの場合、処理なし
  98.             return;
  99.         }
  100.         if (
  101.             ($this->baseInfo->isOptionCustomerActivate() && !$this->baseInfo->isOptionActivateDevice())
  102.             ||
  103.             !$this->baseInfo->isOptionCustomerActivate()
  104.         ) {
  105.             // デバイス認証なし かつ 2段階認証使用しない場合は処理なし
  106.             return;
  107.         }
  108.         $route $event->getRequest()->attributes->get('_route');
  109.         if ($this->isActivationRoute($route)) {
  110.             // デバイス認証(アクティベーション前に介入)
  111.             $this->deviceAuth($event);
  112.         }
  113.     }
  114.     /**
  115.      * アクティベーションルートかチェック.
  116.      *
  117.      * @param string $route
  118.      *
  119.      * @return bool
  120.      */
  121.     private function isActivationRoute(string $route): bool
  122.     {
  123.         // ルートで認証
  124.         return $route === self::ACTIVATE_ROUTE;
  125.     }
  126.     /**
  127.      * デバイス認証.
  128.      *
  129.      * @param mixed $event
  130.      *
  131.      * @throws NotFoundHttpException
  132.      */
  133.     private function deviceAuth($event)
  134.     {
  135.         // アクティベーション
  136.         $secret_key $event->getRequest()->attributes->get('secret_key');
  137.         $Customer $this->customerRepository->getProvisionalCustomerBySecretKey($secret_key);
  138.         if (is_null($Customer)) {
  139.             throw new NotFoundHttpException();
  140.         }
  141.         if ($Customer->isDeviceAuthed()) {
  142.             return;
  143.         }
  144.         // デバイス認証されていない場合
  145.         if ($this->baseInfo->isOptionActivateDevice() && $this->baseInfo->isOptionCustomerActivate()) {
  146.             // 仮会員登録機能:有効 / SMSによる本人認証:有効の場合 デバイス認証画面へリダイレクト
  147.             $url $this->router->generate(
  148.                 'plg_customer_2fa_device_auth_send_onetime',
  149.                 ['secret_key' => $secret_key]
  150.             );
  151.             $event->setController(function () use ($url) {
  152.                 return new RedirectResponse($url302);
  153.             });
  154.         }
  155.     }
  156. }