FOSUserBundle - force password change after the first login

In a Symfony2 application that uses FOSUserBundle to manage users, a user table is populated by importing a script from a csv file and a password generated from a combination of data.

I would like to force the user to change the password at the first login.

When an event occurs FOSUserEvents::SECURITY_IMPLICIT_LOGIN, redirect to the route fos_user_change_passwordif the field last_loginis NULL.

My idea was rewriting a onImplicitLogin(UserEvent $event)class method AGI\UserBundle\EventListener\LastLoginListenerlike this, but the class was not rewriting:

public function onImplicitLogin(UserEvent $event) {
    $user = $event->getUser ();

    if ($user->getLastLogin () === null) {
        $user->setLastLogin ( new \DateTime () );
        $this->userManager->updateUser ( $user );
        $response = new RedirectResponse ( $this->router->generate ( 'fos_user_change_password' ) );
        $this->session->getFlashBag ()->add ( 'notice', 'Please change your password' );
        $event->setResponse ( $response );
    }
}

I already have a rewritable FOSUserBundle package, and it works for controllers, forms, etc. But it looks like this is not a way to do this with eventListeners.

How can I get the user to change the password after the first login?

+4
1

@sjagr fos_user.security.implicit_login, fos_user.security.implicit_login , .

AGI\UserBundle\Resources\Config\services.yml

login_listener:
    class: 'AGI\UserBundle\EventListener\LoginListener'
    arguments: ['@security.context', '@router', '@event_dispatcher']
    tags:
        - { name: 'kernel.event_listener', event: 'security.interactive_login', method: onSecurityInteractiveLogin }

AGI\UserBundle\EventListener\LoginListener.php

<?php

namespace AGI\UserBundle\EventListener;

use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

class LoginListener {

    private $securityContext;
    private $router;
    private $dispatcher;

    public function __construct(SecurityContext $securityContext, Router $router, EventDispatcherInterface $dispatcher) {
        $this->securityContext = $securityContext;
        $this->router = $router;
        $this->dispatcher = $dispatcher;
    }
    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event) {
        if ($this->securityContext->isGranted ( 'IS_AUTHENTICATED_FULLY' )) {
            $user = $event->getAuthenticationToken ()->getUser ();

            if ($user->getLastLogin () === null) {
                $this->dispatcher->addListener ( KernelEvents::RESPONSE, array (
                        $this,
                        'onKernelResponse' 
                ) );
            }
        }
    }
    public function onKernelResponse(FilterResponseEvent $event) {
        $response = new RedirectResponse ( $this->router->generate ( 'fos_user_change_password' ) );
        $event->setResponse ( $response );
    }
}

+8

All Articles