app/Plugin/AlwaysReCaptcha42/Event.php line 108

Open in your IDE?
  1. <?php
  2. namespace Plugin\AlwaysReCaptcha42;
  3. use Eccube\Common\Constant;
  4. use Eccube\Event\TemplateEvent;
  5. use Eccube\Form\Type\Admin\LoginType;
  6. use Customize\Form\Type\Front\CustomerLoginType;
  7. use Plugin\AlwaysReCaptcha42\Entity\Config;
  8. use Plugin\AlwaysReCaptcha42\Exception\TokenNotFoundException;
  9. use Plugin\AlwaysReCaptcha42\Exception\VerifyFailException;
  10. use Plugin\AlwaysReCaptcha42\Repository\ConfigRepository;
  11. use ReCaptcha\ReCaptcha;
  12. use ReCaptcha\RequestMethod\CurlPost;
  13. use ReCaptcha\RequestMethod\Post;
  14. use ReCaptcha\RequestMethod\SocketPost;
  15. use Symfony\Component\Form\FormFactoryInterface;
  16. use Symfony\Component\HttpFoundation\RedirectResponse;
  17. use Symfony\Component\HttpKernel\Event\RequestEvent;
  18. use Symfony\Component\HttpKernel\KernelEvents;
  19. use Symfony\Component\Security\Core\Security;
  20. use function Symfony\Component\Translation\t;
  21. class Event implements \Symfony\Component\EventDispatcher\EventSubscriberInterface
  22. {
  23.     /** @var ConfigRepository */
  24.     protected $configRepository;
  25.     /** @var FormFactoryInterface */
  26.     private $formFactory;
  27.     /**
  28.      * ConfigController constructor.
  29.      *
  30.      * @param ConfigRepository $configRepository
  31.      * @param FormFactoryInterface $formFactory
  32.      */
  33.     public function __construct(
  34.         ConfigRepository $configRepository,
  35.         FormFactoryInterface $formFactory
  36.     ) {
  37.         $this->configRepository $configRepository;
  38.         $this->formFactory $formFactory;
  39.     }
  40.     /**
  41.      * @inheritDoc
  42.      */
  43.     public static function getSubscribedEvents(): array
  44.     {
  45.         return [
  46.             'Entry/index.twig' => 'entryIndexTwig',
  47.             'Entry/confirm.twig' => 'entryConfirmTwig',
  48.             'Forgot/index.twig' => 'forgotIndexTwig',
  49.             'Contact/index.twig' => 'contactIndexTwig',
  50.             'Contact/confirm.twig' => 'contactConfirmTwig',
  51.             'Mypage/login.twig' => 'mypageLoginTwig',
  52.             'Shopping/index.twig' => 'shoppingIndexTwig',
  53.             'Shopping/confirm.twig' => 'shoppingConfirmTwig',
  54.             'Shopping/login.twig' => 'shoppingLoginTwig',
  55.             'Shopping/nonmember.twig' => 'shoppingNonMemberTwig',
  56.             KernelEvents::REQUEST => ['onKernelRequest'9],
  57.         ];
  58.     }
  59.     /**
  60.      * @param TemplateEvent $event
  61.      */
  62.     public function entryIndexTwig(TemplateEvent $event)
  63.     {
  64.         /** @var Config $Config */
  65.         $Config $this->configRepository->get();
  66.         if ($Config->isEnableEntry() && !empty($Config->getSiteKey()) && !empty($Config->getSecretKey())) {
  67.             $this->addReCaptchaSnippet($eventtrue$Config->getSiteKey(), $Config->isHideBadge(), 'entry_recaptcha_response''entry');
  68.         }
  69.     }
  70.     /**
  71.      * @param TemplateEvent $event
  72.      */
  73.     public function entryConfirmTwig(TemplateEvent $event)
  74.     {
  75.         /** @var Config $Config */
  76.         $Config $this->configRepository->get();
  77.         if ($Config->isEnableEntry() && !empty($Config->getSiteKey()) && !empty($Config->getSecretKey())) {
  78.             $this->addReCaptchaSnippet($eventtrue$Config->getSiteKey(), $Config->isHideBadge(), 'entry_recaptcha_response''entry');
  79.         }
  80.     }
  81.     /**
  82.      * @param TemplateEvent $event
  83.      */
  84.     public function forgotIndexTwig(TemplateEvent $event)
  85.     {
  86.         /** @var Config $Config */
  87.         $Config $this->configRepository->get();
  88.         if ($Config->isEnableForgot() && !empty($Config->getSiteKey()) && !empty($Config->getSecretKey())) {
  89.             $this->addReCaptchaSnippet($eventfalse$Config->getSiteKey(), $Config->isHideBadge(), 'form1''forgot');
  90.         }
  91.     }
  92.     /**
  93.      * @param TemplateEvent $event
  94.      */
  95.     public function contactIndexTwig(TemplateEvent $event)
  96.     {
  97.         /** @var Config $Config */
  98.         $Config $this->configRepository->get();
  99.         if ($Config->isEnableContact() && !empty($Config->getSiteKey()) && !empty($Config->getSecretKey())) {
  100.             $this->addReCaptchaSnippet($eventtrue$Config->getSiteKey(), $Config->isHideBadge(), 'contact_recaptcha_response''contact');
  101.         }
  102.     }
  103.     /**
  104.      * @param TemplateEvent $event
  105.      */
  106.     public function contactConfirmTwig(TemplateEvent $event)
  107.     {
  108.         /** @var Config $Config */
  109.         $Config $this->configRepository->get();
  110.         if ($Config->isEnableContact() && !empty($Config->getSiteKey()) && !empty($Config->getSecretKey())) {
  111.             $this->addReCaptchaSnippet($eventtrue$Config->getSiteKey(), $Config->isHideBadge(), 'contact_recaptcha_response''contact');
  112.         }
  113.     }
  114.     /**
  115.      * @param TemplateEvent $event
  116.      */
  117.     public function mypageLoginTwig(TemplateEvent $event)
  118.     {
  119.         /** @var Config $Config */
  120.         $Config $this->configRepository->get();
  121.         if ($Config->isEnableFrontLogin() && !empty($Config->getSiteKey()) && !empty($Config->getSecretKey())) {
  122.             $this->addReCaptchaSnippet($eventfalse$Config->getSiteKey(), $Config->isHideBadge(), 'login_mypage''login');
  123.         }
  124.     }
  125.     /**
  126.      * @param TemplateEvent $event
  127.      */
  128.     public function shoppingIndexTwig(TemplateEvent $event)
  129.     {
  130.         /** @var Config $Config */
  131.         $Config $this->configRepository->get();
  132.         if ($Config->isEnableShopping() && !empty($Config->getSiteKey()) && !empty($Config->getSecretKey())) {
  133.             $this->addReCaptchaSnippet($eventfalse$Config->getSiteKey(), $Config->isHideBadge(), 'shopping-form''shopping');
  134.         }
  135.     }
  136.     /**
  137.      * @param TemplateEvent $event
  138.      */
  139.     public function shoppingConfirmTwig(TemplateEvent $event)
  140.     {
  141.         /** @var Config $Config */
  142.         $Config $this->configRepository->get();
  143.         if ($Config->isEnableShopping() && !empty($Config->getSiteKey()) && !empty($Config->getSecretKey())) {
  144.             $this->addReCaptchaSnippet($eventfalse$Config->getSiteKey(), $Config->isHideBadge(), 'shopping-form''shopping');
  145.         }
  146.     }
  147.     /**
  148.      * @param TemplateEvent $event
  149.      */
  150.     public function shoppingLoginTwig(TemplateEvent $event)
  151.     {
  152.         /** @var Config $Config */
  153.         $Config $this->configRepository->get();
  154.         if ($Config->isEnableFrontLogin() && !empty($Config->getSiteKey()) && !empty($Config->getSecretKey())) {
  155.             $this->addReCaptchaSnippet($eventfalse$Config->getSiteKey(), $Config->isHideBadge(), 'shopping_login''login');
  156.         }
  157.     }
  158.     /**
  159.      * @param TemplateEvent $event
  160.      */
  161.     public function shoppingNonMemberTwig(TemplateEvent $event)
  162.     {
  163.         /** @var Config $Config */
  164.         $Config $this->configRepository->get();
  165.         if ($Config->isEnableNonMember() && !empty($Config->getSiteKey()) && !empty($Config->getSecretKey())) {
  166.             $event->addSnippet('@AlwaysReCaptcha42/Form/non_member_snippet.twig');
  167.             $event->setParameter('recaptcha_site_key'$Config->getSiteKey());
  168.             $event->setParameter('recaptcha_action''non_member');
  169.             if ($Config->isHideBadge()) {
  170.                 $event->addAsset('@AlwaysReCaptcha42/Form/hide_badge_asset.twig');
  171.             }
  172.         }
  173.     }
  174.     /**
  175.      * @param TemplateEvent $event
  176.      * @param bool $withConfirm
  177.      * @param string $siteKey
  178.      * @param bool $hideBadge
  179.      * @param string $formId
  180.      * @param string $action
  181.      */
  182.     private function addReCaptchaSnippet(
  183.         TemplateEvent $event,
  184.         bool $withConfirm,
  185.         string $siteKey,
  186.         bool $hideBadge,
  187.         string $formId,
  188.         string $action
  189.     ) {
  190.         if ($withConfirm) {
  191.             $event->addSnippet('@AlwaysReCaptcha42/Form/with_confirm_snippet.twig');
  192.             $event->setParameter('recaptcha_input_id'$formId);
  193.         } else {
  194.             $event->addSnippet('@AlwaysReCaptcha42/Form/no_confirm_snippet.twig');
  195.             $event->setParameter('recaptcha_form_id'$formId);
  196.         }
  197.         $event->setParameter('recaptcha_site_key'$siteKey);
  198.         $event->setParameter('recaptcha_action'$action);
  199.         if ($hideBadge) {
  200.             $event->addAsset('@AlwaysReCaptcha42/Form/hide_badge_asset.twig');
  201.         }
  202.     }
  203.     public function onKernelRequest(RequestEvent $event)
  204.     {
  205.         /** @var Config $Config */
  206.         $Config $this->configRepository->get();
  207.         $route $event->getRequest()->attributes->get('_route');
  208.         if (
  209.             'admin_login' === $route
  210.             && $Config->isEnableAdminLogin() && !empty($Config->getSiteKey()) && !empty($Config->getSecretKey())
  211.         ) {
  212.             $loginForm $this->formFactory->createNamed(''LoginType::class);
  213.             $loginForm->handleRequest($event->getRequest());
  214.             if (!$loginForm->isSubmitted()) {
  215.                 return;
  216.             }
  217.             $threshold $Config->getThresholdAdminLogin();
  218.             $userName $loginForm->get('login_id')->getData();
  219.         } elseif (
  220.             ('shopping_login' === $route || 'mypage_login' === $route)
  221.             && $Config->isEnableFrontLogin() && !empty($Config->getSiteKey()) && !empty($Config->getSecretKey())
  222.         ) {
  223.             $loginForm $this->formFactory->createNamed(''CustomerLoginType::class);
  224.             $loginForm->handleRequest($event->getRequest());
  225.             if (!$loginForm->isSubmitted()) {
  226.                 return;
  227.             }
  228.             $threshold $Config->getThreshold();
  229.             $userName $loginForm->get('login_email')->getData();
  230.         } else {
  231.             return;
  232.         }
  233.         $request $event->getRequest();
  234.         $session $request->getSession();
  235.         $recaptchaToken $loginForm->get('recaptcha_response')->getData();
  236.         if (empty($recaptchaToken)) {
  237.             $session->set(Security::AUTHENTICATION_ERROR, new TokenNotFoundException('Google reCAPTCHA Token is not set. Try again later or contact the site administrator.'));
  238.         } else {
  239.             switch ($Config->getRequestMethod()) {
  240.                 case Config::REQUEST_METHOD_CURL:
  241.                     $requestMethod = new CurlPost();
  242.                     break;
  243.                 case Config::REQUEST_METHOD_SOCKET:
  244.                     $requestMethod = new SocketPost();
  245.                     break;
  246.                 default:
  247.                     $requestMethod = new Post();
  248.                     break;
  249.             }
  250.             $recaptcha = new ReCaptcha($Config->getSecretKey(), $requestMethod);
  251.             $resp $recaptcha->setExpectedHostname($request->getHost())
  252.                 ->setExpectedAction('login')
  253.                 ->setScoreThreshold($threshold)
  254.                 ->verify($recaptchaToken$request->getClientIp());
  255.             if ($resp->isSuccess()) {
  256.                 if ($Config->getLogMode() == Config::LOG_MODE_ALL) {
  257.                     log_info('いつも reCAPTCHA 認証ログ', [$resp->toArray()]);
  258.                 }
  259.                 return;
  260.             }
  261.             $session->set(Security::AUTHENTICATION_ERROR, new VerifyFailException('Google reCAPTCHA verification is failed. Try again later or contact the site administrator.'));
  262.             log_warning('いつも reCAPTCHA 認証ログ', [$resp->toArray()]);
  263.         }
  264.         $session->set(Security::LAST_USERNAME$userName);
  265.         //to prevent request to call next event
  266.         $event->setResponse(new RedirectResponse($event->getRequest()->getRequestUri()));
  267.     }
  268. }