src/UI/WebBundle/Controller/Security/SecurityController.php line 62

Open in your IDE?
  1. <?php
  2. namespace Whater\UI\WebBundle\Controller\Security;
  3. use Whater\UI\WebBundle\Controller\AbstractBusController;
  4. use Whater\Infrastructure\SecurityBundle\Form\Type\LoginType;
  5. use Symfony\Component\HttpFoundation\Request;
  6. use Symfony\Component\Security\Core\Security;
  7. use Symfony\Component\HttpFoundation\RedirectResponse;
  8. use Symfony\Component\Routing\Annotation\Route;
  9. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  10. use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
  11. use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
  12. use Symfony\Component\Security\Http\SecurityEvents;
  13. use Whater\Application\UseCase\Security\CommandRequest\LoginCommand;
  14. use Whater\Application\UseCase\Security\CommandRequest\ForgotPasswordCommand;
  15. use Whater\Infrastructure\SecurityBundle\Form\Type\ForgotPaswordType;
  16. use Whater\Infrastructure\SecurityBundle\Form\Type\ResetPaswordType;
  17. use Whater\Application\UseCase\Security\CommandRequest\ResetPasswordCommand;
  18. use Whater\Application\UseCase\Security\CommandRequest\SignupCommand;
  19. use Whater\Domain\User\Exception\UserNotFoundException;
  20. use Whater\Domain\User\Exception\ResetTokenExpiredException;
  21. use Whater\Application\UseCase\User\CommandRequest\GetUserByUsernameCommand;
  22. use Whater\Domain\Security\Exception\InvalidUsernameException;
  23. use Whater\Infrastructure\SecurityBundle\Form\Type\SignupType;
  24. use Whater\Infrastructure\SecurityBundle\Security\Model\Auth;
  25. /**
  26. * @Route("")
  27. */
  28. class SecurityController extends AbstractBusController
  29. {
  30. /**
  31. * @Route("/login", name="web_login", defaults={"_format" = "html"})
  32. */
  33. public function loginAction(Request $request)
  34. {
  35. // save redirect_after_login in session
  36. $session = $request->getSession();
  37. $redirectAfterRegister = $request->query->get('redirect_after_login');
  38. if ($redirectAfterRegister) {
  39. $session->set('redirect_after_login', $redirectAfterRegister);
  40. }
  41. // If user is authenticated redirect to user dashboard
  42. if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
  43. return new RedirectResponse($this->router()->generate('web_app_user_dashboard'));
  44. }
  45. $targetPath = $request->get('_target_path');
  46. $form = $this->getFormFactory()->create(LoginType::class, LoginCommand::convertToDTO(), array(
  47. 'action' => $this->router()->generate('web_login_check', array('_target_path' => $targetPath), true),
  48. 'method' => 'POST',
  49. 'csrf_protection' => true
  50. ));
  51. $session = $request->getSession();
  52. if ($request->attributes->has(Security::AUTHENTICATION_ERROR)) {
  53. $error = $request->attributes->get(Security::AUTHENTICATION_ERROR);
  54. } elseif (null !== $session && $session->has(Security::AUTHENTICATION_ERROR)) {
  55. $error = $session->get(Security::AUTHENTICATION_ERROR);
  56. $session->remove(Security::AUTHENTICATION_ERROR);
  57. } else {
  58. $error = null;
  59. }
  60. if (!$error instanceof AuthenticationException) {
  61. $error = null;
  62. }
  63. if (!empty($error)) {
  64. $this->setFlash('error', $this->translator()->trans($error->getMessageKey(), $error->getMessageData(), 'security'));
  65. }
  66. return $this->render('Security/login.html.twig', array('form' => $form->createView()));
  67. }
  68. /**
  69. * @Route("/login_check", name="web_login_check", defaults={"_format" = "html"})
  70. */
  71. public function loginCheckAction(Request $request)
  72. {
  73. throw new \RuntimeException('You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.');
  74. }
  75. /**
  76. * @Route("/logout", name="web_logout", defaults={"_format" = "html"})
  77. */
  78. public function logoutAction()
  79. {
  80. throw new \RuntimeException('You must activate the logout in your security firewall configuration.');
  81. }
  82. /**
  83. * @Route("/forgot_password", name="web_forgot_password", defaults={"_format" = "html"})
  84. */
  85. public function forgotPasswordAction(Request $request)
  86. {
  87. // If user is authenticated redirect to user dashboard
  88. if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
  89. return new RedirectResponse($this->router()->generate('web_init'));
  90. }
  91. $form = $this->getFormFactory()->create(ForgotPaswordType::class, ForgotPasswordCommand::convertToDTO(), array(
  92. 'action' => $this->router()->generate('web_forgot_password', array(), true),
  93. 'method' => 'POST',
  94. 'csrf_protection' => true
  95. ));
  96. if ('POST' === $request->getMethod()) {
  97. $form->handleRequest($request);
  98. $error = '';
  99. if ($form->isSubmitted() && $form->isValid()) {
  100. try {
  101. $this->handle(ForgotPasswordCommand::fromDTO($form->getData()));
  102. $this->setFlash('success', $this->translator()->trans('web.security.forgot_password.success'));
  103. } catch (UserNotFoundException $e) {
  104. $this->setFlash('error', $this->translator()->trans('web.security.forgot_password.user_not_found'));
  105. }
  106. } else {
  107. $this->setFlash('error', $this->translator()->trans('web.security.forgot_password.error'));
  108. }
  109. }
  110. return $this->render(
  111. 'Security/forgot_password.html.twig',
  112. array('form' => $form->createView())
  113. );
  114. }
  115. /**
  116. * @Route("/reset_password/{resetToken}", name="web_reset_password", defaults={"_format" = "html"})
  117. */
  118. public function forgotPasswordLandingAction(Request $request, string $resetToken)
  119. {
  120. // If user is authenticated redirect to user dashboard
  121. if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
  122. return new RedirectResponse($this->router()->generate('web_init'));
  123. }
  124. $form = $this->getFormFactory()->create(ResetPaswordType::class, ResetPasswordCommand::convertToDTO(), array(
  125. 'action' => $this->router()->generate(
  126. 'web_reset_password',
  127. array(
  128. 'resetToken' => $resetToken
  129. ),
  130. true
  131. ),
  132. 'method' => 'POST',
  133. 'csrf_protection' => true,
  134. 'resetToken' => $resetToken
  135. ));
  136. if ('POST' === $request->getMethod()) {
  137. $form->handleRequest($request);
  138. if ($form->isSubmitted() && $form->isValid()) {
  139. try {
  140. $username = $this->handle(ResetPasswordCommand::fromDTO($form->getData()));
  141. $user = $this->handle(new GetUserByUsernameCommand($username));
  142. //Autenticate and go to dashboard
  143. $token = new UsernamePasswordToken(new Auth($user), null, "main", $user->rolesAsArray());
  144. $this->tokenStorage()->setToken($token); //now the user is logged in
  145. $this->session()->set('_security_main', serialize($token));
  146. return new RedirectResponse($this->router()->generate('web_init'));
  147. } catch (ResetTokenExpiredException $e) {
  148. $this->setFlash('error', $this->translator()->trans('web.security.reset_password.invalid_token'));
  149. } catch (UserNotFoundException $e) {
  150. $this->setFlash('error', $this->translator()->trans('web.security.reset_password.user_not_found'));
  151. }
  152. } else {
  153. $this->setFlash('error', $this->translator()->trans('web.security.reset_password.error'));
  154. }
  155. }
  156. return $this->render(
  157. 'Security/reset_password.html.twig',
  158. array('form' => $form->createView())
  159. );
  160. }
  161. /**
  162. * @Route("/signup", name="web_signup", defaults={"_format" = "html"})
  163. */
  164. public function signupUserAction(Request $request)
  165. {
  166. if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
  167. return new RedirectResponse($this->router()->generate('web_init'));
  168. }
  169. $form = $this->getFormFactory()->create(SignupType::class, SignupCommand::convertToDTO(), array(
  170. 'method' => 'POST',
  171. 'csrf_protection' => true
  172. ));
  173. if ('POST' === $request->getMethod()) {
  174. $form->handleRequest($request);
  175. if ($form->isSubmitted() && $form->isValid()) {
  176. try {
  177. $user = $this->handle(SignupCommand::fromDTO($form->getData()));
  178. //Autenticate and go to dashboard
  179. $roles = ['ROLE_USER'];
  180. foreach ($user->roles() as $role) {
  181. $roles[] = $role->roleType();
  182. }
  183. $token = new UsernamePasswordToken(new Auth($user), null, "main", $roles);
  184. $this->tokenStorage()->setToken($token); //now the user is logged in
  185. $this->session()->set('_security_main', serialize($token));
  186. $loginEvent = new InteractiveLoginEvent($request, $token);
  187. $this->eventDispatcher()->dispatch($loginEvent, SecurityEvents::INTERACTIVE_LOGIN);
  188. $this->setFlash('info', $this->translator()->trans('web.security.signup.success'));
  189. $session = $request->getSession();
  190. if ($session->has('redirect_after_login')) {
  191. $redirectUrl = $session->get('redirect_after_login');
  192. $session->remove('redirect_after_login');
  193. // Seguridad: evitar redirecciones externas
  194. if ($redirectUrl && parse_url($redirectUrl, PHP_URL_HOST) === null) {
  195. return new RedirectResponse($redirectUrl);
  196. }
  197. }
  198. return new RedirectResponse($this->router()->generate('web_app_whater_map'));
  199. } catch (InvalidUsernameException $e) {
  200. $this->setFlash('error', $this->translator()->trans('web.security.signup.invalid_username'));
  201. } catch (\Exception $e) {
  202. $this->logger()->error($e->getMessage());
  203. $this->setFlash('error', $this->translator()->trans('web.security.signup.exception'));
  204. }
  205. } else {
  206. $this->setFlash('error', $this->translator()->trans('web.security.signup.error'));
  207. }
  208. }
  209. $referralCode = $request->get('referral_code');
  210. $response = $this->render(
  211. 'Security/signup.html.twig',
  212. array(
  213. 'form' => $form->createView(),
  214. 'referralCode' => $referralCode
  215. )
  216. );
  217. return $response;
  218. }
  219. }