app/Customize/Controller/AuthController.php line 139

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 $request, AuthenticationUtils $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($event, EccubeEvents::FRONT_MYPAGE_MYPAGE_LOGIN_INITIALIZE);
  119. $form = $builder->getForm();
  120. return [
  121. 'error' => $utils->getLastAuthenticationError(false),
  122. 'form' => $form->createView(),
  123. ];
  124. }
  125. /**
  126. * Logout
  127. *
  128. * @Route("/customer_logout", name="customer_logout", methods={"GET"})
  129. */
  130. public function logout()
  131. {
  132. if ($this->tokenStorage->getToken() && $this->tokenStorage->getToken()->getUser() instanceof Customer) {
  133. $this->tokenStorage->setToken(null);
  134. return $this->redirectToRoute('homepage');
  135. }
  136. }
  137. /**
  138. * 会員登録画面.
  139. *
  140. * @Route("/register", name="register", methods={"GET", "POST"})
  141. * @Route("/register", name="register_confirm", methods={"GET", "POST"})
  142. * @Template("@user_data/auth/mypage_register.twig")
  143. */
  144. public function index(Request $request)
  145. {
  146. if ($this->isGranted('ROLE_USER')) {
  147. log_info('認証済のためログイン処理をスキップ');
  148. return $this->redirectToRoute('mypage_index');
  149. }
  150. /** @var $Customer \Eccube\Entity\Customer */
  151. $Customer = $this->customerRepository->newCustomer();
  152. /* @var $builder \Symfony\Component\Form\FormBuilderInterface */
  153. $builder = $this->formFactory->createBuilder(EntryType::class, $Customer);
  154. $event = new EventArgs(
  155. [
  156. 'builder' => $builder,
  157. 'Customer' => $Customer,
  158. ],
  159. $request
  160. );
  161. $this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_ENTRY_INDEX_INITIALIZE);
  162. /* @var $form \Symfony\Component\Form\FormInterface */
  163. $form = $builder->getForm();
  164. $form->handleRequest($request);
  165. if ($form->isSubmitted() && $form->isValid()) {
  166. $mailmagaFlg = $form->get('mailmaga_flg')->getData() ? 1 : 0;
  167. $Customer->setMailmagaFlg($mailmagaFlg);
  168. switch ($request->get('mode')) {
  169. case 'confirm':
  170. log_info('会員登録確認開始');
  171. log_info('会員登録確認完了');
  172. return $this->render(
  173. '@user_data/auth/mypage_register_confirm.twig',
  174. [
  175. 'form' => $form->createView(),
  176. 'Page' => $this->pageRepository->getPageByRoute('register_confirm'),
  177. ]
  178. );
  179. case 'complete':
  180. log_info('会員登録開始');
  181. $encoder = $this->encoderFactory->getEncoder($Customer);
  182. $salt = $encoder->createSalt();
  183. $password = $encoder->encodePassword($Customer->getPlainPassword(), $salt);
  184. $secretKey = $this->customerRepository->getUniqueSecretKey();
  185. $Customer
  186. ->setSalt($salt)
  187. ->setPassword($password)
  188. ->setSecretKey($secretKey)
  189. ->setPoint(0);
  190. $this->entityManager->persist($Customer);
  191. $this->entityManager->flush();
  192. log_info('会員登録完了');
  193. $event = new EventArgs(
  194. [
  195. 'form' => $form,
  196. 'Customer' => $Customer,
  197. ],
  198. $request
  199. );
  200. $this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_ENTRY_INDEX_COMPLETE);
  201. $activateFlg = $this->BaseInfo->isOptionCustomerActivate();
  202. // 仮会員設定が有効な場合は、確認メールを送信し完了画面表示.
  203. if ($activateFlg) {
  204. $activateUrl = $this->generateUrl('register_activate', ['secret_key' => $Customer->getSecretKey()], UrlGeneratorInterface::ABSOLUTE_URL);
  205. // メール送信
  206. $this->mailService->sendCustomerConfirmMail($Customer, $activateUrl);
  207. if ($event->hasResponse()) {
  208. return $event->getResponse();
  209. }
  210. log_info('仮会員登録完了画面へリダイレクト');
  211. return $this->redirectToRoute('register_complete');
  212. } else {
  213. // 仮会員設定が無効な場合は、会員登録を完了させる.
  214. $qtyInCart = $this->entryActivate($request, $Customer->getSecretKey());
  215. // URLを変更するため完了画面にリダイレクト
  216. return $this->redirectToRoute('register_activate', [
  217. 'secret_key' => $Customer->getSecretKey(),
  218. 'qtyInCart' => $qtyInCart,
  219. ]);
  220. }
  221. }
  222. }
  223. return [
  224. 'form' => $form->createView(),
  225. ];
  226. }
  227. /**
  228. * 会員登録完了画面.
  229. *
  230. * @Route("/register/complete", name="register_complete", methods={"GET"})
  231. * @Template("@user_data/auth/mypage_register_complete.twig")
  232. */
  233. public function register_complete()
  234. {
  235. return [];
  236. }
  237. /**
  238. * 会員のアクティベート(本会員化)を行う.
  239. *
  240. * @Route("/register/activate/{secret_key}/{qtyInCart}", name="register_activate", methods={"GET"})
  241. * @Template("@user_data/auth/mypage_register_activate.twig")
  242. */
  243. public function activate(Request $request, $secret_key, $qtyInCart = null)
  244. {
  245. $errors = $this->recursiveValidator->validate(
  246. $secret_key,
  247. [
  248. new Assert\NotBlank(),
  249. new Assert\Regex(
  250. [
  251. 'pattern' => '/^[a-zA-Z0-9]+$/',
  252. ]
  253. ),
  254. ]
  255. );
  256. if (!$this->session->has('eccube.login.target.path')) {
  257. $this->setLoginTargetPath($this->generateUrl('mypage', [], UrlGeneratorInterface::ABSOLUTE_URL));
  258. }
  259. if (!is_null($qtyInCart)) {
  260. return [
  261. 'qtyInCart' => $qtyInCart,
  262. ];
  263. } elseif ($request->getMethod() === 'GET' && count($errors) === 0) {
  264. // 会員登録処理を行う
  265. try {
  266. $qtyInCart = $this->entryActivate($request, $secret_key);
  267. return [
  268. 'qtyInCart' => $qtyInCart,
  269. ];
  270. } catch(Exception $e) {
  271. return $this->redirectToRoute('homepage');
  272. }
  273. }
  274. throw new HttpException\NotFoundHttpException();
  275. }
  276. /**
  277. * 会員登録処理を行う
  278. *
  279. * @param Request $request
  280. * @param $secret_key
  281. *
  282. * @return \Eccube\Entity\Cart|mixed
  283. */
  284. private function entryActivate(Request $request, $secret_key)
  285. {
  286. log_info('本会員登録開始');
  287. $Customer = $this->customerRepository->getProvisionalCustomerBySecretKey($secret_key);
  288. if (is_null($Customer)) {
  289. throw new HttpException\NotFoundHttpException();
  290. }
  291. $CustomerStatus = $this->customerStatusRepository->find(CustomerStatus::REGULAR);
  292. $Customer->setStatus($CustomerStatus);
  293. $this->entityManager->persist($Customer);
  294. $this->entityManager->flush();
  295. log_info('本会員登録完了');
  296. $event = new EventArgs(
  297. [
  298. 'Customer' => $Customer,
  299. ],
  300. $request
  301. );
  302. $this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_ENTRY_ACTIVATE_COMPLETE);
  303. // メール送信
  304. $this->mailService->sendCustomerCompleteMail($Customer);
  305. // Assign session carts into customer carts
  306. $Carts = $this->cartService->getCarts();
  307. $qtyInCart = 0;
  308. foreach ($Carts as $Cart) {
  309. $qtyInCart += $Cart->getTotalQuantity();
  310. }
  311. if ($qtyInCart) {
  312. $this->cartService->save();
  313. }
  314. return $qtyInCart;
  315. }
  316. /**
  317. * パスワードリマインダ.
  318. *
  319. * @Route("/forgot_password", name="forgot_password", methods={"GET", "POST"})
  320. * @Template("@user_data/auth/mypage_forgot_password.twig")
  321. */
  322. public function forgot(Request $request)
  323. {
  324. if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
  325. throw new HttpException\NotFoundHttpException();
  326. }
  327. $builder = $this->formFactory
  328. ->createNamedBuilder('', ForgotType::class);
  329. $event = new EventArgs(
  330. [
  331. 'builder' => $builder,
  332. ],
  333. $request
  334. );
  335. $this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_FORGOT_INDEX_INITIALIZE);
  336. $form = $builder->getForm();
  337. $form->handleRequest($request);
  338. if ($form->isSubmitted() && $form->isValid()) {
  339. $Customer = $this->customerRepository
  340. ->getRegularCustomerByEmail($form->get('login_email')->getData());
  341. if (!is_null($Customer)) {
  342. // リセットキーの発行・有効期限の設定
  343. $Customer
  344. ->setResetKey($this->customerRepository->getUniqueResetKey())
  345. ->setResetExpire(new \DateTime('+' . $this->eccubeConfig['eccube_customer_reset_expire'] . ' min'));
  346. // リセットキーを更新
  347. $this->entityManager->persist($Customer);
  348. $this->entityManager->flush();
  349. $event = new EventArgs(
  350. [
  351. 'form' => $form,
  352. 'Customer' => $Customer,
  353. ],
  354. $request
  355. );
  356. $this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_FORGOT_INDEX_COMPLETE);
  357. // 完了URLの生成
  358. $reset_url = $this->generateUrl('forgot_password_reset', ['reset_key' => $Customer->getResetKey()], UrlGeneratorInterface::ABSOLUTE_URL);
  359. // メール送信
  360. $this->mailService->sendPasswordResetNotificationMail($Customer, $reset_url);
  361. // ログ出力
  362. log_info('send reset password mail to:' . "{$Customer->getId()} {$Customer->getEmail()} {$request->getClientIp()}");
  363. } else {
  364. log_warning(
  365. 'Un active customer try send reset password email: ',
  366. ['Enter email' => $form->get('login_email')->getData()]
  367. );
  368. }
  369. return $this->redirectToRoute('forgot_password_complete');
  370. }
  371. return [
  372. 'form' => $form->createView(),
  373. ];
  374. }
  375. /**
  376. * 再設定URL送信完了画面.
  377. *
  378. * @Route("/forgot_password/complete", name="forgot_password_complete", methods={"GET"})
  379. * @Template("@user_data/auth/forgot_password_complete.twig")
  380. */
  381. public function complete(Request $request)
  382. {
  383. if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
  384. throw new HttpException\NotFoundHttpException();
  385. }
  386. return [];
  387. }
  388. /**
  389. * パスワード再発行実行画面.
  390. *
  391. * @Route("/forgot_password/reset/{reset_key}", name="forgot_password_reset", methods={"GET", "POST"})
  392. * @Template("@user_data/auth/mypage_reset_password.twig")
  393. */
  394. public function reset(Request $request, $reset_key)
  395. {
  396. if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
  397. throw new HttpException\NotFoundHttpException();
  398. }
  399. $errors = $this->recursiveValidator->validate(
  400. $reset_key,
  401. [
  402. new Assert\NotBlank(),
  403. new Assert\Regex(
  404. [
  405. 'pattern' => '/^[a-zA-Z0-9]+$/',
  406. ]
  407. ),
  408. ]
  409. );
  410. if (count($errors) > 0) {
  411. // リセットキーに異常がある場合
  412. throw new HttpException\NotFoundHttpException();
  413. }
  414. $Customer = $this->customerRepository
  415. ->getRegularCustomerByResetKey($reset_key);
  416. if (null === $Customer) {
  417. // リセットキーから会員データが取得できない場合
  418. throw new HttpException\NotFoundHttpException();
  419. }
  420. $builder = $this->formFactory
  421. ->createNamedBuilder('', PasswordResetType::class);
  422. $form = $builder->getForm();
  423. $form->handleRequest($request);
  424. $error = null;
  425. if ($form->isSubmitted() && $form->isValid()) {
  426. // リセットキー・入力メールアドレスで会員情報検索
  427. $Customer = $this->customerRepository
  428. ->getRegularCustomerByResetKey($reset_key, $form->get('login_email')->getData());
  429. if ($Customer) {
  430. // パスワードの発行・更新
  431. $encoder = $this->encoderFactory->getEncoder($Customer);
  432. $pass = $form->get('password')->getData();
  433. $Customer->setPassword($pass);
  434. // 発行したパスワードの暗号化
  435. if ($Customer->getSalt() === null) {
  436. $Customer->setSalt($this->encoderFactory->getEncoder($Customer)->createSalt());
  437. }
  438. $encPass = $encoder->encodePassword($pass, $Customer->getSalt());
  439. // パスワードを更新
  440. $Customer->setPassword($encPass);
  441. // リセットキーをクリア
  442. $Customer->setResetKey(null);
  443. // パスワードを更新
  444. $this->entityManager->persist($Customer);
  445. $this->entityManager->flush();
  446. $event = new EventArgs(
  447. [
  448. 'Customer' => $Customer,
  449. ],
  450. $request
  451. );
  452. $this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_FORGOT_RESET_COMPLETE);
  453. // 完了メッセージを設定
  454. $this->addFlash('password_reset_complete', trans('front.forgot.reset_complete'));
  455. // ログインページへリダイレクト
  456. return $this->redirectToRoute('mypage-login');
  457. } else {
  458. // リセットキー・メールアドレスから会員データが取得できない場合
  459. $error = trans('front.forgot.reset_not_found');
  460. }
  461. }
  462. return [
  463. 'error' => $error,
  464. 'form' => $form->createView(),
  465. ];
  466. }
  467. }