<?php
namespace App\Listener;
use App\Controller\RestController;
use App\Entity\Customer;
use App\Entity\Device;
use App\Entity\Employee;
use App\Entity\Collaborator;
use App\Entity\Manager;
use App\Repository\CustomerRepository;
use App\Repository\EmployeeRepository;
use App\Repository\CollaboratorRepository;
use App\Repository\ManagerRepository;
use App\Service\Security;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Contracts\Translation\TranslatorInterface;
class RequestListener extends RestController
{
private CustomerRepository $customerRepository;
private EmployeeRepository $employeeRepository;
private CollaboratorRepository $collaboratorRepository;
private ManagerRepository $managerRepository;
public function __construct(
EntityManagerInterface $em,
CustomerRepository $customerRepository,
EmployeeRepository $employeeRepository,
CollaboratorRepository $collaboratorRepository,
TranslatorInterface $translator,
ManagerRepository $managerRepository
)
{
$this->em = $em;
$this->customerRepository = $customerRepository;
$this->employeeRepository = $employeeRepository;
$this->collaboratorRepository = $collaboratorRepository;
$this->translator = $translator;
$this->managerRepository = $managerRepository;
}
private function getDevice(Request $request): Device
{
$headers = $request->headers;
$deviceId = $headers->get('deviceId', 'robot');
$deviceType = $headers->get('deviceType', '-1');
$deviceModel = $headers->get('deviceModel', null);
$deviceVersion = $headers->get('deviceVersion', null);
$deviceOs = $headers->get('deviceOs', null);
$deviceNetwork = $headers->get('deviceNetwork', null);
$device = $this->em->getRepository(Device::class)->findOneBy(
['device_id' => $deviceId, 'type' => $deviceType]
);
if (!$device instanceof Device) {
$device = new Device();
$device->setDeviceId($deviceId);
$device->setType((int)$deviceType);
$device->setModel($deviceModel);
$device->setOs($deviceOs);
$this->em->persist($device);
$this->em->flush();
}
$device->setVersion($deviceVersion);
$device->setNetwork($deviceNetwork);
$request->attributes->set('device', $device);
return $device;
}
/**
* @throws \Exception
*/
public function onKernelRequest(RequestEvent $event): ?RequestEvent
{
$request = $event->getRequest();
$route = $request->attributes->get('_route');
$route = explode('_', $route)[0];
switch ($route) {
case 'auth':
$this->getDevice($request);
break;
case 'api':
$token = (string)$request->headers->get('token', null);
if (!Security::validateToken($token)) {
return $event->setResponse($this->json(
['message' => $this->translator->trans('Token inválido o expirado')],
Response::HTTP_UNAUTHORIZED
));
}
$data = Security::decodeToken($token);
$customer = $this->customerRepository->findOneBy(['hash' => $data['user_id']]);
if (!$customer instanceof Customer) {
return $event->setResponse($this->json(
['message' => $this->translator->trans('Cliente no encontrado')],
Response::HTTP_UNAUTHORIZED
));
}
if (!is_null($request->headers->get('deviceId'))) {
$device = $this->getDevice($request);
if ($device->getRefreshTokenExpiration() && $device->getRefreshTokenExpiration() < new \DateTime()) {
$event->setResponse(new JsonResponse(['message' => 'Invalid or expired token'], 401));
}
$device->setCustomer($customer);
$this->em->flush();
}
$request->attributes->set('customer', $customer);
break;
case 'cms':
$token = (string)$request->headers->get('token', null);
if (!Security::validateToken($token)) {
return $event->setResponse($this->json(
['message' => $this->translator->trans('Token inválido o expirado')],
Response::HTTP_UNAUTHORIZED
));
}
$data = Security::decodeToken($token);
$employee = $this->employeeRepository->findOneBy(['hash' => $data['user_id']]);
if (!$employee instanceof Employee) {
return $event->setResponse($this->json(
['message' => $this->translator->trans('Empleado no encontrado')],
Response::HTTP_UNAUTHORIZED
));
}
$request->attributes->set('employee', $employee);
break;
case 'col':
$token = (string)$request->headers->get('token', null);
if (!Security::validateToken($token)) {
return $event->setResponse($this->json(
['message' => $this->translator->trans('Token inválido o expirado')],
Response::HTTP_UNAUTHORIZED
));
}
$data = Security::decodeToken($token);
$collaborator = $this->collaboratorRepository->findOneBy(['hash' => $data['user_id']]);
if (!$collaborator instanceof Collaborator) {
return $event->setResponse($this->json(
['message' => $this->translator->trans('Proveedor no encontrado')],
Response::HTTP_UNAUTHORIZED
));
}
$request->attributes->set('collaborator', $collaborator);
break;
case 'ent':
$token = (string)$request->headers->get('token', null);
if (!Security::validateToken($token)) {
return $event->setResponse($this->json(
['message' => $this->translator->trans('Token inválido o expirado')],
Response::HTTP_UNAUTHORIZED
));
}
$data = Security::decodeToken($token);
$manager = $this->managerRepository->findOneBy(['hash' => $data['user_id']]);
if (!$manager instanceof Manager) {
return $event->setResponse($this->json(
['message' => $this->translator->trans('Manager no encontrado')],
Response::HTTP_UNAUTHORIZED
));
}
$request->attributes->set('manager', $manager);
break;
}
return null;
}
}