2016-12-05 00:47:34 +01:00
< ? php
App :: uses ( 'AppModel' , 'Model' );
2021-01-17 18:16:02 +01:00
App :: uses ( 'TmpFileTool' , 'Tools' );
2021-02-21 16:26:02 +01:00
/**
* @ property Tag $Tag
2022-04-24 18:29:32 +02:00
* @ property Galaxy $Galaxy
2021-02-24 18:05:59 +01:00
* @ property GalaxyClusterRelation $GalaxyClusterRelation
2022-03-27 18:45:14 +02:00
* @ property GalaxyElement $GalaxyElement
2022-05-22 17:09:00 +02:00
* @ property SharingGroup $SharingGroup
2021-02-21 16:26:02 +01:00
*/
2018-07-19 11:48:22 +02:00
class GalaxyCluster extends AppModel
{
public $useTable = 'galaxy_clusters' ;
2016-12-05 00:47:34 +01:00
2018-07-19 11:48:22 +02:00
public $recursive = - 1 ;
2016-12-05 00:47:34 +01:00
2018-07-19 11:48:22 +02:00
public $actsAs = array (
2021-01-22 13:01:23 +01:00
'AuditLog' ,
2020-11-12 11:18:36 +01:00
'SysLogLogable.SysLogLogable' => array ( // TODO Audit, logable
'userModel' => 'User' ,
'userKey' => 'user_id' ,
'change' => 'full' ),
'Containable' ,
2018-07-19 11:48:22 +02:00
);
2016-12-05 00:47:34 +01:00
2020-06-12 15:58:24 +02:00
private $__assetCache = array ();
2018-07-19 11:48:22 +02:00
public $validate = array (
2020-07-15 10:01:59 +02:00
'value' => array (
2020-04-15 08:46:21 +02:00
'stringNotEmpty' => array (
'rule' => array ( 'stringNotEmpty' )
)
),
'uuid' => array (
'uuid' => array (
2021-02-17 18:51:52 +01:00
'rule' => 'uuid' ,
'message' => 'Please provide a valid RFC 4122 UUID'
2020-04-15 08:46:21 +02:00
),
'unique' => array (
'rule' => 'isUnique' ,
'message' => 'The UUID provided is not unique' ,
'required' => 'create'
)
),
'distribution' => array (
2020-05-07 11:03:18 +02:00
'rule' => array ( 'inList' , array ( '0' , '1' , '2' , '3' , '4' )),
'message' => 'Options: Your organisation only, This community only, Connected communities, All communities, Sharing group' ,
2020-04-15 08:46:21 +02:00
'required' => true
2020-06-16 16:36:49 +02:00
),
'published' => array (
'boolean' => array (
'rule' => array ( 'boolean' ),
),
),
2018-07-19 11:48:22 +02:00
);
2016-12-05 00:47:34 +01:00
2018-07-19 11:48:22 +02:00
public $belongsTo = array (
'Galaxy' => array (
'className' => 'Galaxy' ,
'foreignKey' => 'galaxy_id' ,
),
'Tag' => array (
'foreignKey' => false ,
'conditions' => array ( 'GalaxyCluster.tag_name = Tag.name' )
2020-04-15 08:46:21 +02:00
),
'Org' => array (
'className' => 'Organisation' ,
'foreignKey' => 'org_id'
),
'Orgc' => array (
'className' => 'Organisation' ,
'foreignKey' => 'orgc_id'
2020-04-22 08:40:18 +02:00
),
'SharingGroup' => array (
'className' => 'SharingGroup' ,
'foreignKey' => 'sharing_group_id'
2018-07-19 11:48:22 +02:00
)
);
2016-12-05 00:47:34 +01:00
2018-11-23 14:11:33 +01:00
private $__clusterCache = array ();
2020-07-08 16:56:31 +02:00
private $deletedClusterUUID ;
2021-10-30 23:05:11 +02:00
public $bulkEntry = false ;
2016-12-09 07:58:03 +01:00
2018-07-19 11:48:22 +02:00
public $hasMany = array (
'GalaxyElement' => array ( 'dependent' => true ),
2020-05-25 10:04:07 +02:00
'GalaxyClusterRelation' => array (
'className' => 'GalaxyClusterRelation' ,
'foreignKey' => 'galaxy_cluster_id' ,
'dependent' => true ,
),
2020-06-12 15:09:54 +02:00
'TargetingClusterRelation' => array (
2020-05-25 10:04:07 +02:00
'className' => 'GalaxyClusterRelation' ,
'foreignKey' => 'referenced_galaxy_cluster_id' ,
),
2018-07-19 11:48:22 +02:00
);
2016-12-05 00:47:34 +01:00
2020-05-26 11:17:58 +02:00
public $validFormats = array (
'json' => array ( 'json' , 'JsonExport' , 'json' ),
);
2018-07-19 11:48:22 +02:00
public function beforeValidate ( $options = array ())
{
2021-10-30 23:05:11 +02:00
$cluster = & $this -> data [ 'GalaxyCluster' ];
if ( ! isset ( $cluster [ 'description' ])) {
$cluster [ 'description' ] = '' ;
2018-07-19 11:48:22 +02:00
}
2021-10-30 23:05:11 +02:00
if ( isset ( $cluster [ 'distribution' ]) && $cluster [ 'distribution' ] != 4 ) {
$cluster [ 'sharing_group_id' ] = null ;
2020-05-20 10:33:33 +02:00
}
2021-10-30 23:05:11 +02:00
if ( ! isset ( $cluster [ 'published' ])) {
$cluster [ 'published' ] = false ;
2020-06-16 16:36:49 +02:00
}
2022-03-27 19:15:10 +02:00
if ( ! isset ( $cluster [ 'authors' ])) {
2021-10-30 23:05:11 +02:00
$cluster [ 'authors' ] = '' ;
} elseif ( is_array ( $cluster [ 'authors' ])) {
2022-03-27 19:15:10 +02:00
$cluster [ 'authors' ] = JsonTool :: encode ( $cluster [ 'authors' ]);
2020-05-20 10:33:33 +02:00
}
2018-07-19 11:48:22 +02:00
return true ;
}
2016-12-05 00:47:34 +01:00
2018-07-19 11:48:22 +02:00
public function afterFind ( $results , $primary = false )
{
foreach ( $results as $k => $result ) {
2021-10-30 23:05:11 +02:00
if ( isset ( $result [ $this -> alias ][ 'authors' ])) {
2022-03-27 19:15:10 +02:00
$results [ $k ][ $this -> alias ][ 'authors' ] = json_decode ( $result [ $this -> alias ][ 'authors' ], true );
2020-05-25 10:04:07 +02:00
}
2022-03-27 19:15:10 +02:00
if ( isset ( $result [ $this -> alias ][ 'distribution' ]) && $result [ $this -> alias ][ 'distribution' ] != 4 ) {
2020-05-25 16:38:18 +02:00
unset ( $results [ $k ][ 'SharingGroup' ]);
2020-05-25 10:04:07 +02:00
}
2022-03-27 19:15:10 +02:00
if ( isset ( $result [ $this -> alias ][ 'org_id' ]) && $result [ $this -> alias ][ 'org_id' ] == 0 ) {
2020-05-25 16:38:18 +02:00
if ( isset ( $results [ $k ][ 'Org' ])) {
2021-08-11 12:43:19 +02:00
$results [ $k ][ 'Org' ] = Organisation :: GENERIC_MISP_ORGANISATION ;
2020-05-25 16:38:18 +02:00
}
2020-05-25 10:04:07 +02:00
}
2022-03-27 19:15:10 +02:00
if ( isset ( $result [ $this -> alias ][ 'orgc_id' ]) && $result [ $this -> alias ][ 'orgc_id' ] == 0 ) {
2020-05-25 16:38:18 +02:00
if ( isset ( $results [ $k ][ 'Orgc' ])) {
2021-08-11 12:43:19 +02:00
$results [ $k ][ 'Orgc' ] = Organisation :: GENERIC_MISP_ORGANISATION ;
2020-05-25 16:38:18 +02:00
}
2018-07-19 11:48:22 +02:00
}
2020-05-27 09:35:27 +02:00
2021-10-30 23:05:11 +02:00
if ( ! empty ( $result [ 'GalaxyClusterRelation' ])) {
2022-03-27 19:15:10 +02:00
foreach ( $result [ 'GalaxyClusterRelation' ] as $i => $relation ) {
2020-05-27 09:35:27 +02:00
if ( isset ( $relation [ 'distribution' ]) && $relation [ 'distribution' ] != 4 ) {
unset ( $results [ $k ][ 'GalaxyClusterRelation' ][ $i ][ 'SharingGroup' ]);
}
}
}
2018-07-19 11:48:22 +02:00
}
return $results ;
}
2016-12-05 00:47:34 +01:00
2020-06-08 11:33:34 +02:00
public function afterSave ( $created , $options = array ())
2020-05-25 10:04:07 +02:00
{
2020-07-08 16:56:31 +02:00
// Update all relations IDs that are unknown but saved
2021-10-30 23:05:11 +02:00
if ( ! $this -> bulkEntry ) {
2020-11-23 19:38:19 +01:00
$cluster = $this -> data [ $this -> alias ];
$cluster = $this -> fetchAndSetUUID ( $cluster );
$this -> GalaxyClusterRelation -> updateAll (
array ( 'GalaxyClusterRelation.referenced_galaxy_cluster_id' => $cluster [ 'id' ]),
array ( 'GalaxyClusterRelation.referenced_galaxy_cluster_uuid' => $cluster [ 'uuid' ])
);
}
2020-06-08 11:33:34 +02:00
}
public function afterDelete ()
{
2020-07-08 16:56:31 +02:00
// Remove all relations IDs now that the cluster is unknown
2020-07-02 11:27:28 +02:00
if ( ! empty ( $this -> deletedClusterUUID )) {
$this -> GalaxyClusterRelation -> updateAll (
array ( 'GalaxyClusterRelation.referenced_galaxy_cluster_id' => 0 ),
array ( 'GalaxyClusterRelation.referenced_galaxy_cluster_uuid' => $this -> deletedClusterUUID )
);
$this -> GalaxyElement -> deleteAll ( array ( 'GalaxyElement.galaxy_cluster_id' => $this -> id ));
$this -> GalaxyClusterRelation -> deleteAll ( array ( 'GalaxyClusterRelation.galaxy_cluster_uuid' => $this -> deletedClusterUUID ));
}
2020-05-25 10:04:07 +02:00
}
2018-07-19 11:48:22 +02:00
public function beforeDelete ( $cascade = true )
{
2020-07-02 11:27:28 +02:00
$cluster = $this -> find ( 'first' , array (
'conditions' => array ( 'id' => $this -> id ),
'fields' => array ( 'uuid' ),
));
if ( ! empty ( $cluster )) {
$this -> deletedClusterUUID = $cluster [ $this -> alias ][ 'uuid' ];
} else {
$this -> deletedClusterUUID = null ;
}
2018-07-19 11:48:22 +02:00
}
2020-11-23 19:38:19 +01:00
2020-07-08 16:56:31 +02:00
/**
* arrangeData Move linked data into the cluster model key
*
* @ return array The arranged cluster
*/
2020-06-12 15:08:01 +02:00
public function arrangeData ( $cluster )
2020-06-09 11:39:31 +02:00
{
2020-07-02 11:27:28 +02:00
$models = array ( 'Galaxy' , 'SharingGroup' , 'GalaxyElement' , 'GalaxyClusterRelation' , 'Org' , 'Orgc' , 'TargetingClusterRelation' );
2020-06-09 11:39:31 +02:00
foreach ( $models as $model ) {
2020-06-12 15:08:01 +02:00
if ( isset ( $cluster [ $model ])) {
$cluster [ 'GalaxyCluster' ][ $model ] = $cluster [ $model ];
unset ( $cluster [ $model ]);
}
2020-06-09 11:39:31 +02:00
}
return $cluster ;
}
2020-11-24 13:51:13 +01:00
public function generateMissingRelations ()
2020-11-23 19:38:19 +01:00
{
2021-07-27 21:10:45 +02:00
$missingRelations = $this -> GalaxyClusterRelation -> find ( 'column' , [
2020-11-23 19:38:19 +01:00
'conditions' => [ 'referenced_galaxy_cluster_id' => 0 ],
2021-07-27 21:10:45 +02:00
'fields' => [ 'referenced_galaxy_cluster_uuid' ],
'unique' => true ,
2020-11-23 19:38:19 +01:00
]);
2021-07-27 21:10:45 +02:00
if ( empty ( $missingRelations )) {
return ;
}
2020-11-23 19:38:19 +01:00
$ids = $this -> find ( 'list' , [
2021-07-27 21:10:45 +02:00
'conditions' => [ 'uuid' => $missingRelations ],
2020-11-23 19:38:19 +01:00
'fields' => [ 'uuid' , 'id' ]
]);
foreach ( $ids as $uuid => $id ) {
$this -> GalaxyClusterRelation -> updateAll (
[ 'referenced_galaxy_cluster_id' => $id ],
[ 'referenced_galaxy_cluster_uuid' => $uuid ]
);
}
}
2020-06-19 10:45:15 +02:00
public function fetchAndSetUUID ( $cluster )
{
if ( ! isset ( $cluster [ 'uuid' ])) {
$alias = $this -> alias ;
$tmp = $this -> find ( 'first' , array (
'recursive' => - 1 ,
'fields' => array ( " ${ alias } .id " , " ${ alias } .uuid " ),
'conditions' => array ( " ${ alias } .id " => $cluster [ 'id' ])
));
$cluster [ 'uuid' ] = $tmp [ $alias ][ 'uuid' ];
}
return $cluster ;
}
2020-07-08 16:56:31 +02:00
/**
* saveCluster Respecting ACL saves a cluster , its elements , relations and set correct fields where applicable
*
* @ param array $user
* @ param array $cluster
* @ param bool $allowEdit redirects to the edit function
* @ return array The errors if any
*/
public function saveCluster ( array $user , array $cluster , $allowEdit = false )
2020-04-15 11:49:50 +02:00
{
2020-06-15 14:37:37 +02:00
$errors = array ();
2020-04-15 11:49:50 +02:00
if ( ! $user [ 'Role' ][ 'perm_galaxy_editor' ] && ! $user [ 'Role' ][ 'perm_site_admin' ]) {
2020-06-15 14:37:37 +02:00
$errors [] = __ ( 'Incorrect permission' );
return $errors ;
2020-04-15 11:49:50 +02:00
}
$galaxy = $this -> Galaxy -> find ( 'first' , array ( 'conditions' => array (
'id' => $cluster [ 'GalaxyCluster' ][ 'galaxy_id' ]
)));
if ( empty ( $galaxy )) {
2020-06-09 11:01:25 +02:00
$errors [] = __ ( 'Galaxy not found' );
return $errors ;
2020-04-15 11:49:50 +02:00
} else {
$galaxy = $galaxy [ 'Galaxy' ];
}
unset ( $cluster [ 'GalaxyCluster' ][ 'id' ]);
2020-06-10 09:37:25 +02:00
$cluster [ 'GalaxyCluster' ][ 'locked' ] = false ;
2020-07-13 16:48:14 +02:00
2020-04-15 11:49:50 +02:00
if ( isset ( $cluster [ 'GalaxyCluster' ][ 'uuid' ])) {
2020-07-13 16:48:14 +02:00
$this -> GalaxyClusterBlocklist = ClassRegistry :: init ( 'GalaxyClusterBlocklist' );
if ( $this -> GalaxyClusterBlocklist -> checkIfBlocked ( $cluster [ 'GalaxyCluster' ][ 'uuid' ])) {
$errors [] = __ ( 'Blocked by blocklist' );
return $errors ;
}
2020-04-15 11:49:50 +02:00
// check if the uuid already exists
$existingGalaxyCluster = $this -> find ( 'first' , array ( 'conditions' => array ( 'GalaxyCluster.uuid' => $cluster [ 'GalaxyCluster' ][ 'uuid' ])));
if ( $existingGalaxyCluster ) {
2020-04-22 08:40:18 +02:00
if ( $existingGalaxyCluster [ 'GalaxyCluster' ][ 'galaxy_id' ] != $galaxy [ 'id' ]) { // cluster already exists in another galaxy
2020-06-09 11:01:25 +02:00
$errors [] = __ ( 'Cluster already exists in another galaxy' );
2020-07-07 08:16:46 +02:00
return $errors ;
2020-06-09 11:01:25 +02:00
}
if ( ! $existingGalaxyCluster [ 'GalaxyCluster' ][ 'default' ]) {
$errors [] = __ ( 'Edit not allowed on default clusters' );
return $errors ;
2020-04-22 08:40:18 +02:00
}
2020-06-09 11:01:25 +02:00
if ( ! $allowEdit ) {
$errors [] = __ ( 'Edit not allowed' );
return $errors ;
2020-04-15 11:49:50 +02:00
}
2020-06-09 11:01:25 +02:00
$errors = $this -> editCluster ( $user , $cluster );
return $errors ;
2020-04-15 11:49:50 +02:00
}
} else {
$cluster [ 'GalaxyCluster' ][ 'uuid' ] = CakeText :: uuid ();
}
2020-07-09 17:22:08 +02:00
if ( ! isset ( $cluster [ 'GalaxyCluster' ][ 'default' ])) {
$cluster [ 'GalaxyCluster' ][ 'default' ] = false ;
}
2020-06-16 16:36:49 +02:00
if ( ! isset ( $cluster [ 'GalaxyCluster' ][ 'published' ])) {
$cluster [ 'GalaxyCluster' ][ 'published' ] = false ;
}
2020-07-03 15:04:22 +02:00
if ( ! isset ( $cluster [ 'GalaxyCluster' ][ 'collection_uuid' ])) {
$cluster [ 'GalaxyCluster' ][ 'collection_uuid' ] = '' ;
}
2020-07-02 11:27:28 +02:00
if ( ! empty ( $cluster [ 'GalaxyCluster' ][ 'extends_uuid' ])) {
$forkedCluster = $this -> find ( 'first' , array ( 'conditions' => array ( 'GalaxyCluster.uuid' => $cluster [ 'GalaxyCluster' ][ 'extends_uuid' ])));
if ( ! empty ( $forkedCluster ) && $forkedCluster [ 'GalaxyCluster' ][ 'galaxy_id' ] != $galaxy [ 'id' ]) {
2020-07-08 16:56:31 +02:00
$errors [] = __ ( 'Cluster forks have to belong to the same galaxy as the parent' );
2020-07-02 11:27:28 +02:00
return $errors ;
}
} else {
$cluster [ 'GalaxyCluster' ][ 'extends_version' ] = null ;
2020-04-22 08:40:18 +02:00
}
2020-07-13 16:48:14 +02:00
if ( ! isset ( $cluster [ 'GalaxyCluster' ][ 'distribution' ])) {
$cluster [ 'GalaxyCluster' ][ 'distribution' ] = Configure :: read ( 'MISP.default_event_distribution' ); // use default event distribution
}
if ( $cluster [ 'GalaxyCluster' ][ 'distribution' ] != 4 ) {
$cluster [ 'GalaxyCluster' ][ 'sharing_group_id' ] = null ;
}
2020-07-08 16:56:31 +02:00
// In contrary to the capture context, we make sure the cluster belongs to the organisation initiating the save
2020-06-09 10:08:36 +02:00
$cluster [ 'GalaxyCluster' ][ 'org_id' ] = $user [ 'Organisation' ][ 'id' ];
2020-06-11 17:00:25 +02:00
$cluster [ 'GalaxyCluster' ][ 'orgc_id' ] = $user [ 'Organisation' ][ 'id' ];
2020-06-05 11:00:02 +02:00
2020-06-09 10:08:36 +02:00
if ( $user [ 'Role' ][ 'perm_sync' ]) {
if ( isset ( $cluster [ 'GalaxyCluster' ][ 'distribution' ]) && $cluster [ 'GalaxyCluster' ][ 'distribution' ] == 4 && ! $this -> SharingGroup -> checkIfAuthorised ( $user , $cluster [ 'GalaxyCluster' ][ 'sharing_group_id' ])) {
2020-06-09 11:01:25 +02:00
$errors [] = __ ( 'The sync user has to have access to the sharing group in order to be able to edit it' );
2020-07-07 08:16:46 +02:00
return $errors ;
2020-06-05 11:00:02 +02:00
}
}
2020-04-15 11:49:50 +02:00
$cluster [ 'GalaxyCluster' ][ 'type' ] = $galaxy [ 'type' ];
2020-06-09 10:08:36 +02:00
if ( ! isset ( $cluster [ 'GalaxyCluster' ][ 'version' ])) {
2020-04-15 11:49:50 +02:00
$date = new DateTime ();
$cluster [ 'GalaxyCluster' ][ 'version' ] = $date -> getTimestamp ();
}
2020-04-15 14:50:02 +02:00
$cluster [ 'GalaxyCluster' ][ 'tag_name' ] = sprintf ( 'misp-galaxy:%s="%s"' , $galaxy [ 'type' ], $cluster [ 'GalaxyCluster' ][ 'uuid' ]);
2020-04-15 11:49:50 +02:00
$this -> create ();
$saveSuccess = $this -> save ( $cluster );
2020-04-15 14:50:02 +02:00
if ( $saveSuccess ) {
2020-04-20 11:22:55 +02:00
$savedCluster = $this -> find ( 'first' , array (
'conditions' => array ( 'id' => $this -> id ),
2020-04-15 14:50:02 +02:00
'recursive' => - 1
));
2020-06-09 10:08:36 +02:00
if ( ! empty ( $cluster [ 'GalaxyCluster' ][ 'GalaxyElement' ])) {
$elementsToSave = array ();
foreach ( $cluster [ 'GalaxyCluster' ][ 'GalaxyElement' ] as $element ) { // transform cluster into Galaxy meta format
$elementsToSave [ $element [ 'key' ]][] = $element [ 'value' ];
}
$this -> GalaxyElement -> updateElements ( - 1 , $savedCluster [ 'GalaxyCluster' ][ 'id' ], $elementsToSave );
}
if ( ! empty ( $cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ])) {
2020-07-09 14:44:21 +02:00
$this -> GalaxyClusterRelation -> saveRelations ( $user , $cluster [ 'GalaxyCluster' ], $cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ], $captureTag = true );
2020-06-05 11:00:02 +02:00
}
2020-06-09 11:01:25 +02:00
} else {
2020-07-07 08:16:46 +02:00
foreach ( $this -> validationErrors as $validationError ) {
2020-06-09 11:01:25 +02:00
$errors [] = $validationError [ 0 ];
}
2020-04-15 14:50:02 +02:00
}
2020-06-09 11:01:25 +02:00
return $errors ;
2020-04-15 14:50:02 +02:00
}
2020-07-08 16:56:31 +02:00
/**
* editCluster Respecting ACL edits a cluster , its elements , relations and set correct fields where applicable
*
* @ param array $user
* @ param array $cluster
* @ param array $fieldList Only edit the fields provided
* @ param bool $deleteOldElements Should already existing element be deleted or not
* @ return array The errors if any
*/
public function editCluster ( array $user , array $cluster , array $fieldList = array (), $deleteOldElements = true )
2020-04-15 14:50:02 +02:00
{
2020-04-22 08:40:18 +02:00
$this -> SharingGroup = ClassRegistry :: init ( 'SharingGroup' );
2020-04-15 14:50:02 +02:00
$errors = array ();
if ( ! $user [ 'Role' ][ 'perm_galaxy_editor' ] && ! $user [ 'Role' ][ 'perm_site_admin' ]) {
$errors [] = __ ( 'Incorrect permission' );
}
if ( isset ( $cluster [ 'GalaxyCluster' ][ 'uuid' ])) {
$existingCluster = $this -> find ( 'first' , array ( 'conditions' => array ( 'GalaxyCluster.uuid' => $cluster [ 'GalaxyCluster' ][ 'uuid' ])));
} else {
$errors [] = __ ( 'UUID not provided' );
}
if ( empty ( $existingCluster )) {
$errors [] = __ ( 'Unkown UUID' );
} else {
// For users that are of the creating org of the cluster, always allow the edit
// For users that are sync users, only allow the edit if the cluster is locked
2020-07-08 16:56:31 +02:00
if (
$existingCluster [ 'GalaxyCluster' ][ 'orgc_id' ] === $user [ 'org_id' ] ||
( $user [ 'Role' ][ 'perm_sync' ] && $existingCluster [ 'GalaxyCluster' ][ 'locked' ]) || $user [ 'Role' ][ 'perm_site_admin' ]
) {
2020-04-15 14:50:02 +02:00
if ( $user [ 'Role' ][ 'perm_sync' ]) {
2020-07-08 16:56:31 +02:00
if (
isset ( $cluster [ 'GalaxyCluster' ][ 'distribution' ]) && $cluster [ 'GalaxyCluster' ][ 'distribution' ] == 4 && ! $this -> SharingGroup -> checkIfAuthorised ( $user , $cluster [ 'GalaxyCluster' ][ 'sharing_group_id' ])
) {
2020-04-15 14:50:02 +02:00
$errors [] = array ( __ ( 'Galaxy Cluster could not be saved: The sync user has to have access to the sharing group in order to be able to edit it.' ));
}
}
} else {
2020-05-07 15:15:14 +02:00
$errors [] = array ( __ ( 'Galaxy Cluster could not be saved: The user used to edit the cluster is not authorised to do so. This can be caused by the user not being of the same organisation as the original creator of the cluster whilst also not being a site administrator.' ));
2020-04-15 14:50:02 +02:00
}
$cluster [ 'GalaxyCluster' ][ 'id' ] = $existingCluster [ 'GalaxyCluster' ][ 'id' ];
if ( empty ( $errors )) {
$date = new DateTime ();
2020-06-09 10:08:36 +02:00
$cluster [ 'GalaxyCluster' ][ 'version' ] = $date -> getTimestamp ();
2020-04-15 14:50:02 +02:00
$cluster [ 'GalaxyCluster' ][ 'default' ] = false ;
2020-06-16 16:36:49 +02:00
if ( ! isset ( $cluster [ 'GalaxyCluster' ][ 'published' ])) {
$cluster [ 'GalaxyCluster' ][ 'published' ] = false ;
}
2020-11-12 10:09:46 +01:00
if ( isset ( $cluster [ 'GalaxyCluster' ][ 'distribution' ]) && $cluster [ 'GalaxyCluster' ][ 'distribution' ] != 4 ) {
2020-07-13 16:48:14 +02:00
$cluster [ 'GalaxyCluster' ][ 'sharing_group_id' ] = null ;
}
2020-05-04 16:20:09 +02:00
if ( empty ( $fieldList )) {
2020-06-16 16:36:49 +02:00
$fieldList = array ( 'value' , 'description' , 'version' , 'source' , 'authors' , 'distribution' , 'sharing_group_id' , 'default' , 'published' );
2020-05-04 16:20:09 +02:00
}
2020-04-15 14:50:02 +02:00
$saveSuccess = $this -> save ( $cluster , array ( 'fieldList' => $fieldList ));
if ( $saveSuccess ) {
2020-12-02 11:21:52 +01:00
if ( isset ( $cluster [ 'GalaxyCluster' ][ 'GalaxyElement' ])) {
2020-06-09 10:08:36 +02:00
$elementsToSave = array ();
foreach ( $cluster [ 'GalaxyCluster' ][ 'GalaxyElement' ] as $element ) { // transform cluster into Galaxy meta format
$elementsToSave [ $element [ 'key' ]][] = $element [ 'value' ];
}
$this -> GalaxyElement -> updateElements ( $cluster [ 'GalaxyCluster' ][ 'id' ], $cluster [ 'GalaxyCluster' ][ 'id' ], $elementsToSave , $delete = $deleteOldElements );
2020-04-21 10:11:26 +02:00
}
2020-06-09 10:36:00 +02:00
if ( ! empty ( $cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ])) {
2020-07-09 14:44:21 +02:00
$this -> GalaxyClusterRelation -> saveRelations ( $user , $cluster [ 'GalaxyCluster' ], $cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ], $captureTag = true , $force = true );
2020-06-09 10:08:36 +02:00
}
2020-04-15 14:50:02 +02:00
} else {
2020-07-07 08:16:46 +02:00
foreach ( $this -> validationErrors as $validationError ) {
2020-04-15 14:50:02 +02:00
$errors [] = $validationError [ 0 ];
}
}
}
}
return $errors ;
2020-04-15 11:49:50 +02:00
}
2020-11-23 19:38:19 +01:00
2020-07-08 16:56:31 +02:00
/**
* publishRouter
*
* @ param array $user
2020-07-09 16:29:31 +02:00
* @ param mixed $cluster
2020-07-08 16:56:31 +02:00
* @ param int | null $passAlong The server id from which the publish is issued
* @ return mixed The process id or the publish result depending on background jobs
*/
2020-07-09 16:29:31 +02:00
public function publishRouter ( array $user , $cluster , $passAlong = null )
2020-06-26 15:48:50 +02:00
{
if ( Configure :: read ( 'MISP.background_jobs' )) {
2020-06-29 16:25:58 +02:00
if ( is_numeric ( $cluster )) {
$clusterId = $cluster ;
} elseif ( isset ( $cluster [ 'GalaxyCluster' ])) {
$clusterId = $cluster [ 'GalaxyCluster' ][ 'id' ];
} else {
return false ;
}
2021-11-03 10:57:13 +01:00
/** @var Job $job */
2020-06-26 15:48:50 +02:00
$job = ClassRegistry :: init ( 'Job' );
2021-11-03 10:57:13 +01:00
$jobId = $job -> createJob (
'SYSTEM' ,
Job :: WORKER_PRIO ,
'publish_galaxy_clusters' ,
'Cluster ID: ' . $clusterId ,
'Publishing.'
2020-06-26 15:48:50 +02:00
);
2021-11-03 10:57:13 +01:00
return $this -> getBackgroundJobsTool () -> enqueue (
BackgroundJobsTool :: PRIO_QUEUE ,
BackgroundJobsTool :: CMD_EVENT ,
[
'publish_galaxy_clusters' ,
$clusterId ,
$jobId ,
$user [ 'id' ],
$passAlong
],
true ,
$jobId
2020-06-26 15:48:50 +02:00
);
2021-11-03 10:57:13 +01:00
2020-06-26 15:48:50 +02:00
} else {
$result = $this -> publish ( $cluster , $passAlong = $passAlong );
return $result ;
}
}
2020-07-08 16:56:31 +02:00
/**
* publish
*
2020-07-09 16:37:21 +02:00
* @ param mixed $cluster
2020-07-08 16:56:31 +02:00
* @ param int | null $passAlong The server id from which the publish is issued
* @ return bool The success of the publish operation
*/
2020-07-09 16:37:21 +02:00
public function publish ( $cluster , $passAlong = null )
2020-06-16 16:36:49 +02:00
{
2020-06-16 16:54:00 +02:00
if ( is_numeric ( $cluster )) {
2020-06-26 15:48:50 +02:00
$clusterId = $cluster ;
2020-06-16 16:54:00 +02:00
} elseif ( isset ( $cluster [ 'GalaxyCluster' ])) {
2020-06-26 15:48:50 +02:00
$clusterId = $cluster [ 'GalaxyCluster' ][ 'id' ];
}
2020-07-14 14:30:20 +02:00
$this -> id = $clusterId ;
$saved = $this -> saveField ( 'published' , True );
2020-11-12 11:05:58 +01:00
if ( $saved [ 'GalaxyCluster' ][ 'published' ]) {
$this -> uploadClusterToServersRouter ( $clusterId );
return true ;
2020-06-16 16:54:00 +02:00
}
return false ;
2020-06-16 16:36:49 +02:00
}
2020-07-09 16:37:21 +02:00
public function unpublish ( $cluster )
2020-06-16 16:36:49 +02:00
{
2020-06-16 16:54:00 +02:00
if ( is_numeric ( $cluster )) {
$this -> id = $cluster ;
} elseif ( isset ( $cluster [ 'GalaxyCluster' ])) {
2020-07-14 14:30:20 +02:00
$this -> id = $cluster [ 'GalaxyCluster' ][ 'id' ];
2020-06-16 16:54:00 +02:00
}
2020-07-14 14:30:20 +02:00
return $this -> saveField ( 'published' , False );
2020-06-16 16:36:49 +02:00
}
2020-11-23 19:38:19 +01:00
2020-07-13 12:48:11 +02:00
/**
* deleteCluster Delete the cluster . Also creates an entry in the cluster blocklist when hard - deleting
*
* @ param int $id
* @ param bool $hard
* @ return bool
*/
2020-07-13 12:34:58 +02:00
public function deleteCluster ( $id , $hard = false )
{
if ( $hard ) {
2020-07-13 12:48:11 +02:00
$cluster = $this -> find ( 'first' , array ( 'conditions' => array ( 'id' => $id ), 'recursive' => - 1 ));
$this -> GalaxyClusterBlocklist = ClassRegistry :: init ( 'GalaxyClusterBlocklist' );
$this -> GalaxyClusterBlocklist -> create ();
2020-09-23 16:21:17 +02:00
if ( ! empty ( $cluster [ 'GalaxyCluster' ][ 'orgc_id' ])) {
$orgc = $this -> Orgc -> find ( 'first' , array (
'conditions' => array ( 'Orgc.id' => $cluster [ 'GalaxyCluster' ][ 'orgc_id' ]),
'recursive' => - 1 ,
'fields' => array ( 'Orgc.name' )
));
} else {
$orgc = [ 'Orgc' => [ 'name' => 'MISP' ]];
}
2020-07-13 12:48:11 +02:00
$this -> GalaxyClusterBlocklist -> save ( array ( 'cluster_uuid' => $cluster [ 'GalaxyCluster' ][ 'uuid' ], 'cluster_info' => $cluster [ 'GalaxyCluster' ][ 'value' ], 'cluster_orgc' => $orgc [ 'Orgc' ][ 'name' ]));
$deleteResult = $this -> delete ( $id , true );
return $deleteResult ;
2020-07-13 12:34:58 +02:00
} else {
2020-11-13 11:50:06 +01:00
$version = ( new DateTime ()) -> getTimestamp ();
2020-07-13 12:34:58 +02:00
return $this -> save ( array (
'id' => $id ,
'published' => false ,
2020-11-13 11:50:06 +01:00
'version' => $version ,
2020-07-13 12:34:58 +02:00
'deleted' => true ,
2020-11-13 11:50:06 +01:00
), array ( 'fieldList' => array ( 'published' , 'deleted' , 'version' )));
2020-07-13 12:34:58 +02:00
}
}
public function restoreCluster ( $id )
{
2020-11-13 11:50:06 +01:00
$version = ( new DateTime ()) -> getTimestamp ();
2020-07-13 12:34:58 +02:00
return $this -> save ( array (
'id' => $id ,
'published' => false ,
2020-11-13 11:50:06 +01:00
'version' => $version ,
2020-07-13 12:34:58 +02:00
'deleted' => false ,
2020-11-13 11:50:06 +01:00
), array ( 'fieldList' => array ( 'published' , 'deleted' , 'version' )));
2020-07-13 12:34:58 +02:00
}
2021-03-01 15:56:04 +01:00
public function touchTimestamp ( $id )
{
$version = ( new DateTime ()) -> getTimestamp ();
return $this -> save ( array (
'id' => $id ,
'version' => $version ,
), array ( 'fieldList' => array ( 'version' )));
}
2021-04-21 12:53:05 +02:00
/**
* wipe_default Delete all default galaxy clusters and their associations .
* Relying on the cake ' s recursive deletion for the associations adds an non - negligible overhead .
* Same for cake ' s before / afterDelete callbacks . We do it by hand to speed up the process
*
*/
public function wipe_default ()
{
$clusters = $this -> find ( 'all' , [
'conditions' => [ 'default' => true ],
'fields' => [ 'id' , 'uuid' ]
]);
$cluster_ids = Hash :: extract ( $clusters , '{n}.GalaxyCluster.id' );
$cluster_uuids = Hash :: extract ( $clusters , '{n}.GalaxyCluster.uuid' );
$relation_ids = $this -> GalaxyClusterRelation -> find ( 'list' , [
'conditions' => [ 'galaxy_cluster_id' => $cluster_ids ],
'fields' => [ 'id' ]
]);
$this -> deleteAll ([ 'GalaxyCluster.default' => true ], false , false );
$this -> GalaxyElement -> deleteAll ([ 'GalaxyElement.galaxy_cluster_id' => $cluster_ids ], false , false );
$this -> GalaxyClusterRelation -> deleteAll ([ 'GalaxyClusterRelation.galaxy_cluster_id' => $cluster_ids ], false , false );
$this -> GalaxyClusterRelation -> updateAll (
[ 'GalaxyClusterRelation.referenced_galaxy_cluster_id' => 0 ],
[ 'GalaxyClusterRelation.referenced_galaxy_cluster_uuid' => $cluster_uuids ] // For all default clusters being referenced
);
$this -> GalaxyClusterRelation -> GalaxyClusterRelationTag -> deleteAll ([ 'GalaxyClusterRelationTag.galaxy_cluster_relation_id' => $relation_ids ], false , false );
$this -> Log = ClassRegistry :: init ( 'Log' );
$this -> Log -> createLogEntry ( 'SYSTEM' , 'wipe_default' , 'GalaxyCluster' , 0 , " Wiping default galaxy clusters " );
2021-06-04 00:11:55 +02:00
2021-04-21 12:53:05 +02:00
}
2020-07-08 16:56:31 +02:00
/**
* uploadClusterToServersRouter Upload the cluster to all remote servers
*
* @ param int $clusterId
* @ param int | null $passAlong The server id from which the publish is issued
* @ return bool the upload result
*/
2020-06-26 15:48:50 +02:00
private function uploadClusterToServersRouter ( $clusterId , $passAlong = null )
{
$clusterOrgcId = $this -> find ( 'first' , array (
'conditions' => array ( 'GalaxyCluster.id' => $clusterId ),
'recursive' => - 1 ,
'fields' => array ( 'GalaxyCluster.orgc_id' )
));
$elevatedUser = array (
'Role' => array (
'perm_site_admin' => 1 ,
2022-03-13 13:06:11 +01:00
'perm_sync' => 1 ,
'perm_audit' => 0 ,
2020-06-26 15:48:50 +02:00
),
'org_id' => $clusterOrgcId [ 'GalaxyCluster' ][ 'orgc_id' ]
);
$cluster = $this -> fetchGalaxyClusters ( $elevatedUser , array ( 'minimal' => true , 'conditions' => array ( 'id' => $clusterId )), $full = false );
if ( empty ( $cluster )) {
return true ;
}
$cluster = $cluster [ 0 ];
$this -> Server = ClassRegistry :: init ( 'Server' );
2020-07-08 16:56:31 +02:00
$conditions = array ( 'push' => 1 , 'push_galaxy_clusters' => 1 ); // Notice: Cluster will be pushed only for servers having both these conditions
2020-06-26 15:48:50 +02:00
if ( $passAlong ) {
$conditions [] = array ( 'Server.id !=' => $passAlong );
}
$servers = $this -> Server -> find ( 'all' , array (
'conditions' => $conditions ,
'order' => array ( 'Server.priority ASC' , 'Server.id ASC' )
));
// iterate over the servers and upload the event
if ( empty ( $servers )) {
return true ;
}
$uploaded = false ;
2022-03-13 13:06:11 +01:00
foreach ( $servers as $server ) {
2020-06-26 15:48:50 +02:00
if (( ! isset ( $server [ 'Server' ][ 'internal' ]) || ! $server [ 'Server' ][ 'internal' ]) && $cluster [ 'GalaxyCluster' ][ 'distribution' ] < 2 ) {
continue ;
}
$fakeSyncUser = array (
2020-07-02 15:14:02 +02:00
'id' => 0 ,
'email' => 'fakeSyncUser@user.test' ,
2020-06-26 15:48:50 +02:00
'org_id' => $server [ 'Server' ][ 'remote_org_id' ],
'Organisation' => array (
2020-07-02 15:14:02 +02:00
'id' => $server [ 'Server' ][ 'remote_org_id' ],
'name' => 'fakeSyncOrg' ,
2020-06-26 15:48:50 +02:00
),
'Role' => array (
2020-07-06 09:11:12 +02:00
'perm_site_admin' => 0 ,
'perm_sync' => 1
2020-06-26 15:48:50 +02:00
)
);
$cluster = $this -> fetchGalaxyClusters ( $fakeSyncUser , array ( 'conditions' => array ( 'GalaxyCluster.id' => $clusterId )), $full = true );
if ( empty ( $cluster )) {
2022-03-13 13:06:11 +01:00
continue ;
2020-06-26 15:48:50 +02:00
}
$cluster = $cluster [ 0 ];
2022-03-13 13:06:11 +01:00
$serverSync = new ServerSyncTool ( $server , $this -> setupSyncRequest ( $server ));
$result = $this -> uploadClusterToServer ( $cluster , $server , $serverSync , $fakeSyncUser );
if ( $result === 'Success' ) {
2020-06-26 15:48:50 +02:00
$uploaded = true ;
}
}
return $uploaded ;
}
2020-06-08 10:09:00 +02:00
public function unsetFieldsForExport ( $clusters )
{
foreach ( $clusters as $k => $cluster ) {
unset ( $clusters [ $k ][ 'GalaxyCluster' ][ 'galaxy_id' ]);
$modelsToUnset = array ( 'GalaxyCluster' , 'Galaxy' , 'Org' , 'Orgc' );
2020-07-07 08:16:46 +02:00
foreach ( $modelsToUnset as $modelName ) {
2020-06-08 10:09:00 +02:00
unset ( $clusters [ $k ][ $modelName ][ 'id' ]);
}
2020-06-12 15:09:54 +02:00
$modelsToUnset = array ( 'GalaxyClusterRelation' , 'TargetingClusterRelation' );
2020-07-07 08:16:46 +02:00
foreach ( $modelsToUnset as $modelName ) {
2021-04-27 16:49:52 +02:00
if ( ! empty ( $cluster [ 'GalaxyCluster' ][ $modelName ])) {
foreach ( $cluster [ 'GalaxyCluster' ][ $modelName ] as $i => $relation ) {
unset ( $clusters [ $k ][ 'GalaxyCluster' ][ $modelName ][ $i ][ 'id' ]);
unset ( $clusters [ $k ][ 'GalaxyCluster' ][ $modelName ][ $i ][ 'galaxy_cluster_id' ]);
unset ( $clusters [ $k ][ 'GalaxyCluster' ][ $modelName ][ $i ][ 'referenced_galaxy_cluster_id' ]);
if ( isset ( $relation [ 'Tag' ])) {
foreach ( $relation [ 'Tag' ] as $j => $tags ) {
unset ( $clusters [ $k ][ 'GalaxyCluster' ][ $modelName ][ $i ][ 'Tag' ][ $j ][ 'id' ]);
unset ( $clusters [ $k ][ 'GalaxyCluster' ][ $modelName ][ $i ][ 'Tag' ][ $j ][ 'org_id' ]);
unset ( $clusters [ $k ][ 'GalaxyCluster' ][ $modelName ][ $i ][ 'Tag' ][ $j ][ 'user_id' ]);
}
2020-06-08 10:09:00 +02:00
}
}
}
}
2020-07-07 08:16:46 +02:00
foreach ( $cluster [ 'GalaxyCluster' ][ 'GalaxyElement' ] as $i => $element ) {
2020-06-12 15:08:01 +02:00
unset ( $clusters [ $k ][ 'GalaxyCluster' ][ 'GalaxyElement' ][ $i ][ 'id' ]);
unset ( $clusters [ $k ][ 'GalaxyCluster' ][ 'GalaxyElement' ][ $i ][ 'galaxy_cluster_id' ]);
2020-06-08 10:09:00 +02:00
}
}
return $clusters ;
}
2020-05-20 10:33:33 +02:00
/**
* Gets a cluster then save it .
*
* @ param $user
* @ param array $cluster Cluster to be saved
2020-07-10 15:06:55 +02:00
* @ param bool $fromPull If the current capture is performed from a PULL sync
* @ param int $orgId The organisation id that should own the cluster
2020-05-27 09:35:27 +02:00
* @ param array $server The server for which to capture is ongoing
2020-07-13 16:48:14 +02:00
* @ return array Result of the capture including successes , fails and errors
2020-05-20 10:33:33 +02:00
*/
2020-05-27 09:35:27 +02:00
public function captureCluster ( $user , $cluster , $fromPull = false , $orgId = 0 , $server = false )
2020-05-20 10:33:33 +02:00
{
$results = array ( 'success' => false , 'imported' => 0 , 'ignored' => 0 , 'failed' => 0 , 'errors' => array ());
if ( $fromPull ) {
$cluster [ 'GalaxyCluster' ][ 'org_id' ] = $orgId ;
} else {
$cluster [ 'GalaxyCluster' ][ 'org_id' ] = $user [ 'Organisation' ][ 'id' ];
}
2020-07-13 16:48:14 +02:00
$this -> GalaxyClusterBlocklist = ClassRegistry :: init ( 'GalaxyClusterBlocklist' );
if ( $this -> GalaxyClusterBlocklist -> checkIfBlocked ( $cluster [ 'GalaxyCluster' ][ 'uuid' ])) {
$results [ 'errors' ][] = __ ( 'Blocked by blocklist' );
$results [ 'ignored' ] ++ ;
return $results ;
}
2020-05-20 10:33:33 +02:00
if ( ! isset ( $cluster [ 'GalaxyCluster' ][ 'orgc_id' ]) && ! isset ( $cluster [ 'Orgc' ])) {
$cluster [ 'GalaxyCluster' ][ 'orgc_id' ] = $cluster [ 'GalaxyCluster' ][ 'org_id' ];
} else {
if ( ! isset ( $cluster [ 'GalaxyCluster' ][ 'Orgc' ])) {
if ( isset ( $cluster [ 'GalaxyCluster' ][ 'orgc_id' ]) && $cluster [ 'GalaxyCluster' ][ 'orgc_id' ] != $user [ 'org_id' ] && ! $user [ 'Role' ][ 'perm_sync' ] && ! $user [ 'Role' ][ 'perm_site_admin' ]) {
2020-06-15 15:00:58 +02:00
$cluster [ 'GalaxyCluster' ][ 'orgc_id' ] = $cluster [ 'GalaxyCluster' ][ 'org_id' ]; // Only sync user can create cluster on behalf of other users
2020-05-20 10:33:33 +02:00
}
} else {
if ( $cluster [ 'GalaxyCluster' ][ 'Orgc' ][ 'uuid' ] != $user [ 'Organisation' ][ 'uuid' ] && ! $user [ 'Role' ][ 'perm_sync' ] && ! $user [ 'Role' ][ 'perm_site_admin' ]) {
2020-06-15 15:00:58 +02:00
$cluster [ 'GalaxyCluster' ][ 'orgc_id' ] = $cluster [ 'GalaxyCluster' ][ 'org_id' ]; // Only sync user can create cluster on behalf of other users
2020-05-20 10:33:33 +02:00
}
}
if ( isset ( $cluster [ 'GalaxyCluster' ][ 'orgc_id' ]) && $cluster [ 'GalaxyCluster' ][ 'orgc_id' ] != $user [ 'org_id' ] && ! $user [ 'Role' ][ 'perm_sync' ] && ! $user [ 'Role' ][ 'perm_site_admin' ]) {
2020-06-15 15:00:58 +02:00
$cluster [ 'GalaxyCluster' ][ 'orgc_id' ] = $cluster [ 'GalaxyCluster' ][ 'org_id' ]; // Only sync user can create cluster on behalf of other users
2020-05-20 10:33:33 +02:00
}
}
2020-09-22 14:02:44 +02:00
if ( ! Configure :: check ( 'MISP.enableOrgBlocklisting' ) || Configure :: read ( 'MISP.enableOrgBlocklisting' ) !== false ) {
$this -> OrgBlocklist = ClassRegistry :: init ( 'OrgBlocklist' );
2020-05-20 10:33:33 +02:00
if ( ! isset ( $cluster [ 'GalaxyCluster' ][ 'Orgc' ][ 'uuid' ])) {
$orgc = $this -> Orgc -> find ( 'first' , array ( 'conditions' => array ( 'Orgc.id' => $cluster [ 'GalaxyCluster' ][ 'orgc_id' ]), 'fields' => array ( 'Orgc.uuid' ), 'recursive' => - 1 ));
} else {
$orgc = array ( 'Orgc' => array ( 'uuid' => $cluster [ 'GalaxyCluster' ][ 'Orgc' ][ 'uuid' ]));
}
2020-09-22 14:02:44 +02:00
if ( $cluster [ 'GalaxyCluster' ][ 'orgc_id' ] != 0 && $this -> OrgBlocklist -> hasAny ( array ( 'OrgBlocklist.org_uuid' => $orgc [ 'Orgc' ][ 'uuid' ]))) {
$results [ 'errors' ][] = __ ( 'Organisation blocklisted (%s)' , $orgc [ 'Orgc' ][ 'uuid' ]);
2020-07-08 16:56:31 +02:00
$results [ 'ignored' ] ++ ;
2020-05-20 10:33:33 +02:00
return $results ;
}
}
2020-06-26 15:48:50 +02:00
if ( $cluster [ 'GalaxyCluster' ][ 'default' ]) {
2020-07-08 16:56:31 +02:00
$results [ 'errors' ][] = __ ( 'Only non-default clusters can be saved' );
2020-06-26 15:48:50 +02:00
$results [ 'failed' ] ++ ;
return $results ;
}
2020-05-20 10:33:33 +02:00
$cluster = $this -> captureOrganisationAndSG ( $cluster , 'GalaxyCluster' , $user );
2020-05-26 15:08:24 +02:00
$existingGalaxyCluster = $this -> find ( 'first' , array ( 'conditions' => array (
'GalaxyCluster.uuid' => $cluster [ 'GalaxyCluster' ][ 'uuid' ]
)));
2020-06-05 11:00:02 +02:00
$cluster [ 'GalaxyCluster' ][ 'tag_name' ] = sprintf ( 'misp-galaxy:%s="%s"' , $cluster [ 'GalaxyCluster' ][ 'type' ], $cluster [ 'GalaxyCluster' ][ 'uuid' ]);
2020-07-13 16:48:14 +02:00
if ( ! isset ( $cluster [ 'GalaxyCluster' ][ 'distribution' ])) {
$cluster [ 'GalaxyCluster' ][ 'distribution' ] = Configure :: read ( 'MISP.default_event_distribution' ); // use default event distribution
}
if ( $cluster [ 'GalaxyCluster' ][ 'distribution' ] != 4 ) {
$cluster [ 'GalaxyCluster' ][ 'sharing_group_id' ] = null ;
}
2020-06-16 16:36:49 +02:00
if ( ! isset ( $cluster [ 'GalaxyCluster' ][ 'published' ])) {
$cluster [ 'GalaxyCluster' ][ 'published' ] = false ;
}
2020-05-26 15:08:24 +02:00
if ( empty ( $existingGalaxyCluster )) {
2020-06-11 14:26:00 +02:00
$galaxy = $this -> Galaxy -> captureGalaxy ( $user , $cluster [ 'GalaxyCluster' ][ 'Galaxy' ]);
$cluster [ 'GalaxyCluster' ][ 'galaxy_id' ] = $galaxy [ 'Galaxy' ][ 'id' ];
2020-07-10 10:57:40 +02:00
unset ( $cluster [ 'GalaxyCluster' ][ 'id' ]);
2020-05-26 15:08:24 +02:00
$this -> create ();
$saveSuccess = $this -> save ( $cluster );
} else {
2020-07-10 14:04:21 +02:00
if ( ! $existingGalaxyCluster [ 'GalaxyCluster' ][ 'locked' ] && empty ( $server [ 'Server' ][ 'internal' ])) {
2020-05-27 09:35:27 +02:00
$results [ 'errors' ][] = __ ( 'Blocked an edit to an cluster that was created locally. This can happen if a synchronised cluster that was created on this instance was modified by an administrator on the remote side.' );
$results [ 'failed' ] ++ ;
return $results ;
}
2020-05-26 15:08:24 +02:00
if ( $cluster [ 'GalaxyCluster' ][ 'version' ] > $existingGalaxyCluster [ 'GalaxyCluster' ][ 'version' ]) {
$cluster [ 'GalaxyCluster' ][ 'id' ] = $existingGalaxyCluster [ 'GalaxyCluster' ][ 'id' ];
$saveSuccess = $this -> save ( $cluster );
} else {
2020-06-08 11:10:59 +02:00
$results [ 'errors' ][] = __ ( 'Remote version is not newer than local one for cluster (%s)' , $cluster [ 'GalaxyCluster' ][ 'uuid' ]);
2020-05-26 15:08:24 +02:00
$results [ 'ignored' ] ++ ;
return $results ;
}
}
2020-05-20 10:33:33 +02:00
if ( $saveSuccess ) {
2020-05-25 10:04:07 +02:00
$results [ 'imported' ] ++ ;
2020-05-20 10:33:33 +02:00
$savedCluster = $this -> find ( 'first' , array (
2020-07-10 10:57:40 +02:00
'conditions' => array ( 'uuid' => $cluster [ 'GalaxyCluster' ][ 'uuid' ]),
2020-05-20 10:33:33 +02:00
'recursive' => - 1
));
2020-06-10 09:37:25 +02:00
if ( ! empty ( $cluster [ 'GalaxyCluster' ][ 'GalaxyElement' ])) {
2020-11-13 08:59:55 +01:00
$this -> GalaxyElement -> deleteAll ( array ( 'GalaxyElement.galaxy_cluster_id' => $savedCluster [ 'GalaxyCluster' ][ 'id' ]));
2020-07-07 08:16:46 +02:00
$this -> GalaxyElement -> captureElements ( $user , $cluster [ 'GalaxyCluster' ][ 'GalaxyElement' ], $savedCluster [ 'GalaxyCluster' ][ 'id' ]);
2020-05-20 10:33:33 +02:00
}
2020-06-10 09:37:25 +02:00
if ( ! empty ( $cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ])) {
2021-03-01 15:57:17 +01:00
$this -> GalaxyClusterRelation -> deleteAll ( array ( 'GalaxyClusterRelation.galaxy_cluster_id' => $savedCluster [ 'GalaxyCluster' ][ 'id' ]));
2020-07-07 08:16:46 +02:00
$saveResult = $this -> GalaxyClusterRelation -> captureRelations ( $user , $savedCluster , $cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ], $fromPull = $fromPull );
2020-05-20 10:33:33 +02:00
if ( $saveResult [ 'failed' ] > 0 ) {
$results [ 'errors' ][] = __ ( 'Issues while capturing relations have been logged.' );
}
}
2020-06-26 15:48:50 +02:00
if ( $savedCluster [ 'GalaxyCluster' ][ 'published' ]) {
2021-02-18 14:11:34 +01:00
$passAlong = isset ( $server [ 'Server' ][ 'id' ]) ? $server [ 'Server' ][ 'id' ] : null ;
$this -> publishRouter ( $user , $savedCluster [ 'GalaxyCluster' ][ 'id' ], $passAlong );
2020-06-26 15:48:50 +02:00
}
2020-05-20 10:33:33 +02:00
} else {
$results [ 'failed' ] ++ ;
2020-07-07 08:16:46 +02:00
foreach ( $this -> validationErrors as $validationError ) {
2020-05-20 10:33:33 +02:00
$results [ 'errors' ][] = $validationError [ 0 ];
}
}
2020-06-25 10:47:54 +02:00
$results [ 'success' ] = $results [ 'imported' ] > 0 ;
2020-05-20 10:33:33 +02:00
return $results ;
}
public function captureOrganisationAndSG ( $element , $model , $user )
{
$this -> Event = ClassRegistry :: init ( 'Event' );
if ( isset ( $element [ $model ][ 'distribution' ]) && $element [ $model ][ 'distribution' ] == 4 ) {
2021-03-17 16:31:36 +01:00
$element [ $model ] = $this -> Event -> captureSGForElement ( $element [ $model ], $user );
2020-05-20 10:33:33 +02:00
}
// first we want to see how the creator organisation is encoded
// The options here are either by passing an organisation object along or simply passing a string along
2020-06-12 10:59:57 +02:00
if ( isset ( $element [ $model ][ 'Orgc' ])) {
$element [ $model ][ 'orgc_id' ] = $this -> Orgc -> captureOrg ( $element [ $model ][ 'Orgc' ], $user );
unset ( $element [ $model ][ 'Orgc' ]);
2020-05-20 10:33:33 +02:00
} else {
// Can't capture the Orgc, default to the current user
$element [ $model ][ 'orgc_id' ] = $user [ 'org_id' ];
}
return $element ;
}
2021-03-01 22:41:38 +01:00
/**
* @ param array $user
* @ param array $clusters
* @ return void
*/
public function attachExtendByInfo ( array $user , array & $clusters )
2020-04-15 15:35:52 +02:00
{
2021-03-01 22:41:38 +01:00
if ( empty ( $clusters )) {
return ;
}
$clusterUuids = array_column ( array_column ( $clusters , 'GalaxyCluster' ), 'uuid' );
$extensions = $this -> fetchGalaxyClusters ( $user , [
'conditions' => [ 'extends_uuid' => $clusterUuids ],
]);
foreach ( $clusters as & $cluster ) {
$extendedBy = [];
foreach ( $extensions as $extension ) {
if ( $cluster [ 'GalaxyCluster' ][ 'uuid' ] === $extension [ 'GalaxyCluster' ][ 'extends_uuid' ]) {
$extendedBy [] = $extension ;
}
}
$cluster [ 'GalaxyCluster' ][ 'extended_by' ] = $extendedBy ;
}
2020-04-15 15:35:52 +02:00
}
public function attachExtendFromInfo ( $user , $cluster )
{
if ( ! empty ( $cluster [ 'GalaxyCluster' ][ 'extends_uuid' ])) {
$extensions = $this -> fetchGalaxyClusters ( $user , array ( 'conditions' => array ( 'uuid' => $cluster [ 'GalaxyCluster' ][ 'extends_uuid' ])));
if ( ! empty ( $extensions )) {
$cluster [ 'GalaxyCluster' ][ 'extended_from' ] = $extensions [ 0 ];
} else {
$cluster [ 'GalaxyCluster' ][ 'extended_from' ] = array ();
}
}
return $cluster ;
}
2018-07-19 11:48:22 +02:00
/* Return a list of all tags associated with the cluster specific cluster within the galaxy ( or all clusters if $clusterValue is false )
* The counts are restricted to the event IDs that the user is allowed to see .
*/
public function getTags ( $galaxyType , $clusterValue = false , $user )
{
$this -> Event = ClassRegistry :: init ( 'Event' );
2021-04-21 09:09:29 +02:00
$event_ids = $this -> Event -> fetchEventIds ( $user , [
'list' => true
]);
2018-07-19 11:48:22 +02:00
$tags = $this -> Event -> EventTag -> Tag -> find ( 'list' , array (
'conditions' => array ( 'name LIKE' => 'misp-galaxy:' . $galaxyType . '="' . ( $clusterValue ? $clusterValue : '%' ) . '"' ),
'fields' => array ( 'name' , 'id' ),
));
$this -> Event -> EventTag -> virtualFields [ 'tag_count' ] = 'COUNT(id)' ;
$tagCounts = $this -> Event -> EventTag -> find ( 'list' , array (
'conditions' => array ( 'EventTag.tag_id' => array_values ( $tags ), 'EventTag.event_id' => $event_ids ),
'fields' => array ( 'EventTag.tag_id' , 'EventTag.tag_count' ),
'group' => array ( 'EventTag.tag_id' )
));
foreach ( $tags as $k => $v ) {
if ( isset ( $tagCounts [ $v ])) {
$tags [ $k ] = array ( 'count' => $tagCounts [ $v ], 'tag_id' => $v );
} else {
unset ( $tags [ $k ]);
}
}
return $tags ;
}
2016-12-09 07:58:03 +01:00
2020-12-18 19:30:59 +01:00
/**
2021-02-11 09:39:45 +01:00
* @ param string | int $name Cluster name or ID
2020-12-18 19:30:59 +01:00
* @ param array $user
* @ return array | mixed
*/
2020-03-12 10:26:09 +01:00
public function getCluster ( $name , $user )
2018-07-19 11:48:22 +02:00
{
2018-11-23 14:11:33 +01:00
if ( isset ( $this -> __clusterCache [ $name ])) {
return $this -> __clusterCache [ $name ];
}
2019-10-18 16:13:26 +02:00
if ( is_numeric ( $name )) {
2021-02-11 09:39:45 +01:00
$conditions = array ( 'GalaxyCluster.id' => $name );
2019-10-18 16:13:26 +02:00
} else {
2021-02-11 09:39:45 +01:00
$isGalaxyTag = strpos ( $name , 'misp-galaxy:' ) === 0 ;
if ( ! $isGalaxyTag ) {
return null ;
}
2021-02-22 10:33:16 +01:00
$conditions = array ( 'GalaxyCluster.tag_name' => $name );
2019-10-18 16:13:26 +02:00
}
2020-06-18 15:26:03 +02:00
$cluster = $this -> fetchGalaxyClusters ( $user , array (
2018-07-19 11:48:22 +02:00
'conditions' => $conditions ,
2020-06-18 15:26:03 +02:00
'first' => true
), true );
2019-10-18 16:13:26 +02:00
2018-07-19 11:48:22 +02:00
if ( ! empty ( $cluster )) {
2019-10-18 16:13:26 +02:00
$cluster = $this -> postprocess ( $cluster );
}
2020-04-09 14:26:48 +02:00
if ( ! empty ( $cluster ) && $cluster [ 'GalaxyCluster' ][ 'default' ]) { // only cache default clusters
2020-03-12 10:26:09 +01:00
$this -> __clusterCache [ $name ] = $cluster ;
}
2019-10-18 16:13:26 +02:00
return $cluster ;
}
2020-11-18 16:50:31 +01:00
/**
* @ param array $namesOrIds Cluster tag names or cluster IDs
* @ param array $user
* @ param bool $postProcess If true , self :: postprocess method will be called .
* @ param bool $fetchFullCluster
* @ return array
*/
2021-02-21 16:26:02 +01:00
public function getClusters ( array $namesOrIds , array $user , $postProcess = true , $fetchFullCluster = true )
2020-03-12 10:26:09 +01:00
{
2020-11-18 16:50:31 +01:00
if ( count ( array_filter ( $namesOrIds , 'is_numeric' )) === count ( $namesOrIds )) { // all elements are numeric
2021-02-21 16:26:02 +01:00
$conditions = array ( 'GalaxyCluster.id' => $namesOrIds );
2020-03-12 10:26:09 +01:00
} else {
2021-02-22 10:33:16 +01:00
$conditions = array ( 'GalaxyCluster.tag_name' => $namesOrIds );
2021-02-21 16:26:02 +01:00
}
$options = [ 'conditions' => $conditions ];
if ( ! $fetchFullCluster ) {
2021-02-23 22:06:29 +01:00
$options [ 'contain' ] = [ 'Galaxy' , 'GalaxyElement' ];
2020-03-12 10:26:09 +01:00
}
2021-02-21 16:26:02 +01:00
$clusters = $this -> fetchGalaxyClusters ( $user , $options , $fetchFullCluster );
2020-03-12 10:26:09 +01:00
if ( ! empty ( $clusters ) && $postProcess ) {
2021-02-21 16:26:02 +01:00
$tagNames = array_map ( 'strtolower' , array_column ( array_column ( $clusters , 'GalaxyCluster' ), 'tag_name' ));
$tagIds = $this -> Tag -> find ( 'list' , [
'conditions' => [ 'LOWER(Tag.name)' => $tagNames ],
'recursive' => - 1 ,
'fields' => array ( 'Tag.name' , 'Tag.id' ),
]);
$tagIds = array_change_key_case ( $tagIds );
2020-06-18 15:26:03 +02:00
foreach ( $clusters as $k => $cluster ) {
2021-02-21 16:26:02 +01:00
$tagName = strtolower ( $cluster [ 'GalaxyCluster' ][ 'tag_name' ]);
$clusters [ $k ] = $this -> postprocess ( $cluster , isset ( $tagIds [ $tagName ]) ? $tagIds [ $tagName ] : null );
2020-06-18 15:26:03 +02:00
}
2020-03-12 10:26:09 +01:00
}
return $clusters ;
}
2020-04-09 14:26:48 +02:00
public function buildConditions ( $user )
{
$conditions = array ();
if ( ! $user [ 'Role' ][ 'perm_site_admin' ]) {
2022-05-22 17:09:00 +02:00
$sgids = $this -> SharingGroup -> authorizedIds ( $user );
2020-06-09 12:57:56 +02:00
$alias = $this -> alias ;
2020-04-09 14:26:48 +02:00
$conditions [ 'AND' ][ 'OR' ] = array (
2020-06-09 12:57:56 +02:00
" ${ alias } .org_id " => $user [ 'org_id' ],
2020-04-09 14:26:48 +02:00
array (
'AND' => array (
2020-06-09 12:57:56 +02:00
" ${ alias } .distribution > " => 0 ,
" ${ alias } .distribution < " => 4
2020-04-09 14:26:48 +02:00
),
),
array (
'AND' => array (
2020-06-09 12:57:56 +02:00
" ${ alias } .sharing_group_id " => $sgids ,
" ${ alias } .distribution " => 4
2020-04-09 14:26:48 +02:00
)
)
);
}
return $conditions ;
}
2020-07-08 16:56:31 +02:00
/**
* fetchGalaxyClusters Very flexible , it ' s basically a replacement for find , with the addition that it restricts access based on user
*
* @ param mixed $user
* @ param mixed $options
* @ param bool $full
* @ return array
*/
public function fetchGalaxyClusters ( array $user , array $options , $full = false )
2020-04-14 15:14:18 +02:00
{
$params = array (
'conditions' => $this -> buildConditions ( $user ),
'recursive' => - 1
);
2020-04-22 08:40:18 +02:00
if ( $full ) {
2020-05-06 07:59:57 +02:00
$params [ 'contain' ] = array (
2020-05-11 16:25:53 +02:00
'Galaxy' ,
2020-05-06 07:59:57 +02:00
'GalaxyElement' ,
2020-06-12 14:07:30 +02:00
'GalaxyClusterRelation' => array (
2020-09-25 11:13:26 +02:00
'conditions' => $this -> GalaxyClusterRelation -> buildConditions ( $user , false ),
2021-02-24 18:05:59 +01:00
'GalaxyClusterRelationTag' ,
2020-09-25 11:13:26 +02:00
'SharingGroup' ,
2020-06-12 14:07:30 +02:00
),
2020-05-06 07:59:57 +02:00
'Orgc' ,
'Org' ,
'SharingGroup'
);
2020-04-22 08:40:18 +02:00
}
2020-04-15 11:49:50 +02:00
if ( ! empty ( $options [ 'contain' ])) {
$params [ 'contain' ] = $options [ 'contain' ];
}
2020-04-14 15:14:18 +02:00
if ( isset ( $options [ 'fields' ])) {
$params [ 'fields' ] = $options [ 'fields' ];
}
if ( isset ( $options [ 'conditions' ])) {
$params [ 'conditions' ][ 'AND' ][] = $options [ 'conditions' ];
}
if ( isset ( $options [ 'group' ])) {
2020-06-17 15:01:23 +02:00
$params [ 'group' ] = $options [ 'group' ];
}
if ( isset ( $options [ 'order' ])) {
$params [ 'order' ] = $options [ 'order' ];
2020-04-14 15:14:18 +02:00
}
2020-05-26 11:17:58 +02:00
if ( isset ( $options [ 'page' ])) {
$params [ 'page' ] = $options [ 'page' ];
}
if ( isset ( $options [ 'limit' ])) {
$params [ 'limit' ] = $options [ 'limit' ];
}
2020-06-17 15:01:23 +02:00
if ( isset ( $options [ 'list' ]) && $options [ 'list' ]) {
return $this -> find ( 'list' , $params );
}
2021-11-06 11:56:40 +01:00
2020-06-17 15:01:23 +02:00
if ( isset ( $options [ 'first' ]) && $options [ 'first' ]) {
$clusters = $this -> find ( 'first' , $params );
2020-11-19 18:17:20 +01:00
} else if ( isset ( $options [ 'count' ]) && $options [ 'count' ]) {
2021-11-06 11:56:40 +01:00
return $this -> find ( 'count' , $params );
2020-06-17 15:01:23 +02:00
} else {
$clusters = $this -> find ( 'all' , $params );
}
2021-11-06 11:56:40 +01:00
2020-11-18 16:50:31 +01:00
if ( empty ( $clusters )) {
return $clusters ;
}
2021-02-24 18:05:59 +01:00
2021-11-06 11:56:40 +01:00
if ( isset ( $options [ 'first' ]) && $options [ 'first' ]) {
$clusters = [ $clusters ];
}
2021-02-24 18:05:59 +01:00
if ( $full ) {
$clusterIds = array_column ( array_column ( $clusters , 'GalaxyCluster' ), 'id' );
$targetingClusterRelations = $this -> TargetingClusterRelation -> fetchRelations ( $user , array (
'contain' => array (
'GalaxyClusterRelationTag' ,
'SharingGroup' ,
),
'conditions' => array (
'TargetingClusterRelation.referenced_galaxy_cluster_id' => $clusterIds ,
)
));
$tagsToFetch = Hash :: extract ( $clusters , " { n}.GalaxyClusterRelation. { n}.GalaxyClusterRelationTag. { n}.tag_id " );
$tagsToFetch = array_merge ( $tagsToFetch , Hash :: extract ( $targetingClusterRelations , " GalaxyClusterRelationTag. { n}.tag_id " ));
2021-11-06 11:56:40 +01:00
if ( ! empty ( $tagsToFetch )) {
$tags = $this -> GalaxyClusterRelation -> GalaxyClusterRelationTag -> Tag -> find ( 'all' , [
2022-05-18 10:06:17 +02:00
'conditions' => [ 'id' => array_unique ( $tagsToFetch , SORT_REGULAR )],
2021-11-06 11:56:40 +01:00
'recursive' => - 1 ,
]);
$tags = array_column ( array_column ( $tags , 'Tag' ), null , 'id' );
} else {
$tags = [];
}
2021-02-24 18:05:59 +01:00
foreach ( $targetingClusterRelations as $k => $targetingClusterRelation ) {
if ( ! empty ( $targetingClusterRelation [ 'GalaxyClusterRelationTag' ])) {
foreach ( $targetingClusterRelation [ 'GalaxyClusterRelationTag' ] as $relationTag ) {
if ( isset ( $tags [ $relationTag [ 'tag_id' ]])) {
$targetingClusterRelation [ 'TargetingClusterRelation' ][ 'Tag' ][] = $tags [ $relationTag [ 'tag_id' ]];
}
}
}
unset ( $targetingClusterRelation [ 'GalaxyClusterRelationTag' ]);
if ( ! empty ( $targetingClusterRelation [ 'SharingGroup' ][ 'id' ])) {
$targetingClusterRelation [ 'TargetingClusterRelation' ][ 'SharingGroup' ] = $targetingClusterRelation [ 'SharingGroup' ];
}
$targetingClusterRelations [ $k ] = $targetingClusterRelation [ 'TargetingClusterRelation' ];
}
}
2020-07-02 15:14:02 +02:00
$this -> Event = ClassRegistry :: init ( 'Event' );
2020-07-06 09:11:12 +02:00
$sharingGroupData = $this -> Event -> __cacheSharingGroupData ( $user , false );
2020-05-06 07:59:57 +02:00
foreach ( $clusters as $i => $cluster ) {
2020-07-02 15:14:02 +02:00
if ( ! empty ( $cluster [ 'GalaxyCluster' ][ 'sharing_group_id' ]) && isset ( $sharingGroupData [ $cluster [ 'GalaxyCluster' ][ 'sharing_group_id' ]])) {
2021-10-17 12:43:30 +02:00
$clusters [ $i ][ 'SharingGroup' ] = $sharingGroupData [ $cluster [ 'GalaxyCluster' ][ 'sharing_group_id' ]];
2020-07-02 15:14:02 +02:00
}
if ( isset ( $cluster [ 'GalaxyClusterRelation' ])) {
foreach ( $cluster [ 'GalaxyClusterRelation' ] as $j => $relation ) {
if ( ! empty ( $relation [ 'sharing_group_id' ]) && isset ( $sharingGroupData [ $relation [ 'sharing_group_id' ]])) {
2021-10-17 12:43:30 +02:00
$clusters [ $i ][ 'GalaxyClusterRelation' ][ $j ][ 'SharingGroup' ] = $sharingGroupData [ $relation [ 'sharing_group_id' ]];
2020-07-02 15:14:02 +02:00
}
2021-02-24 18:05:59 +01:00
foreach ( $relation [ 'GalaxyClusterRelationTag' ] as $relationTag ) {
if ( isset ( $tags [ $relationTag [ 'tag_id' ]])) {
$clusters [ $i ][ 'GalaxyClusterRelation' ][ $j ][ 'Tag' ][] = $tags [ $relationTag [ 'tag_id' ]];
}
}
unset ( $clusters [ $i ][ 'GalaxyClusterRelation' ][ $j ][ 'GalaxyClusterRelationTag' ]);
2020-07-02 15:14:02 +02:00
}
}
2021-02-24 18:05:59 +01:00
if ( $full ) {
foreach ( $targetingClusterRelations as $targetingClusterRelation ) {
if ( $targetingClusterRelation [ 'referenced_galaxy_cluster_id' ] == $cluster [ 'GalaxyCluster' ][ 'id' ]) {
$clusters [ $i ][ 'TargetingClusterRelation' ][] = $targetingClusterRelation ;
2020-09-25 11:13:26 +02:00
}
}
}
2020-06-12 15:08:01 +02:00
$clusters [ $i ] = $this -> arrangeData ( $clusters [ $i ]);
2020-05-04 16:20:09 +02:00
}
2021-11-06 11:56:40 +01:00
if ( isset ( $options [ 'first' ]) && $options [ 'first' ]) {
return $clusters [ 0 ];
}
2020-05-06 07:59:57 +02:00
return $clusters ;
2020-04-14 15:14:18 +02:00
}
2020-07-08 16:56:31 +02:00
public function restSearch ( array $user , $returnFormat , $filters , $paramsOnly = false , $jobId = false , & $elementCounter = 0 )
2020-05-26 11:17:58 +02:00
{
if ( ! isset ( $this -> validFormats [ $returnFormat ][ 1 ])) {
throw new NotFoundException ( 'Invalid output format.' );
}
App :: uses ( $this -> validFormats [ $returnFormat ][ 1 ], 'Export' );
$exportTool = new $this -> validFormats [ $returnFormat ][ 1 ]();
$conditions = $this -> buildFilterConditions ( $user , $filters );
$params = array (
'conditions' => $conditions ,
2020-06-08 16:40:08 +02:00
'full' => ! empty ( $filters [ 'full' ]) ? $filters [ 'full' ] : ( ! empty ( $filters [ 'minimal' ]) ? ! $filters [ 'minimal' ] : true ),
'minimal' => ! empty ( $filters [ 'minimal' ]) ? $filters [ 'minimal' ] : ( ! empty ( $filters [ 'full' ]) ? ! $filters [ 'full' ] : false ),
2020-05-26 11:17:58 +02:00
);
if ( isset ( $filters [ 'limit' ])) {
$params [ 'limit' ] = $filters [ 'limit' ];
if ( ! isset ( $filters [ 'page' ])) {
$filters [ 'page' ] = 1 ;
}
}
if ( isset ( $filters [ 'page' ])) {
$params [ 'page' ] = $filters [ 'page' ];
}
$default_cluster_memory_coefficient = 80 ;
2020-06-08 16:40:08 +02:00
if ( $params [ 'full' ]) {
2020-07-08 16:56:31 +02:00
$default_cluster_memory_coefficient = 0.5 ; // Complete cluster can be massive
2020-05-26 11:17:58 +02:00
}
2020-06-08 16:40:08 +02:00
if ( $params [ 'minimal' ]) {
2020-05-26 11:17:58 +02:00
$default_cluster_memory_coefficient = 100 ;
$params [ 'fields' ] = array ( 'uuid' , 'version' );
}
if ( $paramsOnly ) {
return $params ;
}
if ( method_exists ( $exportTool , 'modify_params' )) {
$params = $exportTool -> modify_params ( $user , $params );
}
$exportToolParams = array (
'user' => $user ,
'params' => $params ,
'returnFormat' => $returnFormat ,
'scope' => 'GalaxyCluster' ,
'filters' => $filters
);
if ( ! empty ( $exportTool -> additional_params )) {
$params = array_merge_recursive (
$params ,
$exportTool -> additional_params
);
}
2020-11-23 19:38:19 +01:00
2021-01-17 18:16:02 +01:00
$tmpfile = new TmpFileTool ();
$tmpfile -> write ( $exportTool -> header ( $exportToolParams ));
2020-05-29 10:47:21 +02:00
$loop = false ;
2020-05-26 11:17:58 +02:00
if ( empty ( $params [ 'limit' ])) {
$memory_in_mb = $this -> convert_to_memory_limit_to_mb ( ini_get ( 'memory_limit' ));
$memory_scaling_factor = $default_cluster_memory_coefficient / 10 ;
$params [ 'limit' ] = intval ( $memory_in_mb * $memory_scaling_factor );
2020-05-29 10:47:21 +02:00
$loop = true ;
2020-05-26 11:17:58 +02:00
$params [ 'page' ] = 1 ;
}
2020-05-29 10:47:21 +02:00
$this -> __iteratedFetch ( $user , $params , $loop , $tmpfile , $exportTool , $exportToolParams , $elementCounter );
2021-01-17 18:16:02 +01:00
$tmpfile -> write ( $exportTool -> footer ( $exportToolParams ));
return $tmpfile ;
2020-05-26 11:17:58 +02:00
}
2021-01-17 18:16:02 +01:00
private function __iteratedFetch ( $user , $params , $loop , TmpFileTool $tmpfile , $exportTool , $exportToolParams , & $elementCounter = 0 )
2020-05-26 11:17:58 +02:00
{
2021-01-17 18:16:02 +01:00
$elementCounter = 0 ;
$separator = $exportTool -> separator ( $exportToolParams );
do {
2020-05-29 10:47:21 +02:00
$results = $this -> fetchGalaxyClusters ( $user , $params , $full = $params [ 'full' ]);
if ( empty ( $results )) {
2021-01-17 18:16:02 +01:00
break ; // nothing found, skip rest
2020-05-29 10:47:21 +02:00
}
2021-01-17 18:16:02 +01:00
$resultCount = count ( $results );
$elementCounter += $resultCount ;
2020-05-29 10:47:21 +02:00
foreach ( $results as $cluster ) {
$handlerResult = $exportTool -> handler ( $cluster , $exportToolParams );
if ( $handlerResult !== '' ) {
2021-01-17 18:16:02 +01:00
$tmpfile -> writeWithSeparator ( $handlerResult , $separator );
2020-05-26 11:17:58 +02:00
}
2020-05-29 10:47:21 +02:00
}
2021-01-17 18:16:02 +01:00
if ( $resultCount < $params [ 'limit' ]) {
break ;
2020-05-26 11:17:58 +02:00
}
2021-01-17 18:16:02 +01:00
$params [ 'page' ] += 1 ;
} while ( $loop );
2020-05-26 11:17:58 +02:00
return true ;
}
public function buildFilterConditions ( $user , $filters )
{
2020-06-08 16:40:08 +02:00
$conditions = $this -> buildConditions ( $user );
2020-05-26 11:17:58 +02:00
if ( isset ( $filters [ 'org_id' ])) {
$this -> Organisation = ClassRegistry :: init ( 'Organisation' );
if ( ! is_array ( $filters [ 'org_id' ])) {
$filters [ 'org_id' ] = array ( $filters [ 'org_id' ]);
}
foreach ( $filters [ 'org_id' ] as $k => $org_id ) {
if ( Validation :: uuid ( $org_id )) {
$org = $this -> Organisation -> find ( 'first' , array ( 'conditions' => array ( 'Organisation.uuid' => $org_id ), 'recursive' => - 1 , 'fields' => array ( 'Organisation.id' )));
if ( empty ( $org )) {
$filters [ 'org_id' ][ $k ] = - 1 ;
} else {
$filters [ 'org_id' ][ $k ] = $org [ 'Organisation' ][ 'id' ];
}
}
}
2020-06-08 16:40:08 +02:00
$conditions [ 'AND' ][ 'GalaxyCluster.org_id' ] = $filters [ 'org_id' ];
2020-05-26 11:17:58 +02:00
}
if ( isset ( $filters [ 'orgc_id' ])) {
$this -> Organisation = ClassRegistry :: init ( 'Organisation' );
if ( ! is_array ( $filters [ 'orgc_id' ])) {
$filters [ 'orgc_id' ] = array ( $filters [ 'orgc_id' ]);
}
foreach ( $filters [ 'orgc_id' ] as $k => $orgc_id ) {
if ( Validation :: uuid ( $orgc_id )) {
$org = $this -> Organisation -> find ( 'first' , array ( 'conditions' => array ( 'Organisation.uuid' => $orgc_id ), 'recursive' => - 1 , 'fields' => array ( 'Organisation.id' )));
if ( empty ( $org )) {
$filters [ 'orgc_id' ][ $k ] = - 1 ;
} else {
$filters [ 'orgc_id' ][ $k ] = $org [ 'Organisation' ][ 'id' ];
}
}
}
2020-06-08 16:40:08 +02:00
$conditions [ 'AND' ][ 'GalaxyCluster.orgc_id' ] = $filters [ 'orgc_id' ];
2020-05-26 11:17:58 +02:00
}
if ( isset ( $filters [ 'galaxy_uuid' ])) {
2020-06-08 16:40:08 +02:00
$galaxyIds = $this -> Galaxy -> find ( 'list' , array (
2020-05-26 11:17:58 +02:00
'recursive' => - 1 ,
'conditions' => array ( 'Galaxy.uuid' => $filters [ 'galaxy_uuid' ]),
2020-06-08 16:40:08 +02:00
'fields' => array ( 'id' )
2020-05-26 11:17:58 +02:00
));
2020-06-08 16:40:08 +02:00
if ( ! empty ( $galaxyIds )) {
$filters [ 'galaxy_id' ] = array_values ( $galaxyIds );
2020-05-26 11:17:58 +02:00
} else {
$filters [ 'galaxy_id' ] = - 1 ;
}
}
2020-06-25 12:14:54 +02:00
if ( isset ( $filters [ 'eventid' ])) {
$clusterUUIDs = $this -> getClusterUUIDsFromAttachedTags ( $user , $filters [ 'eventid' ]);
if ( ! empty ( $clusterUUIDs )) {
$filters [ 'uuid' ] = array_values ( $clusterUUIDs );
} else {
$filters [ 'uuid' ] = - 1 ;
}
}
2020-05-26 11:17:58 +02:00
$simpleParams = array (
2020-06-25 10:47:54 +02:00
'uuid' , 'galaxy_id' , 'version' , 'distribution' , 'type' , 'value' , 'default' , 'extends_uuid' , 'tag_name' , 'published'
2020-05-26 11:17:58 +02:00
);
foreach ( $simpleParams as $k => $simpleParam ) {
if ( isset ( $filters [ $simpleParam ])) {
2020-06-08 16:40:08 +02:00
$conditions [ 'AND' ][ " GalaxyCluster. ${ simpleParam } " ] = $filters [ $simpleParam ];
2020-05-26 11:17:58 +02:00
}
}
if ( isset ( $filters [ 'custom' ])) {
2020-06-08 16:40:08 +02:00
$conditions [ 'AND' ][ 'GalaxyCluster.default' ] = ! $filters [ 'custom' ];
2020-05-26 11:17:58 +02:00
}
return $conditions ;
}
2020-11-23 19:38:19 +01:00
2020-07-08 16:56:31 +02:00
/**
* getClusterUUIDsFromAttachedTags Extract UUIDs from clusters contained in the provided event
*
* @ param array $user
* @ param int $eventId
* @ return array list of cluster UUIDs
*/
private function getClusterUUIDsFromAttachedTags ( array $user , $eventId )
2020-06-25 12:14:54 +02:00
{
$models = array ( 'Attribute' , 'Event' );
$clusterUUIDs = array ();
foreach ( $models as $model ) {
$modelLower = strtolower ( $model );
$joinCondition2 = array ( 'table' => " ${ modelLower } _tags " ,
'alias' => " ${ model } Tag " ,
'type' => 'inner' ,
'conditions' => array (
" Tag.id = ${ model } Tag.tag_id " ,
" ${ model } Tag.event_id " => $eventId ,
)
);
if ( $model == 'Attribute' ) {
// We have to make sure users have access to the event/attributes
2020-07-08 16:56:31 +02:00
// Otherwise, they might enumerate and fetch tags from event/attributes they can't see
2020-06-25 12:14:54 +02:00
$this -> Attribute = ClassRegistry :: init ( 'Attribute' );
$attributes = $this -> Attribute -> fetchAttributes ( $user , array (
'conditions' => array ( 'Attribute.event_id' => $eventId ),
'fields' => array ( 'Attribute.id' ),
'flatten' => 1
));
2020-07-08 16:56:31 +02:00
if ( ! empty ( $attributes )) {
$attributeIds = Hash :: extract ( $attributes , '{n}.Attribute.id' );
} else { // no attributes accessible
$attributeIds = - 1 ;
2020-06-25 12:14:54 +02:00
}
$joinCondition2 [ 'conditions' ][ " ${ model } Tag.attribute_id " ] = $attributeIds ;
}
$options = array (
'joins' => array (
array ( 'table' => 'tags' ,
'alias' => 'Tag' ,
'type' => 'inner' ,
'conditions' => array (
'GalaxyCluster.tag_name = Tag.name'
)
),
$joinCondition2
),
2020-06-25 15:01:54 +02:00
'fields' => array ( 'GalaxyCluster.uuid' ),
'recursive' => - 1 ,
2020-06-25 12:14:54 +02:00
);
$tmp = $this -> find ( 'list' , $options );
$clusterUUIDs = array_merge ( $clusterUUIDs , array_values ( $tmp ));
}
$clusterUUIDs = array_unique ( $clusterUUIDs );
return $clusterUUIDs ;
}
2020-11-23 19:38:19 +01:00
2020-07-08 16:56:31 +02:00
/**
* fetchClusterById Simple ACL - aware method to fetch a cluster by Id or UUID
*
* @ param array $user
* @ param int | string $clusterId
* @ param bool $full
2020-07-09 17:06:43 +02:00
* @ return array
2020-07-08 16:56:31 +02:00
*/
2020-07-09 17:06:43 +02:00
public function fetchClusterById ( array $user , $clusterId , $throwErrors = true , $full = false )
2020-06-17 15:01:23 +02:00
{
2020-06-19 10:45:15 +02:00
$alias = $this -> alias ;
2020-06-18 15:26:03 +02:00
if ( Validation :: uuid ( $clusterId )) {
$temp = $this -> find ( 'first' , array (
2020-06-17 15:01:23 +02:00
'recursive' => - 1 ,
2020-06-19 10:45:15 +02:00
'fields' => array ( " ${ alias } .id " , " ${ alias } .uuid " ),
'conditions' => array ( " ${ alias } .uuid " => $clusterId )
2020-06-17 15:01:23 +02:00
));
2020-07-09 17:06:43 +02:00
if ( empty ( $temp )) {
if ( $throwErrors ) {
throw new NotFoundException ( __ ( 'Invalid galaxy cluster' ));
}
return array ();
2020-06-17 15:01:23 +02:00
}
2020-06-19 10:45:15 +02:00
$clusterId = $temp [ $alias ][ 'id' ];
2020-06-18 15:26:03 +02:00
} elseif ( ! is_numeric ( $clusterId )) {
2020-07-09 17:06:43 +02:00
if ( $throwErrors ) {
throw new NotFoundException ( __ ( 'Invalid galaxy cluster' ));
}
return array ();
2020-06-17 15:01:23 +02:00
}
2020-06-19 10:45:15 +02:00
$conditions = array ( 'conditions' => array ( " ${ alias } .id " => $clusterId ));
2020-07-07 10:39:51 +02:00
$cluster = $this -> fetchGalaxyClusters ( $user , $conditions , $full = $full );
2020-06-18 15:26:03 +02:00
return $cluster ;
}
2020-11-23 19:38:19 +01:00
2020-07-08 16:56:31 +02:00
/**
* fetchIfAuthorized Fetches a cluster and checks if the user has the authorization to perform the requested operation
*
* @ param array $user
* @ param int | string | array $cluster
* @ param mixed $authorizations the requested actions to be performed on the cluster
* @ param bool $throwErrors Should the function throws excpetion if users is not allowed to perform the action
* @ param bool $full
* @ return array The cluster or an error message
*/
public function fetchIfAuthorized ( array $user , $cluster , $authorizations , $throwErrors = true , $full = false )
2020-06-18 15:26:03 +02:00
{
$authorizations = is_array ( $authorizations ) ? $authorizations : array ( $authorizations );
$possibleAuthorizations = array ( 'view' , 'edit' , 'delete' , 'publish' );
if ( ! empty ( array_diff ( $authorizations , $possibleAuthorizations ))) {
throw new NotFoundException ( __ ( 'Invalid authorization requested' ));
}
2020-07-09 14:44:21 +02:00
if ( isset ( $cluster [ 'uuid' ])) {
$cluster [ $this -> alias ] = $cluster ;
}
2020-06-19 10:45:15 +02:00
if ( ! isset ( $cluster [ $this -> alias ][ 'uuid' ])) {
2020-07-09 17:06:43 +02:00
$cluster = $this -> fetchClusterById ( $user , $cluster , $throwErrors = $throwErrors , $full = $full );
2020-06-18 15:26:03 +02:00
if ( empty ( $cluster )) {
$message = __ ( 'Invalid galaxy cluster' );
if ( $throwErrors ) {
throw new NotFoundException ( $message );
}
return array ( 'authorized' => false , 'error' => $message );
}
2020-07-08 16:56:31 +02:00
$cluster = $cluster [ 0 ];
2020-06-17 15:01:23 +02:00
}
2020-06-18 15:26:03 +02:00
if ( $user [ 'Role' ][ 'perm_site_admin' ]) {
return $cluster ;
}
if ( in_array ( 'view' , $authorizations ) && count ( $authorizations ) == 1 ) {
2020-06-17 15:01:23 +02:00
return $cluster ;
} else {
2020-06-18 15:26:03 +02:00
if ( ! $user [ 'Role' ][ 'perm_galaxy_editor' ]) {
$message = __ ( 'You don\'t have the permission to do that.' );
if ( $throwErrors ) {
throw new MethodNotAllowedException ( $message );
}
return array ( 'authorized' => false , 'error' => $message );
}
if ( in_array ( 'edit' , $authorizations ) || in_array ( 'delete' , $authorizations )) {
2020-06-19 14:12:40 +02:00
if ( $cluster [ $this -> alias ][ 'orgc_id' ] != $user [ 'org_id' ]) {
2020-06-18 15:26:03 +02:00
$message = __ ( 'Only the creator organisation can modify the galaxy cluster' );
if ( $throwErrors ) {
throw new MethodNotAllowedException ( $message );
}
return array ( 'authorized' => false , 'error' => $message );
}
2020-06-17 15:01:23 +02:00
}
2020-06-18 15:26:03 +02:00
if ( in_array ( 'publish' , $authorizations )) {
2020-11-12 10:28:29 +01:00
if ( $cluster [ $this -> alias ][ 'orgc_id' ] != $user [ 'org_id' ] && $user [ 'Role' ][ 'perm_publish' ]) {
$message = __ ( 'Only the creator organisation with publishing capabilities can publish the galaxy cluster' );
2020-06-18 15:26:03 +02:00
if ( $throwErrors ) {
throw new MethodNotAllowedException ( $message );
}
return array ( 'authorized' => false , 'error' => $message );
2020-06-17 15:01:23 +02:00
}
}
return $cluster ;
}
}
2019-10-18 16:13:26 +02:00
/**
2020-11-18 16:50:31 +01:00
* @ param array $user
2019-10-18 16:13:26 +02:00
* @ param array $events
2021-02-24 16:52:44 +01:00
* @ param bool $replace Remove galaxy cluster tags
2019-10-18 16:13:26 +02:00
* @ return array
*/
2021-02-24 16:52:44 +01:00
public function attachClustersToEventIndex ( array $user , array $events , $replace = false )
2019-10-18 16:13:26 +02:00
{
2020-11-18 16:50:31 +01:00
$clusterTagNames = [];
2019-10-18 16:13:26 +02:00
foreach ( $events as $event ) {
2021-01-17 13:27:20 +01:00
foreach ( $event [ 'EventTag' ] as $eventTag ) {
2020-11-18 16:50:31 +01:00
if ( $eventTag [ 'Tag' ][ 'is_galaxy' ]) {
2021-02-22 10:33:16 +01:00
$clusterTagNames [ $eventTag [ 'Tag' ][ 'id' ]] = $eventTag [ 'Tag' ][ 'name' ];
2019-10-18 16:13:26 +02:00
}
2018-07-19 11:48:22 +02:00
}
2019-10-18 16:13:26 +02:00
}
2020-09-01 17:56:32 +02:00
if ( empty ( $clusterTagNames )) {
return $events ;
}
2020-11-18 16:50:31 +01:00
$options = [
2021-02-22 10:33:16 +01:00
'conditions' => [ 'GalaxyCluster.tag_name' => $clusterTagNames ],
2021-02-24 16:52:44 +01:00
'contain' => [ 'Galaxy' , 'GalaxyElement' ],
2020-11-18 16:50:31 +01:00
];
2021-02-24 16:52:44 +01:00
$clusters = $this -> fetchGalaxyClusters ( $user , $options );
2019-10-18 16:13:26 +02:00
2020-11-18 16:50:31 +01:00
$clustersByTagName = [];
2019-10-18 16:13:26 +02:00
foreach ( $clusters as $cluster ) {
$clustersByTagName [ strtolower ( $cluster [ 'GalaxyCluster' ][ 'tag_name' ])] = $cluster ;
}
foreach ( $events as $k => $event ) {
foreach ( $event [ 'EventTag' ] as $k2 => $eventTag ) {
2020-11-18 16:50:31 +01:00
if ( ! $eventTag [ 'Tag' ][ 'is_galaxy' ]) {
continue ;
}
2019-10-18 16:13:26 +02:00
$tagName = strtolower ( $eventTag [ 'Tag' ][ 'name' ]);
if ( isset ( $clustersByTagName [ $tagName ])) {
$cluster = $this -> postprocess ( $clustersByTagName [ $tagName ], $eventTag [ 'Tag' ][ 'id' ]);
$cluster [ 'GalaxyCluster' ][ 'local' ] = $eventTag [ 'local' ];
$events [ $k ][ 'GalaxyCluster' ][] = $cluster [ 'GalaxyCluster' ];
if ( $replace ) {
unset ( $events [ $k ][ 'EventTag' ][ $k2 ]);
}
2018-07-19 11:48:22 +02:00
}
}
2019-10-18 16:13:26 +02:00
}
return $events ;
}
/**
* @ param array $cluster
* @ param int | null $tagId
* @ return array
*/
private function postprocess ( array $cluster , $tagId = null )
{
2020-06-29 16:25:58 +02:00
$cluster = $this -> arrangeData ( $cluster );
2019-10-18 16:13:26 +02:00
2020-11-18 16:50:31 +01:00
if ( isset ( $cluster [ 'GalaxyCluster' ][ 'GalaxyElement' ])) {
$elements = array ();
foreach ( $cluster [ 'GalaxyCluster' ][ 'GalaxyElement' ] as $element ) {
if ( ! isset ( $elements [ $element [ 'key' ]])) {
$elements [ $element [ 'key' ]] = array ( $element [ 'value' ]);
} else {
$elements [ $element [ 'key' ]][] = $element [ 'value' ];
}
2019-10-18 16:13:26 +02:00
}
2020-11-18 16:50:31 +01:00
unset ( $cluster [ 'GalaxyCluster' ][ 'GalaxyElement' ]);
$cluster [ 'GalaxyCluster' ][ 'meta' ] = $elements ;
2019-10-18 16:13:26 +02:00
}
if ( $tagId ) {
$cluster [ 'GalaxyCluster' ][ 'tag_id' ] = $tagId ;
} else {
2018-07-19 11:48:22 +02:00
$this -> Tag = ClassRegistry :: init ( 'Tag' );
$tag_id = $this -> Tag -> find (
'first' ,
array (
'conditions' => array (
2019-08-02 16:28:08 +02:00
'LOWER(Tag.name)' => strtolower ( $cluster [ 'GalaxyCluster' ][ 'tag_name' ])
2018-07-19 11:48:22 +02:00
),
'recursive' => - 1 ,
'fields' => array ( 'Tag.id' )
)
);
if ( ! empty ( $tag_id )) {
$cluster [ 'GalaxyCluster' ][ 'tag_id' ] = $tag_id [ 'Tag' ][ 'id' ];
}
}
2016-12-09 07:58:03 +01:00
2019-10-18 16:13:26 +02:00
return $cluster ;
2018-07-19 11:48:22 +02:00
}
2019-11-06 10:38:34 +01:00
2020-03-12 10:26:09 +01:00
public function getClusterTagsFromMeta ( $galaxyElements , $user )
2019-11-06 10:38:34 +01:00
{
// AND operator between cluster metas
$tmpResults = array ();
foreach ( $galaxyElements as $galaxyElementKey => $galaxyElementValue ) {
$tmpResults [] = array_values ( $this -> GalaxyElement -> find ( 'list' , array (
'conditions' => array (
2020-06-18 15:26:03 +02:00
'LOWER(GalaxyElement.key)' => strtolower ( $galaxyElementKey ),
'LOWER(GalaxyElement.value)' => strtolower ( $galaxyElementValue ),
2019-11-06 10:38:34 +01:00
),
'fields' => array ( 'galaxy_cluster_id' ),
'recursive' => - 1
)));
}
$clusterTags = array ();
if ( ! empty ( $tmpResults )) {
// Get all Clusters matching all conditions
$matchingClusters = $tmpResults [ 0 ];
array_shift ( $tmpResults );
foreach ( $tmpResults as $tmpResult ) {
$matchingClusters = array_intersect ( $matchingClusters , $tmpResult );
}
2020-06-18 15:26:03 +02:00
$clusterTags = $this -> fetchGalaxyClusters ( $user , array (
2019-11-06 10:38:34 +01:00
'conditions' => array ( 'id' => $matchingClusters ),
'fields' => array ( 'GalaxyCluster.tag_name' ),
2020-06-18 15:26:03 +02:00
'list' => true ,
), $full = false );
2019-11-06 10:38:34 +01:00
}
return array_values ( $clusterTags );
}
2020-05-26 15:08:24 +02:00
2020-06-25 16:02:03 +02:00
public function getElligibleClustersToPush ( $user , $conditions = array (), $full = false )
2020-05-26 15:30:53 +02:00
{
$options = array (
'conditions' => array (
'GalaxyCluster.default' => 0 ,
2020-06-18 15:26:03 +02:00
'GalaxyCluster.published' => 1 ,
2020-05-26 15:30:53 +02:00
),
);
2020-06-25 16:02:03 +02:00
$options [ 'conditions' ] = array_merge ( $options [ 'conditions' ], $conditions );
if ( ! $full ) {
$options [ 'fields' ] = array ( 'uuid' , 'version' );
$options [ 'list' ] = true ;
}
$clusters = $this -> fetchGalaxyClusters ( $user , $options , $full = $full );
2020-06-18 15:26:03 +02:00
return $clusters ;
2020-05-26 15:30:53 +02:00
}
2020-06-18 15:26:03 +02:00
public function getElligibleLocalClustersToUpdate ( $user )
2020-05-27 09:35:27 +02:00
{
$options = array (
'conditions' => array (
'GalaxyCluster.default' => 0 ,
'GalaxyCluster.locked' => 1 ,
),
2020-06-18 15:26:03 +02:00
'fields' => array ( 'uuid' , 'version' ),
'list' => true ,
2020-05-27 09:35:27 +02:00
);
$clusters = $this -> fetchGalaxyClusters ( $user , $options , $full = false );
2020-06-18 15:26:03 +02:00
return $clusters ;
2020-05-27 09:35:27 +02:00
}
2020-11-23 19:38:19 +01:00
2020-07-08 16:56:31 +02:00
/**
* @ return string | bool The result of the upload . True if success , a string otherwise
2022-03-13 13:06:11 +01:00
* @ throws Exception
2020-07-08 16:56:31 +02:00
*/
2022-03-13 13:06:11 +01:00
public function uploadClusterToServer ( array $cluster , array $server , ServerSyncTool $serverSync , array $user )
2020-05-26 15:08:24 +02:00
{
2022-03-13 13:06:11 +01:00
$cluster = $this -> __prepareForPushToServer ( $cluster , $server );
if ( is_numeric ( $cluster )) {
return $cluster ;
2020-05-26 15:08:24 +02:00
}
2022-03-13 13:06:11 +01:00
2020-05-26 15:08:24 +02:00
try {
2022-03-13 13:06:11 +01:00
if ( ! $serverSync -> isSupported ( ServerSyncTool :: PERM_SYNC ) || $serverSync -> isSupported ( ServerSyncTool :: PERM_GALAXY_EDITOR )) {
return __ ( 'The remote user does not have the permission to manipulate galaxies - the upload of the galaxy clusters has been blocked.' );
}
$serverSync -> pushGalaxyCluster ( $cluster ) -> json ();
2020-05-26 15:08:24 +02:00
} catch ( Exception $e ) {
2022-03-13 13:06:11 +01:00
$title = __ ( 'Uploading GalaxyCluster (%s) to Server (%s)' , $cluster [ 'GalaxyCluster' ][ 'id' ], $server [ 'Server' ][ 'id' ]);
$this -> loadLog () -> createLogEntry ( $user , 'push' , 'GalaxyCluster' , $cluster [ 'GalaxyCluster' ][ 'id' ], $title , $e -> getMessage ());
2020-05-26 15:08:24 +02:00
2022-03-13 13:06:11 +01:00
$this -> logException ( " Could not push galaxy cluster to remote server { $serverSync -> serverId () } " , $e );
return $e -> getMessage ();
2020-05-26 15:08:24 +02:00
}
2022-03-13 13:06:11 +01:00
return 'Success' ;
2020-05-26 15:08:24 +02:00
}
2020-11-23 19:38:19 +01:00
2020-07-08 16:56:31 +02:00
/**
* __prepareForPushToServer Check distribution and alter the cluster for sync
*
* @ param array $cluster
* @ param array $server
2022-03-13 13:06:11 +01:00
* @ return array | int The cluster ready to be pushed
2020-07-08 16:56:31 +02:00
*/
private function __prepareForPushToServer ( array $cluster , array $server )
2020-05-26 16:06:20 +02:00
{
if ( $cluster [ 'GalaxyCluster' ][ 'distribution' ] == 4 ) {
2020-06-12 15:08:01 +02:00
if ( ! empty ( $cluster [ 'GalaxyCluster' ][ 'SharingGroup' ][ 'SharingGroupServer' ])) {
2020-05-26 16:06:20 +02:00
$found = false ;
2020-06-12 15:08:01 +02:00
foreach ( $cluster [ 'GalaxyCluster' ][ 'SharingGroup' ][ 'SharingGroupServer' ] as $sgs ) {
2020-05-26 16:06:20 +02:00
if ( $sgs [ 'server_id' ] == $server [ 'Server' ][ 'id' ]) {
$found = true ;
}
}
if ( ! $found ) {
return 403 ;
}
2020-07-07 08:16:46 +02:00
} elseif ( empty ( $cluster [ 'GalaxyCluster' ][ 'SharingGroup' ][ 'roaming' ])) {
2020-05-26 16:06:20 +02:00
return 403 ;
}
}
$this -> Event = ClassRegistry :: init ( 'Event' );
if ( $this -> Event -> checkDistributionForPush ( $cluster , $server , 'GalaxyCluster' )) {
2022-03-13 13:06:11 +01:00
return $this -> __updateClusterForSync ( $cluster , $server );
2020-05-26 16:06:20 +02:00
}
2022-03-13 13:06:11 +01:00
return 403 ;
2020-05-26 16:06:20 +02:00
}
2020-11-23 19:38:19 +01:00
2020-07-08 16:56:31 +02:00
/**
* __updateClusterForSync Cleanup the cluster and adapt data for sync
*
* @ param array $cluster
* @ param array $server
* @ return array The cluster ready do be sync
*/
private function __updateClusterForSync ( array $cluster , array $server )
2020-05-26 16:06:20 +02:00
{
$this -> Event = ClassRegistry :: init ( 'Event' );
// cleanup the array from things we do not want to expose
foreach ( array ( 'org_id' , 'orgc_id' , 'id' , 'galaxy_id' ) as $field ) {
unset ( $cluster [ 'GalaxyCluster' ][ $field ]);
}
// Add the local server to the list of instances in the SG
2020-06-12 15:08:01 +02:00
if ( isset ( $cluster [ 'GalaxyCluster' ][ 'SharingGroup' ]) && isset ( $cluster [ 'GalaxyCluster' ][ 'SharingGroup' ][ 'SharingGroupServer' ])) {
foreach ( $cluster [ 'GalaxyCluster' ][ 'SharingGroup' ][ 'SharingGroupServer' ] as & $s ) {
2020-05-26 16:06:20 +02:00
if ( $s [ 'server_id' ] == 0 ) {
$s [ 'Server' ] = array (
'id' => 0 ,
'url' => $this -> Event -> __getAnnounceBaseurl (),
'name' => $this -> Event -> __getAnnounceBaseurl ()
);
}
}
}
$cluster = $this -> __prepareElementsForSync ( $cluster , $server );
$cluster = $this -> __prepareRelationsForSync ( $cluster , $server );
// Downgrade the event from connected communities to community only
if ( ! $server [ 'Server' ][ 'internal' ] && $cluster [ 'GalaxyCluster' ][ 'distribution' ] == 2 ) {
$cluster [ 'GalaxyCluster' ][ 'distribution' ] = 1 ;
}
return $cluster ;
}
private function __prepareElementsForSync ( $cluster , $server )
{
2020-06-12 15:08:01 +02:00
if ( ! empty ( $cluster [ 'GalaxyCluster' ][ 'GalaxyElement' ])) {
2020-07-07 08:16:46 +02:00
foreach ( $cluster [ 'GalaxyCluster' ][ 'GalaxyElement' ] as $k => $element ) {
2020-06-12 15:08:01 +02:00
$cluster [ 'GalaxyCluster' ][ 'GalaxyElement' ][ $k ] = $this -> __updateElementForSync ( $element , $server );
2020-05-26 16:06:20 +02:00
}
}
return $cluster ;
}
private function __prepareRelationsForSync ( $cluster , $server )
{
$this -> Event = ClassRegistry :: init ( 'Event' );
2020-06-12 15:08:01 +02:00
if ( ! empty ( $cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ])) {
2020-07-07 08:16:46 +02:00
foreach ( $cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ] as $k => $relation ) {
2020-06-12 15:08:01 +02:00
$cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ][ $k ] = $this -> __updateRelationsForSync ( $relation , $server );
if ( empty ( $cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ][ $k ])) {
unset ( $cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ][ $k ]);
2020-05-26 16:06:20 +02:00
} else {
2020-06-12 15:08:01 +02:00
$cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ][ $k ] = $this -> Event -> __removeNonExportableTags ( $cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ][ $k ], 'GalaxyClusterRelation' );
2020-05-26 16:06:20 +02:00
}
}
2020-06-12 15:08:01 +02:00
$cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ] = array_values ( $cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ]);
2020-05-26 16:06:20 +02:00
}
return $cluster ;
}
private function __updateElementForSync ( $element , $server )
{
unset ( $element [ 'id' ]);
unset ( $element [ 'galaxy_cluster_id' ]);
return $element ;
}
private function __updateRelationsForSync ( $relation , $server )
{
// do not keep attributes that are private, nor cluster
if ( ! $server [ 'Server' ][ 'internal' ] && $relation [ 'distribution' ] < 2 ) {
return false ;
}
// Downgrade the attribute from connected communities to community only
if ( ! $server [ 'Server' ][ 'internal' ] && $relation [ 'distribution' ] == 2 ) {
$relation [ 'distribution' ] = 1 ;
}
2020-07-02 15:14:02 +02:00
$this -> Event = ClassRegistry :: init ( 'Event' );
2020-05-26 16:06:20 +02:00
// If the attribute has a sharing group attached, make sure it can be transferred
if ( $relation [ 'distribution' ] == 4 ) {
2020-07-02 15:14:02 +02:00
if ( ! $server [ 'Server' ][ 'internal' ] && $this -> Event -> checkDistributionForPush ( array ( 'GalaxyClusterRelation' => $relation ), $server , 'GalaxyClusterRelation' ) === false ) {
2020-05-26 16:06:20 +02:00
return false ;
}
// Add the local server to the list of instances in the SG
if ( ! empty ( $relation [ 'SharingGroup' ][ 'SharingGroupServer' ])) {
foreach ( $relation [ 'SharingGroup' ][ 'SharingGroupServer' ] as & $s ) {
if ( $s [ 'server_id' ] == 0 ) {
$s [ 'Server' ] = array (
'id' => 0 ,
2020-07-10 15:06:55 +02:00
'url' => $this -> Event -> __getAnnounceBaseurl (),
'name' => $this -> Event -> __getAnnounceBaseurl ()
2020-05-26 16:06:20 +02:00
);
}
}
}
}
unset ( $relation [ 'id' ]);
unset ( $relation [ 'galaxy_cluster_id' ]);
unset ( $relation [ 'referenced_galaxy_cluster_id' ]);
return $relation ;
}
2020-07-08 16:56:31 +02:00
/**
* pullGalaxyClusters
*
2022-03-12 18:54:32 +01:00
* @ param array $user
* @ param ServerSyncTool $serverSync
* @ param string | int $technique The technique startegy used for pulling
2020-07-08 16:56:31 +02:00
* allowed :
* - int < event id > event containing the clusters to pulled
* - string < full > pull everything
* - string < update > pull updates of cluster present locally
* - string < pull_relevant_clusters > pull clusters based on tags present locally
2021-01-17 18:16:02 +01:00
* @ return int The number of pulled clusters
2022-03-12 18:54:32 +01:00
* @ throws HttpSocketHttpException
* @ throws HttpSocketJsonException
2020-07-08 16:56:31 +02:00
*/
2022-03-12 18:54:32 +01:00
public function pullGalaxyClusters ( array $user , ServerSyncTool $serverSync , $technique = 'full' )
2020-05-27 09:35:27 +02:00
{
2022-03-12 18:54:32 +01:00
$compatible = $serverSync -> isSupported ( ServerSyncTool :: FEATURE_EDIT_OF_GALAXY_CLUSTER );
2022-05-06 21:15:45 +02:00
if ( ! $compatible ) {
2020-11-13 11:45:26 +01:00
return 0 ;
}
2022-03-12 18:54:32 +01:00
$clusterIds = $this -> getClusterIdListBasedOnPullTechnique ( $user , $technique , $serverSync );
$successes = 0 ;
2020-05-27 09:35:27 +02:00
// now process the $clusterIds to pull each of the events sequentially
if ( ! empty ( $clusterIds )) {
// download each cluster
2022-03-12 18:54:32 +01:00
foreach ( $clusterIds as $clusterId ) {
if ( $this -> __pullGalaxyCluster ( $clusterId , $serverSync , $user )) {
$successes ++ ;
}
2020-05-27 09:35:27 +02:00
}
}
2022-03-12 18:54:32 +01:00
return $successes ;
2020-05-27 09:35:27 +02:00
}
2020-11-23 19:38:19 +01:00
2020-07-08 16:56:31 +02:00
/**
* getClusterIdListBasedOnPullTechnique Collect the list of remote cluster IDs to be pulled based on the technique
*
* @ param array $user
* @ param string | int $technique
2022-03-12 18:54:32 +01:00
* @ param ServerSyncTool $serverSync
2020-07-08 16:56:31 +02:00
* @ return array cluster ID list to be pulled
*/
2022-03-12 18:54:32 +01:00
private function getClusterIdListBasedOnPullTechnique ( array $user , $technique , ServerSyncTool $serverSync )
2020-05-27 09:35:27 +02:00
{
$this -> Server = ClassRegistry :: init ( 'Server' );
2021-05-24 15:17:01 +02:00
try {
if ( " update " === $technique ) {
$localClustersToUpdate = $this -> getElligibleLocalClustersToUpdate ( $user );
2022-03-12 18:54:32 +01:00
$clusterIds = $this -> Server -> getElligibleClusterIdsFromServerForPull ( $serverSync , $onlyUpdateLocalCluster = true , $elligibleClusters = $localClustersToUpdate );
2021-05-24 15:17:01 +02:00
} elseif ( " pull_relevant_clusters " === $technique ) {
// Fetch all local custom cluster tags then fetch their corresponding clusters on the remote end
$tagNames = $this -> Tag -> find ( 'column' , array (
'conditions' => array (
'Tag.is_custom_galaxy' => true
),
'fields' => array ( 'Tag.name' ),
));
$clusterUUIDs = array ();
$re = '/^misp-galaxy:[^:="]+="(?<uuid>[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})"$/m' ;
foreach ( $tagNames as $tagName ) {
preg_match ( $re , $tagName , $matches );
if ( isset ( $matches [ 'uuid' ])) {
$clusterUUIDs [ $matches [ 'uuid' ]] = true ;
}
2020-06-25 15:01:54 +02:00
}
2021-05-24 15:17:01 +02:00
$localClustersToUpdate = $this -> getElligibleLocalClustersToUpdate ( $user );
$conditions = array ( 'uuid' => array_keys ( $clusterUUIDs ));
2022-03-12 18:54:32 +01:00
$clusterIds = $this -> Server -> getElligibleClusterIdsFromServerForPull ( $serverSync , $onlyUpdateLocalCluster = false , $elligibleClusters = $localClustersToUpdate , $conditions = $conditions );
2021-05-24 15:17:01 +02:00
} elseif ( is_numeric ( $technique )) {
$conditions = array ( 'eventid' => $technique );
2022-03-12 18:54:32 +01:00
$clusterIds = $this -> Server -> getElligibleClusterIdsFromServerForPull ( $serverSync , $onlyUpdateLocalCluster = false , $elligibleClusters = array (), $conditions = $conditions );
2021-05-24 15:17:01 +02:00
} else {
2022-03-12 18:54:32 +01:00
$clusterIds = $this -> Server -> getElligibleClusterIdsFromServerForPull ( $serverSync , $onlyUpdateLocalCluster = false );
2020-05-27 09:35:27 +02:00
}
2021-05-24 15:17:01 +02:00
} catch ( HttpSocketHttpException $e ) {
if ( $e -> getCode () === 403 ) {
return array ( 'error' => array ( 1 , null ));
} else {
2022-03-12 18:54:32 +01:00
$this -> logException ( " Could not get eligible cluster IDs from server { $serverSync -> serverId () } for pull. " , $e );
2021-05-24 15:17:01 +02:00
return array ( 'error' => array ( 2 , $e -> getMessage ()));
}
} catch ( Exception $e ) {
2022-03-12 18:54:32 +01:00
$this -> logException ( " Could not get eligible cluster IDs from server { $serverSync -> serverId () } for pull. " , $e );
2021-05-24 15:17:01 +02:00
return array ( 'error' => array ( 2 , $e -> getMessage ()));
2020-05-27 09:35:27 +02:00
}
return $clusterIds ;
}
2022-03-12 18:54:32 +01:00
private function __pullGalaxyCluster ( $clusterId , ServerSyncTool $serverSync , array $user )
2020-05-27 09:35:27 +02:00
{
2022-03-12 18:54:32 +01:00
try {
$cluster = $serverSync -> fetchGalaxyCluster ( $clusterId ) -> json ();
} catch ( Exception $e ) {
$this -> logException ( " Could not fetch galaxy cluster $clusterId from server { $serverSync -> serverId () } " , $e );
return false ;
2020-05-27 09:35:27 +02:00
}
2020-06-10 09:37:25 +02:00
2022-03-12 18:54:32 +01:00
$cluster = $this -> updatePulledClusterBeforeInsert ( $cluster , $serverSync -> server (), $user );
$result = $this -> captureCluster ( $user , $cluster , $fromPull = true , $orgId = $serverSync -> server ()[ 'Server' ][ 'org_id' ]);
return $result [ 'success' ];
2020-05-27 09:35:27 +02:00
}
2020-07-08 16:56:31 +02:00
private function updatePulledClusterBeforeInsert ( $cluster , $server , $user )
2020-05-27 09:35:27 +02:00
{
// The cluster came from a pull, so it should be locked and distribution should be adapted.
$cluster [ 'GalaxyCluster' ][ 'locked' ] = true ;
if ( ! isset ( $cluster [ 'GalaxyCluster' ][ 'distribution' ])) {
$cluster [ 'GalaxyCluster' ][ 'distribution' ] = '1' ;
}
if ( empty ( Configure :: read ( 'MISP.host_org_id' )) || ! $server [ 'Server' ][ 'internal' ] || Configure :: read ( 'MISP.host_org_id' ) != $server [ 'Server' ][ 'org_id' ]) {
switch ( $cluster [ 'GalaxyCluster' ][ 'distribution' ]) {
case 1 :
$cluster [ 'GalaxyCluster' ][ 'distribution' ] = 0 ; // if community only, downgrade to org only after pull
break ;
case 2 :
$cluster [ 'GalaxyCluster' ][ 'distribution' ] = 1 ; // if connected communities downgrade to community only
break ;
}
2020-06-10 09:37:25 +02:00
if ( ! empty ( $cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ])) {
foreach ( $cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ] as $k => $relation ) {
2020-05-27 09:35:27 +02:00
switch ( $relation [ 'distribution' ]) {
case 1 :
2020-06-10 09:37:25 +02:00
$cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ][ $k ][ 'distribution' ] = 0 ;
2020-05-27 09:35:27 +02:00
break ;
case 2 :
2020-06-10 09:37:25 +02:00
$cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ][ $k ][ 'distribution' ] = 1 ;
2020-05-27 09:35:27 +02:00
break ;
}
}
}
}
return $cluster ;
}
2020-05-06 11:44:53 +02:00
2021-07-12 11:34:09 +02:00
public function attachClusterToRelations ( $user , $cluster , $both = true )
2020-05-06 11:44:53 +02:00
{
2020-06-12 15:08:01 +02:00
if ( ! empty ( $cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ])) {
foreach ( $cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ] as $k => $relation ) {
2020-05-25 10:04:07 +02:00
$conditions = array ( 'conditions' => array ( 'GalaxyCluster.uuid' => $relation [ 'referenced_galaxy_cluster_uuid' ]));
2020-05-06 11:44:53 +02:00
$relatedCluster = $this -> fetchGalaxyClusters ( $user , $conditions , false );
if ( ! empty ( $relatedCluster )) {
2020-06-12 15:08:01 +02:00
$cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ][ $k ][ 'GalaxyCluster' ] = $relatedCluster [ 0 ][ 'GalaxyCluster' ];
2020-05-06 11:44:53 +02:00
}
}
}
2021-07-12 11:34:09 +02:00
if ( $both ) {
if ( ! empty ( $cluster [ 'GalaxyCluster' ][ 'TargetingClusterRelation' ])) {
foreach ( $cluster [ 'GalaxyCluster' ][ 'TargetingClusterRelation' ] as $k => $relation ) {
$conditions = array ( 'conditions' => array ( 'GalaxyCluster.uuid' => $relation [ 'galaxy_cluster_uuid' ]));
$relatedCluster = $this -> fetchGalaxyClusters ( $user , $conditions , false );
if ( ! empty ( $relatedCluster )) {
$cluster [ 'GalaxyCluster' ][ 'TargetingClusterRelation' ][ $k ][ 'GalaxyCluster' ] = $relatedCluster [ 0 ][ 'GalaxyCluster' ];
}
2020-05-08 09:17:37 +02:00
}
}
}
return $cluster ;
}
2020-06-12 15:58:24 +02:00
public function cacheGalaxyClusterIDs ( $user )
{
if ( isset ( $this -> __assetCache [ 'gcids' ])) {
return $this -> __assetCache [ 'gcids' ];
} else {
$gcids = $this -> fetchGalaxyClusters ( $user , array (
'fields' => 'id' ,
), false );
$alias = $this -> alias ;
$gcids = Hash :: extract ( $gcids , " { n}. ${ alias } .id " );
if ( empty ( $gcids )) {
$gcids = array ( - 1 );
}
$this -> __assetCache [ 'gcids' ] = $gcids ;
return $gcids ;
}
}
2020-09-25 11:56:44 +02:00
public function cacheGalaxyClusterOwnerIDs ( $user )
{
if ( isset ( $this -> __assetCache [ 'gcOwnerIds' ])) {
return $this -> __assetCache [ 'gcOwnerIds' ];
} else {
$gcOwnerIds = $this -> fetchGalaxyClusters ( $user , array (
'fields' => 'id' ,
'conditions' => array (
'org_id' => $user [ 'org_id' ]
)
), false );
$alias = $this -> alias ;
$gcOwnerIds = Hash :: extract ( $gcOwnerIds , " { n}. ${ alias } .id " );
if ( empty ( $gcOwnerIds )) {
$gcOwnerIds = array ( - 1 );
}
$this -> __assetCache [ 'gcOwnerIds' ] = $gcOwnerIds ;
return $gcOwnerIds ;
}
}
2020-09-15 23:52:52 +02:00
public function getTagIdByClusterId ( $cluster_id )
{
$cluster = $this -> find ( 'first' , [
'recursive' => - 1 ,
'conditions' => [ 'GalaxyCluster.id' => $cluster_id ],
'contain' => [ 'Tag' ]
]);
return empty ( $cluster [ 'Tag' ][ 'id' ]) ? false : $cluster [ 'Tag' ][ 'id' ];
}
2021-06-04 00:11:55 +02:00
public function getCyCatRelations ( $cluster )
{
2021-06-04 10:16:23 +02:00
$CyCatRelations = [];
if ( empty ( Configure :: read ( 'Plugin.CyCat_enable' ))) {
return $CyCatRelations ;
}
2021-06-04 00:11:55 +02:00
App :: uses ( 'SyncTool' , 'Tools' );
$cycatUrl = empty ( Configure :: read ( " Plugin.CyCat_url " )) ? 'https://api.cycat.org' : Configure :: read ( " Plugin.CyCat_url " );
$syncTool = new SyncTool ();
if ( empty ( $this -> HttpSocket )) {
$this -> HttpSocket = $syncTool -> createHttpSocket ();
}
$request = array (
'header' => array (
'Accept' => array ( 'application/json' ),
'MISP-version' => implode ( '.' , $this -> checkMISPVersion ()),
'MISP-uuid' => Configure :: read ( 'MISP.uuid' ),
'x-ground-truth' => 'Dogs are superior to cats'
)
);
$response = $this -> HttpSocket -> get ( $cycatUrl . '/lookup/' . $cluster [ 'GalaxyCluster' ][ 'uuid' ], array (), $request );
if ( $response -> code === '200' ) {
$response = $this -> HttpSocket -> get ( $cycatUrl . '/relationships/' . $cluster [ 'GalaxyCluster' ][ 'uuid' ], array (), $request );
if ( $response -> code === '200' ) {
2021-06-04 10:16:23 +02:00
$relationUUIDs = json_decode ( $response -> body );
if ( ! empty ( $relationUUIDs )) {
foreach ( $relationUUIDs as $relationUUID ) {
$response = $this -> HttpSocket -> get ( $cycatUrl . '/lookup/' . $relationUUID , array (), $request );
2021-06-04 00:11:55 +02:00
if ( $response -> code === '200' ) {
2021-06-04 10:16:23 +02:00
$lookupResult = json_decode ( $response -> body , true );
$lookupResult [ 'uuid' ] = $relationUUID ;
$CyCatRelations [ $relationUUID ] = $lookupResult ;
2021-06-04 00:11:55 +02:00
}
}
}
}
}
2021-06-04 10:16:23 +02:00
return $CyCatRelations ;
2021-06-04 00:11:55 +02:00
}
2016-12-05 00:47:34 +01:00
}