vendor/ibexa/personalization/src/lib/Event/Listener/LoginListener.php line 69

Open in your IDE?
  1. <?php
  2. /**
  3.  * @copyright Copyright (C) Ibexa AS. All rights reserved.
  4.  * @license For full copyright and license information view LICENSE file distributed with this source code.
  5.  */
  6. declare(strict_types=1);
  7. namespace Ibexa\Personalization\Event\Listener;
  8. use GuzzleHttp\Exception\RequestException;
  9. use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface;
  10. use Ibexa\Core\MVC\Symfony\Security\UserInterface;
  11. use Ibexa\Core\MVC\Symfony\SiteAccess\SiteAccessServiceInterface;
  12. use Ibexa\Personalization\Client\PersonalizationClientInterface;
  13. use Ibexa\Personalization\Value\Session as RecommendationSession;
  14. use Psr\Log\LoggerInterface;
  15. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  16. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  17. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  18. use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
  19. /**
  20.  * Sends notification to Recommendation servers when user is logged in.
  21.  */
  22. final class LoginListener
  23. {
  24.     /** @var \Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface */
  25.     private $authorizationChecker;
  26.     /** @var \Symfony\Component\HttpFoundation\Session\SessionInterface */
  27.     private $session;
  28.     /** @var \Ibexa\Personalization\Client\PersonalizationClientInterface */
  29.     private $client;
  30.     /** @var \Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface */
  31.     private $configResolver;
  32.     /** @var \Psr\Log\LoggerInterface|null */
  33.     private $logger;
  34.     /** @var \Ibexa\Core\MVC\Symfony\SiteAccess\SiteAccessServiceInterface */
  35.     private $siteAccessService;
  36.     private string $trackingEndpointUrl;
  37.     /**
  38.      * @param \Psr\Log\LoggerInterface $logger
  39.      */
  40.     public function __construct(
  41.         AuthorizationCheckerInterface $authorizationChecker,
  42.         SessionInterface $session,
  43.         PersonalizationClientInterface $client,
  44.         ConfigResolverInterface $configResolver,
  45.         LoggerInterface $logger,
  46.         SiteAccessServiceInterface $siteAccessService,
  47.         string $trackingEndpointUrl
  48.     ) {
  49.         $this->authorizationChecker $authorizationChecker;
  50.         $this->session $session;
  51.         $this->client $client;
  52.         $this->configResolver $configResolver;
  53.         $this->logger $logger;
  54.         $this->siteAccessService $siteAccessService;
  55.         $this->trackingEndpointUrl $trackingEndpointUrl;
  56.     }
  57.     public function onSecurityInteractiveLogin(InteractiveLoginEvent $event): void
  58.     {
  59.         if ($event->getRequest()->get('is_rest_request')) {
  60.             return;
  61.         }
  62.         if (!$this->authorizationChecker->isGranted('IS_AUTHENTICATED_FULLY'// user has just logged in
  63.             || !$this->authorizationChecker->isGranted('IS_AUTHENTICATED_REMEMBERED'// user has logged in using remember_me cookie
  64.         ) {
  65.             return;
  66.         }
  67.         $currentSiteAccess $this->siteAccessService->getCurrent();
  68.         if ($currentSiteAccess === null) {
  69.             return;
  70.         }
  71.         $siteAccessName $currentSiteAccess->name;
  72.         $customerId $this->getCustomerId($siteAccessName);
  73.         $sessionKey RecommendationSession::RECOMMENDATION_SESSION_KEY;
  74.         if (!isset($customerId)) {
  75.             return;
  76.         }
  77.         if (!$event->getRequest()->cookies->has($sessionKey)) {
  78.             if (!$this->session->isStarted()) {
  79.                 $this->session->start();
  80.             }
  81.             $event->getRequest()->cookies->set($sessionKey$this->session->getId());
  82.         }
  83.         $notificationUri $this->getNotificationUri(
  84.             $this->trackingEndpointUrl,
  85.             $customerId,
  86.             (string) $event->getRequest()->cookies->get($sessionKey),
  87.             $this->getUser($event->getAuthenticationToken())
  88.         );
  89.         $this->logger->debug(sprintf('Send login event notification to Recommendation: %s'$notificationUri));
  90.         try {
  91.             /** @var \Psr\Http\Message\ResponseInterface $response */
  92.             $response $this->client->getHttpClient()->get($notificationUri);
  93.             $this->logger->debug(sprintf('Got %s from Recommendation login event notification'$response->getStatusCode()));
  94.         } catch (RequestException $e) {
  95.             $this->logger->error(sprintf('Recommendation login event notification error: %s'$e->getMessage()));
  96.         }
  97.     }
  98.     private function getCustomerId(string $siteAccessName): ?int
  99.     {
  100.         $parameterNameCustomerId 'personalization.authentication.customer_id';
  101.         if (!$this->configResolver->hasParameter(
  102.             $parameterNameCustomerId,
  103.             null,
  104.             $siteAccessName
  105.         )) {
  106.             return null;
  107.         }
  108.         $customerId = (int)$this->configResolver->getParameter(
  109.             $parameterNameCustomerId,
  110.             null,
  111.             $siteAccessName
  112.         );
  113.         return $customerId ?: null;
  114.     }
  115.     /**
  116.      * Returns notification API end-point.
  117.      */
  118.     private function getNotificationUri(string $endpointint $customerIdstring $sessionIdstring $userId): string
  119.     {
  120.         return sprintf(
  121.             '%s/api/%d/%s/%s/%s',
  122.             $endpoint,
  123.             $customerId,
  124.             'login',
  125.             $sessionId,
  126.             $userId
  127.         );
  128.     }
  129.     /**
  130.      * Returns current username or ApiUser id.
  131.      */
  132.     private function getUser(TokenInterface $authenticationToken): string
  133.     {
  134.         $user $authenticationToken->getUser();
  135.         if ($user instanceof UserInterface) {
  136.             return (string) $user->getAPIUser()->id;
  137.         }
  138.         return $authenticationToken->getUserIdentifier();
  139.     }
  140. }
  141. class_alias(LoginListener::class, 'EzSystems\EzRecommendationClient\Event\Listener\LoginListener');