mirror of https://github.com/MISP/MISP
chg: [internal] Faster adding tags to attributes
parent
9260da8d0c
commit
8bee6de811
|
@ -2622,7 +2622,7 @@ class AttributesController extends AppController
|
|||
);
|
||||
$RearrangeTool = new RequestRearrangeTool();
|
||||
$this->request->data = $RearrangeTool->rearrangeArray($this->request->data, $rearrangeRules);
|
||||
$local = empty($this->params['named']['local']) ? 0 : 1;
|
||||
$local = empty($this->request->params['named']['local']) ? 0 : 1;
|
||||
if (!$this->request->is('post')) {
|
||||
if ($id === false) {
|
||||
throw new NotFoundException(__('Invalid attribute'));
|
||||
|
@ -2660,10 +2660,7 @@ class AttributesController extends AppController
|
|||
if (empty($tagCollection)) {
|
||||
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag Collection.')), 'status'=>200, 'type' => 'json'));
|
||||
}
|
||||
$tag_id_list = array();
|
||||
foreach ($tagCollection[0]['TagCollectionTag'] as $tagCollectionTag) {
|
||||
$tag_id_list[] = $tagCollectionTag['tag_id'];
|
||||
}
|
||||
$tag_id_list = array_column($tagCollection[0]['TagCollectionTag'], 'tag_id');
|
||||
} else {
|
||||
// try to parse json array
|
||||
$tag_ids = json_decode($tag_id);
|
||||
|
@ -2677,9 +2674,7 @@ class AttributesController extends AppController
|
|||
if (empty($tagCollection)) {
|
||||
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag Collection.')), 'status'=>200, 'type' => 'json'));
|
||||
}
|
||||
foreach ($tagCollection[0]['TagCollectionTag'] as $tagCollectionTag) {
|
||||
$tag_id_list[] = $tagCollectionTag['tag_id'];
|
||||
}
|
||||
$tag_id_list = array_column($tagCollection[0]['TagCollectionTag'], 'tag_id');
|
||||
} else {
|
||||
$tag_id_list[] = $tag_id;
|
||||
}
|
||||
|
@ -2704,90 +2699,68 @@ class AttributesController extends AppController
|
|||
if (empty($tag_id_list)) {
|
||||
$tag_id_list = array($tag_id);
|
||||
}
|
||||
|
||||
$conditions = ['Tag.id' => $tag_id_list];
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
$conditions['Tag.org_id'] = array(0, $this->Auth->user('org_id'));
|
||||
$conditions['Tag.user_id'] = array(0, $this->Auth->user('id'));
|
||||
}
|
||||
$tags = $this->Attribute->AttributeTag->Tag->find('list', array(
|
||||
'conditions' => $conditions,
|
||||
'fields' => ['Tag.id', 'Tag.name'],
|
||||
));
|
||||
|
||||
$success = 0;
|
||||
$fails = 0;
|
||||
$this->Taxonomy = ClassRegistry::init('Taxonomy');
|
||||
foreach ($idList as $id) {
|
||||
$attributes = $this->Attribute->fetchAttributes(
|
||||
$this->Auth->user(),
|
||||
array(
|
||||
'conditions' => array('Attribute.id' => $id, 'Attribute.deleted' => 0),
|
||||
'flatten' => 1,
|
||||
'contain' => array('Event.orgc_id')
|
||||
)
|
||||
);
|
||||
if (empty($attributes)) {
|
||||
$attribute = $this->Attribute->fetchAttributeSimple($this->Auth->user(), [
|
||||
'conditions' => array('Attribute.id' => $id, 'Attribute.deleted' => 0),
|
||||
]);
|
||||
if (empty($attribute)) {
|
||||
throw new NotFoundException(__('Invalid attribute'));
|
||||
} else {
|
||||
$attribute = $attributes[0];
|
||||
}
|
||||
$eventId = $attribute['Attribute']['event_id'];
|
||||
$event = $this->Attribute->Event->find('first', array(
|
||||
'conditions' => array('Event.id' => $eventId),
|
||||
'recursive' => -1
|
||||
));
|
||||
if (!$this->__canModifyTag($event, $local)) {
|
||||
if (!$this->__canModifyTag($attribute, $local)) {
|
||||
$fails++;
|
||||
continue;
|
||||
}
|
||||
if (!$this->_isRest()) {
|
||||
$this->Attribute->Event->insertLock($this->Auth->user(), $eventId);
|
||||
$this->Attribute->Event->insertLock($this->Auth->user(), $attribute['Event']['id']);
|
||||
}
|
||||
$changeTimestamp = false;
|
||||
foreach ($tag_id_list as $tag_id) {
|
||||
$conditions = ['Tag.id' => $tag_id];
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
$conditions['Tag.org_id'] = array('0', $this->Auth->user('org_id'));
|
||||
$conditions['Tag.user_id'] = array('0', $this->Auth->user('id'));
|
||||
}
|
||||
$tag = $this->Attribute->AttributeTag->Tag->find('first', array(
|
||||
'conditions' => $conditions,
|
||||
'recursive' => -1,
|
||||
'fields' => array('Tag.name')
|
||||
));
|
||||
if (!$tag) {
|
||||
if (!isset($tags[$tag_id])) {
|
||||
// Tag not found or user don't have permission to add it.
|
||||
$fails++;
|
||||
continue;
|
||||
}
|
||||
$found = $this->Attribute->AttributeTag->find('first', array(
|
||||
'conditions' => array(
|
||||
'attribute_id' => $id,
|
||||
'tag_id' => $tag_id
|
||||
),
|
||||
'recursive' => -1,
|
||||
));
|
||||
$this->autoRender = false;
|
||||
if (!empty($found)) {
|
||||
$tagName = $tags[$tag_id];
|
||||
$found = $this->Attribute->AttributeTag->hasAny([
|
||||
'attribute_id' => $id,
|
||||
'tag_id' => $tag_id,
|
||||
]);
|
||||
if ($found) {
|
||||
// Tag is already assigned to given attribute.
|
||||
$fails++;
|
||||
continue;
|
||||
}
|
||||
$tagsOnAttribute = $this->Attribute->AttributeTag->find('all', array(
|
||||
$tagsOnAttribute = $this->Attribute->AttributeTag->find('column', array(
|
||||
'conditions' => array(
|
||||
'AttributeTag.attribute_id' => $id,
|
||||
'AttributeTag.local' => $local
|
||||
'AttributeTag.local' => $local,
|
||||
),
|
||||
'contain' => 'Tag',
|
||||
'fields' => array('Tag.name'),
|
||||
'recursive' => -1
|
||||
));
|
||||
$exclusiveTestPassed = $this->Taxonomy->checkIfNewTagIsAllowedByTaxonomy($tag['Tag']['name'], Hash::extract($tagsOnAttribute, '{n}.Tag.name'));
|
||||
$exclusiveTestPassed = $this->Taxonomy->checkIfNewTagIsAllowedByTaxonomy($tagName, $tagsOnAttribute);
|
||||
if (!$exclusiveTestPassed) {
|
||||
$fails++;
|
||||
continue;
|
||||
}
|
||||
$this->Attribute->AttributeTag->create();
|
||||
if ($this->Attribute->AttributeTag->save(array('attribute_id' => $id, 'tag_id' => $tag_id, 'event_id' => $eventId, 'local' => $local))) {
|
||||
if ($this->Attribute->AttributeTag->save(array('attribute_id' => $id, 'tag_id' => $tag_id, 'event_id' => $attribute['Event']['id'], 'local' => $local))) {
|
||||
if (!$local) {
|
||||
$event['Event']['published'] = 0;
|
||||
$date = new DateTime();
|
||||
$event['Event']['timestamp'] = $date->getTimestamp();
|
||||
$result = $this->Attribute->Event->save($event);
|
||||
$attribute['Attribute']['timestamp'] = $date->getTimestamp();
|
||||
if ($attribute['Attribute']['object_id'] != 0) {
|
||||
$this->Attribute->Object->updateTimestamp($attribute['Attribute']['object_id'], $date->getTimestamp());
|
||||
}
|
||||
$this->Attribute->save($attribute);
|
||||
$changeTimestamp = true;
|
||||
}
|
||||
$log = ClassRegistry::init('Log');
|
||||
$log->createLogEntry(
|
||||
|
@ -2799,7 +2772,7 @@ class AttributesController extends AppController
|
|||
'Attached%s tag (%s) "%s" to attribute (%s)',
|
||||
$local ? ' local' : '',
|
||||
$tag_id,
|
||||
$tag['Tag']['name'],
|
||||
$tagName,
|
||||
$id
|
||||
),
|
||||
sprintf(
|
||||
|
@ -2814,8 +2787,20 @@ class AttributesController extends AppController
|
|||
$fails++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($changeTimestamp) {
|
||||
$attribute['Event']['published'] = 0;
|
||||
$date = new DateTime();
|
||||
$attribute['Event']['timestamp'] = $date->getTimestamp();
|
||||
$result = $this->Attribute->Event->save($attribute['Event']);
|
||||
$attribute['Attribute']['timestamp'] = $date->getTimestamp();
|
||||
if ($attribute['Attribute']['object_id'] != 0) {
|
||||
$this->Attribute->Object->updateTimestamp($attribute['Attribute']['object_id'], $date->getTimestamp());
|
||||
}
|
||||
$this->Attribute->save($attribute['Attribute']);
|
||||
}
|
||||
}
|
||||
if ($fails == 0) {
|
||||
if ($fails === 0) {
|
||||
$message = __n('Tag added.', '%s tags added', $success, $success);
|
||||
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => $message, 'check_publish' => true)), 'status' => 200, 'type' => 'json'));
|
||||
} else {
|
||||
|
@ -2823,7 +2808,7 @@ class AttributesController extends AppController
|
|||
if ($success > 0) {
|
||||
$message .= __n(' However, %s tag was added.', ' However, %s tags were added.', $success, $success);
|
||||
}
|
||||
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $message)), 'status' => 200, 'type' => 'json'));
|
||||
return new CakeResponse(array('body' => json_encode(array('saved' => false, 'errors' => $message)), 'status' => 200, 'type' => 'json'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2669,6 +2669,30 @@ class Attribute extends AppModel
|
|||
return $attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $user
|
||||
* @param array $options
|
||||
* @return array
|
||||
*/
|
||||
public function fetchAttributeSimple(array $user, array $options = [])
|
||||
{
|
||||
$query = [
|
||||
'recursive' => -1,
|
||||
'conditions' => $this->buildConditions($user),
|
||||
'contain' => ['Event', 'Object'], // by default include Event and Object, because it is required for conditions
|
||||
];
|
||||
if (isset($options['conditions'])) {
|
||||
$query['conditions']['AND'][] = $options['conditions'];
|
||||
}
|
||||
if (isset($options['fields'])) {
|
||||
$query['fields'] = $options['fields'];
|
||||
}
|
||||
if (isset($options['contain'])) {
|
||||
$query['contain'] = $options['contain'];
|
||||
}
|
||||
return $this->find('first', $query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches attributes that $user can see.
|
||||
*
|
||||
|
|
|
@ -1155,14 +1155,19 @@ class MispObject extends AppModel
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param false|int $timestamp
|
||||
* @return array|bool|mixed|null
|
||||
* @throws Exception
|
||||
*/
|
||||
public function updateTimestamp($id, $timestamp = false)
|
||||
{
|
||||
$date = new DateTime();
|
||||
$object = $this->find('first', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('Object.id' => $id)
|
||||
));
|
||||
$object['Object']['timestamp'] = $timestamp == false ? $date->getTimestamp() : $timestamp;
|
||||
$object['Object']['timestamp'] = $timestamp === false ? time() : $timestamp;
|
||||
$object['Object']['skip_zmq'] = 1;
|
||||
$object['Object']['skip_kafka'] = 1;
|
||||
$result = $this->save($object);
|
||||
|
|
|
@ -649,7 +649,7 @@ class Taxonomy extends AppModel
|
|||
$prefixIsFree = true;
|
||||
foreach ($tagNameList as $tagName) {
|
||||
$tagShortened = $this->stripLastTagComponent($tagName);
|
||||
if ($newTagShortened == $tagShortened) {
|
||||
if ($newTagShortened === $tagShortened) {
|
||||
$prefixIsFree = false;
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue