<?php
namespace App\EventSubscriber\File;
use App\Entity\File\OSFile;
use App\Security\Voter\OSFileAccessVoter;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\UriSigner;
use Symfony\Component\Security\Core\Security;
class FileReadSubscriber implements EventSubscriberInterface
{
public function __construct(private UriSigner $uriSigner, private Security $security, private EntityManagerInterface $manager){}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => 'onKernelRequest',
];
}
/**
* @throws InvalideFileSignatureException
* @throws FileAccessNotGrantedException
*/
public function onKernelRequest(RequestEvent $event): void
{
$request = $event->getRequest();
if (!$event->isMainRequest() ) {
return;
}
$secureRoute= ["file-read", "file-download"];
if (!in_array($request->get('_route'), $secureRoute, true)) {
return;
}
if ($request->get('_hash') && !$this->uriSigner->checkRequest($request)) {
throw new InvalideFileSignatureException($request);
}
$doc= $this->manager->getRepository(OSFile::class)->find($request->get('id'));
if(!$this->security->isGranted(OSFileAccessVoter::DOWNLOAD, $doc)){
throw new FileAccessNotGrantedException($request, $doc, OSFileAccessVoter::DOWNLOAD);
}
}
}