src/Controller/SecurityController.php line 34

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\User;
  4. use App\Events\Events;
  5. use App\Form\PwdType;
  6. use App\Form\ResetPwdType;
  7. use App\Service\email\EmailHandlerMailgun;
  8. use App\Service\JwtHandler;
  9. use Doctrine\Persistence\ManagerRegistry;
  10. use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
  11. use KnpU\OAuth2ClientBundle\Client\Provider\KeycloakClient;
  12. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  13. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  14. use Symfony\Component\EventDispatcher\GenericEvent;
  15. use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
  16. use Symfony\Component\Form\Extension\Core\Type\EmailType;
  17. use Symfony\Component\HttpFoundation\Request;
  18. use Symfony\Component\HttpFoundation\Response;
  19. use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
  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\Core\Exception\BadCredentialsException;
  24. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  25. use Symfony\Component\Validator\Constraints\IsTrue;
  26. class SecurityController extends AbstractController
  27. {
  28.     /**
  29.      * @Route("/login", name="app_login")
  30.      */
  31.     public function login(AuthenticationUtils $authenticationUtilsClientRegistry $clientRegistry): Response
  32.     {
  33.         // Si le visiteur est déjà identifié, on le redirige
  34.         if ($this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
  35.             return $this->redirectToRoute('user_dashboard');
  36.         }
  37.             //TODO redirection vers keycloak
  38. //        /** @var KeycloakClient $client */
  39. //        $client = $clientRegistry->getClient('keycloak');
  40. //        return $client->redirect(['openid','kinalgo-user']);
  41.         // get the login error if there is one
  42.         $error $authenticationUtils->getLastAuthenticationError();
  43.         /*Custom message error if bad credential*/
  44.         if ($error instanceof BadCredentialsException) {
  45.             $error = new \stdClass();
  46.             $error->message 'Email ou mot de passe non valide';
  47.         }
  48.         // last username entered by the user
  49.         $lastUsername $authenticationUtils->getLastUsername();
  50.         return $this->render('security/screen/login.html.twig', ['last_username' => $lastUsername'error' => $error]);
  51.     }
  52.     /**
  53.      * @Route("/open-id/check-auth", name="openid_check_auth")
  54.      */
  55.     public function redirectUri(){}
  56.     /**
  57.      * @Route("/logout", name="logout", methods={"GET"})
  58.      */
  59.     public function logout()
  60.     {
  61.         // controller can be blank: it will never be executed!
  62.         throw new \Exception('Don\'t forget to activate logout in security.yaml');
  63.     }
  64.     /**
  65.      * Envoie d'un email pour réinitialisation mot de passe ou création de compte
  66.      * @Route("/security/password/{context}", requirements={"context":"reset|create"}, name="security-reset",methods={"POST","GET"})
  67.      */
  68.     public function reset(Request $requeststring $contextEventDispatcherInterface $eventDispatcher,ManagerRegistry $em)
  69.     {
  70.         /*Create form*/
  71.         $form $this->createFormBuilder()
  72.             ->add('email'EmailType::class, array('required' => true'label' => false,
  73.                 'attr' => array('class' => 'user-form__input')))
  74.             ->getForm();
  75.         $form->handleRequest($request);
  76.         /*form is submitted*/
  77.         if ($form->isSubmitted() && $form->isValid()) {
  78.             $data $form->getData();
  79.             //check email
  80.             /* @var $user User*/
  81.             $user $em->getRepository(User::class)->findOneBy(['email' => $data['email']]);
  82.             if (!$user || empty($user)) {
  83.                 $this->addFlash('notice-warning''Aucun compte associé à cet email n\'a été trouvé.');
  84.                 return $this->redirectToRoute('security-reset',["context"=>$context]);
  85.             }
  86.             if($context === 'reset' && $user->getPassword() === null){
  87.                 $createPassHref $this->generateUrl('security-reset',['context'=>'create']);
  88.                 $link "<a class='text-decoration-underline' href='${createPassHref}'>Créer mon compte maintenant</a>";
  89.                 $message sprintf('Vous ne pouvez pas réinitialiser votre mot de passe car votre compte n’est pas encore finalisé. Cliquez sur %s ou contactez le référent prévention de votre établissement.',$link);
  90.                 $this->addFlash('notice-warning'$message);
  91.                 return $this->redirectToRoute('security-reset',["context"=>$context]);
  92.             }
  93.             if($context === 'create' && $user->getPassword() !== null){
  94.                 $forgotPassHref $this->generateUrl('security-reset',['context'=>'reset']);
  95.                 $link "<a class='text-decoration-underline' href='${forgotPassHref}'>mot de passe oublié</a>";
  96.                 $message sprintf('Vous avez déjà créé votre mot de passe. Cliquez sur %s pour le réinitialiser.',$link);
  97.                 $this->addFlash('notice-warning'$message);
  98.                 return $this->redirectToRoute('security-reset',["context"=>$context]);
  99.             }
  100.             /*==============>Email exist*/
  101.             $event = new GenericEvent(['user'=>$user,'context'=>$context]);
  102.             $eventDispatcher->dispatch($eventEvents::EMAIL_FORGOT_PWD);
  103.             $message $context === "reset" "Un email a été envoyé a l'adresse {$user->getEmail()}, suivez le lien pour changer votre mot de passe." :
  104.                 "Un email a été envoyé a l'adresse {$user->getEmail()}, suivez le lien pour créer votre mot de passe.";
  105.             $this->addFlash('notice-success'$message);
  106.             return $this->redirectToRoute('app_login', array(
  107.                     'last_username' => $user->getEmail(),
  108.                 )
  109.             );
  110.         }
  111.         return $this->render('security/screen/reset.html.twig', array(
  112.             'form' => $form->createView(),
  113.             'title_page' => $context === 'reset' 'Mot de passe oublié' "Création de compte",
  114.             'context' => $context
  115.         ));
  116.     }
  117.     /**
  118.      * @Route("/reset-password/{user}", name="reset-password", methods={"GET", "POST"})
  119.      */
  120.     public function resetPassword(Request $requestUser $userJwtHandler $jwtUserPasswordHasherInterface $encoder,ManagerRegistry $managerRegistry)
  121.     {
  122.         $token $request->query->get('token');
  123.         $decoded $jwt->verifyToken($token);
  124.         if (!$decoded || !$jwt->verifyUserToken($user->getId(), $decoded)) {
  125.             throw $this->createAccessDeniedException();
  126.         }
  127.         $form $this->createForm(PwdType::class, $user);
  128.         $form->handleRequest($request);
  129.         if ($form->isSubmitted() && $form->isValid()) {
  130.             $encoded $encoder->hashPassword($user$user->getPlainPassword());
  131.             $user->setPassword($encoded);
  132.             $entityManager $managerRegistry->getManager();
  133.             $entityManager->persist($user);
  134.             $entityManager->flush();
  135.             $this->addFlash('notice-success'"Votre mot de passe a été créé, vous pouvez vous connecter.");
  136.             return $this->redirectToRoute('app_login');
  137.         }
  138.         return $this->render('security/screen/reset-pwd.html.twig', array(
  139.             'form' => $form->createView(),
  140.             'title_page' => 'Réinitialisation du mot de passe'
  141.         ));
  142.     }
  143.     /**
  144.      * @Route("/create-account/{user}", name="create-account", methods={"GET", "POST"})
  145.      */
  146.     public function createAccount(Request $requestUser $userJwtHandler $jwtUserPasswordHasherInterface $encoderManagerRegistry $managerRegistry)
  147.     {
  148.         $token $request->query->get('token');
  149.         $decoded $jwt->verifyToken($token);
  150.         if (
  151.             !$decoded || !$jwt->verifyUserToken($user->getId(), $decoded) ||
  152.             $user->getPassword() // déjà un compte avec mot de passe
  153.         ) {
  154.             throw $this->createAccessDeniedException();
  155.         }
  156.         $form $this->createForm(PwdType::class, $user)
  157.             ->add('agreeTerms'CheckboxType::class, [
  158.                 'label' =>false,
  159.                 'label_html' => true,
  160.                 'mapped' => false,
  161.                 'constraints' => [
  162.                     new IsTrue([
  163.                         'message' => 'Vous devez accepter les conditions générales.',
  164.                     ]),
  165.                 ],
  166.                 'required' => true,
  167.             ]);
  168.         $form->handleRequest($request);
  169.         if ($form->isSubmitted() && $form->isValid()) {
  170.             $encoded $encoder->hashPassword($user$user->getPlainPassword());
  171.             $user->setPassword($encoded);
  172.             $user->setCgu(true);
  173.             $user->setAgreeTermsAt(new \DateTime("now", new \DateTimeZone("Europe/Paris")));
  174.             $entityManager $managerRegistry->getManager();
  175.             $entityManager->persist($user);
  176.             $entityManager->flush();
  177.             $this->addFlash('notice-success'"Votre mot de passe a été créé, vous pouvez vous connecter.");
  178.             return $this->redirectToRoute('app_login');
  179.         }
  180.         return $this->render('security/screen/create-account.html.twig', array(
  181.             'form' => $form->createView(),
  182.             'title_page' => 'Création du mot de passe'
  183.         ));
  184.     }
  185. }