fix: [Sighting] rework of the loading via restsearch

- the chunking and limiting by attribute IDs in the sighting restsearch caused long delays due to a select with two AND-ed in value lists causing the query optimiser to constantly run statistics on the table
- moved the filtering by attribute to PHP side via a loop, it should boost the performance of the function - and with it the sync considerably
composer_fix
iglocska 2023-03-02 09:49:44 +01:00
parent 68c6563dc8
commit cdf270606c
No known key found for this signature in database
GPG Key ID: BEA224F1FEF113AC
1 changed files with 46 additions and 12 deletions

View File

@ -220,18 +220,7 @@ class Sighting extends AppModel
return [];
}
// Create conditions for fetching just sightings that user can see according to sightings policy
$conditions = $this->createConditionsByAttributes($user, $attributes);
if (empty($conditions)) {
return [];
}
$conditions['Sighting.id'] = $ids;
$sightings = $this->find('all', [
'recursive' => -1,
'conditions' => $conditions,
'order' => 'Sighting.id',
]);
$sightings = $this->filterSightingsByAttributeACL($user, $attributes, $ids);
if (empty($sightings)) {
return [];
@ -369,6 +358,51 @@ class Sighting extends AppModel
return $this->generateStatistics($groupedSightings, $csvWithFalsePositive);
}
/**
* @param array $user
* @param array $attributes Attributes with `Attribute.id`, `Event.id` and `Event.org_id` fields
* @param array $ids
* @return array
*/
private function filterSightingsByAttributeACL(array $user, array $attributes, array $ids)
{
$sightingsPolicy = $this->sightingsPolicy();
$attributesKeyed = [];
$hostOrgId = Configure::read('MISP.host_org_id');
$userOrgId = $user['org_id'];
foreach ($attributes as $attribute) {
$attributesKeyed[$attribute['Attribute']['id']] = $attribute;
}
unset($attributes);
$sightings = $this->find('all', [
'recursive' => -1,
'conditions' => [
'Sighting.id' => $ids
],
'order' => 'Sighting.id'
]);
foreach ($sightings as $k => $sighting) {
$attribute = $attributesKeyed[$sighting['Sighting']['attribute_id']];
$ownEvent = $attribute['Event']['org_id'] == $userOrgId;
if (!$ownEvent) {
if ($sightingsPolicy === self::SIGHTING_POLICY_EVENT_OWNER) {
if ($sighting['Sighting']['org_id'] != $userOrgId) {
unset($sightings[$k]);
}
} else if ($sightingsPolicy === self::SIGHTING_POLICY_SIGHTING_REPORTER) {
if (!$this->isreporter($attribute['Event']['id'], $userOrgId)) {
unset($sightings[$k]);
}
} else if ($sightingsPolicy === self::SIGHTING_POLICY_HOST_ORG) {
if (!in_array($sighting['Sighting']['org_id'], [$userOrgId, $hostOrgId])) {
unset($sightings[$k]);
}
}
}
}
return array_values($sightings);
}
/**
* @param array $user
* @param array $attributes Attributes with `Attribute.id`, `Event.id` and `Event.org_id` fields