app/Customize/Controller/AuthController.php line 121

Open in your IDE?
  1. <?php
  2. namespace Customize\Controller;
  3. use Eccube\Form\Type\Front\CustomerLoginType;
  4. use Eccube\Repository\NewsRepository;
  5. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
  6. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
  7. use Symfony\Component\HttpFoundation\Response;
  8. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  9. use Symfony\Component\HttpFoundation\Request;
  10. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  11. use Eccube\Event\EventArgs;
  12. use Eccube\Entity\Customer;
  13. use Eccube\Event\EccubeEvents;
  14. use Eccube\Controller\AbstractController;
  15. use Eccube\Repository\CustomerRepository;
  16. use Eccube\Form\Type\Front\EntryType;
  17. use Eccube\Repository\PageRepository;
  18. use Eccube\Service\MailService;
  19. use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
  20. use Eccube\Repository\BaseInfoRepository;
  21. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  22. use Symfony\Component\Validator\Validator\ValidatorInterface;
  23. use Eccube\Entity\Master\CustomerStatus;
  24. use Eccube\Service\CartService;
  25. use Eccube\Repository\Master\CustomerStatusRepository;
  26. use Symfony\Component\Validator\Constraints as Assert;
  27. use Symfony\Component\HttpKernel\Exception as HttpException;
  28. use Eccube\Form\Type\Front\ForgotType;
  29. use Eccube\Form\Type\Front\PasswordResetType;
  30. use Exception;
  31. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  32. class AuthController extends AbstractController
  33. {
  34.   /**
  35.    * @var CustomerRepository
  36.    */
  37.   protected $customerRepository;
  38.   /**
  39.    * @var PageRepository
  40.    */
  41.   protected $pageRepository;
  42.   /**
  43.    * @var EncoderFactoryInterface
  44.    */
  45.   protected $encoderFactory;
  46.   /**
  47.    * @var CustomerStatusRepository
  48.    */
  49.   protected $customerStatusRepository;
  50.   /**
  51.    * @var BaseInfo
  52.    */
  53.   protected $BaseInfo;
  54.   /**
  55.    * @var MailService
  56.    */
  57.   protected $mailService;
  58.   /**
  59.    * @var \Eccube\Service\CartService
  60.    */
  61.   protected $cartService;
  62.   /**
  63.    * @var ValidatorInterface
  64.    */
  65.   protected $recursiveValidator;
  66.   /**
  67.    * @var TokenStorageInterface
  68.    */
  69.   protected $tokenStorage;
  70.   public function __construct(
  71.     CustomerRepository $customerRepository,
  72.     PageRepository $pageRepository,
  73.     BaseInfoRepository $baseInfoRepository,
  74.     MailService $mailService,
  75.     EncoderFactoryInterface $encoderFactory,
  76.     ValidatorInterface $validatorInterface,
  77.     CartService $cartService,
  78.     CustomerStatusRepository $customerStatusRepository,
  79.     TokenStorageInterface $tokenStorage
  80.   ) {
  81.     $this->BaseInfo $baseInfoRepository->get();
  82.     $this->customerRepository $customerRepository;
  83.     $this->pageRepository $pageRepository;
  84.     $this->encoderFactory $encoderFactory;
  85.     $this->mailService $mailService;
  86.     $this->recursiveValidator $validatorInterface;
  87.     $this->cartService $cartService;
  88.     $this->customerStatusRepository $customerStatusRepository;
  89.     $this->tokenStorage $tokenStorage;
  90.   }
  91.   /**
  92.    * @Route("/mypage-login", name="mypage-login", methods={"GET", "POST"})
  93.    * @Template("@user_data/auth/mypage_login.twig")
  94.    */
  95.   public function login(Request $requestAuthenticationUtils $utils)
  96.   {
  97.     if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
  98.       log_info('認証済のためログイン処理をスキップ');
  99.       return $this->redirectToRoute('mypage_index');
  100.     }
  101.     /* @var $form \Symfony\Component\Form\FormInterface */
  102.     $builder $this->formFactory
  103.       ->createNamedBuilder(''CustomerLoginType::class);
  104.     $builder->get('login_memory')->setData((bool) $request->getSession()->get('_security.login_memory'));
  105.     if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
  106.       $Customer $this->getUser();
  107.       if ($Customer instanceof Customer) {
  108.         $builder->get('login_email')
  109.           ->setData($Customer->getEmail());
  110.       }
  111.     }
  112.     $event = new EventArgs(
  113.       [
  114.         'builder' => $builder,
  115.       ],
  116.       $request
  117.     );
  118.     $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_MYPAGE_MYPAGE_LOGIN_INITIALIZE);
  119.     $form $builder->getForm();
  120.     $this->tokenStorage->setToken(null);
  121.     return [
  122.       'error' => $utils->getLastAuthenticationError(false),
  123.       'form' => $form->createView(),
  124.     ];
  125.   }
  126.   /**
  127.    * Logout
  128.    *
  129.    * @Route("/customer_logout", name="customer_logout", methods={"GET"})
  130.    */
  131.   public function logout()
  132.   {
  133.       if ($this->tokenStorage->getToken() && $this->tokenStorage->getToken()->getUser() instanceof Customer) {
  134.           $this->tokenStorage->setToken(null);
  135.           
  136.           return $this->redirectToRoute('homepage');
  137.       }
  138.   }
  139.   /**
  140.    * 会員登録画面.
  141.    *
  142.    * @Route("/register", name="register", methods={"GET", "POST"})
  143.    * @Route("/register", name="register_confirm", methods={"GET", "POST"})
  144.    * @Template("@user_data/auth/mypage_register.twig")
  145.    */
  146.   public function index(Request $request)
  147.   {
  148.     if ($this->isGranted('ROLE_USER')) {
  149.       log_info('認証済のためログイン処理をスキップ');
  150.       return $this->redirectToRoute('mypage_index');
  151.     }
  152.     /** @var $Customer \Eccube\Entity\Customer */
  153.     $Customer $this->customerRepository->newCustomer();
  154.     /* @var $builder \Symfony\Component\Form\FormBuilderInterface */
  155.     $builder $this->formFactory->createBuilder(EntryType::class, $Customer);
  156.     $event = new EventArgs(
  157.       [
  158.         'builder' => $builder,
  159.         'Customer' => $Customer,
  160.       ],
  161.       $request
  162.     );
  163.     $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_ENTRY_INDEX_INITIALIZE);
  164.     /* @var $form \Symfony\Component\Form\FormInterface */
  165.     $form $builder->getForm();
  166.     $form->handleRequest($request);
  167.     if ($form->isSubmitted() && $form->isValid()) {
  168.       $mailmagaFlg $form->get('mailmaga_flg')->getData() ? 0;
  169.       $Customer->setMailmagaFlg($mailmagaFlg);
  170.       switch ($request->get('mode')) {
  171.         case 'confirm':
  172.           log_info('会員登録確認開始');
  173.           log_info('会員登録確認完了');
  174.           return $this->render(
  175.             '@user_data/auth/mypage_register_confirm.twig',
  176.             [
  177.               'form' => $form->createView(),
  178.               'Page' => $this->pageRepository->getPageByRoute('register_confirm'),
  179.             ]
  180.           );
  181.         case 'complete':
  182.           log_info('会員登録開始');
  183.           $encoder $this->encoderFactory->getEncoder($Customer);
  184.           $salt $encoder->createSalt();
  185.           $password $encoder->encodePassword($Customer->getPlainPassword(), $salt);
  186.           $secretKey $this->customerRepository->getUniqueSecretKey();
  187.           $Customer
  188.             ->setSalt($salt)
  189.             ->setPassword($password)
  190.             ->setSecretKey($secretKey)
  191.             ->setPoint(0);
  192.           $this->entityManager->persist($Customer);
  193.           $this->entityManager->flush();
  194.           log_info('会員登録完了');
  195.           $event = new EventArgs(
  196.             [
  197.               'form' => $form,
  198.               'Customer' => $Customer,
  199.             ],
  200.             $request
  201.           );
  202.           $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_ENTRY_INDEX_COMPLETE);
  203.           $activateFlg $this->BaseInfo->isOptionCustomerActivate();
  204.           // 仮会員設定が有効な場合は、確認メールを送信し完了画面表示.
  205.           if ($activateFlg) {
  206.             $activateUrl $this->generateUrl('register_activate', ['secret_key' => $Customer->getSecretKey()], UrlGeneratorInterface::ABSOLUTE_URL);
  207.             // メール送信
  208.             $this->mailService->sendCustomerConfirmMail($Customer$activateUrl);
  209.             if ($event->hasResponse()) {
  210.               return $event->getResponse();
  211.             }
  212.             log_info('仮会員登録完了画面へリダイレクト');
  213.             return $this->redirectToRoute('register_complete');
  214.           } else {
  215.             // 仮会員設定が無効な場合は、会員登録を完了させる.
  216.             $qtyInCart $this->entryActivate($request$Customer->getSecretKey());
  217.             // URLを変更するため完了画面にリダイレクト
  218.             return $this->redirectToRoute('register_activate', [
  219.               'secret_key' => $Customer->getSecretKey(),
  220.               'qtyInCart' => $qtyInCart,
  221.             ]);
  222.           }
  223.       }
  224.     }
  225.     return [
  226.       'form' => $form->createView(),
  227.     ];
  228.   }
  229.   /**
  230.    * 会員登録完了画面.
  231.    *
  232.    * @Route("/register/complete", name="register_complete", methods={"GET"})
  233.    * @Template("@user_data/auth/mypage_register_complete.twig")
  234.    */
  235.   public function register_complete()
  236.   {
  237.     return [];
  238.   }
  239.   /**
  240.    * 会員のアクティベート(本会員化)を行う.
  241.    *
  242.    * @Route("/register/activate/{secret_key}/{qtyInCart}", name="register_activate", methods={"GET"})
  243.    * @Template("@user_data/auth/mypage_register_activate.twig")
  244.    */
  245.   public function activate(Request $request$secret_key$qtyInCart null)
  246.   {
  247.     $errors $this->recursiveValidator->validate(
  248.       $secret_key,
  249.       [
  250.         new Assert\NotBlank(),
  251.         new Assert\Regex(
  252.           [
  253.             'pattern' => '/^[a-zA-Z0-9]+$/',
  254.           ]
  255.         ),
  256.       ]
  257.     );
  258.     if (!$this->session->has('eccube.login.target.path')) {
  259.       $this->setLoginTargetPath($this->generateUrl('mypage', [], UrlGeneratorInterface::ABSOLUTE_URL));
  260.     }
  261.     if (!is_null($qtyInCart)) {
  262.       return [
  263.         'qtyInCart' => $qtyInCart,
  264.       ];
  265.     } elseif ($request->getMethod() === 'GET' && count($errors) === 0) {
  266.       // 会員登録処理を行う
  267.       try {
  268.         $qtyInCart $this->entryActivate($request$secret_key);
  269.         return [
  270.           'qtyInCart' => $qtyInCart,
  271.         ];
  272.       } catch(Exception $e) {
  273.         return $this->redirectToRoute('homepage');
  274.       }
  275.     }
  276.     throw new HttpException\NotFoundHttpException();
  277.   }
  278.   /**
  279.    * 会員登録処理を行う
  280.    *
  281.    * @param Request $request
  282.    * @param $secret_key
  283.    *
  284.    * @return \Eccube\Entity\Cart|mixed
  285.    */
  286.   private function entryActivate(Request $request$secret_key)
  287.   {
  288.     log_info('本会員登録開始');
  289.     $Customer $this->customerRepository->getProvisionalCustomerBySecretKey($secret_key);
  290.     if (is_null($Customer)) {
  291.       throw new HttpException\NotFoundHttpException();
  292.     }
  293.     $CustomerStatus $this->customerStatusRepository->find(CustomerStatus::REGULAR);
  294.     $Customer->setStatus($CustomerStatus);
  295.     $this->entityManager->persist($Customer);
  296.     $this->entityManager->flush();
  297.     log_info('本会員登録完了');
  298.     $event = new EventArgs(
  299.       [
  300.         'Customer' => $Customer,
  301.       ],
  302.       $request
  303.     );
  304.     $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_ENTRY_ACTIVATE_COMPLETE);
  305.     // メール送信
  306.     $this->mailService->sendCustomerCompleteMail($Customer);
  307.     // Assign session carts into customer carts
  308.     $Carts $this->cartService->getCarts();
  309.     $qtyInCart 0;
  310.     foreach ($Carts as $Cart) {
  311.       $qtyInCart += $Cart->getTotalQuantity();
  312.     }
  313.     if ($qtyInCart) {
  314.       $this->cartService->save();
  315.     }
  316.     return $qtyInCart;
  317.   }
  318.   /**
  319.    * パスワードリマインダ.
  320.    *
  321.    * @Route("/forgot_password", name="forgot_password", methods={"GET", "POST"})
  322.    * @Template("@user_data/auth/mypage_forgot_password.twig")
  323.    */
  324.   public function forgot(Request $request)
  325.   {
  326.     if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
  327.       throw new HttpException\NotFoundHttpException();
  328.     }
  329.     $builder $this->formFactory
  330.       ->createNamedBuilder(''ForgotType::class);
  331.     $event = new EventArgs(
  332.       [
  333.         'builder' => $builder,
  334.       ],
  335.       $request
  336.     );
  337.     $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_FORGOT_INDEX_INITIALIZE);
  338.     $form $builder->getForm();
  339.     $form->handleRequest($request);
  340.     if ($form->isSubmitted() && $form->isValid()) {
  341.       $Customer $this->customerRepository
  342.         ->getRegularCustomerByEmail($form->get('login_email')->getData());
  343.       if (!is_null($Customer)) {
  344.         // リセットキーの発行・有効期限の設定
  345.         $Customer
  346.           ->setResetKey($this->customerRepository->getUniqueResetKey())
  347.           ->setResetExpire(new \DateTime('+' $this->eccubeConfig['eccube_customer_reset_expire'] . ' min'));
  348.         // リセットキーを更新
  349.         $this->entityManager->persist($Customer);
  350.         $this->entityManager->flush();
  351.         $event = new EventArgs(
  352.           [
  353.             'form' => $form,
  354.             'Customer' => $Customer,
  355.           ],
  356.           $request
  357.         );
  358.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_FORGOT_INDEX_COMPLETE);
  359.         // 完了URLの生成
  360.         $reset_url $this->generateUrl('forgot_password_reset', ['reset_key' => $Customer->getResetKey()], UrlGeneratorInterface::ABSOLUTE_URL);
  361.         // メール送信
  362.         $this->mailService->sendPasswordResetNotificationMail($Customer$reset_url);
  363.         // ログ出力
  364.         log_info('send reset password mail to:' "{$Customer->getId()} {$Customer->getEmail()} {$request->getClientIp()}");
  365.       } else {
  366.         log_warning(
  367.           'Un active customer try send reset password email: ',
  368.           ['Enter email' => $form->get('login_email')->getData()]
  369.         );
  370.       }
  371.       return $this->redirectToRoute('forgot_password_complete');
  372.     }
  373.     return [
  374.       'form' => $form->createView(),
  375.     ];
  376.   }
  377.   /**
  378.    * 再設定URL送信完了画面.
  379.    *
  380.    * @Route("/forgot_password/complete", name="forgot_password_complete", methods={"GET"})
  381.    * @Template("@user_data/auth/forgot_password_complete.twig")
  382.    */
  383.   public function complete(Request $request)
  384.   {
  385.     if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
  386.       throw new HttpException\NotFoundHttpException();
  387.     }
  388.     return [];
  389.   }
  390.   /**
  391.    * パスワード再発行実行画面.
  392.    *
  393.    * @Route("/forgot_password/reset/{reset_key}", name="forgot_password_reset", methods={"GET", "POST"})
  394.    * @Template("@user_data/auth/mypage_reset_password.twig")
  395.    */
  396.   public function reset(Request $request$reset_key)
  397.   {
  398.     if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
  399.       throw new HttpException\NotFoundHttpException();
  400.     }
  401.     $errors $this->recursiveValidator->validate(
  402.       $reset_key,
  403.       [
  404.         new Assert\NotBlank(),
  405.         new Assert\Regex(
  406.           [
  407.             'pattern' => '/^[a-zA-Z0-9]+$/',
  408.           ]
  409.         ),
  410.       ]
  411.     );
  412.     if (count($errors) > 0) {
  413.       // リセットキーに異常がある場合
  414.       throw new HttpException\NotFoundHttpException();
  415.     }
  416.     $Customer $this->customerRepository
  417.       ->getRegularCustomerByResetKey($reset_key);
  418.     if (null === $Customer) {
  419.       // リセットキーから会員データが取得できない場合
  420.       throw new HttpException\NotFoundHttpException();
  421.     }
  422.     $builder $this->formFactory
  423.       ->createNamedBuilder(''PasswordResetType::class);
  424.     $form $builder->getForm();
  425.     $form->handleRequest($request);
  426.     $error null;
  427.     if ($form->isSubmitted() && $form->isValid()) {
  428.       // リセットキー・入力メールアドレスで会員情報検索
  429.       $Customer $this->customerRepository
  430.         ->getRegularCustomerByResetKey($reset_key$form->get('login_email')->getData());
  431.       if ($Customer) {
  432.         // パスワードの発行・更新
  433.         $encoder $this->encoderFactory->getEncoder($Customer);
  434.         $pass $form->get('password')->getData();
  435.         $Customer->setPassword($pass);
  436.         // 発行したパスワードの暗号化
  437.         if ($Customer->getSalt() === null) {
  438.           $Customer->setSalt($this->encoderFactory->getEncoder($Customer)->createSalt());
  439.         }
  440.         $encPass $encoder->encodePassword($pass$Customer->getSalt());
  441.         // パスワードを更新
  442.         $Customer->setPassword($encPass);
  443.         // リセットキーをクリア
  444.         $Customer->setResetKey(null);
  445.         // パスワードを更新
  446.         $this->entityManager->persist($Customer);
  447.         $this->entityManager->flush();
  448.         $event = new EventArgs(
  449.           [
  450.             'Customer' => $Customer,
  451.           ],
  452.           $request
  453.         );
  454.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_FORGOT_RESET_COMPLETE);
  455.         // 完了メッセージを設定
  456.         $this->addFlash('password_reset_complete'trans('front.forgot.reset_complete'));
  457.         // ログインページへリダイレクト
  458.         return $this->redirectToRoute('mypage-login');
  459.       } else {
  460.         // リセットキー・メールアドレスから会員データが取得できない場合
  461.         $error trans('front.forgot.reset_not_found');
  462.       }
  463.     }
  464.     return [
  465.       'error' => $error,
  466.       'form' => $form->createView(),
  467.     ];
  468.   }
  469. }