Merge pull request #8577 from JakubOnderka/correlation-fixes

Correlation fixes
pull/8596/head
Jakub Onderka 2022-09-20 10:47:58 +02:00 committed by GitHub
commit c1e91e91ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 249 additions and 249 deletions

View File

@ -1704,9 +1704,6 @@ class AttributesController extends AppController
$clusters = [];
}
// Fetch correlations in one query
$correlations = $this->Attribute->Event->getRelatedAttributes($user, $attributeIds, false, 'attribute');
// `attachFeedCorrelations` method expects different attribute format, so we need to transform that, then process
// and then take information back to original attribute structure.
$fakeEventArray = [];

View File

@ -83,33 +83,38 @@ class CorrelationsController extends AppController
'page' => 1,
'order' => 'occurrence desc'
];
foreach (array_keys($query) as $custom_param) {
if (isset($this->params['named'][$custom_param])) {
$query[$custom_param] = $this->params['named'][$custom_param];
}
}
if (isset($this->params['named']['scope'])) {
$limit = $this->Correlation->OverCorrelatingValue->getLimit();
if ($this->params['named']['scope'] === 'over_correlating') {
$query['conditions'][] = ['occurrence >=' => $limit];
} else if ($this->params['named']['scope'] === 'not_over_correlating') {
$query['conditions'][] = ['occurrence <' => $limit];
foreach ($query as $customParam => $foo) {
if (isset($this->request->params['named'][$customParam])) {
$query[$customParam] = $this->request->params['named'][$customParam];
}
}
if (isset($this->request->params['named']['scope'])) {
$limit = $this->Correlation->OverCorrelatingValue->getLimit();
if ($this->request->params['named']['scope'] === 'over_correlating') {
$scope = 'over_correlating';
$query['conditions'][] = ['occurrence >=' => $limit];
} else if ($this->request->params['named']['scope'] === 'not_over_correlating') {
$query['conditions'][] = ['occurrence <' => $limit];
$scope = 'not_over_correlating';
}
} else {
$scope = 'all';
}
$data = $this->Correlation->OverCorrelatingValue->getOverCorrelations($query);
$data = $this->Correlation->attachExclusionsToOverCorrelations($data);
if ($this->_isRest()) {
return $this->RestResponse->viewData($data, 'json');
} else {
$this->__setPagingParams($query['page'], $query['limit'], count($data), 'named');
$this->set('data', $data);
$this->set('title_for_layout', __('Index of over correlating values'));
$this->set('menuData', [
'menuList' => 'correlationExclusions',
'menuItem' => 'over'
]);
}
$this->__setPagingParams($query['page'], $query['limit'], count($data), 'named');
$this->set('data', $data);
$this->set('scope', $scope);
$this->set('title_for_layout', __('Index of over correlating values'));
$this->set('menuData', [
'menuList' => 'correlationExclusions',
'menuItem' => 'over'
]);
}
public function switchEngine(string $engine)
@ -205,17 +210,15 @@ class CorrelationsController extends AppController
{
$this->loadModel('OverCorrelatingValue');
$this->OverCorrelatingValue->generateOccurrencesRouter();
$message = __('Job queued.');
if (Configure::read('MISP.background_jobs')) {
$message = __('Job queued.');
} else {
$message = __('Over-correlations counted successfully.');
}
if (!$this->_isRest()) {
$this->Flash->info($message);
$this->redirect(['controller' => 'correlations', 'action' => 'overCorrelations']);
} else {
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('Correlations', 'generateOccurrences', false, $this->response->type(), $message);
}
$this->Flash->info($message);
$this->redirect(['controller' => 'correlations', 'action' => 'overCorrelations']);
}
}

View File

@ -204,7 +204,7 @@ class DefaultCorrelationBehavior extends ModelBehavior
/**
* Fetch correlations for given event.
* @param array $user
* @param int $eventId
* @param int|array $eventId
* @param array $sgids
* @param bool $primary
* @return array
@ -245,7 +245,6 @@ class DefaultCorrelationBehavior extends ModelBehavior
'contain' => [
'CorrelationValue' => [
'fields' => [
'CorrelationValue.id',
'CorrelationValue.value'
]
]
@ -264,7 +263,7 @@ class DefaultCorrelationBehavior extends ModelBehavior
/**
* @param Correlation $Model
* @param array $user
* @param int $id Event ID
* @param int|array $id Event ID
* @param array $sgids
* @return array
*/
@ -337,7 +336,6 @@ class DefaultCorrelationBehavior extends ModelBehavior
[
'1_attribute_id',
'1_object_id',
'1_event_id',
'1_distribution',
'1_object_distribution',
'1_event_distribution',
@ -345,12 +343,10 @@ class DefaultCorrelationBehavior extends ModelBehavior
'1_object_sharing_group_id',
'1_event_sharing_group_id',
'1_org_id',
'value_id'
],
[
'attribute_id',
'object_id',
'event_id',
'distribution',
'object_distribution',
'event_distribution',
@ -358,11 +354,10 @@ class DefaultCorrelationBehavior extends ModelBehavior
'object_sharing_group_id',
'event_sharing_group_id',
'org_id',
'value_id'
]
];
$prefixes = ['1_', ''];
$correlated_attribute_ids = [];
$correlatedAttributeIds = [];
foreach ($conditions as $k => $condition) {
$temp_correlations = $Model->find('all', [
'recursive' => -1,
@ -376,10 +371,15 @@ class DefaultCorrelationBehavior extends ModelBehavior
continue;
}
}
$correlated_attribute_ids[] = $temp_correlation['Correlation'][$prefixes[$k] . 'attribute_id'];
$correlatedAttributeIds[] = $temp_correlation['Correlation'][$prefixes[$k] . 'attribute_id'];
}
}
}
if (empty($correlatedAttributeIds)) {
return [];
}
$contain = [];
if (!empty($includeEventData)) {
$contain['Event'] = [
@ -402,7 +402,7 @@ class DefaultCorrelationBehavior extends ModelBehavior
$relatedAttributes = $Model->Attribute->find('all', [
'recursive' => -1,
'conditions' => [
'Attribute.id' => $correlated_attribute_ids
'Attribute.id' => $correlatedAttributeIds
],
'fields' => $fields,
'contain' => $contain

View File

@ -8,7 +8,7 @@ class NoAclCorrelationBehavior extends ModelBehavior
{
const TABLE_NAME = 'no_acl_correlations';
private $__config = [
const CONFIG = [
'AttributeFetcher' => [
'fields' => [
'Attribute.event_id',
@ -132,26 +132,37 @@ class NoAclCorrelationBehavior extends ModelBehavior
}
}
/**
* @param Model $Model
* @param string|null $filter
* @return false|mixed
*/
public function getContainRules(Model $Model, $filter = null)
{
if (empty($filter)) {
return $this->__config['AttributeFetcher']['contain'];
return self::CONFIG['AttributeFetcher']['contain'];
} else {
return empty($this->__config['AttributeFetcher']['contain'][$filter]) ? false : $this->__config['AttributeFetcher']['contain'][$filter];
return self::CONFIG['AttributeFetcher']['contain'][$filter] ?? false;
}
}
public function getFieldRules(Model $Model)
{
return $this->__config['AttributeFetcher']['fields'];
return self::CONFIG['AttributeFetcher']['fields'];
}
private function __collectCorrelations($user, $id, $primary)
/**
* @param array $user
* @param int $eventId
* @param bool $primary
* @return array
*/
private function __collectCorrelations(array $user, $eventId, $primary)
{
$max_correlations = Configure::read('MISP.max_correlations_per_event') ?: 5000;
$source = $primary ? '' : '1_';
$prefix = $primary ? '1_' : '';
$correlations = $this->Correlation->find('all', [
return $this->Correlation->find('all', [
'fields' => [
$source . 'attribute_id',
$prefix . 'attribute_id',
@ -159,7 +170,7 @@ class NoAclCorrelationBehavior extends ModelBehavior
],
'conditions' => [
'OR' => [
$source . 'event_id' => $id
$source . 'event_id' => $eventId
],
'AND' => [
[
@ -174,7 +185,6 @@ class NoAclCorrelationBehavior extends ModelBehavior
'contain' => [
'CorrelationValue' => [
'fields' => [
'CorrelationValue.id',
'CorrelationValue.value'
]
]
@ -182,13 +192,18 @@ class NoAclCorrelationBehavior extends ModelBehavior
'order' => false,
'limit' => $max_correlations
]);
return $correlations;
}
public function runGetAttributesRelatedToEvent(Model $Model, $user, $id)
/**
* @param Model $Model
* @param array $user
* @param int|array $id Event ID
* @return array
*/
public function runGetAttributesRelatedToEvent(Model $Model, array $user, $id)
{
$correlations = [];
$event_ids = [];
$eventIds = [];
$temp_correlations = $this->__collectCorrelations($user, $id, false);
foreach ($temp_correlations as $temp_correlation) {
@ -196,9 +211,9 @@ class NoAclCorrelationBehavior extends ModelBehavior
'id' => $temp_correlation['Correlation']['event_id'],
'attribute_id' => $temp_correlation['Correlation']['attribute_id'],
'parent_id' => $temp_correlation['Correlation']['1_attribute_id'],
'value' => $temp_correlation['CorrelationValue']['value']
'value' => $temp_correlation['CorrelationValue']['value'],
];
$event_ids[$temp_correlation['Correlation']['event_id']] = true;
$eventIds[$temp_correlation['Correlation']['event_id']] = true;
}
$temp_correlations = $this->__collectCorrelations($user, $id, true);
@ -207,15 +222,15 @@ class NoAclCorrelationBehavior extends ModelBehavior
'id' => $temp_correlation['Correlation']['1_event_id'],
'attribute_id' => $temp_correlation['Correlation']['1_attribute_id'],
'parent_id' => $temp_correlation['Correlation']['attribute_id'],
'value' => $temp_correlation['CorrelationValue']['value']
'value' => $temp_correlation['CorrelationValue']['value'],
];
$event_ids[$temp_correlation['Correlation']['1_event_id']] = true;
$eventIds[$temp_correlation['Correlation']['1_event_id']] = true;
}
if (empty($correlations)) {
return [];
}
$conditions = [
'Event.id' => array_keys($event_ids)
'Event.id' => array_keys($eventIds)
];
$events = $Model->Event->find('all', array(
'recursive' => -1,
@ -231,9 +246,9 @@ class NoAclCorrelationBehavior extends ModelBehavior
continue;
}
$event = $events[$eventId];
$correlation['org_id'] = $events[$eventId]['orgc_id'];
$correlation['info'] = $events[$eventId]['info'];
$correlation['date'] = $events[$eventId]['date'];
$correlation['org_id'] = $event['orgc_id'];
$correlation['info'] = $event['info'];
$correlation['date'] = $event['date'];
$parentId = $correlation['parent_id'];
unset($correlation['parent_id']);
$relatedAttributes[$parentId][] = $correlation;
@ -243,54 +258,38 @@ class NoAclCorrelationBehavior extends ModelBehavior
/**
* @param Correlation $Model
* @param $user
* @param $sgids
* @param array $user Not used
* @param array $sgids Not used
* @param array $attribute
* @param array $fields
* @param array $fields Attribute fields to fetch
* @param bool $includeEventData
* @return array
*/
public function runGetRelatedAttributes(Model $Model, $user, $sgids, $attribute, $fields = [], $includeEventData = false)
{
// LATER getRelatedAttributes($attribute) this might become a performance bottleneck
// prepare the conditions
$conditions = [
[
$correlatedAttributeIds = $Model->find('column', [
'conditions' => [
'Correlation.1_event_id !=' => $attribute['event_id'],
'Correlation.attribute_id' => $attribute['id']
'Correlation.attribute_id' => $attribute['id'],
],
[
'fields' => ['1_attribute_id'],
]);
$correlatedAttributeIds2 = $Model->find('column', [
'conditions' => [
'Correlation.event_id !=' => $attribute['event_id'],
'Correlation.1_attribute_id' => $attribute['id']
]
];
$corr_fields = [
[
'1_attribute_id',
'1_event_id',
'value_id'
'Correlation.1_attribute_id' => $attribute['id'],
],
[
'attribute_id',
'event_id',
'value_id'
]
];
$prefixes = ['1_', ''];
$correlated_attribute_ids = [];
foreach ($conditions as $k => $condition) {
$temp_correlations = $Model->find('all', [
'recursive' => -1,
'conditions' => $condition,
'fields' => $corr_fields[$k]
]);
if (!empty($temp_correlations)) {
foreach ($temp_correlations as $temp_correlation) {
$correlated_attribute_ids[] = $temp_correlation['Correlation'][$prefixes[$k] . 'attribute_id'];
}
}
'fields' => ['attribute_id'],
]);
foreach ($correlatedAttributeIds2 as $tempCorrelation) {
$correlatedAttributeIds[] = $tempCorrelation;
}
$contain = [];
if (empty($correlatedAttributeIds)) {
return [];
}
if (!empty($includeEventData)) {
$contain['Event'] = [
'fields' => [
@ -308,11 +307,14 @@ class NoAclCorrelationBehavior extends ModelBehavior
'Event.org_id'
]
];
} else {
$contain = [];
}
$relatedAttributes = $Model->Attribute->find('all', [
'recursive' => -1,
'conditions' => [
'Attribute.id' => $correlated_attribute_ids
'Attribute.id' => $correlatedAttributeIds
],
'fields' => $fields,
'contain' => $contain
@ -330,19 +332,15 @@ class NoAclCorrelationBehavior extends ModelBehavior
}
}
/**
* @param Correlation $Model
* @param array $user Not used
* @param int $eventId
* @param array $sgids Not used
* @return array
*/
public function fetchRelatedEventIds(Model $Model, array $user, int $eventId, array $sgids)
{
// search the correlation table for the event ids of the related events
// Rules:
// 1. Event is owned by the user (org_id matches)
// 2. User is allowed to see both the event and the org:
// a. Event:
// i. Event has a distribution between 1-3 (community only, connected communities, all orgs)
// ii. Event has a sharing group that the user is accessible to view
// b. Attribute:
// i. Attribute has a distribution of 5 (inheritance of the event, for this the event check has to pass anyway)
// ii. Attribute has a distribution between 1-3 (community only, connected communities, all orgs)
// iii. Attribute has a sharing group that the user is accessible to view
$primaryEventIds = $this->__filterRelatedEvents($Model, $eventId, true);
$secondaryEventIds = $this->__filterRelatedEvents($Model, $eventId, false);
return array_unique(array_merge($primaryEventIds, $secondaryEventIds), SORT_REGULAR);

View File

@ -17,7 +17,8 @@ class Correlation extends AppModel
const CACHE_NAME = 'misp:top_correlations',
CACHE_AGE = 'misp:top_correlations_age';
private $__compositeTypes = [];
/** @var array */
private $__compositeTypes;
public $belongsTo = array(
'Attribute' => [
@ -828,7 +829,7 @@ class Correlation extends AppModel
*/
public function getRelatedAttributes($user, $sgids, $attribute, $fields=[], $includeEventData = false)
{
if (in_array($attribute['type'], Attribute::NON_CORRELATING_TYPES)) {
if (in_array($attribute['type'], Attribute::NON_CORRELATING_TYPES, true)) {
return [];
}
return $this->runGetRelatedAttributes($user, $sgids, $attribute, $fields, $includeEventData);
@ -836,7 +837,7 @@ class Correlation extends AppModel
/**
* @param array $user User array
* @param int $eventId List of event IDs
* @param int $eventId Event ID
* @param array $sgids List of sharing group IDs
* @return array
*/
@ -908,40 +909,42 @@ class Correlation extends AppModel
public function collectMetrics()
{
$results['engine'] = $this->getCorrelationModelName();
$results['db'] = [
'Default' => [
'name' => __('Default correlation engine'),
'tables' => [
'default_correlations' => [
'id_limit' => 4294967295
],
'correlation_values' => [
'id_limit' => 4294967295
$results = [
'engine' => $this->getCorrelationModelName(),
'db' => [
'Default' => [
'name' => __('Default correlation engine'),
'tables' => [
'default_correlations' => [
'id_limit' => 4294967295
],
'correlation_values' => [
'id_limit' => 4294967295
]
]
],
'NoAcl' => [
'name' => __('No ACL correlation engine'),
'tables' => [
'no_acl_correlations' => [
'id_limit' => 4294967295
],
'correlation_values' => [
'id_limit' => 4294967295
]
]
],
'Legacy' => [
'name' => __('Legacy correlation engine (< 2.4.160)'),
'tables' => [
'correlations' => [
'id_limit' => 2147483647
]
]
]
],
'NoAcl' => [
'name' => __('No ACL correlation engine'),
'tables' => [
'no_acl_correlations' => [
'id_limit' => 4294967295
],
'correlation_values' => [
'id_limit' => 4294967295
]
]
],
'Legacy' => [
'name' => __('Legacy correlation engine (< 2.4.160)'),
'tables' => [
'correlations' => [
'id_limit' => 2147483647
]
]
]
'over_correlations' => $this->OverCorrelatingValue->find('count'),
];
$results['over_correlations'] = $this->OverCorrelatingValue->find('count');
$this->CorrelationExclusion = ClassRegistry::init('CorrelationExclusion');
$results['excluded_correlations'] = $this->CorrelationExclusion->find('count');
foreach ($results['db'] as &$result) {

View File

@ -689,26 +689,18 @@ class Event extends AppModel
}
/**
* Get related attributes for event
* @param array $user
* @param int|array $id Event ID when $scope is 'event', Attribute ID when $scope is 'attribute'
* @param bool $shadowAttribute
* @param string $scope 'event' or 'attribute'
* @param int|array $eventIds Event IDs
* @return array
*/
public function getRelatedAttributes(array $user, $id, $shadowAttribute = false, $scope = 'event')
public function getRelatedAttributes(array $user, $eventIds)
{
if ($shadowAttribute) {
// no longer supported
return [];
} else {
$parentIdField = '1_attribute_id';
$correlationModelName = 'Correlation';
}
if (!isset($this->{$correlationModelName})) {
$this->{$correlationModelName} = ClassRegistry::init($correlationModelName);
if (!isset($this->Correlation)) {
$this->Correlation = ClassRegistry::init('Correlation');
}
$sgids = $this->SharingGroup->authorizedIds($user);
$relatedAttributes = $this->{$correlationModelName}->getAttributesRelatedToEvent($user, $id, $sgids);
$relatedAttributes = $this->Correlation->getAttributesRelatedToEvent($user, $eventIds, $sgids);
return $relatedAttributes;
}

View File

@ -83,16 +83,11 @@ class OverCorrelatingValue extends AppModel
return $data;
}
public function checkValue($value)
public function findOverCorrelatingValues(array $valuesToCheck): array
{
return $this->hasAny(['value' => self::truncate($value)]);
}
public function findOverCorrelatingValues(array $values_to_check): array
{
$values_to_check_truncated = array_unique(self::truncateValues($values_to_check), SORT_REGULAR);
$valuesToCheck = array_unique(self::truncateValues($valuesToCheck), SORT_REGULAR);
return $this->find('column', [
'conditions' => ['value' => $values_to_check_truncated],
'conditions' => ['value' => $valuesToCheck],
'fields' => ['value'],
]);
}
@ -134,14 +129,23 @@ class OverCorrelatingValue extends AppModel
]);
$this->Attribute = ClassRegistry::init('Attribute');
foreach ($overCorrelations as &$overCorrelation) {
$value = $overCorrelation['OverCorrelatingValue']['value'] . '%';
$count = $this->Attribute->find('count', [
'recursive' => -1,
'conditions' => [
'OR' => [
'Attribute.value1 LIKE' => $overCorrelation['OverCorrelatingValue']['value'] . '%',
'Attribute.value2 LIKE' => $overCorrelation['OverCorrelatingValue']['value'] . '%'
]
]
'Attribute.value1 LIKE' => $value,
'AND' => [
'Attribute.value2 LIKE' => $value,
'NOT' => ['Attribute.type' => Attribute::PRIMARY_ONLY_CORRELATING_TYPES]
],
],
'NOT' => ['Attribute.type' => Attribute::NON_CORRELATING_TYPES],
'Attribute.disable_correlation' => 0,
'Event.disable_correlation' => 0,
'Attribute.deleted' => 0,
],
'contain' => ['Event'],
]);
$overCorrelation['OverCorrelatingValue']['occurrence'] = $count;
}

View File

@ -1,89 +1,92 @@
<?php
echo sprintf('<div%s>', empty($ajax) ? ' class="index"' : '');
echo $this->element('genericElements/IndexTable/index_table', [
'data' => [
'light_paginator' => 1,
'data' => $data,
'top_bar' => [
'children' => [
[
'children' => [
[
'type' => 'simple',
'url' => $baseurl . '/correlations/overCorrelations',
'text' => __('All')
],
[
'type' => 'simple',
'url' => $baseurl . '/correlations/overCorrelations/scope:over_correlating',
'text' => __('Over-correlating')
],
[
'type' => 'simple',
'url' => $baseurl . '/correlations/overCorrelations/scope:not_over_correlating',
'text' => __('Not over-correlating')
],
[
'type' => 'simple',
'url' => $baseurl . '/correlations/generateOccurrences',
'text' => __('Regenerate occurrence counts')
]
echo sprintf('<div%s>', empty($ajax) ? ' class="index"' : '');
echo $this->element('genericElements/IndexTable/index_table', [
'data' => [
'light_paginator' => 1,
'data' => $data,
'top_bar' => [
'children' => [
[
'children' => [
[
'type' => 'simple',
'url' => $baseurl . '/correlations/overCorrelations',
'text' => __('All'),
'active' => $scope === 'all',
],
[
'type' => 'simple',
'url' => $baseurl . '/correlations/overCorrelations/scope:over_correlating',
'text' => __('Over-correlating'),
'active' => $scope === 'over_correlating',
],
[
'type' => 'simple',
'url' => $baseurl . '/correlations/overCorrelations/scope:not_over_correlating',
'text' => __('Not over-correlating'),
'active' => $scope === 'not_over_correlating',
],
[
'type' => 'simple',
'url' => $baseurl . '/correlations/generateOccurrences',
'text' => __('Regenerate occurrence counts')
]
]
]
],
'fields' => [
[
'name' => 'Value',
'element' => 'postlink',
'data_path' => 'OverCorrelatingValue.value',
'url' => '/attributes/search/results',
'payload_paths' => [
'value' => 'OverCorrelatingValue.value'
]
],
[
'name' => 'Occurrences',
'data_path' => 'OverCorrelatingValue.occurrence',
'class' => 'shortish'
],
[
'name' => 'Blocked by Threshold',
'data_path' => 'OverCorrelatingValue.over_correlation',
'class' => 'shortish',
'element' => 'boolean'
],
[
'name' => 'Excluded by Exclusion List',
'data_path' => 'OverCorrelatingValue.excluded',
'class' => 'shortish',
'element' => 'boolean'
]
],
'fields' => [
[
'name' => 'Value',
'element' => 'postlink',
'data_path' => 'OverCorrelatingValue.value',
'url' => '/attributes/search/results',
'payload_paths' => [
'value' => 'OverCorrelatingValue.value'
]
],
'title' => empty($ajax) ? $title_for_layout : false,
'description' => empty($ajax) ? __('The values with the most correlation entries.') : false,
'pull' => 'right',
'actions' => [
[
'onclick' => sprintf(
'openGenericModal(\'%s/correlation_exclusions/add/redirect_controller:correlations/redirect:top/value:[onclick_params_data_path]\');',
$baseurl
),
'onclick_params_data_path' => 'OverCorrelatingValue.value',
'icon' => 'trash',
'title' => __('Add exclusion entry for value'),
'complex_requirement' => [
'function' => function (array $row) {
return !$row['OverCorrelatingValue']['excluded'];
}
]
[
'name' => 'Occurrences',
'data_path' => 'OverCorrelatingValue.occurrence',
'class' => 'shortish'
],
[
'name' => 'Blocked by Threshold',
'data_path' => 'OverCorrelatingValue.over_correlation',
'class' => 'shortish',
'element' => 'boolean'
],
[
'name' => 'Excluded by Exclusion List',
'data_path' => 'OverCorrelatingValue.excluded',
'class' => 'shortish',
'element' => 'boolean'
]
],
'title' => empty($ajax) ? $title_for_layout : false,
'description' => empty($ajax) ? __('The values with the most correlation entries.') : false,
'pull' => 'right',
'actions' => [
[
'onclick' => sprintf(
'openGenericModal(\'%s/correlation_exclusions/add/redirect_controller:correlations/redirect:top/value:[onclick_params_data_path]\');',
$baseurl
),
'onclick_params_data_path' => 'OverCorrelatingValue.value',
'icon' => 'trash',
'title' => __('Add exclusion entry for value'),
'complex_requirement' => [
'function' => function (array $row) {
return !$row['OverCorrelatingValue']['excluded'];
}
]
]
]
]);
echo '</div>';
if (empty($ajax)) {
echo $this->element('/genericElements/SideMenu/side_menu', $menuData);
}
]
]);
echo '</div>';
if (empty($ajax)) {
echo $this->element('/genericElements/SideMenu/side_menu', $menuData);
}

View File

@ -1,7 +1,7 @@
<?php
if (!empty($event['Related' . $scope][$object['id']])) {
$i = 0;
$linkColour = ($scope == 'Attribute') ? 'red' : 'white';
$linkColour = $scope === 'Attribute' ? 'red' : 'white';
$withPivot = isset($withPivot) ? $withPivot : false;
// remove duplicates
$relatedEvents = array();
@ -15,16 +15,16 @@
$count = count($event['Related' . $scope][$object['id']]);
foreach ($event['Related' . $scope][$object['id']] as $relatedAttribute) {
if ($i == 4 && $count > 5) {
$expandButton = __('Show %s more...', $count - 4);
$expandButton = __('Show %s more', $count - 4);
echo sprintf(
'<li class="no-side-padding correlation-expand-button useCursorPointer linkButton %s">%s</li>',
'<li class="no-side-padding correlation-expand-button useCursorPointer linkButton %s">%s</li> ',
$linkColour,
$expandButton
);
}
$relatedData = array(
'Orgc' => !empty($orgTable[$relatedAttribute['org_id']]) ? $orgTable[$relatedAttribute['org_id']] : 'N/A',
'Date' => isset($relatedAttribute['date']) ? $relatedAttribute['date'] : 'N/A',
'Orgc' => $orgTable[$relatedAttribute['org_id']] ?? 'N/A',
'Date' => $relatedAttribute['date'] ?? 'N/A',
'Event' => $relatedAttribute['info'],
'Correlating Value' => $relatedAttribute['value']
);
@ -59,13 +59,13 @@
}
if (!empty($object['correlation_exclusion'])) {
echo sprintf(
'<span class="bold red" title="%s">%s</span> ',
'<span class="red" title="%s">%s</span> ',
__('The attribute value matches a correlation exclusion rule defined by a site-administrator for this instance. Click the magnifying glass to search for all occurrences of the value.'),
__('Excluded.')
);
} else if (!empty($object['over_correlation'])) {
echo sprintf(
'<span class="bold red" title="%s">%s</span> ',
'<span class="red" title="%s">%s</span> ',
__('The instance threshold for the maximum number of correlations for the given attribute value has been exceeded. Click the magnifying glass to search for all occurrences of the value.'),
__('Too many correlations.')
);