src/Controller/DefaultController.php line 202

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Account;
  4. use App\Entity\LoginLog;
  5. use App\Entity\TrainingRequest;
  6. use App\Entity\TrainingRequestHistory;
  7. use App\Services\SendEmailService;
  8. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  9. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  10. use Symfony\Component\Form\Extension\Core\Type\EmailType;
  11. use Symfony\Component\Form\Extension\Core\Type\PasswordType;
  12. use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
  13. use Symfony\Component\Form\Extension\Core\Type\TextType;
  14. use Symfony\Component\HttpFoundation\Request;
  15. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  16. use Symfony\Component\Routing\Annotation\Route;
  17. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  18. use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
  19. use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
  20. use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
  21. use App\Security\PasswordEncoder;
  22. use Symfony\Component\Validator\Constraints as Assert;
  23. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  24. /**
  25.  * @Route("/", name="default_")
  26.  */
  27. class DefaultController extends AbstractController
  28. {
  29.     private $eventDispatcher;
  30.     public function __construct(EventDispatcherInterface $eventDispatcher)
  31.     {
  32.         $this->eventDispatcher $eventDispatcher;
  33.     }
  34.     /**
  35.      * @Route("/", name="homepage")
  36.      */
  37.     public function indexAction(Request $request)
  38.     {
  39.         if ($this->getUser()) {
  40.             if ($this->isGranted("ROLE_MANAGER")) {
  41.                 return $this->redirectToRoute("manager_homepage");
  42.             } else {
  43.                 return $this->redirectToRoute("user_homepage");
  44.             }
  45.         }
  46.         return $this->redirectToRoute("default_login");
  47.     }
  48.     /**
  49.      * @Route("/login", name="login")
  50.      */
  51.     public function loginAction(Request $requestSendEmailService $sendEmailService)
  52.     {
  53.         $PasswordEncoder = new PasswordEncoder;
  54.         if ($this->getUser()) {
  55.             if ($this->isGranted("ROLE_MANAGER")) {
  56.                 return $this->redirectToRoute("manager_homepage");
  57.             } else {
  58.                 return $this->redirectToRoute("user_homepage");
  59.             }
  60.         }
  61.         $form $this->createFormBuilder()
  62.             ->add('username'TextType::class, array(
  63.                 'attr' => array(
  64.                     'placeholder' => 'Identifiant',
  65.                 ),
  66.                 'required' => true,
  67.             ))
  68.             ->add('password'PasswordType::class, array(
  69.                 'attr' => array(
  70.                     'placeholder' => 'Mot de passe',
  71.                 ),
  72.                 'required' => true,
  73.             ))->getForm();
  74.         $form->handleRequest($request);
  75.         $error null;
  76.         if ($form->isSubmitted()) {
  77.             if ($form->isValid()) {
  78.                 $data $form->getData();
  79.                 $em $this->getDoctrine()->getManager();
  80.                 $account $em
  81.                     ->getRepository(Account::class)
  82.                     ->findOneBy(["email" => $data["username"]]);
  83.                 if ($account) {
  84.                     $isValid $PasswordEncoder->isPasswordValid($account->getPassword(), $data["password"], $account->getSalt());
  85.                     if ($isValid) {
  86.                         if ($account->isEnabled()) {
  87.                             if (!$account->isLocked()) {
  88.                                 $now = new \DateTime("now");
  89.                                 $account->setLastLogin($now);
  90.                                 $loginLog = new LoginLog();
  91.                                 $loginLog->setAccount($account);
  92.                                 $loginLog->setDate($now);
  93.                                 $loginLog->setEndDate($now);
  94.                                 $loginLog->setIp($this->getUserIPAddress());
  95.                                 $em->persist($loginLog);
  96.                                 $account->setLoginLog($loginLog);
  97.                                 $em->flush();
  98.                                 $session $this->get('session');
  99.                                 $firewall 'main';
  100.                                 $token = new UsernamePasswordToken($accountnull$firewall$account->getRoles());
  101.                                 $this->get('security.token_storage')->setToken($token);
  102.                                 $session->set('_security_'.$firewallserialize($token));
  103.                                 $event = new InteractiveLoginEvent($request$token);
  104.                                 $this->eventDispatcher->dispatch($event"security.interactive_login");
  105.                                 // $this->get("event_dispatcher")->dispatch("security.interactive_login", $event);
  106.                                 return $this->redirectToRoute("default_homepage");
  107.                             } else {
  108.                                 $this->get('session')->getFlashBag()->add("danger""Votre compte a été bloqué en raison d’un nombre d’erreur de connexion trop important. Veuillez contacter votre délégué à la protection des données.");
  109.                             }
  110.                         } else {
  111.                             $this->get('session')->getFlashBag()->add("danger""Votre compte n'est pas actif");
  112.                         }
  113.                     } else {
  114.                         if ($account->getUser()) {
  115.                             $account->setErroredLoginCount($account->getErroredLoginCount()+1);
  116.                             if ($account->getErroredLoginCount() == 5) {
  117.                                 $account->setLocked(true);
  118.                                 $em->flush();
  119.                                 $content "<p>Bonjour,<br/>
  120.                         <br/>
  121.                         Une compte utilisateur du client ".$account->getUser()->getCompanyName()." a été bloqué suite à un nombre trop important de tentatives de connexion.<br/>
  122.                         <br/>
  123.                         <br/>
  124.                         <i>Cet e-mail a été envoyé depuis le site myDigitplace. NE PAS répondre à ce message automatique.</i><br/>
  125.                         </p>";
  126.                                 $sendEmailService->send(
  127.                                     "Compte utilisateur bloqué",
  128.                                     $account->getUser()->getManager()->getEmail(),
  129.                                     'template_emails/left_text.html.twig',
  130.                                     [
  131.                                         "title" => "Compte utilisateur bloqué",
  132.                                         "content" => $content
  133.                                     ]
  134.                                 );
  135.                             }
  136.                             if ($account->getErroredLoginCount() >= 5) {
  137.                                 $this->get('session')->getFlashBag()->add("danger""Votre compte a été bloqué en raison d’un nombre d’erreur de connexion trop important. Veuillez contacter votre délégué à la protection des données.");
  138.                             } else {
  139.                                 $this->get('session')->getFlashBag()->add("danger""Identifiant ou mot de passe incorrect");
  140.                             }
  141.                         } else {
  142.                             $this->get('session')->getFlashBag()->add("danger""Identifiant ou mot de passe incorrect");
  143.                         }
  144.                     }
  145.                 } else {
  146.                     $this->get('session')->getFlashBag()->add("danger""Identifiant ou mot de passe incorrect");
  147.                 }
  148.             } else {
  149.                 $this->get('session')->getFlashBag()->add("warning""Merci de saisir votre identifiant et votre mot de passe");
  150.             }
  151.         }
  152.         return $this->render('login.html.twig', [
  153.             "form" => $form->createView(),
  154.         ]);
  155.     }
  156.     /**
  157.      * @Route("/logout", name="logout")
  158.      */
  159.     public function logoutAction(Request $request)
  160.     {
  161.         $this->get('security.token_storage')->setToken(null);
  162.         $this->get('session')->invalidate();
  163.         return $this->redirectToRoute("default_homepage");
  164.     }
  165.     /**
  166.      * @Route("/logoutabo", name="logout_abo")
  167.      */
  168.     public function logoutAboAction(Request $request)
  169.     {
  170.         $this->get('security.token_storage')->setToken(null);
  171.         $this->get('session')->invalidate();
  172.         $this->get('session')->getFlashBag()->add('danger''Vous ne disposez d\'aucun abonnement actif. Veuillez contacter votre interlocuteur myDiditplace');
  173.         return $this->redirectToRoute("default_homepage");
  174.     }
  175.     /**
  176.      * @Route("/forgot", name="forgot_password")
  177.      */
  178.     public function forgotPasswordAction(Request $requestSendEmailService $sendEmailService)
  179.     {
  180.         $form $this->createFormBuilder()
  181.             ->add('email'EmailType::class, array(
  182.                 'attr' => array(
  183.                     'placeholder' => 'Adresse mail',
  184.                 ),
  185.                 'required' => true,
  186.             ))
  187.             ->getForm();
  188.         $form->handleRequest($request);
  189.         $error null;
  190.         if ($form->isSubmitted()) {
  191.             if ($form->isValid()) {
  192.                 $data $form->getData();
  193.                 $em $this->getDoctrine()->getManager();
  194.                 $account $em->getRepository(Account::class)->findOneBy(["email" => $data["email"]]);
  195.                 if ($account) {
  196.                     if ($account->isEnabled()) {
  197.                         if (!$account->isLocked()) {
  198.                             $token hash("sha256"uniqid());
  199.                             $account->setPasswordRequest($token);
  200.                             $account->setPasswordRequestDate(new \DateTime('now'));
  201.                             $em->flush();
  202.                             if ($account->getUser()) {
  203.                                 $firstName $account->getUser()->getContactFirstName();
  204.                             } else {
  205.                                 $firstName $account->getManager()->getFirstName();
  206.                             }
  207.                             $content "<p>Bonjour ".$firstName.",<br/>
  208.                         <br/>
  209.                         Vous venez de demander à réinitialiser votre mot de passe sur le site myDigitplace.<br/>
  210.                         <br/>
  211.                         <br/>
  212.                         Voici votre lien pour définir un nouveau mot de passe:<br/><a href='".$this->generateUrl("default_reset_password", ["email" => $account->getEmail(), "token" => $token], UrlGeneratorInterface::ABSOLUTE_URL)."'>
  213.                         ".$this->generateUrl("default_reset_password", ["email" => $account->getEmail(), "token" => $token], UrlGeneratorInterface::ABSOLUTE_URL)."
  214.                         </a>
  215.                         <br/>
  216.                         <br/>
  217.                         Si le lien n'est pas cliquable, collez le dans la barre d'adresse de votre navigateur.<br/><br/>
  218.                         Si vous n'êtes pas à l'origine de cette demande, vous pouvez ignorer ce message. Votre compte est toujours sécurisé.<br/>
  219.                         <br/>
  220.                         Bien cordialement,<br/>
  221.                         <br/>
  222.                         L’équipe myDigitplace<br/>
  223.                         <br/>
  224.                         <i>Cet e-mail a été envoyé depuis le site myDigitplace. NE PAS répondre à ce message automatique.</i><br/>
  225.                         </p>";
  226.                             $sendEmailService->send(
  227.                                 "Réinitialisation de votre mot de passe",
  228.                                 $account->getEmail(),
  229.                                 'template_emails/left_text.html.twig',
  230.                                 [
  231.                                     "title" => "Réinitialisation de votre mot de passe",
  232.                                     "content" => $content
  233.                                 ]
  234.                             );
  235.                             $this->get('session')->getFlashBag()->add("success""Un mail contenant un lien de réinitialisation a été envoyé à l'adresse indiquée. Ce lien est valide pendant 24h.");
  236.                             return $this->redirectToRoute("default_login");
  237.                         } else {
  238.                             $this->get('session')->getFlashBag()->add("warning""Votre compte a été bloqué en raison d’un nombre d’erreur de connexion trop important. Veuillez contacter votre délégué à la protection des données.");
  239.                         }
  240.                     } else {
  241.                         $this->get('session')->getFlashBag()->add("warning""Votre compte n'est pas actif");
  242.                     }
  243.                 } else {
  244.                     $this->get('session')->getFlashBag()->add("danger""Aucun compte trouvé avec cette adresse");
  245.                 }
  246.             } else {
  247.                 $this->get('session')->getFlashBag()->add("warning""Merci de saisir une adresse mail valide");
  248.             }
  249.         }
  250.         return $this->render('forgot_pwd.html.twig', [
  251.             "form" => $form->createView(),
  252.         ]);
  253.     }
  254.     /**
  255.      * @Route("/reset/{email}/{token}", name="reset_password")
  256.      */
  257.     public function resetPasswordAction(Request $request)
  258.     {
  259.         $em $this->getDoctrine()->getManager();
  260.         $account $em->getRepository(Account::class)->findOneBy(["email" => $request->get("email")]);
  261.         if ($account) {
  262.             if ($account->getPasswordRequest() && $account->getPasswordRequestDate()) {
  263.                 if ($account->getPasswordRequest() == $request->get("token")) {
  264.                     $now = new \DateTime('now');
  265.                     if ($now->getTimestamp() - $account->getPasswordRequestDate()->getTimestamp() < 86400) {
  266.                         $form $this->createFormBuilder()
  267.                             ->add('password'RepeatedType::class, array(
  268.                                 'type' => PasswordType::class,
  269.                                 'invalid_message' => 'Les mot de passe ne sont pas identiques',
  270.                                 'first_options'  => array(
  271.                                     'attr' => array(
  272.                                         'placeholder' => 'Changer mot de passe'
  273.                                     ),
  274.                                     'constraints' =>[
  275.                                         new Assert\NotBlank([
  276.                                             'message' => 'Merci de saisir un mot de passe'
  277.                                         ]),
  278.                                         new Assert\Regex([
  279.                                             'pattern' => '/^(?:(?=(\S*?[A-Z]){1})(?=(\S*?[a-z]){1})(?=(\S*?[0-9]){1})(?=\S*?[~!^(){}<>%@#&*+=_\-$`,.\/\\\;:\'"|\[\]]){1}.{12,})$/m',
  280.                                             'message' => "Votre mot de passe doit respecter les recommandations de l'ANSSI : au moins 12 caractères de types différents (majuscules, minuscules, chiffres, caractères spéciaux)"
  281.                                         ])
  282.                                     ],
  283.                                 ),
  284.                                 'second_options' => array('attr' => array('placeholder' => 'Confirmation mot de passe')),
  285.                                 'label' => false,
  286.                                 'mapped' => false
  287.                             ))->getForm();
  288.                         $form->handleRequest($request);
  289.                         if ($form->isSubmitted() && $form->isValid()) {
  290.                             $salt md5(uniqid());
  291.                             $pwd $form['password']->getData();
  292.                             $account->setSalt($salt);
  293.                             $PasswordEncoder = new PasswordEncoder;
  294.                             $enc_pwd $PasswordEncoder->encodePassword($pwd$salt);
  295.                             $account->setPassword($enc_pwd);
  296.                             $account->setPasswordRequest(null);
  297.                             $account->setPasswordRequestDate(null);
  298.                             $em->flush();
  299.                             $this->get('session')->getFlashBag()->add("success""Votre mot de passe a été réinitialisé, vous pouvez maintenant vous connecter à votre espace.");
  300.                             return $this->redirectToRoute("default_login");
  301.                         }
  302.                         return $this->render('reset_pwd.html.twig', [
  303.                             "form" => $form->createView(),
  304.                         ]);
  305.                     } else {
  306.                         throw new NotFoundHttpException("Cette URL n'est plus valide");
  307.                     }
  308.                 } else {
  309.                     throw new NotFoundHttpException("Cette URL n'est pas valide");
  310.                 }
  311.             }
  312.         }
  313.         throw new NotFoundHttpException();
  314.     }
  315.     /**
  316.      * @Route("/training/{email}/{token}", name="training")
  317.      */
  318.     public function trainingAction(Request $request$email$token)
  319.     {
  320.         $em $this->getDoctrine()->getManager();
  321.         $trainingRequest $em->getRepository(TrainingRequest::class)->findOneBy(["email" => $email"token" => $token]);
  322.         if (!$trainingRequest) {
  323.             throw new NotFoundHttpException();
  324.         }
  325.         if ($request->get("reset")) {
  326.             $trainingRequest->setAnswerDate(null);
  327.             $trainingRequest->setUserAnswers(null);
  328.             $trainingRequest->setResult(0);
  329.             $em->flush();
  330.             return $this->redirectToRoute("default_training", ["email" => $email"token" => $token]);
  331.         }
  332.         if ($request->get("answers")) {
  333.             return $this->render('training_answers.html.twig', [
  334.                 "trainingRequest" => $trainingRequest
  335.             ]);
  336.         }
  337.         $now = new \DateTime('now');
  338.         $form $this->createFormBuilder()
  339.             ->add("firstName"TextType::class, [
  340.                 "attr" => [
  341.                     "placeholder" => "Prénom"
  342.                 ],
  343.                 "label" => "Prénom",
  344.                 "data" => $trainingRequest->getLastName()
  345.             ])
  346.             ->add("lastName"TextType::class, [
  347.                 "attr" => [
  348.                     "placeholder" => "Nom"
  349.                 ],
  350.                 "label" => "Nom",
  351.                 "data" => $trainingRequest->getFirstName()
  352.             ])
  353.             ->add("position"TextType::class, [
  354.                 "attr" => [
  355.                     "placeholder" => "Fonction"
  356.                 ],
  357.                 "label" => "Fonction",
  358.                 "data" => $trainingRequest->getPosition()
  359.             ]);
  360.         foreach ($trainingRequest->getTrainingCampain()->getQuestions() as $key => $question) {
  361.             $choices = [];
  362.             foreach ($question["choices"] as $choiceKey => $choiceValue) {
  363.                 $choices[$choiceValue] = $choiceKey;
  364.             }
  365.             $this->shuffle_assoc($choices);
  366.             $form->add("question_".$keyChoiceType::class, [
  367.                 "choices" => $choices,
  368.                 "expanded" => true,
  369.                 "multiple" => $question["multiple"],
  370.             ]);
  371.         }
  372.         $form $form->getForm();
  373.         $form->handleRequest($request);
  374.         if ($form->isSubmitted() && $form->isValid()) {
  375.             $em $this->getDoctrine()->getManager();
  376.             $answers = [];
  377.             $goodAnswers 0;
  378.             foreach ($trainingRequest->getTrainingCampain()->getQuestions() as $key => $question) {
  379.                 $answers[$key] = $form["question_".$key]->getData();
  380.                 if (is_array($trainingRequest->getTrainingCampain()->getAnswers()[$key])) {
  381.                     if (is_array($answers[$key])) {
  382.                         if ($this->consistsOfTheSameValues($answers[$key], $trainingRequest->getTrainingCampain()->getAnswers()[$key])) {
  383.                             $goodAnswers++;
  384.                         }
  385.                     }
  386.                 } else {
  387.                     if ($answers[$key] == $trainingRequest->getTrainingCampain()->getAnswers()[$key]) {
  388.                         $goodAnswers++;
  389.                     }
  390.                 }
  391.             }
  392.             $trainingRequest->setFirstName($form["firstName"]->getData());
  393.             $trainingRequest->setLastName($form["lastName"]->getData());
  394.             $trainingRequest->setPosition($form["position"]->getData());
  395.             $trainingRequest->setAnswerDate($now);
  396.             $trainingRequest->setUserAnswers($answers);
  397.             $trainingRequest->setResult($goodAnswers count($trainingRequest->getTrainingCampain()->getQuestions()));
  398.             $trainingRequestHistory = new TrainingRequestHistory();
  399.             $trainingRequestHistory->setAnswerDate($now);
  400.             $trainingRequestHistory->setUserAnswers($answers);
  401.             $trainingRequestHistory->setResult($goodAnswers count($trainingRequest->getTrainingCampain()->getQuestions()));
  402.             $trainingRequestHistory->setTrainingRequest($trainingRequest);
  403.             $em->persist($trainingRequestHistory);
  404.             $em->flush();
  405.             return $this->redirectToRoute("default_training", ["email" => $email"token" => $token]);
  406.         }
  407.         return $this->render('training.html.twig', [
  408.             "form" => $form->createView(),
  409.             "trainingRequest" => $trainingRequest
  410.         ]);
  411.     }
  412.     public function shuffle_assoc(&$array) {
  413.         $keys array_keys($array);
  414.         shuffle($keys);
  415.         foreach($keys as $key) {
  416.             $new[$key] = $array[$key];
  417.         }
  418.         $array $new;
  419.         return true;
  420.     }
  421.     public function consistsOfTheSameValues(array $a, array $b)
  422.     {
  423.         // check size of both arrays
  424.         if (count($a) !== count($b)) {
  425.             return false;
  426.         }
  427.         foreach ($b as $key => $bValue) {
  428.             // check that expected value exists in the array
  429.             if (!in_array($bValue$atrue)) {
  430.                 return false;
  431.             }
  432.             // check that expected value occurs the same amount of times in both arrays
  433.             if (count(array_keys($a$bValuetrue)) !== count(array_keys($b$bValuetrue))) {
  434.                 return false;
  435.             }
  436.         }
  437.         return true;
  438.     }
  439.     public function getUserIPAddress() {
  440.         //whether ip is from the share internet
  441.         if(!empty($_SERVER['HTTP_CLIENT_IP'])) {
  442.             $ip $_SERVER['HTTP_CLIENT_IP'];
  443.         }
  444.         //whether ip is from the proxy
  445.         elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  446.             $ip $_SERVER['HTTP_X_FORWARDED_FOR'];
  447.         }
  448.         //whether ip is from the remote address
  449.         else{
  450.             $ip $_SERVER['REMOTE_ADDR'];
  451.         }
  452.         return $ip;
  453.     }
  454. }