8000 feature #37704 [MonologBridge] Added SwitchUserTokenProcessor to log … · symfony/symfony@3ba965a · GitHub
[go: up one dir, main page]

Skip to content

Commit 3ba965a

Browse files
committed
feature #37704 [MonologBridge] Added SwitchUserTokenProcessor to log the impersonator (IgorTimoshenko)
This PR was squashed before being merged into the 5.2-dev branch. Discussion ---------- [MonologBridge] Added SwitchUserTokenProcessor to log the impersonator | Q | A | ------------- | --- | Branch? | master <!-- see below --> | Bug fix? | no | New feature? | yes <!-- please update src/**/CHANGELOG.md files --> | Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tickets | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead --> | License | MIT | Doc PR | symfony/symfony-docs#... <!-- required for new features --> This pull request adds the ability to log the impersonator user in case of user impersonation feature usage. The current TokenProcessor logs only the current token and there are no ability to simply log the original token, so we need to copy-paste the TokenProcessor and change a few lines to log the original token Commits ------- 2f8651d [MonologBridge] Added SwitchUserTokenProcessor to log the impersonator
2 parents 3892615 + 2f8651d commit 3ba965a

File tree

4 files changed

+154
-19
lines changed

4 files changed

+154
-19
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Monolog\Processor;
13+
14+
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
15+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
16+
17+
/**
18+
* The base class for security token processors.
19+
*
20+
* @author Dany Maillard <danymaillard93b@gmail.com>
21+
* @author Igor Timoshenko <igor.timoshenko@i.ua>
22+
*/
23+
abstract class AbstractTokenProcessor
24+
{
25+
/**
26+
* @var TokenStorageInterface
27+
*/
28+
protected $tokenStorage;
29+
30+
public function __construct(TokenStorageInterface $tokenStorage)
31+
{
32+
$this->tokenStorage = $tokenStorage;
33+
}
34+
35+
abstract protected function getKey(): string;
36+
37+
abstract protected function getToken(): ?TokenInterface;
38+
39+
public function __invoke(array $record): array
40+
{
41+
$record['extra'][$this->getKey()] = null;
42+
43+
if (null !== $token = $this->getToken()) {
44+
$record['extra'][$this->getKey()] = [
45+
'username' => $token->getUsername(),
46+
'authenticated' => $token->isAuthenticated(),
47+
'roles' => $token->getRoleNames(),
48+
];
49+
}
50+
51+
return $record;
52+
}
53+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Monolog\Processor;
13+
14+
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
15+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
16+
17+
/**
18+
* Adds the original security token to the log entry.
19+
*
20+
* @author Igor Timoshenko <igor.timoshenko@i.ua>
21+
*/
22+
class SwitchUserTokenProcessor extends AbstractTokenProcessor
23+
{
24+
/**
25+
* {@inheritdoc}
26+
*/
27+
protected function getKey(): string
28+
{
29+
return 'impersonator_token';
30+
}
31+
32+
/**
33+
* {@inheritdoc}
34+
*/
35+
protected function getToken(): ?TokenInterface
36+
{
37+
$token = $this->tokenStorage->getToken();
38+
39+
if ($token instanceof SwitchUserToken) {
40+
return $token->getOriginalToken();
41+
}
42+
43+
return null;
44+
}
45+
}

src/Symfony/Bridge/Monolog/Processor/TokenProcessor.php

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,35 +11,29 @@
1111

1212
namespace Symfony\Bridge\Monolog\Processor;
1313

14-
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
14+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
1515

1616
/**
1717
* Adds the current security token to the log entry.
1818
*
1919
* @author Dany Maillard <danymaillard93b@gmail.com>
20+
* @author Igor Timoshenko <igor.timoshenko@i.ua>
2021
*/
21-
class TokenProcessor
22+
class TokenProcessor extends AbstractTokenProcessor
2223
{
23-
private $tokenStorage;
24-
25-
public function __construct(TokenStorageInterface $tokenStorage)
24+
/**
25+
* {@inheritdoc}
26+
*/
27+
protected function getKey(): string
2628
{
27-
$this->tokenStorage = $tokenStorage;
29+
return 'token';
2830
}
2931

30-
public function __invoke(array $records)
32+
/**
33+
* {@inheritdoc}
34+
*/
35+
protected function getToken(): ?TokenInterface
3136
{
32-
$records['extra']['token'] = null;
33-
if (null !== $token = $this->tokenStorage->getToken()) {
34-
$roles = $token->getRoleNames();
35-
36-
$records['extra']['token'] = [
37-
'username' => $token->getUsername(),
38-
'authenticated' => $token->isAuthenticated(),
39-
'roles' => $roles,
40-
];
41-
}
42-
43-
return $records;
37+
return $this->tokenStorage->getToken();
4438
}
4539
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Monolog\Tests\Processor;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Bridge\Monolog\Processor\SwitchUserTokenProcessor;
16+
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
17+
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
18+
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
19+
20+
/**
21+
* Tests the SwitchUserTokenProcessor.
22+
*
23+
* @author Igor Timoshenko <igor.timoshenko@i.ua>
24+
*/
25+
class SwitchUserTokenProcessorTest extends TestCase
26+
{
27+
public function testProcessor()
28+
{
29+
$originalToken = new UsernamePasswordToken('original_user', 'password', 'provider', ['ROLE_SUPER_ADMIN']);
30+
$switchUserToken = new SwitchUserToken('user', 'passsword', 'provider', ['ROLE_USER'], $originalToken);
31+
$tokenStorage = $this->getMockBuilder(TokenStorageInterface::class)->getMock();
32+
$tokenStorage->method('getToken')->willReturn($switchUserToken);
33+
34+
$processor = new SwitchUserTokenProcessor($tokenStorage);
35+
$record = ['extra' => []];
36+
$record = $processor($record);
37+
38+
$this->assertArrayHasKey('original_token', $record['extra']);
39+
$this->assertEquals($originalToken->getUsername(), $record['extra']['original_token']['username']);
40+
$this->assertEquals($originalToken->isAuthenticated(), $record['extra']['original_token']['authenticated']);
41+
$this->assertEquals(['ROLE_SUPER_ADMIN'], $record['extra']['original_token']['roles']);
42+
}
43+
}

0 commit comments

Comments
 (0)
0