From c50ff4b1bd85fba6f57eece63c29258e98d17d2c Mon Sep 17 00:00:00 2001 From: mokaddem Date: Mon, 5 Oct 2020 14:07:51 +0200 Subject: [PATCH] new: [eventReport:markdownEditor] Support to reference object attribute --- app/Model/EventReport.php | 9 +++- .../css/markdownEditor/event-report.css | 8 ++++ app/webroot/js/markdownEditor/event-report.js | 44 +++++++++++++++---- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/app/Model/EventReport.php b/app/Model/EventReport.php index 9223ec337..b5ca554fc 100644 --- a/app/Model/EventReport.php +++ b/app/Model/EventReport.php @@ -421,6 +421,7 @@ class EventReport extends AppModel throw new NotFoundException(__('Invalid Event')); } $event = $event[0]; + $attributes = Hash::combine($event, 'Attribute.{n}.uuid', 'Attribute.{n}'); $this->AttributeTag = ClassRegistry::init('AttributeTag'); $allTagNames = Hash::combine($event['EventTag'], '{n}.Tag.name', '{n}.Tag'); $attributeTags = Hash::combine($this->AttributeTag->getAttributesTags($event['Attribute'], true), '{n}.name', '{n}'); @@ -430,6 +431,12 @@ class EventReport extends AppModel $recordedConditions = []; foreach ($event['Object'] as $k => $object) { $objects[$object['uuid']] = $object; + $objectAttributes = []; + foreach ($object['Attribute'] as $i => $objectAttribute) { + $objectAttributes[$objectAttribute['uuid']] = $object['Attribute'][$i]; + $objectAttributes[$objectAttribute['uuid']]['object_uuid'] = $object['uuid']; + } + $attributes = array_merge($attributes, $objectAttributes); $objectAttributeTags = Hash::combine($this->AttributeTag->getAttributesTags($object['Attribute'], true), '{n}.name', '{n}'); $allTagNames = array_merge($allTagNames, $objectAttributeTags); $uniqueCondition = sprintf('%s.%s', $object['template_uuid'], $object['template_version']); @@ -460,7 +467,7 @@ class EventReport extends AppModel $allowedGalaxies = $this->Galaxy->getAllowedMatrixGalaxies(); $allowedGalaxies = Hash::combine($allowedGalaxies, '{n}.Galaxy.uuid', '{n}.Galaxy'); $proxyMISPElements = [ - 'attribute' => Hash::combine($event, 'Attribute.{n}.uuid', 'Attribute.{n}'), + 'attribute' => $attributes, 'object' => $objects, 'objectTemplates' => $objectTemplates, 'galaxymatrix' => $allowedGalaxies, diff --git a/app/webroot/css/markdownEditor/event-report.css b/app/webroot/css/markdownEditor/event-report.css index 9b520581f..dab8c7a87 100644 --- a/app/webroot/css/markdownEditor/event-report.css +++ b/app/webroot/css/markdownEditor/event-report.css @@ -58,6 +58,14 @@ span.misp-element-wrapper.object { color: #ffffff !important; } +.misp-element-wrapper.object .obj-type .object-attribute-type { + margin-left: 0; + background-color: #f5f5f5; + color: black; + padding: 1px 3px; + border-radius: 7px; +} + .misp-element-wrapper.object .obj-type > span { margin: 2px 3px; } diff --git a/app/webroot/js/markdownEditor/event-report.js b/app/webroot/js/markdownEditor/event-report.js index c3ceba4a3..6039453e7 100644 --- a/app/webroot/js/markdownEditor/event-report.js +++ b/app/webroot/js/markdownEditor/event-report.js @@ -27,6 +27,7 @@ var dotTemplateAttributePicture = doT.template("
"); var dotTemplateTag = doT.template("{{=it.elementid}}"); var dotTemplateObject = doT.template("{{=it.type}}{{=it.value}}"); +var dotTemplateObjectAttribute = doT.template("{{=it.objectname}}{{=it.type}}{{=it.value}}"); var dotTemplateInvalid = doT.template("{{=it.scope}} ({{=it.id}})"); var dotCloseButtonTemplate = doT.template(''); @@ -422,13 +423,23 @@ function renderMISPElement(scope, elementID) { if (scope == 'attribute') { var attribute = proxyMISPElements[scope][elementID] if (attribute !== undefined) { - templateVariables = sanitizeObject({ + var templateToRender = dotTemplateAttribute + var attributeData = { scope: 'attribute', elementid: elementID, type: attribute.type, value: attribute.value - }) - return dotTemplateAttribute(templateVariables); + } + if (isValidObjectAttribute(attribute)) { + var mispObject = getObjectFromAttribute(attribute) + if (mispObject !== undefined) { + attributeData.type = attribute.object_relation + attributeData.objectname = mispObject.name + templateToRender = dotTemplateObjectAttribute + } + } + templateVariables = sanitizeObject(attributeData) + return templateToRender(templateVariables); } } else if (scope == 'object') { var mispObject = proxyMISPElements[scope][elementID] @@ -736,9 +747,10 @@ function closeThePopover(closeButton) { $MISPElement.popover('hide'); } -function constructAttributeRow(attribute) +function constructAttributeRow(attribute, fromObject) { - var attributeFieldsToRender = ['id', 'category', 'type', 'value', 'comment'] + fromObject = fromObject !== undefined ? fromObject : false + var attributeFieldsToRender = ['id', 'category', 'type'].concat(fromObject ? ['object_relation'] : [], ['value', 'comment']) var $tr = $('') attributeFieldsToRender.forEach(function(field) { $tr.append( @@ -776,9 +788,10 @@ function constructAttributeRow(attribute) return $tr } -function constructAttributeHeader(attribute, showAll) { +function constructAttributeHeader(attribute, showAll, fromObject) { showAll = showAll !== undefined ? showAll : false - var attributeFieldsToRender = ['id', 'category', 'type', 'value', 'comment'] + fromObject = fromObject !== undefined ? fromObject : false + var attributeFieldsToRender = ['id', 'category', 'type'].concat(fromObject ? ['object_relation'] : [], ['value', 'comment']) var $tr = $('') attributeFieldsToRender.forEach(function(field) { $tr.append($('').text(field)) @@ -808,10 +821,10 @@ function constructObject(object) { var $attributeTable = $('').addClass('table table-striped table-condensed') .css({'margin-bottom': '3px'}) - var $thead = constructAttributeHeader({}, true) + var $thead = constructAttributeHeader({}, true, true) var $tbody = $('') object.Attribute.forEach(function(attribute) { - $tbody.append(constructAttributeRow(attribute)) + $tbody.append(constructAttributeRow(attribute, true)) }) $attributeTable.append($thead, $tbody) $object.append($top, $attributeTable) @@ -973,6 +986,10 @@ function constructGalaxyInfo(tagData) { function getContentFromMISPElementDOM() { var data = getElementFromDom(this) if (data !== false) { + if (data.scope == 'attribute' && isValidObjectAttribute(data.element)) { + data.scope = 'object' + data.element = getObjectFromAttribute(data.element) + } if (data.scope == 'attribute') { var $thead = constructAttributeHeader(data.element) var $row = constructAttributeRow(data.element) @@ -994,6 +1011,15 @@ function getContentFromMISPElementDOM() { return invalidMessage } +function isValidObjectAttribute(attribute) { + var mispObject = getObjectFromAttribute(attribute) + return attribute.object_relation !== null && mispObject !== undefined +} + +function getObjectFromAttribute(attribute) { + return proxyMISPElements['object'][attribute.object_uuid] +} + function parseTag(str, pos, max) { var level = 0 var lines = 0