Anonymizer.php 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. <?php
  2. /**
  3. * Refer to LICENSE.txt distributed with the Temando Shipping module for notice of license
  4. */
  5. namespace Temando\Shipping\Rest\Logger;
  6. use Temando\Shipping\Webservice\Logger\LogAnonymizerInterface;
  7. /**
  8. * Temando Log Message Anonymizer
  9. *
  10. * Search JSON formatted messages for certain properties and replace their values.
  11. *
  12. * @package Temando\Shipping\Rest
  13. * @author Christoph Aßmann <christoph.assmann@netresearch.de>
  14. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  15. * @link http://www.temando.com/
  16. */
  17. class Anonymizer implements LogAnonymizerInterface
  18. {
  19. /**
  20. * @var array | string[]
  21. */
  22. private $secrets;
  23. /**
  24. * Anonymizer constructor.
  25. * @param string[] $secrets
  26. */
  27. public function __construct($secrets = [])
  28. {
  29. $this->secrets = $secrets;
  30. }
  31. /**
  32. * Strip sensitive strings from message by given property names.
  33. *
  34. * @param string $message
  35. * @return string
  36. */
  37. public function anonymize($message)
  38. {
  39. $patternTemplate = <<<'REGEX'
  40. /(?(DEFINE)
  41. (?<object>(?>\{\s*(?>(?&pair)(?>\s*,\s*(?&pair))*)?\s*\}))
  42. (?<pair>(?>(?&STRING)\s*:\s*(?&value)))
  43. (?<array>(?>\[\s*(?>(?&value)(?>\s*,\s*(?&value))*)?\s*\]))
  44. (?<value>(?>true|false|null|(?&STRING)|(?&NUMBER)|(?&object)|(?&array)))
  45. (?<STRING>(?>"(?>\\\\(?>["\\\\\/bfnrt]|u[a-fA-F0-9]{4})|[^"\\\\\0-\x1F\x7F]+)*"))
  46. (?<NUMBER>(?>-?(?>0|[1-9][0-9]*)(?>\.[0-9]+)?(?>[eE][+-]?[0-9]+)?))
  47. )
  48. (?<key>\"%s\":\s*)(?<replace>(?&value))/xu
  49. REGEX;
  50. foreach ($this->secrets as $key => $newValue) {
  51. $pattern = sprintf($patternTemplate, $key);
  52. $message = preg_replace_callback(
  53. $pattern,
  54. function ($matches) use ($newValue) {
  55. return $matches['key'] . "\"$newValue\"";
  56. },
  57. $message
  58. );
  59. }
  60. return $message;
  61. }
  62. /**
  63. * Processor for Monolog log records.
  64. *
  65. * @param mixed[] $record
  66. * @return mixed[]
  67. */
  68. public function __invoke(array $record)
  69. {
  70. $record['message'] = $this->anonymize($record['message']);
  71. return $record;
  72. }
  73. }