src/Common/EventSubscriber/AccessLogSubscriber.php line 39

Open in your IDE?
  1. <?php
  2. namespace PaperKite\Common\EventSubscriber;
  3. use Psr\Log\LoggerInterface;
  4. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  5. use Symfony\Component\HttpFoundation\Request;
  6. use Symfony\Component\HttpKernel\Event\ExceptionEvent;
  7. use Symfony\Component\HttpKernel\Event\RequestEvent;
  8. use Symfony\Component\HttpKernel\KernelEvents;
  9. use Symfony\Component\Security\Core\Exception\AccessDeniedException;
  10. class AccessLogSubscriber implements EventSubscriberInterface
  11. {
  12.     public function __construct(
  13.         private LoggerInterface $auditLogger,
  14.     ) {
  15.     }
  16.     public static function getSubscribedEvents(): array
  17.     {
  18.         return [
  19.             KernelEvents::REQUEST => 'onKernelRequest',
  20.             KernelEvents::EXCEPTION => ['onKernelException'2],
  21.         ];
  22.     }
  23.     public function onKernelRequest(RequestEvent $event): void
  24.     {
  25.         if (!$event->isMainRequest()) {
  26.             return;
  27.         }
  28.         $mainRequest $event->getRequest();
  29.         $this->buildLogBasedOnRequest('Access requested.'$mainRequest);
  30.     }
  31.     public function onKernelException(ExceptionEvent $event): void
  32.     {
  33.         if (!$event->isMainRequest()) {
  34.             return;
  35.         }
  36.         $exception $event->getThrowable();
  37.         if (!$exception instanceof AccessDeniedException) {
  38.             return;
  39.         }
  40.         $mainRequest $event->getRequest();
  41.         $this->buildLogBasedOnRequest('Access refused.'$mainRequest);
  42.     }
  43.     private function buildLogBasedOnRequest(string $messageRequest $request): void
  44.     {
  45.         $routeName $request->attributes->get('_route');
  46.         if (false === $this->isListenedRoute($routeName)) {
  47.             return;
  48.         }
  49.         $context = [
  50.             'uri' => $request->getRequestUri(),
  51.             'method' => $request->getMethod(),
  52.         ];
  53.         $relatedObjects $this->getRelatedObjectsFromRequest($request);
  54.         if (count($relatedObjects) > 0) {
  55.             $context[] = $relatedObjects;
  56.         }
  57.         $this->auditLogger->info($message$context);
  58.     }
  59.     private function isListenedRoute(string $routeName): bool
  60.     {
  61.         // Use symfony console debug:router command to get full routes list.
  62.         if (
  63.             str_starts_with($routeName'mycmcm_')
  64.             ||
  65.             str_starts_with($routeName'public_')
  66.             ||
  67.             str_starts_with($routeName'_profiler')
  68.             ||
  69.             true === in_array($routeName, [
  70.                 '_preview_error',
  71.                 '_wdt',
  72.                 'admin_dashboard',
  73.                 'company_get_api_version',
  74.                 'company_show_apidoc',
  75.                 'health_mutual_get_api_version',
  76.                 'health_mutual_show_apidoc',
  77.                 'employee_get_api_version',
  78.                 'employee_get_companies',
  79.                 'employee_get_departments',
  80.                 'employee_get_inquiry_statuses',
  81.                 'employee_get_health_insurances',
  82.                 'employee_get_health_mutuals',
  83.                 'employee_get_dossier_types',
  84.                 'employee_get_dossier_statuses',
  85.                 'employee_get_api_version',
  86.                 'employee_list_subscription_plans',
  87.                 'employee_show_apidoc',
  88.                 'employee_support_predefined_templates',
  89.             ])
  90.         ) {
  91.             return false;
  92.         }
  93.         return true;
  94.     }
  95.     private function getRelatedObjectsFromRequest(Request $request): array
  96.     {
  97.         $relatedObject array_merge($request->attributes->get('_route_params'), $request->query->all());
  98.         unset($relatedObject['schemes']);
  99.         unset($relatedObject['_locale']);
  100.         // To log information from post parameter/content - use $request->getContent()
  101.         $relatedObject array_merge($relatedObject, ['Request Content' => json_decode($request->getContent(), true)]);
  102.         return $relatedObject;
  103.     }
  104. }