<?php
declare(strict_types=1);
namespace App\Component\AuditLog\EventSubscriber;
use App\Component\AuditLog\Action;
use App\Component\AuditLog\Message\Command\AuditLogEntry;
use App\Entity\User;
use Scheb\TwoFactorBundle\Security\TwoFactor\Event\TwoFactorAuthenticationEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Event\LoginSuccessEvent;
use Symfony\Component\Security\Http\Event\SwitchUserEvent;
class AuditLogSubscriber implements EventSubscriberInterface
{
public function __construct(private readonly MessageBusInterface $messageBus)
{
}
public static function getSubscribedEvents(): array
{
return [
SwitchUserEvent::class => 'onSecuritySwitchUser',
LoginSuccessEvent::class => 'onLoginSuccess',
'scheb_two_factor.authentication.complete' => 'onTwoFactorAuthenticationComplete',
];
}
public function onTwoFactorAuthenticationComplete(TwoFactorAuthenticationEvent $event): void
{
$this->loginEntry($event->getToken());
}
public function onSecuritySwitchUser(SwitchUserEvent $event): void
{
$user = $event->getToken()?->getUser();
/** @var int $userId */
$userId = $user instanceof User ? $user->getId() : 0;
/** @var User $targetUser */
$targetUser = $event->getTargetUser();
$targetUserId = $targetUser->getId();
if ($userId !== $targetUserId) {
$this->messageBus->dispatch(new AuditLogEntry($userId, Action::USER_SWITCH->value, (string) $targetUserId));
}
}
public function onLoginSuccess(LoginSuccessEvent $event): void
{
$this->loginEntry($event->getAuthenticatedToken());
}
private function loginEntry(TokenInterface $token): void
{
$user = $token->getUser();
/** @var int $userId */
$userId = $user instanceof User ? $user->getId() : 0;
$this->messageBus->dispatch(new AuditLogEntry($userId, Action::USER_LOGIN->value));
}
}