Skip to content

Commit

Permalink
Merge pull request #86 from QoboLtd/sensitive-fields
Browse files Browse the repository at this point in the history
Add support for sensitive fields
  • Loading branch information
dereuromark authored Aug 29, 2024
2 parents 65f9219 + a8d9a6d commit 59ae3c1
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 0 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,18 @@ public function initialize(array $config = []): void
}
```

If you have fields that contain sensitive information but still want to track their changes you can use the `sensitive` configuration:

```php
public function initialize(array $config = []): void
{
...
$this->addBehavior('AuditStash.AuditLog', [
'sensitive' => ['body']
]);
}
```

### Storing The Logged In User

It is often useful to store the identifier of the user that is triggering the changes in a certain table. For this purpose, `AuditStash`
Expand Down
25 changes: 25 additions & 0 deletions src/Model/Behavior/AuditLogBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class AuditLogBehavior extends Behavior
'type' => null,
'blacklist' => ['created', 'modified'],
'whitelist' => [],
'sensitive' => [],
];

/**
Expand Down Expand Up @@ -88,6 +89,26 @@ public function injectTracking(
}
}

/**
* Redacts sensitive fields from the array
*
* @param array<string, mixed> $fields Field
* @return void
*/
private function redactArray(array &$fields): void
{
$sensitive = $this->_config['sensitive'] ?? [];
if ($sensitive === []) {
return;
}

foreach ($fields as $field => &$value) {
if (in_array($field, $sensitive, true)) {
$value = '****';
}
}
}

/**
* Calculates the changes done to the entity and stores the audit log event object into the
* log queue inside the `_auditQueue` key in $options.
Expand Down Expand Up @@ -123,6 +144,7 @@ public function afterSave(
}

$original = $entity->extractOriginal(array_keys($changed));

$properties = $this->getAssociationProperties(array_keys($options['associated']));
foreach ($properties as $property) {
unset($changed[$property], $original[$property]);
Expand All @@ -132,6 +154,9 @@ public function afterSave(
return;
}

$this->redactArray($changed);
$this->redactArray($original);

$primary = $entity->extract((array)$this->_table->getPrimaryKey());
$auditEvent = $entity->isNew() ? AuditCreateEvent::class : AuditUpdateEvent::class;

Expand Down
33 changes: 33 additions & 0 deletions tests/TestCase/Model/Behavior/AuditLogBehaviorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,37 @@ public static function dataProviderForSaveType(): array
[null],
];
}

public function testSensitiveFields(): void
{
$behavior = new AuditLogBehavior($this->table, [
'whitelist' => ['id', 'title', 'body', 'author_id'],
'sensitive' => ['body'],
]);

$data = [
'id' => 13,
'title' => 'The Title',
'body' => 'The Body',
'author_id' => 1,
];
$entity = new Entity($data, ['markNew' => false, 'markClean' => true]);
$entity->body = 'The changed body';

$event = new Event('Model.afterSave');
$queue = new SplObjectStorage();
$behavior->afterSave($event, $entity, new ArrayObject([
'_auditQueue' => $queue,
'_auditTransaction' => '1',
'associated' => [],
]));

$event = $queue[$entity];

$this->assertInstanceOf(AuditUpdateEvent::class, $event);

$changed = $event->getChanged();
$this->assertArrayHasKey('body', $changed);
$this->assertEquals('****', $changed['body']);
}
}

0 comments on commit 59ae3c1

Please sign in to comment.