src/Controller/Abstract/AuthenticationController.php line 183

  1. <?php
  2. namespace App\Controller\Abstract;
  3. use App\Service\AssociationHandlerService;
  4. use App\Service\TaggedTypesService;
  5. use App\Traits\Form\DiscriminatorFormGenerator;
  6. use Doctrine\ORM\EntityManagerInterface;
  7. use Exception;
  8. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  9. use Symfony\Component\HttpFoundation\RedirectResponse;
  10. use Symfony\Component\HttpFoundation\Request;
  11. use Symfony\Component\HttpFoundation\Response;
  12. use Symfony\Component\Mailer\MailerInterface;
  13. use Symfony\Component\Mime\Email;
  14. use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
  15. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  16. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  17. use Symfony\Component\Validator\Validator\ValidatorInterface;
  18. use Symfony\Contracts\Cache\CacheInterface;
  19. use Twig\Environment;
  20. /**
  21.  * Abstract authentication controller.
  22.  *
  23.  */
  24. class AuthenticationController extends CommonController
  25. {
  26.     use DiscriminatorFormGenerator;
  27.     const PATH_PREFIX 'authentication';
  28.     /**
  29.      * Abstract authenticate Method
  30.      *
  31.      * @param AuthenticationUtils $authenticationUtils
  32.      * @param Environment $twig
  33.      * @param TaggedTypesService $taggedTypesService
  34.      * @return RedirectResponse|Response
  35.      *
  36.      */
  37.     public function authenticate(AuthenticationUtils $authenticationUtilsEnvironment $twigTaggedTypesService $taggedTypesService): RedirectResponse|Response
  38.     {
  39.         // get entity class
  40.         $entityClass = static::class::ENTITY_CLASS;
  41.         // get template name
  42.         $method __FUNCTION__;
  43.         // get controller prefix
  44.         $controller = static::class::PATH_PREFIX;
  45.         // get the login error if there is one
  46.         $error $authenticationUtils->getLastAuthenticationError();
  47.         // last username entered by the user
  48.         $lastUsername $authenticationUtils->getLastUsername();
  49.         $templatePath $controller '/' __FUNCTION__ '.html.twig';
  50.         $entityName $taggedTypesService->getShortEntityName($entityClass);
  51.         if ($twig->getLoader()->exists($controller '/' $entityName '/' $method '.html.twig')) {
  52.             $templatePath $controller '/' $entityName '/' $method '.html.twig';
  53.         } else {
  54.             if ($twig->getLoader()->exists($controller '/' $method '.html.twig')) {
  55.                 $templatePath $controller '/' $method '.html.twig';
  56.             }
  57.         }
  58.         return $this->render($templatePath, array(
  59.             'path_prefix' => self::PATH_PREFIX,
  60.             'last_username' => $lastUsername,
  61.             'error' => $error,
  62.             'entity_name' => $entityName,
  63.             'path_entity_name' => $entityClass::ENTITY_PATH_IDENTIFIER,
  64.         ));
  65.     }
  66.     /**
  67.      * Abstract Verify Method
  68.      *
  69.      * @param Request $request
  70.      * @param EntityManagerInterface $entityManager
  71.      *
  72.      * @return RedirectResponse|Response
  73.      */
  74.     public function verify(Request $requestEntityManagerInterface $entityManager): RedirectResponse|Response
  75.     {
  76.         // get entity class
  77.         $entityClass = static::class::ENTITY_CLASS;
  78.         // get user
  79.         $user $entityManager->getRepository($entityClass)->findOneBy(['verificationToken' => $request->get('token')]);
  80.         $user->setVerified(true);
  81.         $user->setVerificationToken(null);
  82.         $entityManager->flush();
  83.         $this->addFlash(
  84.             'success',
  85.             'User successfully verified'
  86.         );
  87.         return $this->redirect('/');
  88.     }
  89.     /**
  90.      * Abstract Reset Method
  91.      *
  92.      * @param Request $request
  93.      * @param ValidatorInterface $validator
  94.      * @param EntityManagerInterface $entityManager
  95.      * @param UrlGeneratorInterface $router
  96.      * @param AssociationHandlerService $associationHandlerService
  97.      * @param TaggedTypesService $taggedTypesService
  98.      * @param Environment $twig
  99.      * @param UserPasswordHasherInterface $passwordHasher
  100.      * @return RedirectResponse|Response
  101.      *
  102.      * @throws Exception
  103.      */
  104.     public function reset(Request $requestValidatorInterface $validatorEntityManagerInterface $entityManagerUrlGeneratorInterface $routerAssociationHandlerService $associationHandlerServiceTaggedTypesService $taggedTypesServiceEnvironment $twigUserPasswordHasherInterface $passwordHasher): RedirectResponse|Response
  105.     {
  106.         // get entity class
  107.         $entityClass = static::class::ENTITY_CLASS;
  108.         // get user
  109.         $user $entityManager->getRepository($entityClass)->findOneBy(['resetToken' => $request->get('token')]);
  110.         // get entities
  111.         $entities = [$user];
  112.         // get controller prefix
  113.         $controller = static::class::PATH_PREFIX;
  114.         // get template name
  115.         $method __FUNCTION__;
  116.         // generate form class pairs
  117.         $formTypeClassPairs $taggedTypesService->getDescendantEntityFormPairs($entityClass$controller$method);
  118.         // post submit function
  119.         $postSubmitFunction = function ($entities$form) use ($passwordHasher) {
  120.             foreach ($entities as $entity) {
  121.                 $entity->setResetToken(null);
  122.                 $hashedPassword $passwordHasher->hashPassword(
  123.                     $entity,
  124.                     $entity->getPassword()
  125.                 );
  126.                 $entity->setPassword($hashedPassword);
  127.             }
  128.         };
  129.         // on success function
  130.         $successFunction = function () {
  131.             $this->addFlash(
  132.                 'success',
  133.                 'Password updated successfully'
  134.             );
  135.             return $this->redirect('/');
  136.         };
  137.         return $this->generic($request$validator$entityManager$associationHandlerService$taggedTypesService$router$twig$entityClass$method$formTypeClassPairs$controller$entitiesnull$postSubmitFunction$successFunctionfalse);
  138.     }
  139.     /**
  140.      * Abstract Register Method
  141.      *
  142.      * @param Request $request
  143.      * @param ValidatorInterface $validator
  144.      * @param EntityManagerInterface $entityManager
  145.      * @param UrlGeneratorInterface $router
  146.      * @param AssociationHandlerService $associationHandlerService
  147.      * @param TaggedTypesService $taggedTypesService
  148.      * @param Environment $twig
  149.      * @return Response | RedirectResponse
  150.      *
  151.      * @throws Exception
  152.      */
  153.     public function register(Request $requestValidatorInterface $validatorEntityManagerInterface $entityManagerUrlGeneratorInterface $routerAssociationHandlerService $associationHandlerServiceTaggedTypesService $taggedTypesServiceEnvironment $twig): Response RedirectResponse
  154.     {
  155.         // get entity class
  156.         $entityClass = static::class::ENTITY_CLASS;
  157.         // get entities
  158.         $entities = [];
  159.         // get template name
  160.         $method __FUNCTION__;
  161.         // get controller prefix
  162.         $controller = static::class::PATH_PREFIX;
  163.         // generate form class pairs
  164.         $formTypeClassPairs $taggedTypesService->getDescendantEntityFormPairs($entityClass$controller$method);
  165.         // post submit function
  166.         $postSubmitFunction = function ($entities$form) use ($entityManager) {
  167.             foreach ($entities as $entity) {
  168.                 $entityManager->persist($entity);
  169.             }
  170.         };
  171.         // on success function
  172.         $successFunction = function () {
  173.             $this->addFlash(
  174.                 'success',
  175.                 'Thank you for registering, please check your email inbox for confirmation'
  176.             );
  177.             return $this->redirect('/');
  178.         };
  179.         return $this->generic($request$validator$entityManager$associationHandlerService$taggedTypesService$router$twig$entityClass$method$formTypeClassPairs$controller$entitiesnull$postSubmitFunction$successFunction);
  180.     }
  181.     /**
  182.      * Abstract Reset Request Method
  183.      *
  184.      * @param Request $request
  185.      * @param ValidatorInterface $validator
  186.      * @param EntityManagerInterface $entityManager
  187.      * @param AssociationHandlerService $associationHandlerService
  188.      * @param TaggedTypesService $taggedTypesService
  189.      * @param Environment $twig
  190.      * @param MailerInterface $mailer
  191.      * @param ParameterBagInterface $params
  192.      * @param UrlGeneratorInterface $router
  193.      * @return Response | RedirectResponse
  194.      *
  195.      * @throws Exception
  196.      */
  197.     public function request(Request $requestValidatorInterface $validatorEntityManagerInterface $entityManagerAssociationHandlerService $associationHandlerServiceTaggedTypesService $taggedTypesServiceEnvironment $twigMailerInterface $mailerParameterBagInterface $paramsUrlGeneratorInterface $router): Response RedirectResponse
  198.     {
  199.         // get entity class
  200.         $entityClass = static::class::ENTITY_CLASS;
  201.         // get entities
  202.         $entities = [];
  203.         // get template name
  204.         $method __FUNCTION__;
  205.         // get controller prefix
  206.         $controller = static::class::PATH_PREFIX;
  207.         // generate form class pairs
  208.         $formTypeClassPairs $taggedTypesService->getDescendantEntityFormPairs($entityClass$controller$method);
  209.         // post submit function
  210.         $postSubmitFunction = function ($entities$form) use ($entityManager$params$mailer$router$entityClass$taggedTypesService) {
  211.             $entityName $taggedTypesService->getShortEntityName($entityClass);
  212.             $pathEntityName strtolower(trim(preg_replace('/(?<!\ )[A-Z]/''_$0'$entityName), '_'));
  213.             $entityArray array_filter(array_merge([], ...array_values($form->getData())));
  214.             foreach ($entityArray as $arrayEntity) {
  215.                 $entity $entityManager->getRepository(get_class($arrayEntity))->findOneBy(['email' => $arrayEntity->getEmail()]);
  216.                 if ($entity) {
  217.                     $token bin2hex(random_bytes(64));
  218.                     $token substr($token064);
  219.                     $entity->setResetToken($token);
  220.                     $email = (new Email())
  221.                         ->from($params->get('site_from_email'))
  222.                         ->to($entity->getEmail())
  223.                         ->subject('Password reset request')
  224.                         ->text('Please visit ' $router->generate('authentication_' $pathEntityName '_reset', ['token' => $token], UrlGeneratorInterface::ABSOLUTE_URL) . ' to reset your password')
  225.                         ->html('<p>Please visit <a href="' $router->generate('authentication_' $pathEntityName '_reset', ['token' => $token], UrlGeneratorInterface::ABSOLUTE_URL) . '">' $params->get('site_short_title') . '</a> to reset your password</p>');
  226.                     $mailer->send($email);
  227.                 }
  228.             }
  229.         };
  230.         // on success function
  231.         $successFunction = function () {
  232.             $this->addFlash(
  233.                 'success',
  234.                 'If a user with that address exists, a password reset link will be emailed to them'
  235.             );
  236.             return $this->redirect('/');
  237.         };
  238.         return $this->generic($request$validator$entityManager$associationHandlerService$taggedTypesService$router$twig$entityClass$method$formTypeClassPairs$controller$entitiesnull$postSubmitFunction$successFunctionfalse);
  239.     }
  240. }