src/TSMS/UserBundle/EventListener/PasswordValidityListener.php line 93

Open in your IDE?
  1. <?php
  2. /**
  3. * Copyright (C) SUEZ Smart Solutions - All Rights Reserved
  4. * On’Connect Gateway Management, 2018
  5. * Unauthorized copying of this file, via any medium is strictly prohibited
  6. * Proprietary and confidential
  7. * For the full copyright and license information, please report to the LICENSE CONTRACT.
  8. */
  9. namespace TSMS\UserBundle\EventListener;
  10. use DateTime;
  11. use FOS\UserBundle\Model\UserManagerInterface;
  12. use FOS\UserBundle\Util\TokenGenerator;
  13. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  14. use Symfony\Component\HttpFoundation\RedirectResponse;
  15. use Symfony\Component\HttpKernel\Event\GetResponseEvent;
  16. use Symfony\Component\Routing\RouterInterface;
  17. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  18. use TSMS\CoreBundle\Entity\User;
  19. use Exception;
  20. class PasswordValidityListener implements EventSubscriberInterface
  21. {
  22.     /**
  23.      * @var UserManagerInterface
  24.      */
  25.     protected $userManager;
  26.     /**
  27.      * @var RouterInterface
  28.      */
  29.     protected $router;
  30.     /**
  31.      * @var TokenStorageInterface
  32.      */
  33.     protected $tokenStorage;
  34.     /**
  35.      * @var TokenGenerator
  36.      */
  37.     protected $tokenGenerator;
  38.     /**
  39.      * @var int Password validity
  40.      */
  41.     protected $passwordValidity;
  42.     /**
  43.      * @var array
  44.      */
  45.     protected $whitelistCheckValidityPassword;
  46.     /**
  47.      * @param UserManagerInterface $userManager
  48.      * @param RouterInterface $router
  49.      * @param TokenStorageInterface $tokenStorage
  50.      * @param TokenGenerator $tokenGenerator
  51.      * @param int $passwordValidity
  52.      * @param array $whitelistCheckValidityPassword
  53.      */
  54.     public function __construct(
  55.         UserManagerInterface $userManager,
  56.         RouterInterface $router,
  57.         TokenStorageInterface $tokenStorage,
  58.         TokenGenerator $tokenGenerator,
  59.         $passwordValidity,
  60.         $whitelistCheckValidityPassword
  61.     ) {
  62.         $this->userManager       $userManager;
  63.         $this->router            $router;
  64.         $this->tokenStorage      $tokenStorage;
  65.         $this->tokenGenerator    $tokenGenerator;
  66.         $this->passwordValidity  $passwordValidity;
  67.         $this->whitelistCheckValidityPassword  $whitelistCheckValidityPassword;
  68.     }
  69.     /**
  70.      * @return array
  71.      */
  72.     public static function getSubscribedEvents()
  73.     {
  74.         return array(
  75.             'kernel.request' => 'onKernelRequest',
  76.         );
  77.     }
  78.     /**
  79.      * @param GetResponseEvent $event
  80.      * @throws Exception
  81.      */
  82.     public function onKernelRequest(GetResponseEvent $event)
  83.     {
  84.         if (!$this->tokenStorage->getToken()) {
  85.             return;
  86.         }
  87.         /** @var User $user */
  88.         $user $this->tokenStorage->getToken()->getUser();
  89.         if (!($user instanceof User)) {
  90.             return;
  91.         }
  92.         if (!$this->isPasswordNeedsChange($user)) {
  93.             return;
  94.         }
  95.         $user->setPasswordRequestedAt(new DateTime());
  96.         $token $user->getConfirmationToken();
  97.         if (!$token) {
  98.             $token $this->tokenGenerator->generateToken();
  99.             $user->setConfirmationToken($token);
  100.         }
  101.         $this->userManager->updateUser($user);
  102.         $redirectUrl $this->router->generate('fos_user_resetting_reset', ['token' => $token]);
  103.         $this->addFlashBagError($event);
  104.         if ($event->getRequest()->getRequestUri() !== $redirectUrl) {
  105.             $event->setResponse(new RedirectResponse($redirectUrl));
  106.         }
  107.     }
  108.     /**
  109.      * Adds flashbag notice to notify user their password is expired.
  110.      *
  111.      * Also I didn't want to have to mock a million stuff in my test.
  112.      *
  113.      * @param GetResponseEvent $event
  114.      */
  115.     protected function addFlashBagError($event)
  116.     {
  117.         $event->getRequest()->getSession()->getFlashBag()->set('error''resetting.reset.password_expired');
  118.     }
  119.     /**
  120.      * Checks if user's password is fresh enough. If not, it must be redefined.
  121.      *
  122.      * @param User $user User logging in
  123.      *
  124.      * @return bool Does password need to be changed
  125.      * @throws Exception
  126.      */
  127.     protected function isPasswordNeedsChange(User $user)
  128.     {
  129.         // We don't check whitelist
  130.         if (in_array($user->getUsername(), $this->whitelistCheckValidityPassword )) {
  131.             return false;
  132.         }
  133.         // We don't check internal users' password expiration because they can not change their passwords
  134.         if ($user->isInternal()) {
  135.             return false;
  136.         }
  137.         // not datetime => not redefined => need to change
  138.         if (!($user->getPasswordChangedAt() instanceof DateTime)) {
  139.             return true;
  140.         }
  141.         $diff $user->getPasswordChangedAt()->diff(new \DateTime());
  142.         return $diff->format('%a') > $this->passwordValidity;
  143.     }
  144. }