Symfony2 security.interactive_login can’t get value correctly of passwordUpdatedAt To disply a flash msg password expire soon

I’m having a problem getting the correct value for one of the user variables.

I create PasswordExpirationListener :

  1. PasswordExpirationListener::onCheckExpiration() To force users to change their passwords after expiration : This listener works perfectly.

  2. PasswordExpirationListener::onCheckExpirationSoon() When the user login check if the validity of PWD less than 7 days and display a flash msg : when I get the logged user the value of the variable $use->getPasswordUpdatedAt is always NULL.

It’s very weird situation, because I can have the correct value of all other user variable like the firstname but not for passwordUpdatedAt

<?php

namespace UserBundleListener;

use SymfonyComponentHttpFoundationRedirectResponse;
use BeSimpleI18nRoutingBundleRoutingRouter;
use SymfonyComponentHttpFoundationSessionSession;
use SymfonyComponentHttpKernelEventGetResponseEvent;
use SymfonyComponentRoutingGeneratorUrlGeneratorInterface;
use SymfonyComponentSecurityCoreAuthenticationTokenStorageTokenStorage;
use SymfonyComponentSecurityCoreAuthorizationAuthorizationCheckerInterface;
use SymfonyComponentSecurityHttpEventInteractiveLoginEvent;
use UserBundleEntityUser;

/**
 * Listener responsible to change the redirection at the end of the password change
 */
class PasswordExpirationListener
{
    /** @var TokenStorage  */
    private $context;
    /** @var UrlGeneratorInterface  */
    private $router;
    /** @var Session  */
    private $session;
    /** @var AuthorizationCheckerInterface  */
    private $authorizationChecker;

    public function __construct(Router $router,
                                TokenStorage $context,
                                Session $session,
                                AuthorizationCheckerInterface $authorizationChecker
    ){
        $this->context = $context;
        $this->router  = $router;
        $this->session = $session;
        $this->authorizationChecker = $authorizationChecker;

    }

    public function onCheckExpiration(GetResponseEvent $event)
    {
        if ($this->context->getToken() && $this->authorizationChecker->isGranted('IS_AUTHENTICATED_FULLY')) {

            if ($event->getRequest()->get('_route') != 'employe_change_password') {
                /** @var User $user */
                $user = $this->context->getToken()->getUser();

                if ($user->getPasswordValidityPeriod() <= 0) {
                    // Display alert
                    $this->session->getFlashBag()->add('danger',
                        'Your password hash expired. Please change it');
                    // Redirect to change password
                    $url = $this->router->generate('employe_change_password', ['user' => $user->getId()]);
                    $event->setResponse(new RedirectResponse($url));
                }
            }
        }
    }

    public function onCheckExpirationSoon(InteractiveLoginEvent $event)
    {
//        writeLog('onCheckExpirationSoon');
        if ($this->context->getToken() && $this->authorizationChecker->isGranted('IS_AUTHENTICATED_FULLY')) {

            /** @var User $user */
           $user = $event->getAuthenticationToken()->getUser();
            writeLog('getFirstname: ' . $user->getFirstname());
            writeLog('getPasswordUpdatedAt: ');
            writeLog($user->getPasswordUpdatedAt());
            if ($user->getPasswordValidityPeriod() <= 7) {
                // how many days before expiration
                $dayBeforeExpiration = 180 - $user->passwordUpdateSince();

                $route = $this->router->generate('employe_change_password',
                    ['user' => $user->getId()]);

                $msg = "Your password will expire in $dayBeforeExpiration days. " .
                    "<a href='$route'>Please click here to change it </a>";
                $this->session->getFlashBag()->add('warning', $msg);
            }
        }
    }

}
# UserBundle/Resources/config/services.yml

user.password_expiration:
        class: UserBundleListenerPasswordExpirationListener
        arguments:
            - @router
            - @security.token_storage
            - @session
            - @security.authorization_checker
        tags:
            - { name: kernel.event_listener, event: kernel.request, method: onCheckExpiration }
            - { name: kernel.event_listener, event: security.interactive_login, method: onCheckExpirationSoon }

// UserBundleEntityUser.php
use FOSUserBundleModelUser as BaseUser;

class user extend BaseUser 
{

    /**
     * @var DateTime
     *
     * @GedmoVersioned
     * @ORMColumn(name="password_updated_at", type="datetime")
     */
    protected $passwordUpdatedAt;

    /**
     * Set created
     *
     * @param  DateTime $passwordUpdatedAt
     * @return User
     */
    public function setPasswordUpdatedAt($passwordUpdatedAt)
    {
        $this->passwordUpdatedAt = $passwordUpdatedAt;

        return $this;
    }

    /**
     * Get created
     *
     * @return DateTime
     */
    public function getPasswordUpdatedAt()
    {
        return $this->passwordUpdatedAt;
    }

    /**
     * After 120 days the password expired.check
     * @return bool
     */
    public function getPasswordValidityPeriod ()
    {
        return ( 120 - (!($this->passwordUpdatedAt instanceof DateTime)? 0 :
            ((int) $this->passwordUpdatedAt
                ->diff((new DateTime()))
                ->format('%a')))
        );
    }
}

There are other user variables that are empty like gender, ip, cid, but all of them have a value in the database. I don’t know why it does not fill all the variables from the BD

src/UserBundle/Listener/PasswordExpirationListener.php:104:
object(UserBundleEntityUser)[571]
  protected 'id' => int 289226
  protected 'username' => string '[email protected]' (length=23)
  protected 'usernameCanonical' => string '[email protected]' (length=23)
  protected 'email' => string '[email protected]' (length=23)
  protected 'emailCanonical' => string '[email protected]' (length=23)
  protected 'enabled' => boolean true
  protected 'salt' => string 'yK0MFvfHbalabalapZzLzpHTbalabaladq1Q' (length=43)
  protected 'password' => string 'cX6TbalabalaQbalababalabalalbVowAhnfbalabalawlv3g==' (length=88)
  protected 'plainPassword' => null
  protected 'lastLogin' => 
    object(DateTime)[70]
      public 'date' => string '2020-08-20 08:23:49.000000' (length=26)
      public 'timezone_type' => int 3
      public 'timezone' => string 'America/Toronto' (length=15)
  protected 'confirmationToken' => null
  protected 'passwordRequestedAt' => null
  protected 'groups' => 
    object(DoctrineCommonCollectionsArrayCollection)[97]
      private 'elements' => 
        array (size=0)
          empty
  protected 'roles' => 
    array (size=1)
      0 => string 'ROLE_SUPER_ADMIN' (length=16)
  protected 'created' => 
    object(DateTime)[576]
      public 'date' => string '2019-04-29 19:43:31.000000' (length=26)
      public 'timezone_type' => int 3
      public 'timezone' => string 'America/Toronto' (length=15)
  protected 'locale' => string 'fr' (length=2)
  protected 'firstname' => string 'Qyokhpppppppppppppg' (length=19)
  protected 'lastname' => string 'Etters' (length=6)
  protected 'passwordUpdatedAt' => null
  private 'gender' => null
  protected 'ip' => null
  protected 'cid' => null
  private 'newsLetter' => boolean true
  protected 'verified' => boolean true
  protected 'lastActivity' => 
    object(DateTime)[574]
      public 'date' => string '2020-08-20 08:23:55.000000' (length=26)
      public 'timezone_type' => int 3
      public 'timezone' => string 'America/Toronto' (length=15)
  protected 'pi_adwords_q' => null
  private 'website' => 

Source: Symfony Questions

Was this helpful?

0 / 0

Leave a Reply 0

Your email address will not be published. Required fields are marked *