src/Controller/SecurityController.php line 123

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Controller;
  4. use App\Entity\Account;
  5. use App\Entity\AccountOrganization;
  6. use App\Entity\AccountPro;
  7. use App\Entity\UserInterface;
  8. use App\Form\AccountOrganizationRegistrationProfilType;
  9. use App\Form\AccountProRegistrationProfilType;
  10. use App\Form\AccountProRegistrationType;
  11. use App\Form\AccountRegistrationProfilType;
  12. use App\Form\AccountRegistrationType;
  13. use App\Form\ResetPasswordRequestFormType;
  14. use App\Kernel;
  15. use App\Repository\AccountOrganizationRepository;
  16. use App\Repository\AccountProRepository;
  17. use App\Repository\AccountRepository;
  18. use App\Repository\OrganizationRepository;
  19. use App\Repository\PermissionRepository;
  20. use App\Repository\PraticienRepository;
  21. use App\Service\AccountOrganizationService;
  22. use App\Service\AccountProService;
  23. use App\Service\AccountService;
  24. use App\Service\AclService;
  25. use App\Service\Mail\AccountOrganizationPasswordMailer;
  26. use App\Service\Mail\AccountPasswordMailer;
  27. use App\Service\Mail\AccountProPasswordMailer;
  28. use App\Service\Mail\AccountProRegistrationMailer;
  29. use App\Service\Mail\AccountRegistrationMailer;
  30. use App\Service\Security;
  31. use App\Service\TelNumberService;
  32. use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
  33. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  34. use Symfony\Component\Form\FormError;
  35. use Symfony\Component\HttpFoundation\RedirectResponse;
  36. use Symfony\Component\HttpFoundation\Request;
  37. use Symfony\Component\HttpFoundation\Response;
  38. use Symfony\Component\Routing\Annotation\Route;
  39. class SecurityController extends AbstractController
  40. {
  41.     #[Route('/deconnexion'name'account_logout')]
  42.     public function accountLogout(Security $security): RedirectResponse
  43.     {
  44.         $security->logout();
  45.         return $this->redirectToRoute('home');
  46.     }
  47.     #[Route('/app/connexion'name'account_login')]
  48.     public function accountLogin(Security $securityRequest $requestAccountService $accountService): Response
  49.     {
  50.         return $this->redirectToRoute("home");
  51.     }
  52.     #[Route('/pro/connexion'name'accountpro_login')]
  53.     public function accountProLogin(Security $securityRequest $requestAccountProService $accountProService): Response
  54.     {
  55.         // Redirige l'utilisateur déjà connecté
  56.         if ($security->getUser() instanceof AccountPro) {
  57.             return $this->redirectToRoute('pro_home');
  58.         }
  59.         // Traite le formulaire de connexion
  60.         if ($request->isMethod('POST') && $this->isCsrfTokenValid('authenticate'$request->request->get('csrf'))) {
  61.             // On récupère le compte qui s'authentifie
  62.             $account $accountProService->getByLogin(
  63.                 $request->request->get('email'),
  64.                 $request->request->get('password'),
  65.             );
  66.             // Si un compte est valide et non supprimé, on le monte en session
  67.             if ($account instanceof AccountPro && !$account->isDeleted()) {
  68.                 $security->login($account,$request);
  69.                 return $this->redirectToRoute('pro_home');
  70.             }
  71.             // Gestion d'un message d'erreur
  72.             $this->addFlash('warning''Ces identifiants ne permettent pas de retrouver votre compte');
  73.         }
  74.         // Affiche le formulaire de connexion
  75.         return $this->render('security/accountpro_login.html.twig');
  76.     }
  77.     #[Route('/gestion/connexion'name 'manager_login')]
  78.     public function managerLogin(
  79.         Security $security,
  80.         Request $request,
  81.         AccountOrganizationService $accountOrganizationService
  82.     ):Response {
  83.         // Redirige l'utilisateur déjà connecté
  84.         if ($security->getUser() instanceof AccountOrganization) {
  85.             return $this->redirectToRoute('manager_home');
  86.         }
  87.         // Traite le formulaire de connexion
  88.         if ($request->isMethod('POST') && $this->isCsrfTokenValid('authenticate'$request->request->get('csrf'))) {
  89.             // On récupère le compte qui s'authentifie
  90.             $account $accountOrganizationService->getByLogin(
  91.                 $request->request->get('email'),
  92.                 $request->request->get('password'),
  93.             );
  94.             // Si un compte est valide et non supprimé, on le monte en session
  95.             if ($account instanceof AccountOrganization) {
  96.                 $security->login($account$request);
  97.                 return $this->redirectToRoute('manager_home');
  98.             }
  99.             // Gestion d'un message d'erreur
  100.             $this->addFlash('warning''Ces identifiants ne permettent pas de retrouver votre compte');
  101.         }
  102.         // Affiche le formulaire de connexion
  103.         return $this->render('security/manager_login.html.twig');
  104.     }
  105.     #[Route('/pro/inscription'name 'accountpro_registration')]
  106.     public function index(
  107.         Request $request,
  108.         AccountProService $accountProService,
  109.         AccountProRegistrationMailer $accountProRegistrationMailer,
  110.         PraticienRepository $praticienRepository,
  111.         Security $security
  112.     ):Response {
  113.         if ($security->getUser()) {
  114.             return $this->redirectToRoute('pro_home');
  115.         }
  116.         // Créé et peuple le formulaire
  117.         $form $this
  118.             ->createForm(AccountProRegistrationType::class)
  119.             ->handleRequest($request);
  120.         // Traite le formulaire
  121.         if ($form->isSubmitted() && $form->isValid()) {
  122.             $data $form->getData();
  123.             $praticien $praticienRepository->findOneBy([
  124.                 'idPP'      => $data['rpps'],
  125.                 'isDeleted' => 0,
  126.             ]);
  127.             if ($praticien) {
  128.                 $accountPro = new AccountPro();
  129.                 $accountPro
  130.                     ->setFirstname($data['firstname'])
  131.                     ->setLastname($data['lastname'])
  132.                     ->setEmail($data['email'])
  133.                     ->setProfession($data['profession'])
  134.                     ->setMobile($data['mobile'])
  135.                     ->setRpps($data['rpps'])
  136.                     ->setIsDeleted(false);
  137.                 // Enregistre le compte en base de données
  138.                 try {
  139.                     $accountProService->register($accountPro);
  140.                     // Envoie du mail de confirmation d'inscription
  141.                     $accountProRegistrationMailer->send($accountPro);
  142.                     return $this->render('registration/accountpro/index_confirmation.html.twig', [
  143.                         'account' => $accountPro,
  144.                     ]);
  145.                 } catch (UniqueConstraintViolationException $e) {
  146.                     // Todo : Gérer avec @UniqueEntity plutôt qu'avec l'exception
  147.                     $form->get('email')->addError(new FormError('Ce compte existe déjà'));
  148.                 }
  149.             } else {
  150.                 $form->get('rpps')->addError(new FormError('Ce numéro n\'est pas autorisé, vérifiez votre carte ou contactez-nous.'));
  151.             }
  152.         }
  153.         return $this->render('registration/accountpro/index.html.twig', [
  154.             'form' => $form->createView(),
  155.         ]);
  156.     }
  157.     #[Route('/pro/activation/{token}'name'accountpro_registration_profil')]
  158.     public function proProfil(
  159.         $token,
  160.         Request $request,
  161.         AccountProService $accountProService,
  162.         Security $security
  163.     ): Response {
  164.         if ($security->getUser()) {
  165.             return $this->redirectToRoute('pro_home');
  166.         }
  167.         $accountPro $accountProService->getByActivationToken($token);
  168.         if (!$accountPro instanceof AccountPro) {
  169.             $this->addFlash('error', [
  170.                 "Le lien d'activation n'est plus valide.",
  171.                 "Indiquez votre adresse email pour récupérer un nouveau lien."
  172.             ]);
  173.             return $this->redirectToRoute('pro_forgot_password_request');
  174.         }
  175.         $form $this
  176.             ->createForm(AccountProRegistrationProfilType::class, $accountPro)
  177.             ->handleRequest($request);
  178.         if ($form->isSubmitted() && $form->isValid()) {
  179.             $accountProService->activate($accountPro);
  180.             $security->login($accountPro$request);
  181.             return $this->redirectToRoute('pro_home');
  182.         }
  183.         return $this->render('registration/accountpro/profil.html.twig', [
  184.             'form'    => $form->createView(),
  185.             'account' => $accountPro,
  186.         ]);
  187.     }
  188.     #[Route('/app/inscription/{urlCode}'name 'account_registration')]
  189.     public function appInscription(
  190.         Request $request,
  191.         AccountService $accountService,
  192.         AccountRegistrationMailer $accountRegistrationMailer,
  193.         Security $security,
  194.         OrganizationRepository $organizationRepository,
  195.         Kernel $kernel,
  196.         ?string $urlCode null,
  197.         PermissionRepository $permissionRepository
  198.     ):Response {
  199.         if ($security->getUser()) {
  200.             return $this->redirectToRoute('app');
  201.         }
  202.         // Récupère le code dans l'url puis l'organisme correspondant s'il existe
  203.         $organization $organizationRepository->findOneBy(['registrationCode' => $urlCode]);
  204.         // S'il y a un code dans l'url et que le code n'est pas un code d'activation valide, la page est redirigée
  205.         if ($urlCode && !$organization) {
  206.             return $this->redirectToRoute('account_registration', ['urlCode' => null]);
  207.         }
  208.         // Créé et peuple le formulaire
  209.         $form $this
  210.             ->createForm(AccountRegistrationType::class, null, ["activationCode" => $urlCode])
  211.             ->handleRequest($request);
  212.         // Traite le formulaire s'il est soumis et valide
  213.         if ($form->isSubmitted() && $form->isValid()) {
  214.             /** @var Account $account */
  215.             $data $form->getData();
  216.             // Récupère le code d'activation correspondant au code saisie dans le formulaire
  217.             $code $form->get('activationCode')->getData();
  218.             $organization $organizationRepository->findOneBy(['registrationCode' => $code]);
  219.             if ($organization?->isEnabledRegistration()) {
  220.                 $account = new Account();
  221.                 $account->setFirstname($data['firstname'])
  222.                         ->setName($data['name'])
  223.                         ->setEmail($data['email'])
  224.                         ->setOrganization($organization)
  225.                         ->setEnable(true)
  226.                 ;
  227.                 // En dev ou beta, les comptes créés sont des comptes de demo
  228.                 if ($kernel->getEnvironment() !== 'prod') {
  229.                     $account->addRole('ROLE_DEMO');
  230.                 }
  231.             } else {
  232.                 //Si le code d'activation n'existe pas ou est désactivé, la création du compte n'est pas possible
  233.                 $this->addFlash('warning', [
  234.                     'Code d\'activation invalide',
  235.                     'Le code d\'activation est fourni par votre entreprise ou votre association.',
  236.                 ]);
  237.                 return $this->render('registration/account/index.html.twig', [
  238.                     'form' => $form->createView(),
  239.                 ]);
  240.             }
  241.             try {
  242.                 // Assigne les permissions à l'utilisateur en fonction de ses roles
  243.                 $aclService = new AclService($security);
  244.                 $permissionNames = [];
  245.                 $rolePermissionMap $aclService->getRolePermissionMap();
  246.                 foreach ($account->getRoles() as $role) {
  247.                     if (isset($rolePermissionMap[$role])) {
  248.                         $permissionNames += $rolePermissionMap[$role];
  249.                     }
  250.                 }
  251.                 $permissions $permissionRepository->findBy(['name' => $permissionNames]);
  252.                 $account->setPermissions($permissions);
  253.                 // Enregistre le compte en base de données
  254.                 $accountService->register($account);
  255.                 // Envoie du mail de confirmation d'inscription
  256.                 $accountRegistrationMailer->send($account);
  257.                 return $this->render('registration/account/index_confirmation.html.twig', [
  258.                     'account' => $account,
  259.                 ]);
  260.             } catch (UniqueConstraintViolationException $e) {
  261.                 // Todo : Gérer avec @UniqueEntity plutôt qu'avec l'exception
  262.                 $form->get('email')->addError(new FormError('Ce compte existe déjà'));
  263.             }
  264.         }
  265.         return $this->render('registration/account/index.html.twig', [
  266.             'form' => $form->createView(),
  267.         ]);
  268.     }
  269.     #[Route('/app/activation/{token}'name'account_registration_profil')]
  270.     public function appProfil(
  271.         $token,
  272.         Request $request,
  273.         AccountService $accountService,
  274.         Security $security,
  275.         TelNumberService $telNumberService
  276.     ): Response {
  277.         if ($security->getUser()) {
  278.             return $this->redirectToRoute('app');
  279.         }
  280.         $account $accountService->getByActivationToken($token);
  281.         if (!$account instanceof Account) {
  282.             $this->addFlash('error', [
  283.                 "Le lien d'activation n'est plus valide.",
  284.                 "Indiquez votre adresse email pour récupérer un nouveau lien."
  285.             ]);
  286.             return $this->redirectToRoute('app_forgot_password_request');
  287.         }
  288.         $form $this
  289.             ->createForm(AccountRegistrationProfilType::class, $account)
  290.             ->handleRequest($request);
  291.         if ($form->isSubmitted() && $form->isValid()) {
  292.             $formattedTelNumber $telNumberService->validateAndFormatPhone($account->getTelNumber());
  293.             $account->setTelNumber($formattedTelNumber);
  294.             
  295.             $accountService->activate($account);
  296.             $security->login($account$request);
  297.             return $this->redirectToRoute('app');
  298.         }
  299.         return $this->render('registration/account/profil.html.twig', [
  300.             'form'    => $form->createView(),
  301.             'account' => $account,
  302.         ]);
  303.     }
  304.     #[Route('/gestion/activation/{token}'name 'account_organization_registration_profil')]
  305.     public function managerProfil(
  306.         $token,
  307.         Request $request,
  308.         AccountOrganizationService $accountOrganizationService,
  309.         Security $security
  310.     ):Response {
  311.         if ($security->getOrganization()) {
  312.             return $this->redirectToRoute('manager_home');
  313.         }
  314.         $account $accountOrganizationService->getByActivationToken($token);
  315.         if (!$account instanceof AccountOrganization) {
  316.             $this->addFlash('error', [
  317.                 "Le lien d'activation n'est plus valide.",
  318.                 'Indiquez votre adresse email pour récupérer un nouveau lien.',
  319.             ]);
  320.             return $this->redirectToRoute('manager_forgot_password_request');
  321.         }
  322.         $form $this
  323.             ->createForm(AccountOrganizationRegistrationProfilType::class, $account)
  324.             ->handleRequest($request);
  325.         if ($form->isSubmitted() && $form->isValid()) {
  326.             $accountOrganizationService->activate($account);
  327.             $security->login($account$request);
  328.             return $this->redirectToRoute('manager_home');
  329.         }
  330.         return $this->render('registration/manager/profil.html.twig', [
  331.             'form'    => $form->createView(),
  332.             'account' => $account,
  333.         ]);
  334.     }
  335.     #[Route('/app/mot-de-passe'name 'app_forgot_password_request')]
  336.     public function password(
  337.         Request $request,
  338.         Security $security,
  339.         AccountService $accountService,
  340.         AccountRepository $accountRepository,
  341.         AccountProRepository $accountProRepository,
  342.         AccountPasswordMailer $accountPasswordMailer
  343.     ):Response {
  344.         if ($security->getUser() instanceof Account) {
  345.             return $this->redirectToRoute('app');
  346.         }
  347.         $form $this->createForm(ResetPasswordRequestFormType::class);
  348.         $form->handleRequest($request);
  349.         if ($form->isSubmitted() && $form->isValid()) {
  350.             $user $accountRepository->findOneBy([
  351.                 'email' => $form->get('email')->getData(),
  352.             ]);
  353.             if ($user === null) {
  354.                 $user $accountProRepository->findOneBy([
  355.                     'email' => $form->get('email')->getData(),
  356.                 ]);
  357.             }
  358.             if ($user instanceof UserInterface) {
  359.                 $token $accountService->tokenRequest($user);
  360.                 $accountPasswordMailer->send($user$token);
  361.             }
  362.             return $this->render('reset_password/check_email.html.twig');
  363.         }
  364.         return $this->render('reset_password/request.html.twig', [
  365.             'requestForm' => $form->createView(),
  366.         ]);
  367.     }
  368.     #[Route('/pro/mot-de-passe'name'pro_forgot_password_request')]
  369.     public function proPassword(
  370.         Request $request,
  371.         Security $security,
  372.         AccountProService $accountProService,
  373.         AccountRepository $accountRepository,
  374.         AccountProRepository $accountProRepository,
  375.         AccountProPasswordMailer $accountProPasswordMailer
  376.     ): Response {
  377.         if ($security->getUser() instanceof AccountPro) {
  378.             return $this->redirectToRoute('app');
  379.         }
  380.         $form $this->createForm(ResetPasswordRequestFormType::class);
  381.         $form->handleRequest($request);
  382.         if ($form->isSubmitted() && $form->isValid()) {
  383.             $user $accountProRepository->findOneBy([
  384.                 'email' => $form->get('email')->getData(),
  385.             ]);
  386.             if ($user === null) {
  387.                 $user $accountRepository->findOneBy([
  388.                     'email' => $form->get('email')->getData(),
  389.                 ]);
  390.             }
  391.             if ($user instanceof UserInterface) {
  392.                 $token $accountProService->tokenRequest($user);
  393.                 $accountProPasswordMailer->send($user$token);
  394.             }
  395.             return $this->render('reset_password/check_email.html.twig', [
  396.                 'context' => 'pro',
  397.             ]);
  398.         }
  399.         return $this->render('reset_password/request.html.twig', [
  400.             'requestForm' => $form->createView(),
  401.             'context'     => 'pro',
  402.         ]);
  403.     }
  404.     #[Route('/gestion/mot-de-passe'name 'manager_forgot_password_request')]
  405.     public function managerPassword(
  406.         Request $request,
  407.         Security $security,
  408.         AccountOrganizationRepository $accountOrganizationRepository,
  409.         AccountOrganizationService $accountOrganizationService,
  410.         AccountOrganizationPasswordMailer $accountOrganizationPasswordMailer
  411.     ):Response {
  412.         if ($security->getOrganization() instanceof AccountOrganization) {
  413.             return $this->redirectToRoute('manager_home');
  414.         }
  415.         $form $this->createForm(ResetPasswordRequestFormType::class);
  416.         $form->handleRequest($request);
  417.         if ($form->isSubmitted() && $form->isValid()) {
  418.             $user $accountOrganizationRepository->findOneBy([
  419.                 'email' => $form->get('email')->getData(),
  420.             ]);
  421.             if ($user instanceof AccountOrganization) {
  422.                 $token $accountOrganizationService->tokenRequest($user);
  423.                 $accountOrganizationPasswordMailer->send($user$token);
  424.             }
  425.             return $this->render('reset_password/check_email.html.twig', [
  426.                 'context' => 'manager',
  427.             ]);
  428.         }
  429.         return $this->render('reset_password/request.html.twig', [
  430.             'requestForm' => $form->createView(),
  431.             'context'     => 'manager',
  432.         ]);
  433.     }
  434. }