<?php
namespace App\Event;
use App\Doctrine\DoctrinePlatformAuthenticator;
use App\Entity\Parametre\Parametre;
use App\Entity\Parametre\Utilisateur;
use App\Helper\UserHelper;
use Doctrine\Bundle\DoctrineBundle\Registry;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authentication\Token\Storage\UsageTrackingTokenStorage;
use Symfony\Contracts\Translation\TranslatorInterface;
use Twig\Environment;
use Webservice\Controller\AbstractWebserviceController;
/**
* KernelRequestEvent.
*
* @author John Doe
* @package App\Event
*/
class KernelRequestEvent {
/** @var Registry */
private $doctrine;
/** @var RequestStack */
private $requestStack;
/** @var TokenStorage */
private $tokenStorage;
/** @var TranslatorInterface */
private $translator;
/** @var Environment */
private $twig;
/**
* SecurityInteractiveLogin constructor.
*
* @param Registry $doctrine
* @param RequestStack $requestStack
* @param TranslatorInterface $translator
* @param TokenStorage $tokenStorage
* @param Environment $twig
*/
public function __construct(Registry $doctrine, RequestStack $requestStack, TranslatorInterface $translator, UsageTrackingTokenStorage $tokenStorage, Environment $twig) {
$this->doctrine = $doctrine;
$this->requestStack = $requestStack;
$this->translator = $translator;
$this->tokenStorage = $tokenStorage;
$this->twig = $twig;
}
/**
* Check user session.
*
* @param Utilisateur $user
*/
private function checkUserSession(Utilisateur $user) {
if ($this->requestStack->getSession()->has("_originalToken") === true) {
return;
}
// Get current session.
$now = new \DateTime();
if ("/login" === $this->requestStack->getCurrentRequest()->getRequestUri()) {
return;
}
// If need to update session user token.
if ($this->requestStack->getSession()->get("UpdateSessionToken") === 1) {
// Update user session.
$user->setSessionToken(UserHelper::generateSessionToken());
$this->em()->flush();
// Remove session.
$this->requestStack->getSession()->remove("UpdateSessionToken");
}
// Check if current session is similar with saved user session.
if ($user->getSessionToken() !== UserHelper::generateSessionToken()) {
session_destroy();
header('Location: /');
exit;
}
// If session was expired, refresh it.
if ($now->getTimestamp() > $user->getDateSessionExpiration()->getTimestamp()) {
$user->setDateSessionExpiration($now);
$user->getDateSessionExpiration()->modify("+2min");
$this->em()->flush();
}
}
/**
* @return \Doctrine\Persistence\ObjectManager
*/
private function em() {
return $this->doctrine->getManager();
}
/**
* @param $name
* @return mixed|null
*/
private function getHeader($name) {
$headers = getallheaders();
foreach ($headers as $key => $value) {
if (strtolower($key) === strtolower($name)) {
return $value;
}
}
return null;
}
/**
* Init platform language.
*
* @param Utilisateur|null $utilisateur
*/
private function initPlatformLangage(RequestEvent $requestEvent, Utilisateur $utilisateur = null) {
// Set default platform langage.
$defaultPlatformLangage = "fr";
// Get current session lanage.
$currentSessionLangage = $this->requestStack->getSession()->get('_locale');
// Get parametre repository.
$parametreRepo = $this->em()->getRepository(Parametre::class);
// If locale was not defined.
if ($currentSessionLangage === null) {
$platformLangage = $defaultPlatformLangage;
// If platform id was defined, get langage.
if (false !== getenv("PLATFORM_ID")) {
// Find parameter.
$findParameter = $parametreRepo->findOneBy([
"cle" => "LANGUAGE",
"platformId" => getenv("PLATFORM_ID"),
]);
// If parameter was found.
if (null !== $findParameter) {
$platformLangage = $findParameter->getValeur();
}
}
// Set the locale.
$this->requestStack->getSession()->set('_locale', $platformLangage);
$requestEvent->getRequest()->setLocale($platformLangage);
// If lang is different, switch it and reload page.
if ($defaultPlatformLangage !== $platformLangage) {
header("Refresh: 0");
exit();
}
}
// If user was connected.
if (null !== $utilisateur && null !== $utilisateur->getLang()) {
$platformLangage = $utilisateur->getLang();
if (null !== $platformLangage) {
$this->requestStack->getSession()->set('_locale', $platformLangage);
$requestEvent->getRequest()->setLocale($platformLangage);
}
}
}
/**
* @param Utilisateur $utilisateur
* @param Request $request
*/
private function initVariablesEnvironment(Utilisateur $utilisateur, Request $request) {
// If platform code was not defined.
if (getenv("PLATFORM_CODE") === false) {
// Get platform code is saved into session.
$sessionPlatformCode = $this->requestStack->getSession()->get("PLATFORM_CODE");
// If session was not initialized.
if (true === empty($sessionPlatformCode)) {
// Execute request to get the platform code.
$find = DoctrinePlatformAuthenticator::queryDbPlatform("SELECT * FROM platform WHERE id = ?", [$utilisateur->getPlatformId()], true);
// If result was found, set code into session and global variable environment.
if (false !== $find) {
$this->requestStack->getSession()->set("PLATFORM_CODE", $find["code"]);
}
}
// Set value to environment variable.
putenv("PLATFORM_CODE={$this->requestStack->getSession()->get("PLATFORM_CODE")}");
}
// Set global variable platform id.
putenv("PLATFORM_ID={$utilisateur->getPlatformId()}");
$companyId = null;
if ($utilisateur->getSocieteSelected() !== null) {
$companyId = $utilisateur->getSocieteSelected()->getId();
} else if ($request->getSession()->has("companySelected")) {
$companyId = $request->getSession()->has("companySelected");
}
putenv("COMPANY_ID=$companyId");
}
/**
* On Kernel Request.
*/
public function onKernelRequest(RequestEvent $requestEvent) {
if (1 === preg_match("/^\/logout/", $requestEvent->getRequest()->getRequestUri())) {
return;
}
if (1 === preg_match("/^\/api/", $requestEvent->getRequest()->getRequestUri())
&& 0 === preg_match("/^\/api\/provider\//", $requestEvent->getRequest()->getRequestUri())) {
return $this->onKernelRequestWebservice($requestEvent);
}
if (true === in_array($requestEvent->getRequest()->getHost(), ["api.px.local", "api.adheria.eu"])
&& 0 === preg_match("/^\/api/", $requestEvent->getRequest()->getRequestUri())) {
AbstractWebserviceController::criticalJsonResponse([
"errorCode" => "NOT_AUTHENTICATED",
]);
}
/** @var Utilisateur|null $user */
$user = $this->tokenStorage->getToken() !== null ? $this->tokenStorage->getToken()->getUser() : null;
// If user is connected.
if (null !== $user) {
// Check user session.
$this->checkUserSession($user);
// Initialize variables environment.
$this->initVariablesEnvironment($user, $requestEvent->getRequest());
}
// Set lang.
$this->initPlatformLangage($requestEvent, $user);
}
/**
* @param RequestEvent $requestEvent
*/
public function onKernelRequestWebservice(RequestEvent $requestEvent) {
// Get the client token.
$clientToken = $this->getHeader("client_token");
if (null === $clientToken) {
AbstractWebserviceController::criticalJsonResponse([
"errorCode" => "CLIENT_TOKEN_NOT_DEFINED",
"errorMessage" => "Client token was not defined.",
]);
}
}
}