<?php
namespace App\EventSubscriber;
use App\Entity\ConnectionLog;
use App\Entity\Local\AdminUser;
use App\Model\ApiUser;
use Doctrine\ORM\EntityManagerInterface;
use Oz\ApiNvl\Model\Permission;
use App\Model\User;
use Oz\ApiNvl\Provider\UserProvider;
use Oz\ApiNvl\Transformer\ContextTransformer;
use Oz\ApiNvl\Transformer\CustomerTransformer;
use Oz\NvlPortalDisplayer\Service\User\UserHelper;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class AuthenticateSubscriber implements EventSubscriberInterface
{
/**
* @var UserProvider
*/
private $userProvider;
/**
* @var EntityManagerInterface
*/
private $em;
/**
* @var UserHelper
*/
private $userHelper;
/**
* @var HttpClientInterface
*/
private $api_nvl;
/**
* @param UserProvider $userProvider
* @param EntityManagerInterface $em
* @param UserHelper $userHelper
* @param HttpClientInterface $api_nvl
*/
public function __construct(
UserProvider $userProvider,
EntityManagerInterface $em,
UserHelper $userHelper,
HttpClientInterface $api_nvl
)
{
$this->userProvider = $userProvider;
$this->em = $em;
$this->userHelper = $userHelper;
$this->api_nvl = $api_nvl;
}
/**
* @return array[]
*/
public static function getSubscribedEvents(): array
{
return [
SecurityEvents::INTERACTIVE_LOGIN => ['interactiveLogin', 10],
];
}
/**
* @param InteractiveLoginEvent $interactiveLoginEvent
*
* @throws ClientExceptionInterface
* @throws DecodingExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
*/
public function interactiveLogin(InteractiveLoginEvent $interactiveLoginEvent): void
{
/** @var User $user */
$user = $interactiveLoginEvent->getAuthenticationToken()->getUser();
if ($user instanceof ApiUser) {
return;
}
$this->setUserInfo($user);
$this->setUserPermissions($user);
}
/**
* @param User $user
*
* @return void
* @throws ClientExceptionInterface
* @throws DecodingExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
*/
private function setUserInfo(User $user)
{
$infosResponse = $this->userProvider->getInfosCustomAppToken($_ENV['APPTOKEN_PORTAIL_NEWS_NVL']);
if (200 != $infosResponse->getStatusCode()) {
throw new Exception('Impossible de récupérer les infos de l\'utilisateur ! 😕');
}
$infos = $infosResponse->toArray();
$user->getInfo()
->setPhone($infos['phone'] ?? null)
->setFonction($infos['function'] ?? null)
->setTrackingTickets($infos['trackingTicket'] ?? null);
$this->setUserContexts($user, $infos['contexts']);
$this->setUserCustomers($user, $infos['customers']);
}
/**
* @param User $user
* @param array $contextsRaw
*/
private function setUserContexts(User $user, array $contextsRaw): void
{
$contexts = iterator_to_array(ContextTransformer::multipleConvertToObjects($contextsRaw));
if (!count($contexts)) {
return;
}
$user->setAvailableContexts($contexts);
$user->setContexts($contexts); // on met tout pour le moment
}
/**
* @param User $user
* @param array $customersRaw
*/
private function setUserCustomers(User $user, array $customersRaw): void
{
$customers = iterator_to_array(CustomerTransformer::multipleConvertToObjects($customersRaw));
$user->setAvailableCustomers($customers);
foreach ($customers as $customer) {
$user->addCustomer($customer);
}
}
/**
* @param User $user
*
* @return void
* @throws ClientExceptionInterface
* @throws DecodingExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
*/
private function setUserPermissions(User $user)
{
$rawDatasourcesResponse = $this->api_nvl->request('GET', '/api/datasources/', [
'headers' => [
'apptoken' => $_ENV['APPTOKEN_PORTAIL_NEWS_NVL'],
'Authorization' => 'Bearer ' . $user->getToken(),
],
]);
if (200 != $rawDatasourcesResponse->getStatusCode()) {
throw new Exception($rawDatasourcesResponse->toArray(false)['message']);
}
$rawDatasources = $rawDatasourcesResponse->toArray();
$permissions = [];
foreach ($rawDatasources as $datasource) {
$permissions[$datasource['id']] = (new Permission($datasource['id']))
->setRead(filter_var($datasource['read'], FILTER_VALIDATE_BOOLEAN))
->setWrite(filter_var($datasource['edit'], FILTER_VALIDATE_BOOLEAN))
->setValidate(filter_var($datasource['validation'], FILTER_VALIDATE_BOOLEAN));
}
$user->setPermissions($permissions);
}
}