Skip to content

Commit

Permalink
Support logging the impersonator user, if any (#647)
Browse files Browse the repository at this point in the history
  • Loading branch information
ste93cry committed Jul 15, 2022
1 parent 0c6eee6 commit 3314c20
Show file tree
Hide file tree
Showing 5 changed files with 234 additions and 64 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Expand Up @@ -3,9 +3,11 @@
## Unreleased

- Add support for tracing of the Symfony HTTP client requests (#606)
- Support logging the impersonator user, if any (#647)

## 4.3.0 (2022-05-30)
- Fix compatibility issue with Symfony >= 6.1.0 (#635)

- Fix compatibility issue with Symfony `>= 6.1.0` (#635)
- Add `TracingDriverConnectionInterface::getNativeConnection()` method to get the original driver connection (#597)
- Add `options.http_timeout` and `options.http_connect_timeout` configuration options (#593)

Expand Down
25 changes: 15 additions & 10 deletions phpstan-baseline.neon
Expand Up @@ -160,16 +160,6 @@ parameters:
count: 1
path: src/EventListener/RequestListener.php

-
message: "#^Cannot call method getUser\\(\\) on Symfony\\\\Component\\\\Security\\\\Core\\\\Authentication\\\\Token\\\\TokenInterface\\|null\\.$#"
count: 1
path: src/EventListener/RequestListener.php

-
message: "#^Parameter \\#1 \\$user of method Sentry\\\\SentryBundle\\\\EventListener\\\\RequestListener\\:\\:getUsername\\(\\) expects object\\|string, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#"
count: 1
path: src/EventListener/RequestListener.php

-
message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpKernel\\\\Event\\\\KernelEvent\\:\\:isMasterRequest\\(\\)\\.$#"
count: 1
Expand Down Expand Up @@ -315,6 +305,21 @@ parameters:
count: 1
path: tests/EventListener/RequestListenerTest.php

-
message: "#^Parameter \\#3 \\$roles of class Symfony\\\\Component\\\\Security\\\\Core\\\\Authentication\\\\Token\\\\SwitchUserToken constructor expects array\\<string\\>, string given\\.$#"
count: 1
path: tests/EventListener/RequestListenerTest.php

-
message: "#^Parameter \\#4 \\$originalToken of class Symfony\\\\Component\\\\Security\\\\Core\\\\Authentication\\\\Token\\\\SwitchUserToken constructor expects Symfony\\\\Component\\\\Security\\\\Core\\\\Authentication\\\\Token\\\\TokenInterface, array\\<int, string\\> given\\.$#"
count: 1
path: tests/EventListener/RequestListenerTest.php

-
message: "#^Parameter \\#5 \\$originatedFromUri of class Symfony\\\\Component\\\\Security\\\\Core\\\\Authentication\\\\Token\\\\SwitchUserToken constructor expects string\\|null, Sentry\\\\SentryBundle\\\\Tests\\\\EventListener\\\\AuthenticatedTokenStub given\\.$#"
count: 1
path: tests/EventListener/RequestListenerTest.php

-
message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpKernel\\\\Event\\\\KernelEvent\\:\\:isMasterRequest\\(\\)\\.$#"
count: 1
Expand Down
36 changes: 26 additions & 10 deletions src/EventListener/RequestListener.php
Expand Up @@ -10,6 +10,7 @@
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\User\UserInterface;

Expand Down Expand Up @@ -62,16 +63,11 @@ public function handleKernelRequestEvent(RequestEvent $event): void
return;
}

$token = null;
$userData = new UserDataBag();
$userData->setIpAddress($event->getRequest()->getClientIp());

if (null !== $this->tokenStorage) {
$token = $this->tokenStorage->getToken();
}

if ($this->isTokenAuthenticated($token)) {
$userData->setUsername($this->getUsername($token->getUser()));
$this->setUserData($userData, $this->tokenStorage->getToken());
}

$this->hub->configureScope(static function (Scope $scope) use ($userData): void {
Expand Down Expand Up @@ -103,7 +99,7 @@ public function handleKernelControllerEvent(ControllerEvent $event): void
}

/**
* @param UserInterface|object|string $user
* @param UserInterface|object|string|null $user
*/
private function getUsername($user): ?string
{
Expand All @@ -128,12 +124,32 @@ private function getUsername($user): ?string
return null;
}

private function isTokenAuthenticated(?TokenInterface $token): bool
private function getImpersonatorUser(TokenInterface $token): ?string
{
if (null === $token) {
return false;
if (!$token instanceof SwitchUserToken) {
return null;
}

return $this->getUsername($token->getOriginalToken()->getUser());
}

private function setUserData(UserDataBag $userData, ?TokenInterface $token): void
{
if (null === $token || !$this->isTokenAuthenticated($token)) {
return;
}

$userData->setUsername($this->getUsername($token->getUser()));

$impersonatorUser = $this->getImpersonatorUser($token);

if (null !== $impersonatorUser) {
$userData->setMetadata('impersonator_username', $impersonatorUser);
}
}

private function isTokenAuthenticated(TokenInterface $token): bool
{
if (method_exists($token, 'isAuthenticated') && !$token->isAuthenticated(false)) {
return false;
}
Expand Down
12 changes: 11 additions & 1 deletion tests/EventListener/Fixtures/UserWithIdentifierStub.php
Expand Up @@ -8,14 +8,24 @@

final class UserWithIdentifierStub implements UserInterface
{
/**
* @var string
*/
private $username;

public function __construct(string $username = 'foo_user')
{
$this->username = $username;
}

public function getUserIdentifier(): string
{
return $this->getUsername();
}

public function getUsername(): string
{
return 'foo_user';
return $this->username;
}

public function getRoles(): array
Expand Down

0 comments on commit 3314c20

Please sign in to comment.