src/Controller/SecurityController.php line 122

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