src/Component/Firewall/FirewallListener.php line 41

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Component\Firewall;
  4. use App\Entity\User;
  5. use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
  6. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  7. use Symfony\Component\HttpFoundation\RedirectResponse;
  8. use Symfony\Component\HttpFoundation\Request;
  9. use Symfony\Component\HttpKernel\Event\ControllerEvent;
  10. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  11. use Symfony\Component\Security\Core\Security;
  12. use Symfony\Component\Security\Http\Event\LogoutEvent;
  13. #[AsEventListener(priority4096)]
  14. readonly class FirewallListener
  15. {
  16.     private const WHITELIST = [
  17.         // Concawe offices (Skynet)
  18.         '91.183.59.41',
  19.         // Concawe offices (Unix Solutions)
  20.         '195.189.202.50',
  21.         // Peter Discart home
  22.         '81.82.232.137',
  23.         // Kristof Torfs home
  24.         '81.82.197.76',
  25.         // Chris Davidson home
  26.         '81.133.240.129',
  27.     ];
  28.     public function __construct(
  29.         private Security $security,
  30.         private TokenStorageInterface $tokenStorage,
  31.         private EventDispatcherInterface $eventDispatcher,
  32.         private string $environment
  33.     ) {
  34.     }
  35.     public function __invoke(ControllerEvent $event): void
  36.     {
  37.         if ('dev' === $this->environment) {
  38.             // Firewall only applies to online environments
  39.             return;
  40.         }
  41.         $user $this->security->getUser();
  42.         if (!$user instanceof User) {
  43.             // Firewall only applies to authenticated users
  44.             return;
  45.         }
  46.         if (!$user->isStaff()) {
  47.             // Firewall only applies to staff members
  48.             return;
  49.         }
  50.         $ip $event->getRequest()->getClientIp();
  51.         if (in_array($ipself::WHITELISTtrue)) {
  52.             // Firewall only applies to IP addresses that are not in the whitelist
  53.             return;
  54.         }
  55.         // Clear authentication
  56.         $this->logout($event->getRequest());
  57.         // Redirect
  58.         $event->setController(fn (): RedirectResponse => new RedirectResponse('/not-secure'));
  59.         // Stop event propagation
  60.         $event->stopPropagation();
  61.     }
  62.     private function logout(Request $request): void
  63.     {
  64.         // FIXME: Use the new Security bundle when upgrading to Symfony 6
  65.         $event = new LogoutEvent($request$this->tokenStorage->getToken());
  66.         $this->eventDispatcher->dispatch($event);
  67.         $this->tokenStorage->setToken(null);
  68.     }
  69. }