<?php
namespace App\Event;
use App\Entity\ClientApiKey;
use App\Entity\User;
use App\Repository\UserRepository;
use App\Security\NotClientContextException;
use Sentry\State\Scope;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\AuthenticationEvents;
use Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent;
use Symfony\Component\Security\Core\Security;
use function Sentry\configureScope;
class AdminEventSubscriber implements EventSubscriberInterface {
protected $requestStack;
protected $userRepository;
protected $security;
public function __construct(Security $security, RequestStack $requestStack, UserRepository $userRepository)
{
$this->requestStack = $requestStack;
$this->userRepository = $userRepository;
$this->security = $security;
}
public static function getSubscribedEvents() {
return [
KernelEvents::CONTROLLER => 'onKernelController',
KernelEvents::EXCEPTION => 'onKernelException',
AuthenticationEvents::AUTHENTICATION_SUCCESS => 'onAuthenticationSuccess',
];
}
public function onKernelController(ControllerEvent $event) {
$user = $this->security->getUser();
if($user) {
configureScope(function(Scope $scope) use($user) {
if($user instanceof User) {
$scope->setUser([
'email' => $user->getUserIdentifier(),
'user_id' => $user->getId(),
'client' => ($user->getClient() ? [
'id' => $user->getClient()->getId(),
'name' => $user->getClient()->getName(),
] : null)
]);
} elseif($user instanceof ClientApiKey) {
$scope->setUser([
'name' => $user->getUserIdentifier(),
'id' => $user->getId(),
'client' => [
'id' => $user->getClient()->getId(),
'name' => $user->getClient()->getName(),
]
]);
}
});
}
}
// AUTO MANAGE CLIENT AND RELOAD IF ADMIN ON NotClientContextException
public function onKernelException(ExceptionEvent $event) {
$ex = $event->getThrowable();
if($ex instanceof NotClientContextException && $this->security->isGranted('ROLE_ADMIN') && $ex->getClient()) {
$this->requestStack->getSession()->set("MANAGE_CLIENT", $ex->getClient()->getId());
$event->setResponse(new RedirectResponse($event->getRequest()->getUri()));
}
}
public function onAuthenticationSuccess(AuthenticationSuccessEvent $event) {
$user = $event->getAuthenticationToken()->getUser();
if(!($user instanceof User)) return;
$this->userRepository->registerLogin($event->getAuthenticationToken()->getUser(), $this->requestStack->getMainRequest());
}
}