mirror of https://github.com/MISP/MISP
new: [objects] pass the /breakOnDuplicate:1 flag to the /objects/add endpoint to deduplicate
- returns an error if the object already exists - objects of the same template_uuid are compared - non deleted attributes only - type + category + value + object_relation tuple is comparedpull/5615/head
parent
934c828192
commit
4ea3612dfc
|
@ -238,6 +238,7 @@ class ObjectsController extends AppController
|
|||
$this->request->data['Attribute'] = $this->request->data['Object']['Attribute'];
|
||||
unset($this->request->data['Object']['Attribute']);
|
||||
}
|
||||
$breakOnDuplicate = !empty($this->request->data['Object']['breakOnDuplicate']) || !empty($this->params['named']['breakOnDuplicate']);
|
||||
$object = $this->MispObject->attributeCleanup($this->request->data);
|
||||
// we pre-validate the attributes before we create an object at this point
|
||||
// This allows us to stop the process and return an error (API) or return
|
||||
|
@ -283,7 +284,7 @@ class ObjectsController extends AppController
|
|||
}
|
||||
if (empty($error)) {
|
||||
unset($object['Object']['id']);
|
||||
$result = $this->MispObject->saveObject($object, $eventId, $template, $this->Auth->user(), $errorBehaviour = 'halt');
|
||||
$result = $this->MispObject->saveObject($object, $eventId, $template, $this->Auth->user(), 'halt', $breakOnDuplicate);
|
||||
if (is_numeric($result)) {
|
||||
$this->MispObject->Event->unpublishEvent($eventId);
|
||||
} else {
|
||||
|
|
|
@ -203,8 +203,49 @@ class MispObject extends AppModel
|
|||
}
|
||||
}
|
||||
|
||||
public function saveObject($object, $eventId, $template = false, $user, $errorBehaviour = 'drop')
|
||||
public function checkForDuplicateObjects($object, $eventId)
|
||||
{
|
||||
$newObjectAttributes = array();
|
||||
$existingObjectAttributes = array();
|
||||
foreach ($object['Attribute'] as $attribute) {
|
||||
$newObjectAttributes[] = hash('sha256', $attribute['object_relation'] . $attribute['category'] . $attribute['type'] . $attribute['value']);
|
||||
}
|
||||
$newObjectAttributeCount = count($newObjectAttributes);
|
||||
$existingObjects = $this->find('all', array(
|
||||
'recursive' => -1,
|
||||
'contain' => array(
|
||||
'Attribute' => array(
|
||||
'fields' => array('value', 'type', 'category', 'object_relation'),
|
||||
'conditions' => array('Attribute.deleted' => 0)
|
||||
)
|
||||
),
|
||||
'fields' => array('template_uuid'),
|
||||
'conditions' => array('template_uuid' => $object['Object']['template_uuid'], 'Object.deleted' => 0)
|
||||
));
|
||||
$oldObjects = array();
|
||||
foreach ($existingObjects as $k => $existingObject) {
|
||||
if (!empty($existingObject['Attribute']) && $newObjectAttributeCount == count($existingObject['Attribute'])) {
|
||||
foreach ($existingObject['Attribute'] as $existingAttribute) {
|
||||
$oldObjects[$k][] = hash('sha256',
|
||||
$attribute['object_relation'] . $existingAttribute['category'] . $existingAttribute['type'] . $existingAttribute['value']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($oldObjects as $k => $object) {
|
||||
if (empty(array_diff($object, $newObjectAttributes))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function saveObject($object, $eventId, $template = false, $user, $errorBehaviour = 'drop', $breakOnDuplicate = false)
|
||||
{
|
||||
if ($breakOnDuplicate) {
|
||||
$duplicate = $this->checkForDuplicateObjects($object, $eventId);
|
||||
return array('value' => array('Duplicate object found. Since breakOnDuplicate is set the object will not be added.'));
|
||||
}
|
||||
$this->create();
|
||||
$templateFields = array(
|
||||
'name' => 'name',
|
||||
|
|
Loading…
Reference in New Issue