Skip to content

Commit df0103d

Browse files
authored
Merge pull request #6 from ntidev/adding-unaudited-fields-feature
Adding functions to remove unaudited fields
2 parents af2e047 + 680791c commit df0103d

File tree

2 files changed

+133
-6
lines changed

2 files changed

+133
-6
lines changed

src/DataDog/AuditBundle/EventListener/ControllerListener.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,32 @@
99
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
1010
use Symfony\Component\DependencyInjection\ContainerInterface;
1111
use DataDog\AuditBundle\Annotations\NTIAudit;
12+
use Exception;
1213

1314
class ControllerListener
1415
{
1516
/** @var ContainerInterface */
1617
protected $container;
18+
protected $unauditedRequestFieldsPath = [];
1719

1820
public function __construct(ContainerInterface $container)
1921
{
2022
$this->container = $container;
2123
}
2224

25+
public function addUnauditedRequestFields(array $unauditedRequestFields)
26+
{
27+
$this->unauditedRequestFieldsPath = $unauditedRequestFields;
28+
}
29+
2330
public function onKernelController(FilterControllerEvent $event){
2431

2532
if(!$this->container->getParameter('nti_audit.audit_request.enabled')){
2633
return;
2734
}
2835

36+
$this->addUnauditedRequestFields($this->container->getParameter('nti_audit.audit_request.unaudited_request_fields'));
37+
2938
if (!is_array($controllers = $event->getController())) {
3039
return;
3140
}
@@ -89,6 +98,10 @@ public function onKernelController(FilterControllerEvent $event){
8998
$queryData = $request->getQueryString();
9099
$data = $request->getContent();
91100

101+
// Filter sensitive data
102+
foreach ($this->unauditedRequestFieldsPath as $unauditedPath)
103+
$data = $this->removeJsonField($unauditedPath, $data);
104+
92105
// Set Object
93106
$audit = new AuditRequest();
94107
$audit->setMethod($method);
@@ -110,4 +123,49 @@ public function onKernelController(FilterControllerEvent $event){
110123

111124
}
112125
}
126+
127+
public function removeJsonField($path, $data) {
128+
129+
$pathKeys = explode(".", $path);
130+
$unauditedField = $pathKeys[count($pathKeys) - 1];
131+
132+
// Remove '$' from keys
133+
array_shift($pathKeys);
134+
135+
if(!is_string($data) || !$this->is_json($data) || !preg_match('/\b'.$unauditedField.'\b/', $data))
136+
return $data;
137+
138+
$data = json_decode($data, true);
139+
$data = $this->searchAndRemoveField($pathKeys, $data);
140+
$data = json_encode($data);
141+
return $data;
142+
}
143+
144+
public function searchAndRemoveField($pathKeys, $data){
145+
$field = &$data;
146+
$pathKeysLeft = $pathKeys;
147+
foreach ($pathKeys as $key) {
148+
try{
149+
if(is_array($field[$key]) && array_values($field[$key]) === $field[$key]){
150+
array_shift($pathKeysLeft);
151+
foreach ($field[$key] as $arrKey => $arr) {
152+
$field[$key][$arrKey] = $this->searchAndRemoveField($pathKeysLeft, $arr);
153+
}
154+
return $data;
155+
} else {
156+
array_shift($pathKeysLeft);
157+
}
158+
$field = &$field[$key];
159+
} catch (Exception $ex){
160+
return $data;
161+
}
162+
}
163+
$field = "*";
164+
return $data;
165+
}
166+
167+
public function is_json($string) {
168+
json_decode($string);
169+
return (json_last_error() == JSON_ERROR_NONE) ? true : false;
170+
}
113171
}

src/DataDog/AuditBundle/EventSubscriber/AuditSubscriber.php

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class AuditSubscriber implements EventSubscriber
3434

3535
protected $auditedEntities = [];
3636
protected $unauditedEntities = [];
37+
protected $unauditedFields = [];
3738

3839
protected $inserted = []; // [$source, $changeset]
3940
protected $updated = []; // [$source, $changeset]
@@ -81,6 +82,15 @@ public function addUnauditedEntities(array $unauditedEntities)
8182
}
8283
}
8384

85+
public function addUnauditedFields(array $unauditedFields)
86+
{
87+
foreach ($unauditedFields as $unauditedField) {
88+
foreach ($unauditedField as $key => $unauditedFieldChild) {
89+
$this->unauditedFields[$key] = $unauditedFieldChild;
90+
}
91+
}
92+
}
93+
8494
public function getUnauditedEntities()
8595
{
8696
return array_keys($this->unauditedEntities);
@@ -365,13 +375,57 @@ protected function id(EntityManager $em, $entity)
365375
return $pk;
366376
}
367377

378+
379+
function is_json($string) {
380+
json_decode($string);
381+
return (json_last_error() == JSON_ERROR_NONE) ? true : false;
382+
}
383+
384+
protected function filterRecursive($unauditedFields, $array){
385+
foreach($array as $key => $value){
386+
if(is_string($key) && in_array($key, $unauditedFields)){
387+
$array[$key] = "*";
388+
}
389+
if(is_array($value)){
390+
$array[$key] = $this->filterRecursive($unauditedFields, $value);
391+
}
392+
}
393+
return $array;
394+
}
395+
396+
protected function removeUnauditedFields($fieldName, $unauditedFields, $data){
397+
if(is_string($fieldName) && in_array($fieldName, $unauditedFields)){
398+
return "*";
399+
}
400+
foreach($unauditedFields as $unauditedField){
401+
if(is_string($data) && preg_match('/\b'.$unauditedField.'\b/', $data)){
402+
if ($this->is_json($data)) {
403+
$decoded = json_decode($data, true);
404+
$decoded = $this->filterRecursive($unauditedFields, $decoded);
405+
$data = json_encode($decoded);
406+
return $data;
407+
} else {
408+
return "*";
409+
}
410+
}
411+
}
412+
return $data;
413+
}
414+
368415
protected function diff(EntityManager $em, $entity, array $ch)
369416
{
370417
$uow = $em->getUnitOfWork();
371418
$meta = $em->getClassMetadata(get_class($entity));
372419
$diff = [];
373420
foreach ($ch as $fieldName => list($old, $new)) {
374421
if ($meta->hasField($fieldName) && !array_key_exists($fieldName, $meta->embeddedClasses)) {
422+
423+
// Filter sensitive data
424+
if(array_key_exists($meta->getName(), $this->unauditedFields)) {
425+
$old = $this->removeUnauditedFields($fieldName, $this->unauditedFields[$meta->getName()], $old);
426+
$new = $this->removeUnauditedFields($fieldName, $this->unauditedFields[$meta->getName()], $new);
427+
}
428+
375429
$mapping = $meta->fieldMappings[$fieldName];
376430
$diff[$fieldName] = [
377431
'old' => $this->value($em, Type::getType($mapping['type']), $old),
@@ -382,11 +436,26 @@ protected function diff(EntityManager $em, $entity, array $ch)
382436
$mapping = $meta->associationMappings[$fieldName];
383437
$colName = $meta->getSingleAssociationJoinColumnName($fieldName);
384438
$assocMeta = $em->getClassMetadata($mapping['targetEntity']);
385-
$diff[$fieldName] = [
386-
'old' => $this->assoc($em, $old, true),
387-
'new' => $this->assoc($em, $new, true),
388-
'col' => $colName,
389-
];
439+
440+
// Filter sensitive data
441+
if(array_key_exists($meta->getName(), $this->unauditedFields)) {
442+
$old = $this->removeUnauditedFields($fieldName, $this->unauditedFields[$meta->getName()], $old);
443+
$new = $this->removeUnauditedFields($fieldName, $this->unauditedFields[$meta->getName()], $new);
444+
}
445+
446+
if($old == "*" && $new == "*"){
447+
$diff[$fieldName] = [
448+
'old' => $old,
449+
'new' => $new,
450+
'col' => $colName,
451+
];
452+
} else {
453+
$diff[$fieldName] = [
454+
'old' => $this->assoc($em, $old, true),
455+
'new' => $this->assoc($em, $new, true),
456+
'col' => $colName,
457+
];
458+
}
390459
}
391460
}
392461
return $diff;
@@ -499,4 +568,4 @@ public function getUser()
499568

500569
return $user;
501570
}
502-
}
571+
}

0 commit comments

Comments
 (0)