Skip to content

Instantly share code, notes, and snippets.

@bernard-ng
Last active September 15, 2021 23:35
Show Gist options
  • Save bernard-ng/445320ec6bb0e80ea6d0d0f616cd51b6 to your computer and use it in GitHub Desktop.
Save bernard-ng/445320ec6bb0e80ea6d0d0f616cd51b6 to your computer and use it in GitHub Desktop.
medium post
<?php
declare(strict_types=1);
namespace App\EventListener;
use App\Repository\DisallowCountryRepository;
use GeoIp2\Database\Reader;
use GeoIp2\Exception\AddressNotFoundException;
use MaxMind\Db\Reader\InvalidDatabaseException;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Intl\Countries;
use Twig\Environment;
/**
* Class DisallowedCountryRequestListener
* @package App\EventListener
* @author bernard-ng <bernard@devscast.tech>
*/
class DisallowedCountryRequestListener
{
private Environment $twig;
private KernelInterface $kernel;
private LoggerInterface $logger;
private DisallowCountryRepository $repository;
public function __construct(
Environment $twig,
KernelInterface $kernel,
LoggerInterface $logger,
DisallowCountryRepository $repository
)
{
$this->twig = $twig;
$this->kernel = $kernel;
$this->logger = $logger;
$this->repository = $repository;
}
public function onKernelRequest(RequestEvent $event): void
{
if (!$event->isMasterRequest()) {
return;
}
$this->restrictAccessOnDisallowedCountries($event);
}
private function restrictAccessOnDisallowedCountries(RequestEvent $event)
{
try {
$request = $event->getRequest();
$reader = new Reader(
$this->kernel->getProjectDir() . "/data/geoip_country.mmdb",
array_unique([$request->getLocale(), 'fr'])
);
$ip = $request->getClientIp();
$record = $reader->country($ip === '127.0.0.1' ? $_ENV['APP_LOCALHOST_IP'] : $ip);
$isoCode = $record->country->isoCode;
if (in_array($isoCode, $this->repository->getDisallowedCountries())) {
$response = new Response();
$response->setStatusCode(Response::HTTP_FORBIDDEN);
$response->setContent($this->twig->render("@common/application/disallowed_country.html.twig", [
'country' => Countries::getName($isoCode),
'iso' => $isoCode
]));
$response->headers->set('Content-Type', 'text/html');
$event->setResponse($response);
}
} catch (AddressNotFoundException | InvalidDatabaseException $e) {
$this->logger->error($e->getMessage(), $e->getTrace());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment