src/Controller/Front/SecurityController.php line 158

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Front;
  3. use App\Entity\Profile;
  4. use App\Entity\User;
  5. use App\Service\Tools;
  6. use Doctrine\ORM\EntityManagerInterface;
  7. use Exception;
  8. use Symfony\Bridge\Twig\Mime\TemplatedEmail;
  9. use Symfony\Component\HttpFoundation\Session\Session;
  10. use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
  11. use Symfony\Component\Mailer\MailerInterface;
  12. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  13. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  14. use Symfony\Component\HttpFoundation\RedirectResponse;
  15. use Symfony\Component\HttpFoundation\Request;
  16. use Symfony\Component\HttpFoundation\Response;
  17. use Symfony\Component\Mime\Address;
  18. use Symfony\Component\Routing\Annotation\Route;
  19. use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
  20. use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
  21. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  22. use Symfony\Component\Security\Http\SecurityEvents;
  23. /**
  24.  * Class SecurityController
  25.  * @package App\Controller
  26.  */
  27. class SecurityController extends AbstractController
  28. {
  29.     private EntityManagerInterface $em;
  30.     public function __construct(
  31.         EntityManagerInterface $em
  32.     ) {
  33.         $this->em $em;
  34.     }
  35.     /**
  36.      * @param AuthenticationUtils $authenticationUtils
  37.      * @param Request $request
  38.      * @param Tools $tools
  39.      * @param EventDispatcherInterface $eventDispatcher
  40.      * @return Response
  41.      * @Route("/login", name="login", options={"expose"=true})
  42.      */
  43.     public function login(
  44.         AuthenticationUtils $authenticationUtils,
  45.         Request $request,
  46.         Tools $tools,
  47.         EventDispatcherInterface $eventDispatcher
  48.     ): Response {
  49.         if ($autoLogin $request->get('al')) {
  50.             /** @var User $currentUser */
  51.             $currentUser $this->getUser();
  52.             /** @var User $user */
  53.             $user $this->em->getRepository(User::class)->find($tools->decrypt($autoLogin));
  54.             if ($user) {
  55.                 // On sauvegarde en session notre user de base
  56.                 if (!is_null($currentUser)) {
  57.                     if ($currentUser->getProfile()->getRole() == Profile::ROLE_EMPLOYEE) {
  58.                         $session = new Session();
  59.                         $session->set('connect_as_master_front'$currentUser->getId() . '|' md5($currentUser->getCreatedAt()->getTimestamp()));
  60.                         $session->set('connect_as_referer_front'$request->server->get('HTTP_REFERER'));
  61.                     }
  62.                 }
  63.                 //On se connecte à l'user
  64.                 $token = new UsernamePasswordToken($usernull'user_provider'$user->getRoles());
  65.                 $this->get('security.token_storage')->setToken($token);
  66.                 $event = new SecurityEvents($request);
  67.                 $eventDispatcher->dispatch($eventSecurityEvents::INTERACTIVE_LOGIN);
  68.                 return $this->redirectToRoute('app_index');
  69.             }
  70.         }
  71.         if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
  72.             return $this->redirectToRoute('app_index');
  73.         }
  74.         // get the login error if there is one
  75.         $error $authenticationUtils->getLastAuthenticationError();
  76.         // last username entered by the user
  77.         $lastUsername $authenticationUtils->getLastUsername();
  78.         return $this->render('front/security/login.html.twig', [
  79.             'last_username' => $lastUsername,
  80.             'error' => $error,
  81.         ]);
  82.     }
  83.     /**
  84.      * @param Request $request
  85.      * @param EventDispatcherInterface $eventDispatcher
  86.      * @return RedirectResponse
  87.      * @Route("/reconnect_as", name="reconnect_as")
  88.      */
  89.     public function reconnectAs(Request $requestEventDispatcherInterface $eventDispatcher): RedirectResponse
  90.     {
  91.         $session = new Session();
  92.         $hash $session->get('connect_as_master_front');
  93.         $redirect $session->get('connect_as_referer_front');
  94.         $reconnected false;
  95.         if (preg_match("/([0-9]+)\|(.*)/"$hash$matches)) {
  96.             $user $this->em->getRepository(User::class)->find($matches[1]);
  97.             if ($user instanceof User && $user->getId()) {
  98.                 if (md5($user->getCreatedAt()->getTimestamp()) == $matches[2]) {
  99.                     //On se reconnecte
  100.                     $token = new UsernamePasswordToken($usernull'user_provider'$user->getRoles());
  101.                     $this->get('security.token_storage')->setToken($token);
  102.                     $event = new SecurityEvents($request);
  103.                     $eventDispatcher->dispatch($eventSecurityEvents::INTERACTIVE_LOGIN);
  104.                     $reconnected true;
  105.                 }
  106.             }
  107.         }
  108.         $session->remove('connect_as_master_front');
  109.         $session->remove('connect_as_referer_front');
  110.         if (!$reconnected) {
  111.             return $this->redirectToRoute('logout');
  112.         }
  113.         if ($redirect) {
  114.             return $this->redirect($redirect);
  115.         }
  116.         return $this->redirectToRoute('front_index');
  117.     }
  118.     /**
  119.      * @throws Exception
  120.      * @Route("/logout", name="logout")
  121.      */
  122.     public function logout(): void
  123.     {
  124.         throw new Exception('This should never be reached!');
  125.     }
  126.     /**
  127.      * @param Request $request
  128.      * @param MailerInterface $mailer
  129.      * @return RedirectResponse|Response
  130.      * @Route("/password-forget", name="password_forget")
  131.      * @throws TransportExceptionInterface
  132.      */
  133.     public function passwordForget(Request $requestMailerInterface $mailer): RedirectResponse|Response
  134.     {
  135.         if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
  136.             return $this->redirectToRoute('app_index');
  137.         }
  138.         $email $request->get('email');
  139.         $error "";
  140.         if ($request->get('submit_password_forget')) {
  141.             /** @var User $user */
  142.             $user $this->em->getRepository(User::class)->findOneBy([
  143.                 'email' => $email
  144.             ]);
  145.             if ($user) {
  146.                 $hash md5(uniqid('pf'));
  147.                 $user->setHash($hash);
  148.                 $message = (new TemplatedEmail())
  149.                     ->from(new Address($this->getParameter('MAILER_FROM'), $this->getParameter('MAILER_FROM_NAME')))
  150.                     ->to($user->getEmail())
  151.                     ->subject("Mot de passe oublié")
  152.                     ->htmlTemplate('email/user/password_forget.html.twig')
  153.                     ->context([
  154.                         'user' => $user,
  155.                         'hash' => $hash,
  156.                     ]);
  157.                 $mailer->send($message);
  158.                 $this->em->persist($user);
  159.                 $this->em->flush();
  160.             }
  161.             $this->addFlash('success'"Un mail vient d'être envoyé à " $email);
  162.             return $this->redirectToRoute('login');
  163.         }
  164.         return $this->render('front/security/password_forget.html.twig', [
  165.             'email' => $email,
  166.             'error' => $error,
  167.             'body_class' => 'login-container',
  168.         ]);
  169.     }
  170.     /**
  171.      * @param string $hash
  172.      * @param Request $request
  173.      * @param UserPasswordEncoderInterface $passwordEncoder
  174.      * @return RedirectResponse|Response
  175.      * @Route("/password-reset/{hash}", name="password_reset")
  176.      */
  177.     public function passwordReset(string $hashRequest $requestUserPasswordEncoderInterface $passwordEncoder): RedirectResponse|Response
  178.     {
  179.         if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
  180.             return $this->redirectToRoute('app_index');
  181.         }
  182.         $error "";
  183.         /** @var User $user */
  184.         $user $this->em->getRepository(User::class)->findOneBy([
  185.             'hash' => $hash
  186.         ]);
  187.         if ($user && $request->get('submit_password_reset') && ($password $request->get('password'))) {
  188.             if (strlen($password) > 5) {
  189.                 $password $passwordEncoder->encodePassword($user$password);
  190.                 $user->setPassword($password);
  191.                 $user->setHash(null);
  192.                 $this->em->persist($user);
  193.                 $this->em->flush();
  194.                 return $this->redirectToRoute('login');
  195.             } else {
  196.                 $error "Veuillez saisir un mot de passe d'au moins 6 caractères";
  197.             }
  198.         }
  199.         return $this->render('front/security/password_reset.html.twig', [
  200.             'error' => $error,
  201.             'body_class' => 'login-container',
  202.         ]);
  203.     }
  204. }