src/Controller/AuthController.php line 116

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Data\User;
  4. use App\EventSubscriber\UserSecurityCheckSubscriber;
  5. use App\Form\LoginSecurityCheckType;
  6. use App\Form\RecoverPasswordNewType;
  7. use App\Form\RecoverPasswordRequestType;
  8. use App\Form\RegisterSecondType;
  9. use App\Form\RegisterThirdType;
  10. use App\Form\RegisterType;
  11. use App\Service\ActionAttemptManager;
  12. use App\Service\Emailer;
  13. use App\Service\Helper;
  14. use App\Service\SmsManager;
  15. use App\Service\UserManager;
  16. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  17. use Symfony\Component\Form\FormError;
  18. use Symfony\Component\HttpFoundation\Request;
  19. use Symfony\Component\HttpFoundation\Response;
  20. use Symfony\Component\Routing\Annotation\Route;
  21. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  22. use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
  23. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  24. use Symfony\Contracts\Translation\TranslatorInterface;
  25. class AuthController extends AbstractController
  26. {
  27.     /**
  28.      * @Route("/login", name="login")
  29.      */
  30.     public function login(AuthenticationUtils $authenticationUtilsRequest $requestActionAttemptManager $actionAttempt): Response
  31.     {
  32.         $actionAllowed $actionAttempt->isActionAllowed(ActionAttemptManager::ACTION_LOGIN);
  33.         $captchaRequired $actionAllowed === 'captcha';
  34.         if ($captchaRequired) {
  35.             $request->getSession()->set('captcha_whitelist_key', ['login']);
  36.         }
  37.         $error $authenticationUtils->getLastAuthenticationError();
  38.         $lastUsername $authenticationUtils->getLastUsername();
  39.         return $this->render('auth/login.html.twig', [
  40.             'last_username' => $lastUsername,
  41.             'error' => $error,
  42.             'captcha_key' => $captchaRequired 'login' null,
  43.             'login_blocked' => $actionAllowed === false
  44.         ]);
  45.     }
  46.     /**
  47.      * @Route("/login/security/check", name="login_security_check")
  48.      */
  49.     public function loginSecurityCheck(Request $requestActionAttemptManager $actionAttempt): Response
  50.     {
  51.         $actionAllowed $actionAttempt->isActionAllowed(ActionAttemptManager::ACTION_LOGIN);
  52.         $user $this->getUser();
  53.         $form $this->createForm(LoginSecurityCheckType::class, $user);
  54.         $form->handleRequest($request);
  55.         if ($form->isSubmitted() && $form->isValid()) {
  56.             $request->getSession()->set(UserSecurityCheckSubscriber::SESSION_KEYtrue);
  57.             return $this->redirectToRoute('home');
  58.         }
  59.         return $this->render('auth/loginSecurityCheck.html.twig', [
  60.             'form' => $form->createView(),
  61.             'login_blocked' => $actionAllowed === false
  62.         ]);
  63.     }
  64.     /**
  65.      * @Route("/register/email/resend/{email}/{code}", name="register_email_resend")
  66.      */
  67.     public function registerEmailResend(Request $requestActionAttemptManager $actionAttemptEmailer $emailerstring $emailstring $code): Response
  68.     {
  69.         $actionAllowed $actionAttempt->isActionAllowed(ActionAttemptManager::ACTION_LOGIN);
  70.         $em $this->getDoctrine()->getManager();
  71.         $email User::urlEmailDecode($email);
  72.         /** @var User $user */
  73.         $user $em->getRepository(User::class)->findOneBy([
  74.             'email' => $email,
  75.             'emailResendRequestCode' => $code,
  76.             'isEmailConfirmed' => false
  77.         ]);
  78.         $datNow = new \DateTime();
  79.         if ($user === null || $datNow $user->getEmailResendRequestCodeExpiryOn()) {
  80.             $this->addFlash('error''recover_password.token_wrong');
  81.             return $this->redirectToRoute('login');
  82.         }
  83.         $user->prepareEmailConfirmation();
  84.         $user->setEmailResendRequestCode(null);
  85.         $user->setEmailResendRequestCodeExpiryOn(null);
  86.         $em->flush();
  87.         $this->sendConfirmationEmail($user$emailer);
  88.         $this->addFlash('notice''registration.complete.1.msg.1');
  89.         $actionAttempt->resetAction(ActionAttemptManager::ACTION_LOGIN);
  90.         return $this->redirectToRoute('login');
  91.     }
  92.     /**
  93.      * @Route("/register", name="register")
  94.      */
  95.     public function register(Request $requestActionAttemptManager $actionAttemptUserManager $userManagerUserPasswordEncoderInterface $passwordEncoder): Response
  96.     {
  97. //        $this->addFlash('notice', 'Testing colors');
  98.         $actionAllowed $actionAttempt->isActionAllowed(ActionAttemptManager::ACTION_REGISTER);
  99.         $user = new User();
  100.         $form $this->createForm(RegisterType::class, $user);
  101.         $form->handleRequest($request);
  102. //        $this->addFlash('notice', 'registration.complete.1.msg.1');
  103.         if ($form->isSubmitted() && $form->isValid() && $actionAllowed) {
  104.             $em $this->getDoctrine()->getManager();
  105.             // check if PRE_USER exists and delete it
  106.             $userDb $em->getRepository(User::class)->findOneByEmail($user->getEmail());
  107.             if ($userDb !== null && $userDb->hasRole('PRE_USER')) {
  108.                 $em->remove($userDb);
  109.                 $em->flush();
  110.             }
  111.             // encode password
  112.             $user->setPassword($passwordEncoder->encodePassword($user$user->getNewPassword()));
  113.             $user->setEmail(strtolower($user->getEmail()));
  114.             // generate email confirmation code
  115.             $user->prepareEmailConfirmation();
  116.             // add PRE_USER role
  117.             $user->addRole('ROLE_PRE_USER');
  118.             // save user in db
  119.             $em->persist($user);
  120.             $em->flush();
  121.             $userManager->sendUserConfirmationEmail($user);
  122.             $this->addFlash('notice''registration.complete.1.msg.1');
  123.             $request->getSession()->set('registerOk'true);
  124.             return $this->redirectToRoute('register');
  125.         }
  126.         return $this->render('auth/register.html.twig', [
  127.             'action_blocked' => !$actionAllowed,
  128.             'form' => $form->createView()
  129.         ]);
  130.     }
  131.     /**
  132.      * @Route("/register/activate/{email}/{code}", name="register_activate")
  133.      */
  134.     public function registerActivate(Request $requestActionAttemptManager $actionAttemptUserPasswordEncoderInterface $passwordEncoderTranslatorInterface $translatorSmsManager $smsManager$email$code): Response
  135.     {
  136.         $actionAllowed $actionAttempt->isActionAllowed(ActionAttemptManager::ACTION_LOGIN);
  137.         $email User::urlEmailDecode($email);
  138.         $em $this->getDoctrine()->getManager();
  139.         $user $em->getRepository(User::class)->findOneBy(['email' => $email'emailConfirmationCode' => $code]);
  140.         $datNow = new \DateTime();
  141.         if ($user === null || $user->getIsEmailConfirmed() || $user->getEmailConfirmationExpiryOn() < $datNow) {
  142.             throw $this->createNotFoundException();
  143.         }
  144.         if ($user->hasRole('PRE_USER')) {
  145.             $user->setLocale($request->getLocale());
  146.             $form $this->createForm(RegisterSecondType::class, $user);
  147.             $form->handleRequest($request);
  148.             if ($form->isSubmitted() && $form->isValid() && $actionAllowed) {
  149.                 $user->setSecurityAnswer1($passwordEncoder->encodePassword($userstrtolower($user->getNewSecurityAnswer1())));
  150.                 $user->setSecurityAnswer2($passwordEncoder->encodePassword($userstrtolower($user->getNewSecurityAnswer2())));
  151.                 $user->setEmailAlternative(strtolower($user->getEmailAlternative()));
  152.                 $otp Helper::randomNumber();
  153.                 $user->setOtp($otp);
  154.                 $em->flush();
  155.                 // send sms
  156.                 $smsMsg $translator->trans('otp.registration') . ' ' $user->getOtp();
  157.                 $smsManager->sendOtp($user->getMobile(), $smsMsg$user->getOtp());
  158.                 return $this->redirectToRoute('register_activate2', ['email' => $user->getUrlEmail(), 'code' => $code]);
  159.             }
  160.             return $this->render('auth/register2.html.twig', [
  161.                 'action_blocked' => !$actionAllowed,
  162.                 'form' => $form->createView()
  163.             ]);
  164.         }
  165.         $user->setIsEmailConfirmed(true);
  166.         $em->flush();
  167.         $this->addFlash('notice''registration.complete.2.msg.1');
  168.         return $this->redirectToRoute('login');
  169.     }
  170.     /**
  171.      * @Route("/register/activate/{email}/{code}/2", name="register_activate2")
  172.      */
  173.     public function registerActivate2(Request $requestActionAttemptManager $actionAttemptUserPasswordEncoderInterface $passwordEncoder$email$code): Response
  174.     {
  175.         $actionAllowed $actionAttempt->isActionAllowed(ActionAttemptManager::ACTION_LOGIN);
  176.         $email User::urlEmailDecode($email);
  177.         $em $this->getDoctrine()->getManager();
  178.         $user $em->getRepository(User::class)->findOneBy(['email' => $email'emailConfirmationCode' => $code]);
  179.         if ($user === null) {
  180.             throw $this->createNotFoundException();
  181.         }
  182.         $datNow = new \DateTime();
  183.         if ($user->getEmailConfirmationExpiryOn() < $datNow || !$user->hasRole('PRE_USER')) {
  184.             throw $this->createNotFoundException();
  185.         }
  186.         $user->setLocale($request->getLocale());
  187.         $form $this->createForm(RegisterThirdType::class, $user);
  188.         $form->handleRequest($request);
  189.         if ($form->isSubmitted() && $form->isValid() && $actionAllowed) {
  190.             $user->removeRole('PRE_USER');
  191.             $user->addRole('FULL_USER');
  192.             $user->setIsEmailConfirmed(true);
  193.             $em->flush();
  194.             $this->addFlash('notice''registration.complete.2.msg.1');
  195.             return $this->redirectToRoute('login');
  196.         }
  197.         return $this->render('auth/register3.html.twig', [
  198.             'action_blocked' => !$actionAllowed,
  199.             'form' => $form->createView()
  200.         ]);
  201.     }
  202.     /**
  203.      * @Route("/recover/password/request", name="password_recover")
  204.      */
  205.     public function passwordRecoverRequest(Request $requestActionAttemptManager $actionAttemptEmailer $emailerUrlGeneratorInterface $urlGenerator): Response
  206.     {
  207.         $actionAllowed $actionAttempt->isActionAllowed(ActionAttemptManager::ACTION_RECOVER_PASSWORD);
  208.         $form $this->createForm(RecoverPasswordRequestType::class);
  209.         $form->handleRequest($request);
  210.         if ($form->isSubmitted() && $form->isValid()) {
  211.             $em $this->getDoctrine()->getManager();
  212.             $email strtolower($form->get('email')->getData());
  213.             $user $em->getRepository(User::class)->findOneByEmail($email);
  214.             $isAltEmail false;
  215.             if ($user === null) {
  216.                 $user $em->getRepository(User::class)->findOneByEmailAlternative($email);
  217.                 $isAltEmail true;
  218.             }
  219.             if ($user !== null) {
  220.                 $user->setRecoverPasswordCode(Helper::generateString());
  221.                 $datNow = new \DateTime();
  222.                 $datNow->add(new \DateInterval('PT4H'));
  223.                 $user->setRecoverPasswordCodeExpiryOn($datNow);
  224.                 $em->flush();
  225.                 $url $urlGenerator->generate('password_recover_process', [ 'code' => $user->getRecoverPasswordCode(), 'email' => $user->getUrlEmail() ], UrlGeneratorInterface::ABSOLUTE_URL);
  226.                 $emailer->sendRecoverPassword($user$url$isAltEmail);
  227.             }
  228.             $this->addFlash('notice''recover_password.request_completed');
  229.             return $this->redirectToRoute('password_recover');
  230.         }
  231.         return $this->render('auth/recoverPasswordRequest.html.twig', [
  232.             'action_blocked' => !$actionAllowed,
  233.             'form' => $form->createView()
  234.         ]);
  235.     }
  236.     /**
  237.      * @Route("/recover/password/process/{email}/{code}", name="password_recover_process")
  238.      */
  239.     public function passwordRecoverNew(Request $requestActionAttemptManager $actionAttemptUserPasswordEncoderInterface $passwordEncoder$email$code): Response
  240.     {
  241.         $actionAllowed $actionAttempt->isActionAllowed(ActionAttemptManager::ACTION_RECOVER_PASSWORD);
  242.         $email User::urlEmailDecode($email);
  243.         $em $this->getDoctrine()->getManager();
  244.         $user $em->getRepository(User::class)->findOneBy(['email' => $email'recoverPasswordCode' => $code]);
  245.         if ($user === null) {
  246.             $user $em->getRepository(User::class)->findOneBy(['emailAlternative' => $email'recoverPasswordCode' => $code]);
  247.         }
  248.         $datNow = new \DateTime();
  249.         if ($user === null || $user->getRecoverPasswordCodeExpiryOn() === null || $user->getRecoverPasswordCodeExpiryOn() < $datNow) {
  250.             $this->addFlash('notice''recover_password.token_wrong');
  251.             return $this->redirectToRoute('password_recover');
  252.         }
  253.         $form $this->createForm(RecoverPasswordNewType::class, $user);
  254.         $form->handleRequest($request);
  255.         if ($form->isSubmitted()) {
  256.             if ($user->getNewPassword() !== null && $passwordEncoder->isPasswordValid($user$user->getNewPassword())) {
  257.                 $form->get('newPassword')->get('first')->addError(new FormError('validate.is_previous_password'));
  258.             }
  259.         }
  260.         if ($form->isSubmitted() && $form->isValid()) {
  261.             $encPassword $passwordEncoder->encodePassword($user$user->getNewPassword());
  262.             $user->setPassword($encPassword);
  263.             $user->setRecoverPasswordCodeExpiryOn(null);
  264.             $user->setRecoverPasswordCode(null);
  265.             $em->flush();
  266.             $this->addFlash('notice''recover_password.completed');
  267.             return $this->redirectToRoute('login');
  268.         }
  269.         return $this->render('auth/recoverPasswordNew.html.twig', [
  270.             'action_blocked' => !$actionAllowed,
  271.             'form' => $form->createView()
  272.         ]);
  273.     }
  274.     /**
  275.      * @Route("/logout", name="logout")
  276.      */
  277.     public function logout()
  278.     {
  279.         throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
  280.     }
  281. }