src/EventSubscriber/LoginSubscriber.php line 41

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber;
  3. use App\Component\UserRole\Manager\UserRoleManager;
  4. use App\Entity\User;
  5. use Scheb\TwoFactorBundle\Security\TwoFactor\Event\TwoFactorAuthenticationEvent;
  6. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  7. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  8. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  9. use Symfony\Component\Security\Http\Event\LoginSuccessEvent;
  10. use Symfony\Component\Security\Http\Event\SwitchUserEvent;
  11. class LoginSubscriber implements EventSubscriberInterface
  12. {
  13.     public function __construct(
  14.         private readonly SessionInterface $session,
  15.         private readonly UserRoleManager $userRoleManager
  16.     ) {
  17.     }
  18.     public static function getSubscribedEvents(): array
  19.     {
  20.         return [
  21.             SwitchUserEvent::class => 'onSecuritySwitchUser',
  22.             LoginSuccessEvent::class => 'onLoginSuccess',
  23.             'scheb_two_factor.authentication.complete' => 'onTwoFactorAuthenticationComplete',
  24.         ];
  25.     }
  26.     public function onLoginSuccess(LoginSuccessEvent $event): void
  27.     {
  28.         $this->interactiveLogin($event->getAuthenticatedToken());
  29.     }
  30.     public function onTwoFactorAuthenticationComplete(TwoFactorAuthenticationEvent $event): void
  31.     {
  32.         $this->interactiveLogin($event->getToken());
  33.     }
  34.     public function onSecuritySwitchUser(SwitchUserEvent $event): void
  35.     {
  36.         $this->setUserGroupPermissions($event->getToken());
  37.     }
  38.     /**
  39.      * calculate and assign UserRoleEntries.
  40.      */
  41.     private function setUserGroupPermissions(TokenInterface $token): void
  42.     {
  43.         // ROLE_SUPER_ADMIN doesn't need user_role_entries
  44.         if (\in_array('ROLE_SUPER_ADMIN'$token->getRoleNames(), true)) {
  45.             return;
  46.         }
  47.         $user $token->getUser();
  48.         if (!$user instanceof User) {
  49.             return;
  50.         }
  51.         $roles $user->getUserRoles();
  52.         if ($roles->isEmpty() && null !== $userRole $this->userRoleManager->getDefaultUserRole()) {
  53.             $roles = [$userRole];
  54.         }
  55.         $entries = [];
  56.         foreach ($roles as $role) {
  57.             $rolePermissions $this->userRoleManager->getRolePermissions($role);
  58.             // if role has all permissions, skip iteration
  59.             if (!$rolePermissions) {
  60.                 $token->setAttribute('user_role_entries', []);
  61.                 return;
  62.             }
  63.             if (\count($entries) > 0) {
  64.                 $rolePermissions array_intersect_key($rolePermissions$entries);
  65.                 foreach (array_diff_key($entries$rolePermissions) as $key => $val) {
  66.                     unset($entries[$key]);
  67.                 }
  68.             }
  69.             foreach ($rolePermissions as $classType => $permission) {
  70.                 // if classType already has a mask, calculate new mask
  71.                 if (\array_key_exists($classType$entries)) {
  72.                     $entries[$classType] = $entries[$classType] | $permission['mask'];
  73.                     continue;
  74.                 }
  75.                 $entries[$classType] = $permission['mask'];
  76.             }
  77.         }
  78.         $token->setAttribute('user_role_entries'$entries);
  79.     }
  80.     private function interactiveLogin(TokenInterface $token): void
  81.     {
  82.         $this->setUserGroupPermissions($token);
  83.         /** @var User $user */
  84.         $user $token->getUser();
  85.         if (null !== $user->getLocale()) {
  86.             $this->session->set(AdminSubscriber::ADMIN_USER_LOCALE$user->getLocale());
  87.         }
  88.         $this->session->set('site_access'true);
  89.     }
  90. }