src/EventListener/ResponseListener.php line 70

Open in your IDE?
  1. <?php
  2. /**
  3.  * User: broasca
  4.  * Date: 06.05.2021
  5.  * Time: 16:07
  6.  */
  7. namespace App\EventListener;
  8. use App\Entity\ApiLog;
  9. use App\Repository\ApiUsageRepository;
  10. use App\Repository\UserRepository;
  11. use App\Service\AbstractEntityService;
  12. use App\Service\UserService;
  13. use DateTime;
  14. use Doctrine\ORM\EntityManagerInterface;
  15. use Lexik\Bundle\JWTAuthenticationBundle\Exception\JWTDecodeFailureException;
  16. use Symfony\Component\HttpFoundation\JsonResponse;
  17. use Symfony\Component\HttpFoundation\Response;
  18. use Symfony\Component\HttpKernel\Event\ResponseEvent;
  19. use Symfony\Contracts\Translation\TranslatorInterface;
  20. class ResponseListener
  21. {
  22.     /**
  23.      * @var EntityManagerInterface
  24.      */
  25.     protected $entityManager;
  26.     /**
  27.      * @var AbstractEntityService
  28.      */
  29.     protected $abstractEntityService;
  30.     /**
  31.      * @var UserRepository
  32.      */
  33.     protected $userRepository;
  34.     /**
  35.      * @var ApiUsageRepository
  36.      */
  37.     protected $apiUsageRepository;
  38.     /**
  39.      * @var TranslatorInterface
  40.      */
  41.     protected $translator;
  42.     /**
  43.      * @var UserService
  44.      */
  45.     protected $userService;
  46.     public function __construct(
  47.         EntityManagerInterface $entityManager,
  48.         AbstractEntityService  $abstractEntityService,
  49.         UserRepository         $userRepository,
  50.         ApiUsageRepository     $apiUsageRepository,
  51.         TranslatorInterface    $translator,
  52.         UserService            $userService
  53.     )
  54.     {
  55.         $this->entityManager $entityManager;
  56.         $this->abstractEntityService $abstractEntityService;
  57.         $this->userRepository $userRepository;
  58.         $this->apiUsageRepository $apiUsageRepository;
  59.         $this->translator $translator;
  60.         $this->userService $userService;
  61.     }
  62.     /**
  63.      * @throws JWTDecodeFailureException
  64.      */
  65.     public function __invoke(ResponseEvent $event)
  66.     {
  67.         $request $event->getRequest();
  68.         $requestUri $request->getRequestUri();
  69.         $statusCode $event->getResponse()->getStatusCode();
  70.         if (strpos($requestUri'api') == 1) {
  71.             $log = new ApiLog();
  72.             try {
  73.                 if ($statusCode != 301) {
  74.                     $log->setMethod($request->getMethod());
  75.                     $log->setIpAddress($request->getClientIp());
  76.                     $log->setHost($request->getHost());
  77.                     $log->setUri($requestUri);
  78.                     $log->setCode($statusCode);
  79.                     $user $this->abstractEntityService->getUser($request);
  80.                     if ($user) {
  81.                         $log->setUser($user);
  82.                         // notes User access check
  83.                         $hasAccess $this->userService->userHasAccess($user);
  84.                         if (!$hasAccess) {
  85.                             throw new \Exception($this->translator->trans('user.access.denied'), Response::HTTP_FORBIDDEN);
  86.                         }
  87.                     }
  88.                     $log->setTimestamp(new DateTime());
  89.                     $log->setUserAgent($request->headers->get('user-agent'));
  90.                     $apiKey $request->headers->get('api-key');
  91.                     if ($apiKey) {
  92.                         $log->setApiKey($apiKey);
  93.                         $log->setPublicUsage(true);
  94.                         $user $this->userRepository->findOneByApiKey($apiKey);
  95.                         $userApiUsage 0;
  96.                         if ($user) {
  97.                             $log->setUser($user);
  98.                             $userApiUsage $user->getApiUsage();
  99.                         }
  100.                         // notes Api usage check
  101.                         $apiUsage $this->apiUsageRepository->findOneByApiKey($apiKey);
  102.                         if ($apiUsage) {
  103.                             $counter $apiUsage->getCounter();
  104.                             $limit $apiUsage->getLimit();
  105.                             if($limit){
  106.                                 if ($limit <= $counter) {
  107.                                     throw new \Exception($this->translator->trans('api.usage.limit.exceeded'), Response::HTTP_FORBIDDEN);
  108.                                 }
  109.                             }
  110.                             if (!$apiUsage->isActive()) {
  111.                                 throw new \Exception($this->translator->trans('api.usage.account.suspended'), Response::HTTP_FORBIDDEN);
  112.                             }
  113.                             $apiUsage->setCounter($counter 1);
  114.                             $this->entityManager->persist($apiUsage);
  115.                             $this->entityManager->flush();
  116.                         }
  117.                     }
  118.                     $requestData $request->request->all();
  119.                     $log->setRequestData($requestData);
  120.                     $requestHeaders $request->headers->all();
  121.                     $log->setRequestHeaders($requestHeaders);
  122.                     $responseData $event->getResponse()->getContent();
  123.                     $log->setResponseData($responseData);
  124.                     $responseHeaders $event->getResponse()->headers->all();
  125.                     $log->setResponseHeaders($responseHeaders);
  126.                 }
  127.             } catch (\Exception $exception) {
  128.                 $log->setCode($exception->getCode());
  129.                 $event->setResponse(new JsonResponse([
  130.                     'code'    => $exception->getCode(),
  131.                     'message' => $exception->getMessage(),
  132.                 ], $exception->getCode()));
  133.             }
  134.             $this->entityManager->persist($log);
  135.             $this->entityManager->flush();
  136.         }
  137.     }
  138. }