src/EventSubscriber/IdentityCompletionSubscriber.php line 33

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber;
  3. use App\Entity\User;
  4. use Symfony\Component\Security\Core\Security// OK pour tes versions
  5. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  6. use Symfony\Component\HttpFoundation\RedirectResponse;
  7. use Symfony\Component\HttpKernel\Event\RequestEvent;
  8. use Symfony\Component\HttpKernel\KernelEvents;
  9. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  10. class IdentityCompletionSubscriber implements EventSubscriberInterface
  11. {
  12.     /**
  13.      * Laisser passer le back-office même si identité incomplète ?
  14.      * -> false : on bloque aussi /admin (recommandé)
  15.      */
  16.     private const ALLOW_BACKOFFICE_BYPASS false;
  17.     public function __construct(
  18.         private Security $security,
  19.         private UrlGeneratorInterface $url,
  20.     ) {}
  21.     public static function getSubscribedEvents(): array
  22.     {
  23.         // priorité haute pour passer AVANT la sécurité
  24.         // Le firewall SecurityListener tourne classiquement autour de 8->0.
  25.         return [KernelEvents::REQUEST => ['onRequest'200]];
  26.     }
  27.     public function onRequest(RequestEvent $event): void
  28.     {
  29.         if (!$event->isMainRequest()) {
  30.             return;
  31.         }
  32.         $request $event->getRequest();
  33.         /** @var User|null $user */
  34.         $user $this->security->getUser();
  35.         if (!$user instanceof User) {
  36.             return; // non connecté
  37.         }
  38.         // --- Whitelist (routes/paths jamais bloqués) ---
  39.         $route = (string) ($request->attributes->get('_route') ?? '');
  40.         $path  $request->getPathInfo();
  41.         $whitelistRoutes = [
  42.             'app_login',
  43.             'app_logout',
  44.             'app_identity_complete'
  45.             '_wdt',
  46.             '_profiler',
  47.         ];
  48.         if (!str_starts_with($path'/admin') && $route !== 'admin' && $route !== 'easyadmin') {
  49.             return;
  50.         }
  51.         if (in_array($route$whitelistRoutestrue)) {
  52.             return;
  53.         }
  54.         if (
  55.             str_starts_with($path'/_profiler') ||
  56.             str_starts_with($path'/assets/')   ||
  57.             str_starts_with($path'/build/')    ||
  58.             str_starts_with($path'/uploads/')  ||
  59.             str_starts_with($route'api_')
  60.         ) {
  61.             return;
  62.         }
  63.         if (self::ALLOW_BACKOFFICE_BYPASS) {
  64.             if ($route === 'easyadmin' || $route === 'admin' || str_starts_with($path'/admin')) {
  65.                 return;
  66.             }
  67.         }
  68.         // --- Condition de blocage (robuste) ---
  69.         // allowSelfEdit via is* OU get* selon ton entité
  70.         $allowSelfEdit false;
  71.         if (method_exists($user'isAllowSelfEdit')) {
  72.             $allowSelfEdit = (bool) $user->isAllowSelfEdit();
  73.         } elseif (method_exists($user'getAllowSelfEdit')) {
  74.             $allowSelfEdit = (bool) $user->getAllowSelfEdit();
  75.         }
  76.         // normalise les champs (trim pour éviter espaces/valeurs " ")
  77.         $ln trim((string) ($user->getLastName()   ?? ''));
  78.         $fn trim((string) ($user->getFirstName()  ?? ''));
  79.         $ec trim((string) ($user->getEntityCode() ?? ''));
  80.         $missingCoreIdentity = ($ln === '' || $fn === '' || $ec === '');
  81.         $needsCompletion $allowSelfEdit && $missingCoreIdentity;
  82.         error_log('[IdentityBlock] route='.$route.' path='.$path);
  83.         error_log('[IdentityBlock] allowSelfEdit='.($allowSelfEdit?'1':'0').' ln=['.$ln.'] fn=['.$fn.'] ec=['.$ec.']');
  84.         error_log('[IdentityBlock] needsCompletion='.($needsCompletion?'1':'0'));
  85.         if (!$needsCompletion) {
  86.             return;
  87.         }
  88.         // Mémorise la première cible pour retour après complétion
  89.         if (!$request->getSession()->has('_identity_target')) {
  90.             $request->getSession()->set('_identity_target'$request->getRequestUri());
  91.         }
  92.         // 🚦 Redirection immédiate vers la complétion
  93.         $event->setResponse(new RedirectResponse($this->url->generate('app_identity_complete')));
  94.     }
  95. }