src/EventSubscriber/PartnerAuthSubscriber.php line 42

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\EventSubscriber;
  4. use App\Helper\Partner\PartnerHelper;
  5. use Croisiland\CommonBundle\Entity\Partner\Partner;
  6. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  7. use Symfony\Component\HttpFoundation\RedirectResponse;
  8. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  9. use Symfony\Component\HttpKernel\Event\RequestEvent;
  10. use Symfony\Component\HttpKernel\KernelEvents;
  11. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  12. readonly class PartnerAuthSubscriber implements EventSubscriberInterface
  13. {
  14. // Liste des routes qui ne nécessitent PAS d'authentification partenaire
  15. private const array PUBLIC_ROUTES = [
  16. 'website_partner_auth.login',
  17. 'website_partner_auth.logout',
  18. '_wdt',
  19. '_profiler',
  20. '_preview_error',
  21. 'sulu_media.website',
  22. ];
  23. public function __construct(
  24. private PartnerHelper $partnerHelper,
  25. private SessionInterface $session,
  26. private UrlGeneratorInterface $urlGenerator,
  27. ) {}
  28. public static function getSubscribedEvents(): array
  29. {
  30. // Priorité légèrement inférieure au resolver pour être sûr que le partenaire est là
  31. return [
  32. KernelEvents::REQUEST => ['onKernelRequest', 10],
  33. ];
  34. }
  35. public function onKernelRequest(RequestEvent $event): void
  36. {
  37. if (!$event->isMainRequest()) {
  38. return;
  39. }
  40. $request = $event->getRequest();
  41. $routeName = $request->attributes->get('_route');
  42. // 1. Vérification immédiate : route publique ?
  43. if ($this->isPublicRoute($routeName)) {
  44. return;
  45. }
  46. // 2. Récupération du partenaire résolu par l'autre subscriber
  47. /** @var Partner|null $partner */
  48. $partner = $request->attributes->get('partner');
  49. // Si pas de partenaire (pas de sous-domaine ou sous-domaine inconnu), on ne fait rien
  50. // (Ou vous pouvez décider de rediriger vers une page 404/erreur ici)
  51. if ($partner === null) {
  52. return;
  53. }
  54. // 3. Vérification de la session
  55. $sessionKey = $this->partnerHelper->getPartnerSessionKey($partner);
  56. if (!$this->session->get($sessionKey, false) && $_ENV['APP_SERV_ENV'] !== 'dev') {
  57. // Redirection vers le login
  58. $loginUrl = $this->urlGenerator->generate('website_partner_auth.login', $request->query->all());
  59. $event->setResponse(new RedirectResponse($loginUrl));
  60. $event->stopPropagation();
  61. }
  62. }
  63. private function isPublicRoute(?string $routeName): bool
  64. {
  65. if ($routeName === null) {
  66. return false;
  67. }
  68. foreach (self::PUBLIC_ROUTES as $publicRoute) {
  69. // Utilisation de str_starts_with pour plus de clarté et de performance que fnmatch
  70. if (str_starts_with($routeName, $publicRoute)) {
  71. return true;
  72. }
  73. }
  74. return false;
  75. }
  76. }