src/Controller/Main/ResettingController.php line 42

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Main;
  3. use App\Entity\Main\User;
  4. use App\Events\Main\Registration\SecurityEvent;
  5. use App\Events\Main\Resetting\ResetEvent;
  6. use App\EventSubscribers\Main\ResettingSubscriber;
  7. use App\EventSubscribers\Main\SecuritySubscriber;
  8. use App\Model\TokenGenerator\TokenGenerator;
  9. use App\Services\EmailManager;
  10. use App\Services\UserManager;
  11. use App\Services\SecurityManager;
  12. use Predis\Client;
  13. use Psr\Log\LoggerInterface;
  14. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  15. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  16. use Symfony\Component\HttpFoundation\RedirectResponse;
  17. use Symfony\Component\HttpFoundation\Request;
  18. use Symfony\Component\HttpFoundation\Response;
  19. use Symfony\Component\Routing\Annotation\Route;
  20. /**
  21.  * Controller managing the resetting of the password.
  22.  *
  23.  * @Route(
  24.  *     condition="not (context.getHost() matches '%coaching_domain.host.regexp%')"
  25.  * )
  26.  *
  27.  */
  28. class ResettingController extends AbstractController
  29. {
  30.     use BrulafineControllerTrait;
  31.     const AUTOLOGIN_ATTEMPTS_REDIS_KEY "autologin_link_request_";
  32.     /**
  33.      * Request reset user password: show form.
  34.      *
  35.      * @Route("/resseting/request", name="user_resetting_request")
  36.      */
  37.     public function requestAction()
  38.     {
  39.         $setup $this->getSetup();
  40.         return $this->render($this->getTemplatesDir() . '/Security/views/Resetting/request.html.twig', [
  41.             'csrf_token' => $this->getLoginCsrfToken(),
  42.             'tracking' => $setup->getTracking(),
  43.             'site' => $setup->getSite(),
  44.         ]);
  45.     }
  46.     /**
  47.      * Request reset user password: submit form and send email.
  48.      *
  49.      * @Route ("/resetting/send-email", name="user_resetting_send_email")
  50.      * @param Request $request
  51.      *
  52.      * @param UserManager $securityManager
  53.      * @param EmailManager $emailFactory
  54.      * @return Response
  55.      * @throws \Exception
  56.      */
  57.     public function sendEmailAction(Request $requestUserManager $securityManagerEmailManager $emailFactoryEventDispatcherInterface $dispatcher)
  58.     {
  59.         $username $request->request->get('username');
  60.         /** @var User $user */
  61.         $user $securityManager->findUserByUsernameOrEmail($username);
  62.         //$ttl = $this->container->getParameter('fos_user.resetting.retry_ttl');
  63.         $ttl 1;
  64.         if (null !== $user && !$user->isPasswordRequestNonExpired($ttl)) {
  65.             $event = new ResetEvent($user$request);
  66.             $dispatcher->dispatch($eventResettingSubscriber::RESETTING_RESET_REQUEST);
  67.             if (null !== $event->getResponse()) {
  68.                 return $event->getResponse();
  69.             }
  70.             if (null === $user->getConfirmationToken()) {
  71.                 $tokenGenerator = new TokenGenerator();
  72.                 $user->setConfirmationToken($tokenGenerator->generateToken());
  73.             }
  74.             // Define here landing page for the autologin.
  75.             $destination $this->getParameter('reset_pw_autologin_destination') ?? null;
  76.             $emailFactory->sendAutoLoginEmailMessage($user$destination);
  77.             $user->setPasswordRequestedAt(new \DateTime());
  78.             $securityManager->updateUser($user);
  79.         }
  80.         return new RedirectResponse($this->generateUrl('user_resetting_check_email', ['username' => $username]));
  81.     }
  82.     /**
  83.      * Tell the user to check his email provider.
  84.      *
  85.      * @param Request $request
  86.      *
  87.      * @Route ("/resseting/check-email", name="user_resetting_check_email")
  88.      * @return Response
  89.      */
  90.     public function checkEmailAction(Request $request)
  91.     {
  92.         $username $request->query->get('username');
  93.         if (empty($username)) {
  94.             // the user does not come from the sendEmail action
  95.             return new RedirectResponse($this->generateUrl('user_resetting_request'));
  96.         }
  97.         $setup $this->getSetup();
  98.         return $this->render($this->getTemplatesDir() . '/Security/views/Resetting/check.html.twig', [
  99.             'csrf_token' => $this->getLoginCsrfToken(),
  100.             'tracking' => $setup->getTracking(),
  101.             'site' => $setup->getSite(),
  102.         ]);
  103.     }
  104.     /**
  105.      * @param Request $request
  106.      * @param $token
  107.      * @param $dest
  108.      * @param LoggerInterface $logger
  109.      * @param SecurityManager $securityManager
  110.      * @return RedirectResponse
  111.      */
  112.     public function autoLoginAction(Request $request$token$destLoggerInterface $loggerUserManager $securityManagerEventDispatcherInterface $eventDispatcher$redisClient)
  113.     {
  114.         $environment $this->getParameter("kernel.environment");
  115.         $redisKey self::AUTOLOGIN_ATTEMPTS_REDIS_KEY $request->getClientIp();
  116.         // prevent brut force attacks by limiting to 50 calls on this address by the same IP.
  117.         $redisClient->setex($redisKey3600, ((int) $redisClient->get($redisKey) + 1));
  118.         if ((int) $redisClient->get($redisKey) > 50 && 'test' != $environment) {
  119.             $this->addFlash("error""flashMessages.site.linkNoValid");
  120.             $logger->alert("Someone is trying to bruteforce the autologin url, IP {$request->getClientIp()}, number of tries so far : {$redisClient->get($redisKey)}");
  121.             return new RedirectResponse($this->generateUrl("brulafine_shipping"));
  122.         }
  123.         // first check if user is already logged in.
  124.         $currentUser $this->getUser();
  125.         if ($currentUser instanceof User) {
  126.             return $this->redirectToRoute($this->getRouteToRedirect($dest));
  127.         }
  128.         $user $securityManager->findUserByConfirmationToken($token);
  129.         if (!$user instanceof User) {
  130.             $this->addFlash("error""flashMessages.site.linkNoValid");
  131.             return new RedirectResponse($this->generateUrl("brulafine_shipping"));
  132.         }
  133.         // check if reset request exists.
  134.         $event = new ResetEvent($user$request);
  135.         $eventDispatcher->dispatch($eventResettingSubscriber::RESETTING_RESET_INITIALIZE);
  136.         if (null !== $event->getResponse()) {
  137.             $this->addFlash("error""flashMessages.site.linkNoValid");
  138.             return new RedirectResponse($this->generateUrl("brulafine_shipping"));
  139.         }
  140.         // update the user data.
  141.         $user->setConfirmationToken(null);
  142.         $user->setPasswordRequestedAt(null);
  143.         $user->setEnabled(true);
  144.         $securityManager->updateUser($user);
  145.         // Force Login the user
  146.         $eventDispatcher->dispatch(
  147.             new SecurityEvent($user$request),
  148.             SecuritySubscriber::USER_LOGGED_IN
  149.         );
  150.         return $this->redirectToRoute($this->getRouteToRedirect($dest));
  151.     }
  152.     /**
  153.      * @param $dest
  154.      * @return string
  155.      */
  156.     private function getRouteToRedirect($dest)
  157.     {
  158.         // define where to redirect the user
  159.         if ('pass' == $dest) {
  160.             $route 'user_change_password';
  161.         } else {
  162.             $route 'brulafine_shipping';
  163.         }
  164.         return $route;
  165.     }
  166. }