From b677cf6395c5c61593c6cdef02623c17bcaa5570 Mon Sep 17 00:00:00 2001 From: Rolland Csatari Date: Wed, 19 Jun 2024 16:52:16 +0200 Subject: [PATCH] fix(GdprProcessor): Fix readonly issue --- .github/workflows/github-actions.yml | 2 +- CHANGELOG.md | 7 ++++++ Monolog/Processor/GdprProcessor.php | 25 +++++++++++++------ Tests/BypassFinalHook.php | 2 +- Tests/Monolog/Processor/GdprProcessorTest.php | 21 +++++++++++----- 5 files changed, 41 insertions(+), 16 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index cadcbca..527618e 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php: [ '8.1', '8.2' ] + php: [ '8.1', '8.2', '8.3' ] steps: - uses: actions/checkout@v2 - name: Setup PHP with tools diff --git a/CHANGELOG.md b/CHANGELOG.md index b374971..8da1fae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ master * todo... +v3.1.0 +------ +* Configure PHP 8.3 in CI +* Fix the context readonly issue into `Monolog/Processor/GdprProcessor` +* Update `Tests/Monolog/Processor/GdprProcessorTest.php` +* Disable bypassReadOnly into `Ekino\DataProtectionBundle\Tests\BypassFinalHook` + v3.0.0 ------ diff --git a/Monolog/Processor/GdprProcessor.php b/Monolog/Processor/GdprProcessor.php index 325ef80..4991f3d 100644 --- a/Monolog/Processor/GdprProcessor.php +++ b/Monolog/Processor/GdprProcessor.php @@ -32,16 +32,25 @@ public function __construct(private EncryptorInterface $encryptor) public function __invoke(LogRecord $record): LogRecord { - foreach ($record->context as $key => &$val) { - if (preg_match('#^private_#', (string) $key)) { - $encoded = json_encode($val); - if (false === $encoded) { - $encoded = ""; - } - $val = $this->encryptor->encrypt($encoded); + $context = []; + + foreach ($record->context as $key => $value) { + if (str_starts_with((string) $key, 'private_')) { + $value = json_encode($value); + $value = \is_string($value) ? $this->encryptor->encrypt($value) : ''; } + + $context[$key] = $value; } - return $record; + return new LogRecord( + $record->datetime, + $record->channel, + $record->level, + $record->message, + $context, + $record->extra, + $record->formatted + ); } } diff --git a/Tests/BypassFinalHook.php b/Tests/BypassFinalHook.php index d671065..31e3799 100644 --- a/Tests/BypassFinalHook.php +++ b/Tests/BypassFinalHook.php @@ -20,6 +20,6 @@ final class BypassFinalHook implements BeforeTestHook { public function executeBeforeTest(string $test): void { - BypassFinals::enable(); + BypassFinals::enable(bypassReadOnly: false); } } diff --git a/Tests/Monolog/Processor/GdprProcessorTest.php b/Tests/Monolog/Processor/GdprProcessorTest.php index c57debf..2301dfe 100644 --- a/Tests/Monolog/Processor/GdprProcessorTest.php +++ b/Tests/Monolog/Processor/GdprProcessorTest.php @@ -36,24 +36,33 @@ public function testProcessor(): void $encryptor = $this->createMock(EncryptorInterface::class); $encryptor->expects($this->once())->method('encrypt')->willReturn('encrypted_data'); - $record = new LogRecord( - new \DateTimeImmutable(), + $originalRecord = new LogRecord( + new \DateTimeImmutable('2024-06-18'), 'main', Level::Debug, 'The log context includes private data.', [ 0 => 'numeric index', 'foo' => 'bar', - 'private_data' => [ - 'foo' => 'baz', - ], + 'private_data' => ['foo' => 'baz'], + 'data_private' => ['foo' => 'baz'], ], ); + $processedRecord = (new GdprProcessor($encryptor))($originalRecord); + + $this->assertSame($originalRecord->datetime, $processedRecord->datetime); + $this->assertSame($originalRecord->channel, $processedRecord->channel); + $this->assertSame($originalRecord->level, $processedRecord->level); + $this->assertSame($originalRecord->message, $processedRecord->message); + $this->assertSame($originalRecord->extra, $processedRecord->extra); + $this->assertSame($originalRecord->formatted, $processedRecord->formatted); + $this->assertSame([ 0 => 'numeric index', 'foo' => 'bar', 'private_data' => 'encrypted_data', - ], ((new GdprProcessor($encryptor))($record))->context); + 'data_private' => ['foo' => 'baz'], + ], $processedRecord->context); } }