<?php
namespace App\Listener;
use App\Controller\RestController;
use App\Entity\Admin;
use App\Entity\Headquarter;
use App\Entity\User;
use App\Entity\UserDevice;
use App\Repository\AdminRepository;
use App\Repository\HeadquarterRepository;
use App\Repository\UserDeviceRepository;
use App\Repository\UserRepository;
use App\Service\Security;
use App\Util\AudienceUtil;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Contracts\Translation\TranslatorInterface;
class RequestListener extends RestController
{
/**
* @throws \Exception
*/
public function onKernelRequest(RequestEvent $event): ?Response
{
$request = $event->getRequest();
$route = $request->attributes->get('_route');
$route = explode('_', $route)[0];
switch ($route) {
case 'external':
$api_key = substr($request->headers->get('Authorization', ''), 7);
$headquarter = $this->em->getRepository(Headquarter::class)->findOneBy([
'external_api_key' => $api_key,
'status' => Headquarter::STATUS_PUBLISHED
]);
if (!$headquarter instanceof Headquarter || is_null($headquarter->getExternalApiConfig())) {
$event->setResponse($this->json(
['message' => $this->translator->trans('auth.headquarter_not_found')],
Response::HTTP_UNAUTHORIZED
));
return null;
}
$request->attributes->set('headquarter', $headquarter);
break;
case 'fingerprint':
$api_key = (string)$request->headers->get('apiKey', null);
$headquarter = $this->em->getRepository(Headquarter::class)->findOneBy([
'api_key' => $api_key,
'status' => Headquarter::STATUS_PUBLISHED
]);
if (!$headquarter instanceof Headquarter) {
$headquarter = $this->em->getRepository(Headquarter::class)->findOneBy([
'status' => Headquarter::STATUS_PUBLISHED,
'is_generic' => true,
]);
}
if (!$headquarter instanceof Headquarter) {
$event->setResponse($this->json(
['message' => $this->translator->trans('auth.headquarter_not_found')],
Response::HTTP_UNAUTHORIZED
));
return null;
}
$fingerPrintEnabled = $headquarter->getWebConfig()['fingerprintEnabled'] ?? false;
if (!$fingerPrintEnabled) {
$event->setResponse($this->json(
['message' => $this->translator->trans('auth.headquarter_not_found')],
Response::HTTP_UNAUTHORIZED
));
}
$request->attributes->set('headquarter', $headquarter);
break;
case 'auth':
$api_key = (string)$request->headers->get('apiKey', null);
$headquarter = $this->em->getRepository(Headquarter::class)->findOneBy([
'api_key' => $api_key,
'is_generic' => false,
'status' => Headquarter::STATUS_PUBLISHED
]);
if (!$headquarter instanceof Headquarter) {
$event->setResponse($this->json(
['message' => $this->translator->trans('auth.headquarter_not_found')],
Response::HTTP_UNAUTHORIZED
));
return null;
}
$request->attributes->set('headquarter', $headquarter);
break;
case 'headquarter':
$api_key = (string)$request->headers->get('apiKey', null);
$headquarter = $this->em->getRepository(Headquarter::class)->findOneBy([
'api_key' => $api_key,
'is_generic' => false,
'status' => Headquarter::STATUS_PUBLISHED
]);
if (!$headquarter instanceof Headquarter) {
$event->setResponse($this->json(
['message' => $this->translator->trans('auth.headquarter_not_found')],
Response::HTTP_UNAUTHORIZED
));
return null;
}
$request->attributes->set('headquarter', $headquarter);
break;
case 'api':
$api_key = (string)$request->headers->get('apiKey', null);
$headquarter = $this->em->getRepository(Headquarter::class)->findOneBy([
'api_key' => $api_key,
'status' => Headquarter::STATUS_PUBLISHED
]);
if (!$headquarter instanceof Headquarter) {
$event->setResponse($this->json(
['message' => $this->translator->trans('auth.headquarter_not_found')],
Response::HTTP_UNAUTHORIZED
));
return null;
}
$token = (string)$request->headers->get('token', null);
$deviceId = (string)$request->headers->get('deviceId', null);
$deviceType = (int)$request->headers->get('deviceType', null);
$deviceModel = (string)$request->headers->get('deviceModel', null);
$deviceOs = (string)$request->headers->get('deviceOs', null);
$deviceVersion = (string)$request->headers->get('deviceVersion', null);
$deviceNetwork = (string)$request->headers->get('deviceNetwork', null);
if (!Security::validateToken($token)) {
$event->setResponse($this->json(
['message' => $this->translator->trans('auth.invalid_or_expired_token')],
Response::HTTP_UNAUTHORIZED
));
return null;
}
$this->decode_token = Security::decodeToken($token);
$user = $this->em->getRepository(User::class)->findOneBy([
'hash' => $this->decode_token['user_id'] ?? null,
'status' => User::STATUS_PUBLISHED
]);
if (!$user instanceof User) {
$event->setResponse($this->json(
['message' => $this->translator->trans('auth.user_not_found')],
Response::HTTP_UNAUTHORIZED
));
return null;
}
$device = $this->em->getRepository(UserDevice::class)->findOneBy([
'user' => $user,
'device_id' => $deviceId,
'type' => $deviceType
]);
if (!$device instanceof UserDevice) {
$event->setResponse($this->json(
['message' => $this->translator->trans('auth.device_not_found')],
Response::HTTP_UNAUTHORIZED
));
return null;
}
$device->setModel($deviceModel);
$device->setOs($deviceOs);
$device->setVersion($deviceVersion);
$device->setNetwork($deviceNetwork);
$this->em->persist($device);
$user->setLastVisitDate(new \DateTime('now'));
$this->em->persist($user);
$this->em->flush();
$request->attributes->set('headquarter', $user->getHeadquarter());
$request->attributes->set('user', $user);
$request->attributes->set('device', $device);
$request->attributes->set('audiences_or_users', [
'audiences' => AudienceUtil::getBy($headquarter, $user),
'users' => [$user->getId()]
]);
break;
case 'cms':
$token = (string)$request->headers->get('token', null);
if (!Security::validateToken($token)) {
$event->setResponse($this->json(
['message' => $this->translator->trans('auth.invalid_or_expired_token')],
Response::HTTP_UNAUTHORIZED
));
return null;
}
$this->decode_token = Security::decodeToken($token);
$admin = $this->em->getRepository(Admin::class)->findOneBy([
'hash' => $this->decode_token['user_id'] ?? null
]);
if (!$admin instanceof Admin) {
$event->setResponse($this->json(
['message' => $this->translator->trans('auth.user_not_found')],
Response::HTTP_UNAUTHORIZED
));
return null;
}
$request->attributes->set('headquarter', $admin->getHeadquarter());
$request->attributes->set('admin', $admin);
break;
case 'super':
$token = (string)$request->headers->get('token', null);
if (!Security::validateToken($token)) {
return $event->setResponse($this->json(
['message' => $this->translator->trans('auth.invalid_or_expired_token')],
Response::HTTP_UNAUTHORIZED
));
}
break;
}
return null;
}
}