<?php
namespace App\EventSubscriber\Framework;
use App\Entity\Profile;
use App\Entity\Profile\JoboffererProfile;
use App\Entity\Profile\JobseekerProfile;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Twig\Environment;
class AccessDeniedSubscriber implements EventSubscriberInterface
{
private $router;
private $entityManager;
private $tokenStorage;
private $template;
public function __construct(RouterInterface $router, EntityManagerInterface $entityManager, TokenStorageInterface $tokenStorage, Environment $template)
{
$this->router = $router;
$this->entityManager = $entityManager;
$this->tokenStorage = $tokenStorage;
$this->template = $template;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::EXCEPTION => ['onKernelException', 1],
];
}
/** @throws Exception */
public function onKernelException(ExceptionEvent $event): void
{
$token = $this->tokenStorage->getToken();
/** @var User $user */
$user = null;
if (!is_null($token)) {
$user = $token->getUser();
}
if (is_object($user) && $event->getThrowable() instanceof AccessDeniedException) {
$request = $event->getRequest();
$matchedRoute = $request->attributes->get('_route');
if (in_array($matchedRoute, [
'account.conversations.show_jobseeker',
'account.conversations.show_jobofferer'
])) {
$username = $this->getLoginUsername($request, $matchedRoute);
$response = new Response($this->template->render('errors/access_denied.html.twig', [
'username' => $username,
'targetPath' => $request->getRequestUri()
]), Response::HTTP_FORBIDDEN);
$response->prepare($request);
$event->setResponse($response);
}
}
}
protected function getLoginUsername(Request $request, string $route): string
{
$profileId = $route === 'account.conversations.show_jobseeker' ? $request->attributes->get('jobseekerProfileId') : $request->attributes->get('joboffererProfileId');
$class = $route === 'account.conversations.show_jobseeker' ? JobseekerProfile::class : JoboffererProfile::class;
/** @var Profile $profile */
$profile = $this->entityManager->getRepository($class)->find($profileId);
return !is_null($profile) ? $profile->getUser()->getUsername() : '';
}
}