src/AppBundle/EventListener/MyLorchAuthenticationListener.php line 34

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace AppBundle\EventListener;
  4. use CustomerManagementFrameworkBundle\CustomerProvider\CustomerProviderInterface;
  5. use CustomerManagementFrameworkBundle\Model\CustomerInterface;
  6. use CustomerManagementFrameworkBundle\CustomerSaveValidator\Exception\DuplicateCustomerException;
  7. use CustomerManagementFrameworkBundle\Security\Authentication\LoginManagerInterface;
  8. use CustomerManagementFrameworkBundle\Security\OAuth\OAuthRegistrationHandler;
  9. use HWI\Bundle\OAuthBundle\Security\Core\Exception\AccountNotLinkedException;
  10. use Pimcore\Logger;
  11. use Pimcore\Model\DataObject\Customer;
  12. use Symfony\Component\HttpFoundation\RedirectResponse;
  13. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  14. use Symfony\Component\Routing\RouterInterface;
  15. use Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent;
  16. use Symfony\Component\Security\Core\Exception\UserNotFoundException;
  17. use Symfony\Component\Security\Core\User\UserInterface;
  18. use Symfony\Component\Security\Http\Event\LoginFailureEvent;
  19. use Symfony\Contracts\EventDispatcher\Event;
  20. class MyLorchAuthenticationListener
  21. {
  22.     public function __construct(
  23.         protected OAuthRegistrationHandler $oAuthHandler,
  24.         protected CustomerProviderInterface $customerProvider,
  25.         protected LoginManagerInterface $loginManager,
  26.         protected RouterInterface $router
  27.     ) {
  28.     }
  29.     public function onSuccess(Event $event): void
  30.     {
  31.         if ($event instanceof AuthenticationSuccessEvent) {
  32.             $user $event->getAuthenticationToken()->getUser();
  33.             try {
  34.                 if ($user !== null) {
  35.                     $this->loginManager->login($user);
  36.                 }
  37.             } catch (\Exception $e) {
  38.                 Logger::error($e->getMessage());
  39.             }
  40.         }
  41.     }
  42.     public function onError(Event $event): void
  43.     {
  44.         if ($event instanceof LoginFailureEvent) {
  45.             $error $event->getException();
  46.             $user $event->getRequest()->getUser();
  47.             // OAuth handling - the OAuth authenticator is configured to return to the login page on errors
  48.             // (see failure_path configuration) - therefore we can fetch the last authentication error
  49.             // here. If the error is an AccountNotLinkedException (as thrown by our user provider) save the
  50.             // OAuth token to the session and redirect to registration with a special key which can be used
  51.             // to load the token to prepopulate the registration form with account data.
  52.             if ($error instanceof AccountNotLinkedException) {
  53.                 $oAuthToken    =  $error->getToken();
  54.                 $oAuthUserInfo $this->oAuthHandler->loadUserInformation($oAuthToken);
  55.                 if ($oAuthUserInfo !== null) {
  56.                     $userData $oAuthUserInfo->getData();
  57.                     $customFields = !(empty($userData['customFields'])) ? $userData['customFields'] : [];
  58.                     /** @var CustomerInterface|Customer $customer */
  59.                     $customer $this->customerProvider->create();
  60.                     $customer->setCompany(!(empty($customFields['company'])) ? $customFields['company'] : null);
  61.                     $customer->setLastname(!(empty($userData['family_name'])) ? $userData['family_name'] : null);
  62.                     $customer->setFirstname(!(empty($userData['given_name'])) ? $userData['given_name'] : null);
  63.                     $customer->setEmail(!(empty($userData['email'])) ? $userData['email'] : null);
  64.                     $customer->setCity(!(empty($customFields['locality'])) ? $customFields['locality'] : null);
  65.                     $customer->setStreet(!(empty($customFields['street_address'])) ? $customFields['street_address'] . (!(empty($customFields['house_number'])) ? ' ' $customFields['house_number'] : null) : null);
  66.                     $customer->setZip(!(empty($customFields['postal_code'])) ? $customFields['postal_code'] : null);
  67.                     $customer->setCountryCode(!(empty($customFields['country'])) ? $customFields['country'] : null);
  68.                     $customer->setActive(true);
  69.                     $customer->save();
  70.                     $this->oAuthHandler->connectSsoIdentity($customer$oAuthUserInfo);
  71.                     $response $this->buildUserRedirect($user);
  72.                     try {
  73.                         $response $this->buildUserRedirect($customer);
  74.                         $this->loginManager->login($customer$event->getRequest(), $event->getResponse());
  75.                     } catch (DuplicateCustomerException $e) {
  76.                         $errors[] = 'Customer already exists';
  77.                     } catch (\Exception $e) {
  78.                         $errors[] = $e->getMessage();
  79.                     }
  80.                     $event->setResponse($response);
  81.                 }
  82.             }
  83.         }
  84.     }
  85.     private function buildUserRedirect(UserInterface $user null): RedirectResponse
  86.     {
  87.         /** @var Customer $user */
  88.         if ($user !== null) {
  89.             $dateTime = new \Carbon\Carbon();
  90.             $user->setLastLogin($dateTime);
  91.             $user->save();
  92.             return $this->redirectToRoute('app_mylorch_index');
  93.         }
  94.         return $this->redirectToRoute('app_auth_login');
  95.     }
  96.     protected function redirectToRoute(string $route, array $parameters = [], int $status 302): RedirectResponse
  97.     {
  98.         return $this->redirect($this->generateUrl($route$parameters), $status);
  99.     }
  100.     protected function redirect(string $urlint $status 302): RedirectResponse
  101.     {
  102.         return new RedirectResponse($url$status);
  103.     }
  104.     protected function generateUrl(string $route, array $parameters = [], int $referenceType UrlGeneratorInterface::ABSOLUTE_PATH): string
  105.     {
  106.         return $this->router->generate($route$parameters$referenceType);
  107.     }
  108. }