diff --git a/src/Entity/LogSystem/SecurityEventLogEntry.php b/src/Entity/LogSystem/SecurityEventLogEntry.php index b1b6227a..ffcfd6a5 100644 --- a/src/Entity/LogSystem/SecurityEventLogEntry.php +++ b/src/Entity/LogSystem/SecurityEventLogEntry.php @@ -64,6 +64,7 @@ class SecurityEventLogEntry extends AbstractLogEntry 6 => SecurityEvents::GOOGLE_DISABLED, 7 => SecurityEvents::TRUSTED_DEVICE_RESET, 8 => SecurityEvents::TFA_ADMIN_RESET, + 9 => SecurityEvents::USER_IMPERSONATED, ]; public function __construct(string $type, string $ip_address, bool $anonymize = true) diff --git a/src/EventSubscriber/LogSystem/SecurityEventLoggerSubscriber.php b/src/EventSubscriber/LogSystem/SecurityEventLoggerSubscriber.php index 78941cd5..d9af32c5 100644 --- a/src/EventSubscriber/LogSystem/SecurityEventLoggerSubscriber.php +++ b/src/EventSubscriber/LogSystem/SecurityEventLoggerSubscriber.php @@ -48,6 +48,7 @@ use App\Events\SecurityEvents; use App\Services\LogSystem\EventLogger; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\Security\Http\Event\SwitchUserEvent; /** * This subscriber writes entries to log if a security related event happens (e.g. the user changes its password). @@ -70,6 +71,7 @@ final class SecurityEventLoggerSubscriber implements EventSubscriberInterface SecurityEvents::GOOGLE_DISABLED => 'google_disabled', SecurityEvents::GOOGLE_ENABLED => 'google_enabled', SecurityEvents::TFA_ADMIN_RESET => 'tfa_admin_reset', + SecurityEvents::USER_IMPERSONATED => 'user_impersonated', ]; } @@ -103,6 +105,11 @@ final class SecurityEventLoggerSubscriber implements EventSubscriberInterface $this->addLog(SecurityEvents::U2F_REMOVED, $event); } + public function user_impersonated(SecurityEvent $event): void + { + $this->addLog(SecurityEvents::USER_IMPERSONATED, $event); + } + public function u2f_added(SecurityEvent $event): void { $this->addLog(SecurityEvents::U2F_ADDED, $event); diff --git a/src/EventSubscriber/SwitchUserEventSubscriber.php b/src/EventSubscriber/SwitchUserEventSubscriber.php new file mode 100644 index 00000000..a7f2e39c --- /dev/null +++ b/src/EventSubscriber/SwitchUserEventSubscriber.php @@ -0,0 +1,64 @@ +. + */ + +declare(strict_types=1); + + +namespace App\EventSubscriber; + +use App\Entity\UserSystem\User; +use App\Events\SecurityEvent; +use App\Events\SecurityEvents; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken; +use Symfony\Component\Security\Http\Event\SwitchUserEvent; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; + +class SwitchUserEventSubscriber implements EventSubscriberInterface +{ + + public function __construct(private readonly EventDispatcherInterface $eventDispatcher) + { + } + + public static function getSubscribedEvents() + { + return [ + 'security.switch_user' => 'onSwitchUser', + ]; + } + + public function onSwitchUser(SwitchUserEvent $event): void + { + $target_user = $event->getTargetUser(); + // We can only handle User objects + if (!$target_user instanceof User) { + return; + } + + //We are only interested in impersonation (not unimpersonation) + if (!$event->getToken() instanceof SwitchUserToken) { + return; + } + + $security_event = new SecurityEvent($target_user); + $this->eventDispatcher->dispatch($security_event, SecurityEvents::USER_IMPERSONATED); + } +} \ No newline at end of file diff --git a/src/Events/SecurityEvents.php b/src/Events/SecurityEvents.php index c7c43882..f2e44c6f 100644 --- a/src/Events/SecurityEvents.php +++ b/src/Events/SecurityEvents.php @@ -52,4 +52,6 @@ class SecurityEvents final public const GOOGLE_DISABLED = 'security.google_disabled'; final public const TRUSTED_DEVICE_RESET = 'security.trusted_device_reset'; final public const TFA_ADMIN_RESET = 'security.2fa_admin_reset'; + + final public const USER_IMPERSONATED = 'security.user_impersonated'; } diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index c00b68c9..ffbd71df 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -11429,5 +11429,11 @@ Element 3 Please note, that you can not impersonate a disabled user. If you try you will get an "Access Denied" message. + + + log.type.security.user_impersonated + User impersonated + +