<?php
/*
* Selon https://stackoverflow.com/questions/18872721/how-to-log-users-off-automatically-after-a-period-of-inactivity
*/
namespace App\PaaBundle\Component\Authentication\Handler;
//use Symfony\Component\BrowserKit\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\RouterInterface;
// LG 20230413 déac use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
use Symfony\Component\HttpFoundation\JsonResponse; // AV 20230414 add
class SessionIdleHandler
{
protected $session;
protected $securityToken;
protected $router;
protected $maxIdleTime;
protected $securityContext; // LG 20230413
public function __construct(SessionInterface $session, TokenStorageInterface $securityToken, AuthorizationChecker $securityContext, RouterInterface $router, $maxIdleTime = 0)
{
$this->session = $session;
$this->securityToken = $securityToken;
$this->securityContext = $securityContext;
$this->router = $router;
$this->maxIdleTime = $maxIdleTime;
}
public function onKernelRequest(GetResponseEvent $event)
{
if (HttpKernelInterface::MASTER_REQUEST != $event->getRequestType()) {
// La requête en cours n'est pas la requête principale
return;
}
// LG 20230905 début
if ($event->getRequest()->getSession() ==null) {
// Il n'y a pas de session en cours
return;
}
if ($this->maxIdleTime <= 0) {
// Il n'y a pas de timeout de session
return ;
}
// LG 20230905 fin
if ($this->securityToken->getToken() === null) {
// Pas de timeout si pas de token de sécurité
return ;
}
if (!$this->securityContext->isGranted('IS_AUTHENTICATED_FULLY')) {
// Pas de timeout si l'user est anonyme ou Remembered
return ;
}
// LG 20230905 déac if ($this->maxIdleTime > 0) {
//Il y a un temps de session maximal défini
$this->session->start();
// AV 20230414 début
// Calcule le temps d'inactivité de la session
$time = time();
$lapse = $time - $this->session->get('manualLastUsedTime');
// Récupère la route de la requête en cours
$route = $event->getRequest()->attributes->get('_route');
// LG 20230905 old if ('paa_checkSecondsToExpire' == $route) {
if (in_array($route, ['checkSecondsToExpire', 'paa_checkSecondsToExpire'])) {
// Cette route est une simple demande du temps de session restant
// Renvoyer le temps restant
// Calcul du nombre de secondes restantes avant l'expiration de la session
$secToExp = $this->maxIdleTime - $lapse;
// Retourne la réponse sous forme de JSON contenant le nombre de secondes restantes
$event->setResponse(new JsonResponse(['secToExp' => $secToExp]));
// LG 20230905 début
return ;
} else if (in_array($route, ['fos_user_security_login', 'paa_pageTestGetTempsSessionRestant'])) {
// Cette route ne doit pas faire le RAZ du temps de connexion restant
// LG 20230905 fin
} else {
//Cette route est une route normale de l'application
//donc on signal que la dernière utilisation de la session est maintenant
$this->session->set('manualLastUsedTime', $time);
}
// AV 20230414 fin
// AV 20230414 déac $lapse = time() - $this->session->getMetadataBag()->getLastUsed();
// LG 20230904 old if ($lapse > $this->maxIdleTime) {
if (($token = $this->securityToken->getToken()) && $token->getProviderKey()=="main" && $lapse > $this->maxIdleTime) {
// Un token existe déjà, et il est appellé par le mode "main" (par opposition à "api")
// Et on a dépassé le timeout
// // Invalider la session (introduit par AV dans testGetTempsSessionRestant)
// $this->session->invalidate();
$this->securityToken->setToken(null);
$this->session->getFlashBag()->set('info', 'Vous avez été déconnecté suite à l\'inactivité de votre session.');
$URI = $event->getRequest()->getUri() ;
$this->session->set('URLDemandée', $URI) ;
// Change the route if you are not using FOSUserBundle.
// $event->setResponse(new RedirectResponse($this->generateUrl('fos_user_security_login')));
// // Code introduit par AV dans testGetTempsSessionRestant début
// // Vérifie si la requête en cours est une requête AJAX
// if ($event->getRequest()->isXmlHttpRequest()) {
// // Si oui, renvoie une réponse HTTP 403 avec un message d'erreur
// $event->setResponse(new Response('Logged out due to inactivity.', Response::HTTP_FORBIDDEN));
// } else {
// // Sinon, redirige l'utilisateur vers la page de connexion
// $event->setResponse(new RedirectResponse($this->router->generate('login')));
// }
// // Code introduit par AV dans testGetTempsSessionRestant fin
}
// LG 20230905 déac }
}
}