diff --git a/CHANGELOG.md b/CHANGELOG.md index 838f8bdf3a43f71a6ba624bc524f7f5ace3eafd1..a295bc383ae017f0295842a618feca2ccdf99be2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [1.12.0] - 2023-07-10 +### Added +- sensitive data replacer + ## [1.11.0] - 2023-07-10 ### Updated - monolog to 2.9.1 diff --git a/composer.json b/composer.json index f94603a76874276f3f2aa725ba298f33494673e6..cdfb1a7fa2f3d526def26c95ce987b1bd478c655 100644 --- a/composer.json +++ b/composer.json @@ -8,22 +8,23 @@ ], "config": { "platform": { - "php": "7.2" + "php": "7.4" }, "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true } }, "require": { - "php": ">=7.2|^8", + "php": ">=7.4|^8", "psr/log": "^1", "monolog/monolog": "^2.9.1", "wpdesk/wp-notice": "^3.0" }, "require-dev": { - "phpunit/phpunit": "^5", + "phpunit/phpunit": "^5|^6|^7|^8|^9", "squizlabs/php_codesniffer": "^3.0.2", - "wpdesk/wp-code-sniffer": "^1.2.3" + "wpdesk/wp-code-sniffer": "^1.2.3", + "10up/wp_mock": "^1.0" }, "autoload": { "psr-4": {"WPDesk\\Logger\\": "src/"} diff --git a/src/Processor/SensitiveDataProcessor.php b/src/Processor/SensitiveDataProcessor.php new file mode 100644 index 0000000000000000000000000000000000000000..f0b6b82c0d4d1f1760e5909baa9bbdec889281dc --- /dev/null +++ b/src/Processor/SensitiveDataProcessor.php @@ -0,0 +1,51 @@ +<?php + +namespace WPDesk\Logger\Processor; + +use Monolog\Processor\ProcessorInterface; + +/** + * Can replace data in log. + * Ie. sensitive data. + * + * @package WPDesk\Logger\Processor + */ +class SensitiveDataProcessor implements ProcessorInterface { + + /** + * Replace array. + * + * @var array + */ + private array $replace; + + public function __construct( array $replace ) { + $this->replace = $replace; + } + + public function __invoke( array $record ): array { + return $this->replace_array( $record ); + } + + private function replace_array( array $value ): array { + foreach ( $value as $key => $item ) { + if ( is_array( $item ) ) { + $value[ $key ] = $this->replace_array( $item ); + } + if ( is_string( $item ) ) { + $value[ $key ] = $this->replace( $item ); + } + } + + return $value; + } + + private function replace( string $value ): string { + foreach ( $this->replace as $search => $replace ) { + $value = str_replace( $search, $replace, $value ); + } + + return $value; + } + +} diff --git a/tests/unit/Processor/TestSensitiveDataProcessor.php b/tests/unit/Processor/TestSensitiveDataProcessor.php new file mode 100644 index 0000000000000000000000000000000000000000..8bc6444fe1571bd63821023a71acaa972049ea2f --- /dev/null +++ b/tests/unit/Processor/TestSensitiveDataProcessor.php @@ -0,0 +1,54 @@ +<?php + +namespace unit\Processor; + +use WP_Mock; +use WP_Mock\Tools\TestCase; +use WPDesk\Logger\Processor\SensitiveDataProcessor; + +class TestSensitiveDataProcessor extends TestCase +{ + + public function setUp(): void { + WP_Mock::setUp(); + } + + public function tearDown(): void { + WP_Mock::tearDown(); + } + + public function testShouldReplaceWhenMatched() { + $processor = new SensitiveDataProcessor( array( 'password' => '***' ) ); + $record = array( + 'password' => 'password', + 'array' => array( + 'password' => 'password', + ), + ); + $expected = array( + 'password' => '***', + 'array' => array( + 'password' => '***', + ), + ); + $this->assertEquals( $expected, $processor->__invoke( $record ) ); + } + + public function testShouldNotReplaceWhenNotMatched() { + $processor = new SensitiveDataProcessor( array( 'password' => '***' ) ); + $record = array( + 'text' => 'text', + 'array' => array( + 'text' => 'text', + ), + ); + $expected = array( + 'text' => 'text', + 'array' => array( + 'text' => 'text', + ), + ); + $this->assertEquals( $expected, $processor->__invoke( $record ) ); + } + +} diff --git a/tests/unit/bootstrap.php b/tests/unit/bootstrap.php index 575b33bd7df4416b1684dcd7b22e6b5beb4760c6..cb597776ea4e7f538a8aaaeed8700498ffcb8418 100644 --- a/tests/unit/bootstrap.php +++ b/tests/unit/bootstrap.php @@ -4,3 +4,20 @@ */ require_once __DIR__ . '/../../vendor/autoload.php'; + +error_reporting( E_ALL & ~E_DEPRECATED ); + +if ( getenv( 'PLUGIN_PATH' ) !== false ) { + define( 'PLUGIN_PATH', getenv( 'PLUGIN_PATH' ) ); +} else { + define( 'PLUGIN_PATH', __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR ); +} + +if ( getenv( 'ABSPATH' ) !== false ) { + define( 'ABSPATH', getenv( 'ABSPATH' ) ); +} else { + define( 'ABSPATH', PLUGIN_PATH . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR ); +} + +WP_Mock::setUsePatchwork( true ); +WP_Mock::bootstrap();