<?php
namespace DW\GingerBundle\EventSubscriber;
use DW\GingerBundle\DWGingerEvents;
use DW\GingerBundle\Entity\AdminLog;
use DW\GingerBundle\Event\AdminLogEvent;
use DW\GingerBundle\Doctrine\AdminLogManager;
use FOS\OAuthServerBundle\Security\Authentication\Token\OAuthToken;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
class AdminLogEventSubscriber implements EventSubscriberInterface
{
/**
* @var \Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface
*/
private $tokenStorage;
/**
* @var \Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface
*/
private $authorizationChecker;
private ?TokenInterface $token = null;
public function __construct(TokenStorageInterface $tokenStorage = null, AuthorizationCheckerInterface $authorizationChecker = null)
{
$this->tokenStorage = $tokenStorage;
$this->authorizationChecker = $authorizationChecker;
}
/**
* Add auth-related information to admin log.
*/
public function addAuthInfo(AdminLogEvent $event)
{
if (null === $this->tokenStorage || null === $this->authorizationChecker) {
return;
}
$this->token = $this->tokenStorage->getToken();
if (null !== $this->token && $this->authorizationChecker->isGranted(AuthenticatedVoter::IS_AUTHENTICATED_FULLY)) {
$log = $event->getAdminLog();
$this->setChannel($log);
$this->setUserName($log);
}
}
/**
* Set channel.
*
* TODO: Also check one user role in case of UsernamePasswordToken ???
*
* @param \DW\GingerBundle\Entity\AdminLog $log
*/
private function setChannel(AdminLog $log)
{
if ($this->token instanceof OAuthToken) {
$log->setChannel(AdminLogManager::CHANNEL_API_CLIENT);
} else if ($this->token instanceof UsernamePasswordToken) {
$log->setChannel(AdminLogManager::CHANNEL_ADMIN_BACKEND);
}
}
/**
* If not username is present, set it from current token.
*
* @param \DW\GingerBundle\Entity\AdminLog $log
*/
private function setUserName(AdminLog $log)
{
if(empty($log->getUsername())) {
$log->setUsername($this->token->getUserIdentifier());
}
}
/**
* @return array|void
*/
public static function getSubscribedEvents()
{
return [
DWGingerEvents::ADMIN_LOG_PRE_PERSIST => 'addAuthInfo'
];
}
}