From f673fb28d54f49e27681a0f2ed80d5df463e4c87 Mon Sep 17 00:00:00 2001 From: Joe Date: Thu, 18 Aug 2022 10:03:55 +0100 Subject: [PATCH 1/4] Update ArrayRedactor.php Instead of calling the ink value if it's callable when the property is set, instead call it when actually redacting a value, so that a dynamic redacted value can be applied for each key in the array --- src/ArrayRedactor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ArrayRedactor.php b/src/ArrayRedactor.php index 76cac82..e98c5dd 100644 --- a/src/ArrayRedactor.php +++ b/src/ArrayRedactor.php @@ -99,7 +99,7 @@ public function redact() // Recursively traverse the array and redact the specified keys array_walk_recursive($this->content, function (&$value, $key) { if (in_array($key, $this->keys, true)) { - $value = $this->ink; + $value = is_callable($ink) ? $ink($value) : $this->ink; } }); From 21035850b21cdb266096334d4ffdc4400403332b Mon Sep 17 00:00:00 2001 From: Joe Date: Thu, 18 Aug 2022 10:14:27 +0100 Subject: [PATCH 2/4] Add doc about passing a callable as the ink --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README.md b/README.md index aa2cf0e..33059f6 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,36 @@ $redactor = (new ArrayRedactor($login, ['password', 'session_id']))->ink(null)-> ]; ``` +If the value you pass into the third constructor argument or the `->ink()` method is callable, it will be invoked when redacting each value, and its return value will be used as the redacted value in the result: + +```php +$login = [ + 'email' => 'john_doe@domain.com', + 'password' => 'secret123', + 'data' => [ + 'session_id' => 'z481jf0an4kasnc8a84aj831' + ], +]; + +$ink_function = function (string $val): string { + return mb_substr($val, 0, 1) . str_repeat('*', mb_strlen($val) - 2) . mb_substr($val, mb_strlen($val) - 1, 1); +}; + +$redactor = (new ArrayRedactor($login, ['password', 'session_id'], $ink_function))->redact(); +// or... +$redactor = (new ArrayRedactor($login, ['password', 'session_id']))->ink($ink_function)->redact(); + +// $redactor will return: +[ + 'email' => 'john_doe@domain.com', + 'password' => 's*******3' + 'data' => [ + 'session_id' => 'z**********************1' + ], +]; + +``` + You can call the ``ArrayRedactor`` as a function and the magic ``__invoke()`` method will call the ``redact`` method for you. ```php From 15a61ceead4add1d9eeebc5a4010d6aef1891e97 Mon Sep 17 00:00:00 2001 From: Joe Pritchard Date: Thu, 18 Aug 2022 10:56:52 +0100 Subject: [PATCH 3/4] Fix the redactor function so it correctly calls $ink, modify the test and readme for the new behaviour --- README.md | 14 +++++++------- src/ArrayRedactor.php | 4 ++-- tests/ArrayRedactorTest.php | 11 ++++++----- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 33059f6..23ed13c 100644 --- a/README.md +++ b/README.md @@ -162,20 +162,20 @@ $login = [ ], ]; -$ink_function = function (string $val): string { - return mb_substr($val, 0, 1) . str_repeat('*', mb_strlen($val) - 2) . mb_substr($val, mb_strlen($val) - 1, 1); +$ink_function = function($val, $key) { + return $key === 'email' ? substr($val, stripos($val, '@')) : '[REDACTED]'; }; -$redactor = (new ArrayRedactor($login, ['password', 'session_id'], $ink_function))->redact(); +$redactor = (new ArrayRedactor($login, ['email', 'password', 'session_id'], $ink_function))->redact(); // or... -$redactor = (new ArrayRedactor($login, ['password', 'session_id']))->ink($ink_function)->redact(); +$redactor = (new ArrayRedactor($login, ['email', 'password', 'session_id']))->ink($ink_function)->redact(); // $redactor will return: [ - 'email' => 'john_doe@domain.com', - 'password' => 's*******3' + 'email' => '@domain.com', + 'password' => '[REDACTED]' 'data' => [ - 'session_id' => 'z**********************1' + 'session_id' => '[REDACTED]' ], ]; diff --git a/src/ArrayRedactor.php b/src/ArrayRedactor.php index e98c5dd..08d1a55 100644 --- a/src/ArrayRedactor.php +++ b/src/ArrayRedactor.php @@ -77,7 +77,7 @@ public function keys($keys = []) */ public function ink($ink = '[REDACTED]') { - $this->ink = is_callable($ink) ? $ink() : $ink; + $this->ink = $ink; return $this; } @@ -99,7 +99,7 @@ public function redact() // Recursively traverse the array and redact the specified keys array_walk_recursive($this->content, function (&$value, $key) { if (in_array($key, $this->keys, true)) { - $value = is_callable($ink) ? $ink($value) : $this->ink; + $value = is_callable($this->ink) ? call_user_func($this->ink, $value, $key) : $this->ink; } }); diff --git a/tests/ArrayRedactorTest.php b/tests/ArrayRedactorTest.php index e854b8e..f9e7494 100644 --- a/tests/ArrayRedactorTest.php +++ b/tests/ArrayRedactorTest.php @@ -6,7 +6,7 @@ class ArrayRedactorTest extends TestCase { - protected function setUp() + protected function setUp(): void { $this->content = [ 'email' => 'mtownsend5512@gmail.com', @@ -98,10 +98,11 @@ public function can_omit_constructor_arguments_in_favor_of_methods() /** @test */ public function can_accept_closure_in_ink() { - $array = $this->content; - $result = (new ArrayRedactor())->content($this->content)->keys(['email'])->ink(function() use ($array) { - return substr($array['email'], stripos($array['email'], '@')); - })->redact(); + $func = function(string $val, string $key): string { + return $key === 'email' ? substr($val, stripos($val, '@')) : $val; + }; + + $result = (new ArrayRedactor())->content($this->content)->keys(['email'])->ink($func)->redact(); $this->assertEquals(array_merge($this->content, [ 'email' => '@gmail.com' ]), $result); From 9eacf17b091aa8edc6fcd0a9d7d843e7f1a9cfb2 Mon Sep 17 00:00:00 2001 From: Joe Pritchard Date: Thu, 18 Aug 2022 10:57:52 +0100 Subject: [PATCH 4/4] Upgrade deps to php 7.4 or 8, and phpunit 9 --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index dd6fe96..c063b7a 100644 --- a/composer.json +++ b/composer.json @@ -28,10 +28,10 @@ ] }, "require": { - "php": ">=5.6" + "php": ">=7.4|>=8.0" }, "require-dev": { - "phpunit/phpunit": "^6.4" + "phpunit/phpunit": "^9" }, "autoload-dev": { "psr-4": {