<?php
namespace App\Listener\Jwt;
use App\DataFixtures\Data\DataInit;
use App\Doctrine\DBAL\DossierConnection;
use App\Entity\Main\Dossier;
use App\Entity\Main\DroitsAcces;
use App\Entity\Main\Parametres;
use App\Entity\Main\Session;
use App\Entity\Main\Utilisateur;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query;
use Doctrine\Persistence\ManagerRegistry;
use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTDecodedEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class JWTDecodedListener
{
/**
* @var RequestStack
*/
private $requestStack;
/**
* @var EntityManagerInterface
*/
private $em;
/**
* @var ManagerRegistry
*/
private $managerRegistry;
/**
* @var EventDispatcherInterface
*/
protected $dispatcher;
/**
* @param RequestStack $requestStack
* @param EntityManagerInterface $em
* @param ManagerRegistry $managerRegistry
* @param EventDispatcherInterface $dispatcher
*/
public function __construct(RequestStack $requestStack, EntityManagerInterface $em, ManagerRegistry $managerRegistry, EventDispatcherInterface $dispatcher)
{
$this->requestStack = $requestStack;
$this->em = $em;
$this->managerRegistry = $managerRegistry;
$this->dispatcher = $dispatcher;
}
/**
* @param JWTDecodedEvent $event
*
* @return void
*/
public function onJWTDecoded(JWTDecodedEvent $event)
{
// si mise en cours, couper la connexion
if($_ENV['AZIZ_MISEAJOURS_BLOQUER_CONNEXION'] == "1"){
$event->markAsInvalid();
}else {
$payload = $event->getPayload();
$request = $this->requestStack->getCurrentRequest();
$query = $request->query->all();
//1- tester si la session == utilisateur.sessionActive
// 1.1 recupérer la session via le front
if (isset($payload['username']) && isset($query['uid'])) {
$uidFront = $query['uid'];
if (!empty($uidFront)) {
/** @var Session $session */
$session = $this->em->getRepository(Session::class)->findOneBy(["uid" => $uidFront]);
/** @var Utilisateur $utilisateur */
$utilisateur = $this->em->getRepository(Utilisateur::class)->findOneBy(["username" => $payload['username']]);
if ($session && $utilisateur) {
//- 1 si la session stcoké dans le front ne correspond pas à la session active, alors decionnectrer l'utilisteur
if ($session->getId() != $utilisateur->getSessionActive()) {
$event->markAsInvalid();
}
//2- vérifier la fermeture de session
$idClient = $utilisateur->getAbonnement()->getClient()->getId();
$updateDateTimeSession = true;
if ($idClient) {
/** @var Parametres $parametres */
$parametres = $this->em->getRepository(Parametres::class)->findOneBy(["client" => $idClient]);
$dateFinSession = $session->getDateTimeFin();
if ($parametres) {
$parms = $parametres->getParametres();
if (sizeof($parms) > 0 && isset($parms[0]['fermetureSession'])) {
$sessionTimeout = $parms[0]['fermetureSession'];
} else {
$sessionTimeout = 20; // en minutes !
}
} else {
$sessionTimeout = 20; // en minutes !
}
if ($dateFinSession) {
// calculer le temps session incative
$now = new \DateTime();
$interval = $dateFinSession->diff($now, true);
$interval_minutes = $interval->format('%i');
$interval_heure = $interval->format('%h');
$interval_days = $interval->format('%d');
$interval_month = $interval->format('%m');
$dif = ($interval_minutes + $interval_heure * 60 + $interval_days * 24 * 60 + $interval_month * 30 * 24 * 60) - $sessionTimeout;
if ($dif > 0) {
$event->markAsInvalid();
$updateDateTimeSession = false;
}
}
}
if (isset($request->attributes->all()["_route"])) {
if ($request->attributes->all()["_route"] == "api_historiqueCollaborateur_getAll") {
$updateDateTimeSession = false;
}
}
if ($updateDateTimeSession) {
//3- update session
$session->setDateTimeFin(new \DateTime());
$this->em->persist($session);
$this->em->flush();
}
}
}
}
// if(isset($payload['markAsInvalid'])){
// if($payload['markAsInvalid'] == "1"){
// $event->markAsInvalid();
// return;
// }
// }
//2- Tester droits d'accèes aux dossier demandé
if (isset($request->attributes->all()['db']) && isset($payload['username'])) {
$nomBase = $request->attributes->all()['db'];
$username = $payload['username'];
$sql = "
SELECT
droitsacces.id,
dossier.utilisable
FROM " . DroitsAcces::class . " as droitsacces
LEFT JOIN " . Utilisateur::class . " as utilisateur WITH droitsacces.utilisateur=utilisateur.id
left join " . Dossier::class . " as dossier WITH droitsacces.dossier=dossier.id
WHERE utilisateur.username='" . $username . "' AND dossier.nomBase='" . $nomBase . "'";
/** @var Query $query */
$query = $this->em->createQuery($sql);
$result = $query->getResult();
if (!$result || sizeof($result) == 0) {
$event->markAsInvalid();
} else {
// changer connextion
/** @var DossierConnection $connection */
$connection = $this->managerRegistry->getConnection('dossier');
$connection->changeParams($nomBase);
$connection->reconnect();
}
}
}
}
}