diff --git a/app/Controller/GalaxyClusterRelationsController.php b/app/Controller/GalaxyClusterRelationsController.php index 03cd45ad4..912f6c956 100644 --- a/app/Controller/GalaxyClusterRelationsController.php +++ b/app/Controller/GalaxyClusterRelationsController.php @@ -72,8 +72,6 @@ class GalaxyClusterRelationsController extends AppController $this->paginate['contain'] = array('SharingGroup', 'SourceCluster' => ['Org', 'Orgc'], 'TargetCluster', 'GalaxyClusterRelationTag' => array('Tag')); $relations = $this->paginate(); $relations = $this->GalaxyClusterRelation->removeNonAccessibleTargetCluster($this->Auth->user(), $relations); - $this->loadModel('SharingGroup'); - $sgs = $this->SharingGroup->fetchAllAuthorised($this->Auth->user()); $this->loadModel('Attribute'); $distributionLevels = $this->Attribute->distributionLevels; unset($distributionLevels[5]); diff --git a/app/Controller/SharingGroupsController.php b/app/Controller/SharingGroupsController.php index 329d39275..7f410ad2b 100644 --- a/app/Controller/SharingGroupsController.php +++ b/app/Controller/SharingGroupsController.php @@ -260,7 +260,7 @@ class SharingGroupsController extends AppController public function index($passive = false) { $passive = $passive === 'true'; - $authorizedSgIds = $this->SharingGroup->fetchAllAuthorised($this->Auth->user()); + $authorizedSgIds = $this->SharingGroup->authorizedIds($this->Auth->user()); $this->paginate['conditions'][] = array('SharingGroup.id' => $authorizedSgIds); $this->paginate['conditions'][] = array('SharingGroup.active' => $passive === true ? 0 : 1); diff --git a/app/Controller/ThreadsController.php b/app/Controller/ThreadsController.php index ad63e8bb2..882a3b171 100644 --- a/app/Controller/ThreadsController.php +++ b/app/Controller/ThreadsController.php @@ -148,7 +148,7 @@ class ThreadsController extends AppController { $this->loadModel('Posts'); $this->loadModel('SharingGroup'); - $sgids = $this->SharingGroup->fetchAllAuthorised($this->Auth->user()); + $sgids = $this->SharingGroup->authorizedIds($this->Auth->user()); $conditions = null; if (!$this->_isSiteAdmin()) { $conditions['AND']['OR'] = array( diff --git a/app/Model/Attribute.php b/app/Model/Attribute.php index fe5ad3505..90d0b6055 100644 --- a/app/Model/Attribute.php +++ b/app/Model/Attribute.php @@ -1897,7 +1897,7 @@ class Attribute extends AppModel { $conditions = array(); if (!$user['Role']['perm_site_admin']) { - $sgids = $this->Event->cacheSgids($user, true); + $sgids = $this->SharingGroup->authorizedIds($user); $eventConditions = $this->Event->createEventConditions($user); $conditions = array( 'AND' => array( @@ -1905,7 +1905,7 @@ class Attribute extends AppModel array( 'OR' => array( 'Event.org_id' => $user['org_id'], - 'Attribute.distribution' => array('1', '2', '3', '5'), + 'Attribute.distribution' => array(1, 2, 3, 5), 'AND '=> array( 'Attribute.distribution' => 4, 'Attribute.sharing_group_id' => $sgids, @@ -1916,7 +1916,7 @@ class Attribute extends AppModel 'OR' => array( 'Attribute.object_id' => 0, 'Event.org_id' => $user['org_id'], - 'Object.distribution' => array('1', '2', '3', '5'), + 'Object.distribution' => array(1, 2, 3, 5), 'AND' => array( 'Object.distribution' => 4, 'Object.sharing_group_id' => $sgids, diff --git a/app/Model/Event.php b/app/Model/Event.php index 8b4292833..bf1cf78be 100755 --- a/app/Model/Event.php +++ b/app/Model/Event.php @@ -491,10 +491,7 @@ class Event extends AppModel */ public function attachCorrelationCountToEvents(array $user, array $events) { - $sgids = $this->SharingGroup->fetchAllAuthorised($user); - if (!isset($sgids) || empty($sgids)) { - $sgids = array(-1); - } + $sgids = $this->SharingGroup->authorizedIds($user); $eventIds = array_column(array_column($events, 'Event'), 'id'); $conditionsCorrelation = $this->__buildEventConditionsCorrelation($user, $eventIds, $sgids); $this->Attribute->Correlation->virtualFields['count'] = 'count(distinct(Correlation.event_id))'; @@ -709,7 +706,7 @@ class Event extends AppModel $this->{$correlationModelName} = ClassRegistry::init($correlationModelName); } if (!$user['Role']['perm_site_admin']) { - $sgids = $this->cacheSgids($user, true); + $sgids = $this->SharingGroup->authorizedIds($user); $conditionsCorrelation = array( 'AND' => array( $correlationModelName . '.1_' . $scope . '_id' => $id, @@ -1340,7 +1337,7 @@ class Event extends AppModel { $conditions = array(); if (!$user['Role']['perm_site_admin']) { - $sgids = $this->cacheSgids($user, true); + $sgids = $this->SharingGroup->authorizedIds($user); $unpublishedPrivate = Configure::read('MISP.unpublishedprivate'); $conditions['AND']['OR'] = [ 'Event.org_id' => $user['org_id'], @@ -1772,7 +1769,7 @@ class Event extends AppModel $flatten = (bool)$options['flatten']; // restricting to non-private or same org if the user is not a site-admin. - $sgids = $this->cacheSgids($user, $useCache); + $sgids = $this->SharingGroup->authorizedIds($user); if (!$isSiteAdmin) { // if delegations are enabled, check if there is an event that the current user might see because of the request itself if (Configure::read('MISP.delegation')) { @@ -5713,22 +5710,6 @@ class Event extends AppModel ]; } - public function cacheSgids($user, $useCache = false) - { - if ($useCache && isset($this->assetCache['sgids'])) { - return $this->assetCache['sgids']; - } else { - $sgids = $this->SharingGroup->fetchAllAuthorised($user); - if (empty($sgids)) { - $sgids = array(-1); - } - if ($useCache) { - $this->assetCache['sgids'] = $sgids; - } - return $sgids; - } - } - public function __cacheSharingGroupData($user, $useCache = false) { if ($useCache && isset($this->assetCache['sharingGroupData'])) { diff --git a/app/Model/EventReport.php b/app/Model/EventReport.php index 52138b18e..4efc03380 100644 --- a/app/Model/EventReport.php +++ b/app/Model/EventReport.php @@ -3,6 +3,7 @@ App::uses('AppModel', 'Model'); /** * @property Event $Event + * @property SharingGroup $SharingGroup */ class EventReport extends AppModel { @@ -249,10 +250,9 @@ class EventReport extends AppModel */ public function buildACLConditions(array $user) { - $this->Event = ClassRegistry::init('Event'); $conditions = array(); if (!$user['Role']['perm_site_admin']) { - $sgids = $this->Event->cacheSgids($user, true); + $sgids = $this->SharingGroup->authorizedIds($user); $eventConditions = $this->Event->createEventConditions($user); $conditions = array( 'AND' => array( @@ -282,9 +282,8 @@ class EventReport extends AppModel */ public function attachReportCountsToEvents(array $user, $events) { - $conditions = array(); if (!$user['Role']['perm_site_admin']) { - $sgids = $this->Event->cacheSgids($user, true); + $sgids = $this->SharingGroup->authorizedIds($user); } foreach ($events as $k => $event) { $conditions = [ diff --git a/app/Model/GalaxyCluster.php b/app/Model/GalaxyCluster.php index 96ae8b1a4..84e368fb2 100644 --- a/app/Model/GalaxyCluster.php +++ b/app/Model/GalaxyCluster.php @@ -7,6 +7,7 @@ App::uses('TmpFileTool', 'Tools'); * @property Galaxy $Galaxy * @property GalaxyClusterRelation $GalaxyClusterRelation * @property GalaxyElement $GalaxyElement + * @property SharingGroup $SharingGroup */ class GalaxyCluster extends AppModel { @@ -1014,10 +1015,9 @@ class GalaxyCluster extends AppModel public function buildConditions($user) { - $this->Event = ClassRegistry::init('Event'); $conditions = array(); if (!$user['Role']['perm_site_admin']) { - $sgids = $this->Event->cacheSgids($user, true); + $sgids = $this->SharingGroup->authorizedIds($user); $alias = $this->alias; $conditions['AND']['OR'] = array( "${alias}.org_id" => $user['org_id'], diff --git a/app/Model/GalaxyClusterRelation.php b/app/Model/GalaxyClusterRelation.php index 7119c9417..7fb182064 100644 --- a/app/Model/GalaxyClusterRelation.php +++ b/app/Model/GalaxyClusterRelation.php @@ -4,6 +4,7 @@ App::uses('AppModel', 'Model'); /** * @property GalaxyClusterRelationTag $GalaxyClusterRelationTag * @property GalaxyCluster $TargetCluster + * @property SharingGroup $SharingGroup */ class GalaxyClusterRelation extends AppModel { @@ -81,9 +82,8 @@ class GalaxyClusterRelation extends AppModel { $conditions = []; if (!$user['Role']['perm_site_admin']) { - $this->Event = ClassRegistry::init('Event'); $alias = $this->alias; - $sgids = $this->Event->cacheSgids($user, true); + $sgids = $this->SharingGroup->authorizedIds($user); $gcOwnerIds = $this->SourceCluster->cacheGalaxyClusterOwnerIDs($user); $conditionsRelations['AND']['OR'] = [ "${alias}.galaxy_cluster_id" => $gcOwnerIds, diff --git a/app/Model/MispObject.php b/app/Model/MispObject.php index ec1c29f04..b927c9548 100644 --- a/app/Model/MispObject.php +++ b/app/Model/MispObject.php @@ -488,7 +488,7 @@ class MispObject extends AppModel return []; } - $sgids = $this->Event->cacheSgids($user, true); + $sgids = $this->SharingGroup->authorizedIds($user); return [ 'AND' => [ 'OR' => [ @@ -543,7 +543,7 @@ class MispObject extends AppModel { $attributeConditions = array(); if (!$user['Role']['perm_site_admin']) { - $sgids = $this->Event->cacheSgids($user, true); + $sgids = $this->SharingGroup->authorizedIds($user); $attributeConditions = array( 'OR' => array( array( diff --git a/app/Model/ShadowAttribute.php b/app/Model/ShadowAttribute.php index f2a7d42cb..9d2a67fcd 100644 --- a/app/Model/ShadowAttribute.php +++ b/app/Model/ShadowAttribute.php @@ -722,7 +722,7 @@ class ShadowAttribute extends AppModel { $conditions = array(); if (!$user['Role']['perm_site_admin']) { - $sgids = $this->Event->cacheSgids($user, true); + $sgids = $this->Event->SharingGroup->authorizedIds($user); $attributeDistribution = array( 'Attribute.distribution' => array(1,2,3,5) ); diff --git a/app/Model/SharingGroup.php b/app/Model/SharingGroup.php index 68a235af3..7f4c50475 100644 --- a/app/Model/SharingGroup.php +++ b/app/Model/SharingGroup.php @@ -72,6 +72,8 @@ class SharingGroup extends AppModel 'access' => array() ); + private $authorizedIds = []; + public function beforeValidate($options = array()) { if (empty($this->data['SharingGroup']['uuid'])) { @@ -121,7 +123,6 @@ class SharingGroup extends AppModel * - sharing_group: specific scope that fetch just necessary information for generating distribution graph * - name: array in ID => name format * - uuid: array in ID => uuid format - * - false: array with all sharing group IDs * * @param array $user * @param string|false $scope @@ -131,29 +132,21 @@ class SharingGroup extends AppModel */ public function fetchAllAuthorised(array $user, $scope = false, $active = false, $id = false) { - $conditions = array(); - if ($id) { - $conditions['AND']['SharingGroup.id'] = $id; - } - if ($active !== false) { - $conditions['AND']['SharingGroup.active'] = $active; + $authorizedIds = $this->authorizedIds($user); + if ($authorizedIds === [-1]) { // hack + return []; } - if ($user['Role']['perm_site_admin']) { - $ids = $this->find('column', array( - 'fields' => array('id'), - 'conditions' => $conditions - )); + if ($id) { + if (!in_array($id, $authorizedIds)) { + return []; // user is not authorized to see that sharing group + } + $conditions['SharingGroup.id'] = $id; } else { - $ids = array_unique(array_merge( - $this->SharingGroupServer->fetchAllAuthorised(), - $this->SharingGroupOrg->fetchAllAuthorised($user['org_id']) - )); + $conditions = ['SharingGroup.id' => $authorizedIds]; } - if (!empty($ids)) { - $conditions['AND'][] = array('SharingGroup.id' => $ids); - } else { - return array(); + if ($active !== false) { + $conditions['SharingGroup.active'] = $active; } if ($scope === 'full') { $sgs = $this->find('all', array( @@ -228,9 +221,8 @@ class SharingGroup extends AppModel 'conditions' => $conditions, )); return $sgs; - } else { - return $ids; } + throw new InvalidArgumentException("Invalid scope $scope"); } /** @@ -473,6 +465,38 @@ class SharingGroup extends AppModel return $authorized; } + /** + * Returns sharing groups IDs that the user is allowed to see it + * @param array $user + * @param bool $useCache + * @return int[] + */ + public function authorizedIds(array $user, $useCache = true) + { + $cacheKey = "{$user['Role']['perm_site_admin']}-{$user['org_id']}"; + if ($useCache && isset($this->authorizedIds[$cacheKey])) { + return $this->authorizedIds[$cacheKey]; + } + + if ($user['Role']['perm_site_admin']) { + $sgids = $this->find('column', [ + 'fields' => ['id'], + ]); + } else { + $sgids = array_unique(array_merge( + $this->SharingGroupServer->fetchAllAuthorised(), + $this->SharingGroupOrg->fetchAllAuthorised($user['org_id']) + ), SORT_REGULAR); + } + if (empty($sgids)) { + $sgids = [-1]; + } + if ($useCache) { + $this->authorizedIds[$cacheKey] = $sgids; + } + return $sgids; + } + /** * @param array $user * @param string|int $id Sharing group ID or UUID