ResettingController.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <?php
  2. /*
  3. * This file is part of the FOSUserBundle package.
  4. *
  5. * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace FOS\UserBundle\Controller;
  11. use Symfony\Component\DependencyInjection\ContainerAware;
  12. use Symfony\Component\HttpFoundation\Response;
  13. use Symfony\Component\HttpFoundation\RedirectResponse;
  14. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  15. use Symfony\Component\Security\Core\Exception\AccountStatusException;
  16. use FOS\UserBundle\Model\UserInterface;
  17. /**
  18. * Controller managing the resetting of the password
  19. *
  20. * @author Thibault Duplessis <thibault.duplessis@gmail.com>
  21. * @author Christophe Coevoet <stof@notk.org>
  22. */
  23. class ResettingController extends ContainerAware
  24. {
  25. const SESSION_EMAIL = 'fos_user_send_resetting_email/email';
  26. /**
  27. * Request reset user password: show form
  28. */
  29. public function requestAction()
  30. {
  31. return $this->container->get('templating')->renderResponse('FOSUserBundle:Resetting:request.html.'.$this->getEngine());
  32. }
  33. /**
  34. * Request reset user password: submit form and send email
  35. */
  36. public function sendEmailAction()
  37. {
  38. $username = $this->container->get('request')->request->get('username');
  39. /** @var $user UserInterface */
  40. $user = $this->container->get('fos_user.user_manager')->findUserByUsernameOrEmail($username);
  41. if (null === $user) {
  42. return $this->container->get('templating')->renderResponse('FOSUserBundle:Resetting:request.html.'.$this->getEngine(), array('invalid_username' => $username));
  43. }
  44. if ($user->isPasswordRequestNonExpired($this->container->getParameter('fos_user.resetting.token_ttl'))) {
  45. return $this->container->get('templating')->renderResponse('FOSUserBundle:Resetting:passwordAlreadyRequested.html.'.$this->getEngine());
  46. }
  47. if (null === $user->getConfirmationToken()) {
  48. /** @var $tokenGenerator \FOS\UserBundle\Util\TokenGeneratorInterface */
  49. $tokenGenerator = $this->container->get('fos_user.util.token_generator');
  50. $user->setConfirmationToken($tokenGenerator->generateToken());
  51. }
  52. $this->container->get('session')->set(static::SESSION_EMAIL, $this->getObfuscatedEmail($user));
  53. $this->container->get('fos_user.mailer')->sendResettingEmailMessage($user);
  54. $user->setPasswordRequestedAt(new \DateTime());
  55. $this->container->get('fos_user.user_manager')->updateUser($user);
  56. return new RedirectResponse($this->container->get('router')->generate('fos_user_resetting_check_email'));
  57. }
  58. /**
  59. * Tell the user to check his email provider
  60. */
  61. public function checkEmailAction()
  62. {
  63. $session = $this->container->get('session');
  64. $email = $session->get(static::SESSION_EMAIL);
  65. $session->remove(static::SESSION_EMAIL);
  66. if (empty($email)) {
  67. // the user does not come from the sendEmail action
  68. return new RedirectResponse($this->container->get('router')->generate('fos_user_resetting_request'));
  69. }
  70. return $this->container->get('templating')->renderResponse('FOSUserBundle:Resetting:checkEmail.html.'.$this->getEngine(), array(
  71. 'email' => $email,
  72. ));
  73. }
  74. /**
  75. * Reset user password
  76. */
  77. public function resetAction($token)
  78. {
  79. $user = $this->container->get('fos_user.user_manager')->findUserByConfirmationToken($token);
  80. if (null === $user) {
  81. throw new NotFoundHttpException(sprintf('The user with "confirmation token" does not exist for value "%s"', $token));
  82. }
  83. if (!$user->isPasswordRequestNonExpired($this->container->getParameter('fos_user.resetting.token_ttl'))) {
  84. return new RedirectResponse($this->container->get('router')->generate('fos_user_resetting_request'));
  85. }
  86. $form = $this->container->get('fos_user.resetting.form');
  87. $formHandler = $this->container->get('fos_user.resetting.form.handler');
  88. $process = $formHandler->process($user);
  89. if ($process) {
  90. $this->setFlash('fos_user_success', 'resetting.flash.success');
  91. $response = new RedirectResponse($this->getRedirectionUrl($user));
  92. $this->authenticateUser($user, $response);
  93. return $response;
  94. }
  95. return $this->container->get('templating')->renderResponse('FOSUserBundle:Resetting:reset.html.'.$this->getEngine(), array(
  96. 'token' => $token,
  97. 'form' => $form->createView(),
  98. ));
  99. }
  100. /**
  101. * Authenticate a user with Symfony Security
  102. *
  103. * @param \FOS\UserBundle\Model\UserInterface $user
  104. * @param \Symfony\Component\HttpFoundation\Response $response
  105. */
  106. protected function authenticateUser(UserInterface $user, Response $response)
  107. {
  108. try {
  109. $this->container->get('fos_user.security.login_manager')->loginUser(
  110. $this->container->getParameter('fos_user.firewall_name'),
  111. $user,
  112. $response);
  113. } catch (AccountStatusException $ex) {
  114. // We simply do not authenticate users which do not pass the user
  115. // checker (not enabled, expired, etc.).
  116. }
  117. }
  118. /**
  119. * Generate the redirection url when the resetting is completed.
  120. *
  121. * @param \FOS\UserBundle\Model\UserInterface $user
  122. *
  123. * @return string
  124. */
  125. protected function getRedirectionUrl(UserInterface $user)
  126. {
  127. return $this->container->get('router')->generate('fos_user_profile_show');
  128. }
  129. /**
  130. * Get the truncated email displayed when requesting the resetting.
  131. *
  132. * The default implementation only keeps the part following @ in the address.
  133. *
  134. * @param \FOS\UserBundle\Model\UserInterface $user
  135. *
  136. * @return string
  137. */
  138. protected function getObfuscatedEmail(UserInterface $user)
  139. {
  140. $email = $user->getEmail();
  141. if (false !== $pos = strpos($email, '@')) {
  142. $email = '...' . substr($email, $pos);
  143. }
  144. return $email;
  145. }
  146. /**
  147. * @param string $action
  148. * @param string $value
  149. */
  150. protected function setFlash($action, $value)
  151. {
  152. $this->container->get('session')->getFlashBag()->set($action, $value);
  153. }
  154. protected function getEngine()
  155. {
  156. return $this->container->getParameter('fos_user.template.engine');
  157. }
  158. }