vendor/roothirsch/core-bundle/Security/Controller/RegistrationController.php line 92

Open in your IDE?
  1. <?php
  2. namespace Roothirsch\CoreBundle\Security\Controller;
  3. use Doctrine\ORM\EntityManagerInterface;
  4. use Roothirsch\CoreBundle\Entity\Address;
  5. use Roothirsch\CoreBundle\Entity\ContactValidation;
  6. use Roothirsch\CoreBundle\Entity\User;
  7. use Roothirsch\CoreBundle\Messaging\MessagingService;
  8. use Roothirsch\CoreBundle\Repository\GroupRepository;
  9. use Roothirsch\CoreBundle\Repository\UserRepository;
  10. use Roothirsch\CoreBundle\Security\Event\RegistrationCompletedEvent;
  11. use Roothirsch\CoreBundle\Security\Event\RegistrationTokenCreatedEvent;
  12. use Roothirsch\CoreBundle\Security\Form\RegistrationUserType;
  13. use Roothirsch\CoreBundle\Security\Form\RegistrationRequestFormType;
  14. use Roothirsch\CoreBundle\Security\UserManager;
  15. use Roothirsch\CoreBundle\Site\Repository\SiteRepository;
  16. use Roothirsch\CoreBundle\Site\SiteProvider;
  17. use Roothirsch\CoreBundle\Translation\Services\CoreTranslator;
  18. use Symfony\Bridge\Twig\Mime\TemplatedEmail;
  19. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  20. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  21. use Symfony\Component\HttpFoundation\RedirectResponse;
  22. use Symfony\Component\HttpFoundation\Request;
  23. use Symfony\Component\HttpFoundation\Response;
  24. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  25. use Symfony\Component\Mailer\MailerInterface;
  26. use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
  27. use Symfony\Component\Routing\Annotation\Route;
  28. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  29. use SymfonyCasts\Bundle\ResetPassword\Exception\ResetPasswordExceptionInterface;
  30. /**
  31. * @Route("/registration", name="app_registration_")
  32. */
  33. class RegistrationController extends AbstractController
  34. {
  35. /** @var UserRepository */
  36. private $userRepository;
  37. /** @var SiteProvider */
  38. private $siteProvider;
  39. /** @var MailerInterface */
  40. private $mailer;
  41. /** @var EntityManagerInterface */
  42. private $entityManager;
  43. /** @var UserPasswordHasherInterface */
  44. private $passwordHasher;
  45. /** @var EventDispatcherInterface */
  46. private $dispatcher;
  47. /** @var GroupRepository */
  48. private $groupRepository;
  49. /** @var MessagingService */
  50. private $messaging;
  51. /** @var CoreTranslator */
  52. private $translationService;
  53. /**
  54. * @param UserRepository $userRepository
  55. * @param SiteProvider $sideProvider
  56. * @param MailerInterface $mailer
  57. * @param EntityManagerInterface $entityManager
  58. * @param UserPasswordHasherInterface $passwordHasher
  59. * @param EventDispatcherInterface $dispatcher
  60. */
  61. public function __construct(UserRepository $userRepository, SiteProvider $sideProvider, MailerInterface $mailer, EntityManagerInterface $entityManager, UserPasswordHasherInterface $passwordHasher, EventDispatcherInterface $dispatcher, GroupRepository $groupRepository, MessagingService $messaging, CoreTranslator $translator)
  62. {
  63. $this->userRepository = $userRepository;
  64. $this->siteProvider = $sideProvider;
  65. $this->mailer = $mailer;
  66. $this->entityManager = $entityManager;
  67. $this->passwordHasher = $passwordHasher;
  68. $this->dispatcher = $dispatcher;
  69. $this->groupRepository = $groupRepository;
  70. $this->messaging = $messaging;
  71. $this->translationService = $translator;
  72. }
  73. /**
  74. * @Route("", name="request")
  75. * @param Request $request
  76. * @return Response
  77. */
  78. public function request(Request $request): Response
  79. {
  80. $form = $this->createForm(RegistrationRequestFormType::class);
  81. $form->handleRequest($request);
  82. if ($form->isSubmitted() && $form->isValid()) {
  83. return $this->processRegistrationData($form->get('email')->getData(), $request->getLocale());
  84. }
  85. return $this->render(
  86. 'security/registration/request.html.twig', [
  87. 'requestForm' => $form->createView()
  88. ]
  89. );
  90. }
  91. /**
  92. * Confirmation page after a user has requested a password reset.
  93. *
  94. * @Route("/check-email", name="check_email")
  95. */
  96. public function checkEmail(): Response
  97. {
  98. // Generate a fake token if the user does not exist or someone hit this page directly.
  99. // This prevents exposing whether or not a user was found with the given email address or not
  100. // if (null === ($resetToken = $this->getTokenObjectFromSession())) {
  101. // $resetToken = $this->resetPasswordHelper->generateFakeResetToken();
  102. // }
  103. return $this->render(
  104. 'security/registration/check_email.html.twig', [
  105. ]
  106. );
  107. }
  108. /**
  109. * Confirmation page after a user has requested a password reset.
  110. *
  111. * @Route("/completed", name="completed")
  112. */
  113. public function completed(): Response
  114. {
  115. return $this->render('security/registration/completed.html.twig');
  116. }
  117. /**
  118. * Confirmation page after a user has requested a password reset.
  119. *
  120. * @Route("/confirm/{token?}", name="confirm")
  121. */
  122. public function confirm(string $token=null, Request $request): Response
  123. {
  124. if($token){
  125. $this->getSessionService()->set("token", $token);
  126. return $this->redirectToRoute('app_registration_confirm');
  127. }
  128. $token = $this->getSessionService()->get("token");
  129. if(!$token){
  130. throw $this->createNotFoundException('Beim Aufruf wurde kein Schlüssel übergeben.');
  131. }
  132. $user = $this->userRepository->findUserByRegistrationToken($token);
  133. if(!$user){
  134. $this->addFlash('error', 'Beim Versuch Ihre Registrierung abzuschließen ist ein Problem aufgetreten');
  135. return $this->redirectToRoute('app_registration_request');
  136. }
  137. if(!$user->getContactValidation()){
  138. $contactValidation = new ContactValidation();
  139. $contactValidation->setAddress(new Address());
  140. $contactValidation->setUser($user);
  141. $user->setContactValidation($contactValidation);
  142. }
  143. $form = $this->createForm(RegistrationUserType::class, $user);
  144. $form->handleRequest($request);
  145. if ($form->isSubmitted() && $form->isValid()) {
  146. $user->addGroup($this->groupRepository->getOrCreateRole('ROLE_USER'));
  147. $user->setPassword($this->passwordHasher->hashPassword($user, $form->get('password')->getData()));
  148. return $this->sendRegistrationNotification($user);
  149. }
  150. return $this->render(
  151. 'security/registration/confirm.html.twig', [
  152. 'form' => $form->createView(),
  153. ]
  154. );
  155. }
  156. private function processRegistrationData(string $emailFormData, $locale = 'de'): RedirectResponse
  157. {
  158. $user = $this->userRepository->findUserByEmail($emailFormData);
  159. // Do not reveal whether a user account was found or not.
  160. if ($user && $user->getActive()) {
  161. return $this->redirectToRoute('app_registration_check_email');
  162. }
  163. if ($user instanceof User) {
  164. $token = $user->getRegistrationToken();
  165. if (empty($token)) {
  166. $token = bin2hex(random_bytes(24));
  167. $user->setRegistrationToken($token);
  168. $this->entityManager->persist($user);
  169. $this->entityManager->flush();
  170. }
  171. } else {
  172. $token = bin2hex(random_bytes(24));
  173. $user = new User();
  174. $user->setUsername($emailFormData);
  175. $user->setEmail($emailFormData);
  176. $user->setActive(false);
  177. $user->setAdmin(false);
  178. $user->setRegistrationToken($token);
  179. $this->entityManager->persist($user);
  180. $this->entityManager->flush();
  181. }
  182. $url = $this->generateUrl('app_registration_confirm', [ 'token' => $user->getRegistrationToken(), 'locale' => $locale ], UrlGeneratorInterface::ABSOLUTE_URL);
  183. $email = $this->messaging->createTranslatedEmail('security/registration/email.html.twig', ['url' => $url], $locale);
  184. $email
  185. ->to($user->getEmail())
  186. ->subject(
  187. $this->translationService->translate('email.registration.user_email.subject', 'Ihre Registrierung bei {siteTitle}', ['siteTitle' => $this->siteProvider->getTitle()])
  188. );
  189. $event = new RegistrationTokenCreatedEvent($user, $this->currentRequest());
  190. $event->addEmail('user_token', $email);
  191. $this->dispatcher->dispatch($event, RegistrationTokenCreatedEvent::EVENT);
  192. if(!$event->isPropagationStopped()){
  193. foreach ($event->getEmails() as $email){
  194. $this->mailer->send($email);
  195. }
  196. }
  197. // Store the token object in session for retrieval in check-email route.
  198. // $this->setTokenObjectInSession($resetToken);
  199. return $this->redirectToRoute('app_registration_check_email');
  200. }
  201. public function sendRegistrationNotification($user)
  202. {
  203. $user->setRegistrationToken(null);
  204. $user->setActive(true);
  205. // Dispatching an event so E-Mails can be properly send.
  206. $event = new RegistrationCompletedEvent($user, $this->currentRequest());
  207. $this->dispatcher->dispatch($event, RegistrationCompletedEvent::EVENT);
  208. if(!$event->isPropagationStopped()){
  209. foreach ($event->getEmails() as $email){
  210. $this->mailer->send($email);
  211. }
  212. }
  213. $this->entityManager->persist($user);
  214. $this->entityManager->flush();
  215. $this->getSessionService()->remove("token");
  216. return $this->redirectToRoute('app_registration_completed');
  217. }
  218. private function getSessionService(): SessionInterface
  219. {
  220. return $this->currentRequest()->getSession();
  221. }
  222. private function currentRequest(): Request{
  223. return $this->container->get('request_stack')->getCurrentRequest();
  224. }
  225. }