2016-12-05 00:47:34 +01:00
< ? php
App :: uses ( 'AppModel' , 'Model' );
2021-07-27 21:10:45 +02:00
/**
* @ property GalaxyCluster $GalaxyCluster
*/
2018-07-19 11:48:22 +02:00
class Galaxy extends AppModel
{
public $useTable = 'galaxies' ;
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
2018-07-19 11:48:22 +02:00
public $hasMany = array (
'GalaxyCluster' => array ( 'dependent' => true )
);
2016-12-05 00:47:34 +01:00
2018-07-19 11:48:22 +02:00
public function beforeValidate ( $options = array ())
{
parent :: beforeValidate ();
2019-02-15 09:54:39 +01:00
if ( isset ( $this -> data [ 'Galaxy' ][ 'kill_chain_order' ])) {
$json = json_encode ( $this -> data [ 'Galaxy' ][ 'kill_chain_order' ]);
if ( $json !== null ) {
$this -> data [ 'Galaxy' ][ 'kill_chain_order' ] = $json ;
} else {
unset ( $this -> data [ 'Galaxy' ][ 'kill_chain_order' ]);
}
}
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 beforeDelete ( $cascade = true )
{
$this -> GalaxyCluster -> deleteAll ( array ( 'GalaxyCluster.galaxy_id' => $this -> id ));
}
2017-08-16 22:18:32 +02:00
2019-02-14 10:24:42 +01:00
public function afterFind ( $results , $primary = false )
{
foreach ( $results as $k => $v ) {
if ( isset ( $v [ 'Galaxy' ][ 'kill_chain_order' ]) && $v [ 'Galaxy' ][ 'kill_chain_order' ] !== '' ) {
$results [ $k ][ 'Galaxy' ][ 'kill_chain_order' ] = json_decode ( $v [ 'Galaxy' ][ 'kill_chain_order' ], true );
} else {
unset ( $results [ $k ][ 'Galaxy' ][ 'kill_chain_order' ]);
}
}
return $results ;
}
2021-07-27 21:10:45 +02:00
/**
* @ param bool $force
* @ return array Galaxy type => Galaxy ID
2021-11-14 16:42:21 +01:00
* @ throws Exception
2021-07-27 21:10:45 +02:00
*/
2018-07-19 11:48:22 +02:00
private function __load_galaxies ( $force = false )
{
2021-11-14 16:42:21 +01:00
$files = new GlobIterator ( APP . 'files' . DS . 'misp-galaxy' . DS . 'galaxies' . DS . '*.json' );
2018-07-19 11:48:22 +02:00
$galaxies = array ();
foreach ( $files as $file ) {
2021-11-14 16:42:21 +01:00
$galaxies [] = FileAccessTool :: readJsonFromFile ( $file -> getPathname ());
2018-07-19 11:48:22 +02:00
}
2021-07-27 21:10:45 +02:00
$existingGalaxies = $this -> find ( 'all' , array (
2018-07-19 11:48:22 +02:00
'fields' => array ( 'uuid' , 'version' , 'id' , 'icon' ),
'recursive' => - 1
));
2021-07-27 21:10:45 +02:00
$existingGalaxies = array_column ( array_column ( $existingGalaxies , 'Galaxy' ), null , 'uuid' );
foreach ( $galaxies as $galaxy ) {
2018-07-19 11:48:22 +02:00
if ( isset ( $existingGalaxies [ $galaxy [ 'uuid' ]])) {
if (
$force ||
$existingGalaxies [ $galaxy [ 'uuid' ]][ 'version' ] < $galaxy [ 'version' ] ||
( ! empty ( $galaxy [ 'icon' ]) && ( $existingGalaxies [ $galaxy [ 'uuid' ]][ 'icon' ] != $galaxy [ 'icon' ]))
) {
$galaxy [ 'id' ] = $existingGalaxies [ $galaxy [ 'uuid' ]][ 'id' ];
$this -> save ( $galaxy );
}
} else {
$this -> create ();
$this -> save ( $galaxy );
}
}
return $this -> find ( 'list' , array ( 'recursive' => - 1 , 'fields' => array ( 'type' , 'id' )));
}
2016-12-05 00:47:34 +01:00
2020-12-17 13:29:11 +01:00
private function __update_prepare_template ( array $cluster_package , array $galaxies )
2020-11-23 19:38:19 +01:00
{
return [
'source' => isset ( $cluster_package [ 'source' ]) ? $cluster_package [ 'source' ] : '' ,
2021-07-27 21:10:45 +02:00
'authors' => json_encode ( isset ( $cluster_package [ 'authors' ]) ? $cluster_package [ 'authors' ] : array ()),
2020-11-23 19:38:19 +01:00
'collection_uuid' => isset ( $cluster_package [ 'uuid' ]) ? $cluster_package [ 'uuid' ] : '' ,
'galaxy_id' => $galaxies [ $cluster_package [ 'type' ]],
'type' => $cluster_package [ 'type' ],
'tag_name' => 'misp-galaxy:' . $cluster_package [ 'type' ] . '="'
];
}
2022-03-27 18:45:14 +02:00
/**
* @ param array $galaxies
* @ param array $cluster_package
* @ return array
*/
2020-12-17 13:29:11 +01:00
private function __getPreExistingClusters ( array $galaxies , array $cluster_package )
2020-11-23 19:38:19 +01:00
{
$temp = $this -> GalaxyCluster -> find ( 'all' , array (
'conditions' => array (
'GalaxyCluster.galaxy_id' => $galaxies [ $cluster_package [ 'type' ]]
),
'recursive' => - 1 ,
'fields' => array ( 'version' , 'id' , 'value' , 'uuid' )
));
2022-03-27 18:45:14 +02:00
return array_column ( array_column ( $temp , 'GalaxyCluster' ), null , 'value' );
2020-11-23 19:38:19 +01:00
}
2020-12-17 13:29:11 +01:00
private function __deleteOutdated ( bool $force , array $cluster_package , array $existingClusters )
2020-11-23 19:38:19 +01:00
{
// Delete all existing outdated clusters
$cluster_ids_to_delete = array ();
$cluster_uuids_to_delete = array ();
foreach ( $cluster_package [ 'values' ] as $k => $cluster ) {
if ( empty ( $cluster [ 'value' ])) {
continue ;
}
if ( isset ( $cluster [ 'version' ])) {
} elseif ( ! empty ( $cluster_package [ 'version' ])) {
$cluster_package [ 'values' ][ $k ][ 'version' ] = $cluster_package [ 'version' ];
} else {
$cluster_package [ 'values' ][ $k ][ 'version' ] = 0 ;
}
2022-03-27 18:45:14 +02:00
if ( isset ( $existingClusters [ $cluster [ 'value' ]])) {
$existing = $existingClusters [ $cluster [ 'value' ]];
if ( $force || $existing [ 'version' ] < $cluster_package [ 'values' ][ $k ][ 'version' ]) {
$cluster_ids_to_delete [] = $existing [ 'id' ];
$cluster_uuids_to_delete [] = $existing [ 'uuid' ];
2020-11-23 19:38:19 +01:00
} else {
unset ( $cluster_package [ 'values' ][ $k ]);
}
}
}
if ( ! empty ( $cluster_ids_to_delete )) {
2022-03-27 18:45:14 +02:00
$this -> GalaxyCluster -> GalaxyElement -> deleteAll ( array ( 'GalaxyElement.galaxy_cluster_id' => $cluster_ids_to_delete ), false );
$this -> GalaxyCluster -> GalaxyClusterRelation -> deleteAll ( array ( 'GalaxyClusterRelation.galaxy_cluster_uuid' => $cluster_uuids_to_delete ));
$this -> GalaxyCluster -> deleteAll ( array ( 'GalaxyCluster.id' => $cluster_ids_to_delete ), false );
2020-11-23 19:38:19 +01:00
}
return $cluster_package ;
}
2020-12-17 13:29:11 +01:00
private function __createClusters ( $cluster_package , $template )
2020-11-23 19:38:19 +01:00
{
$relations = [];
$elements = [];
$this -> GalaxyCluster -> bulkEntry = true ;
2021-10-30 23:05:11 +02:00
// Start transaction
$this -> getDataSource () -> begin ();
2020-11-23 19:38:19 +01:00
foreach ( $cluster_package [ 'values' ] as $cluster ) {
if ( empty ( $cluster [ 'version' ])) {
$cluster [ 'version' ] = 1 ;
}
$template [ 'version' ] = $cluster [ 'version' ];
$this -> GalaxyCluster -> create ();
$cluster_to_save = $template ;
if ( isset ( $cluster [ 'description' ])) {
$cluster_to_save [ 'description' ] = $cluster [ 'description' ];
unset ( $cluster [ 'description' ]);
}
$cluster_to_save [ 'value' ] = $cluster [ 'value' ];
$cluster_to_save [ 'tag_name' ] = $cluster_to_save [ 'tag_name' ] . $cluster [ 'value' ] . '"' ;
if ( ! empty ( $cluster [ 'uuid' ])) {
$cluster_to_save [ 'uuid' ] = $cluster [ 'uuid' ];
}
unset ( $cluster [ 'value' ]);
if ( empty ( $cluster_to_save [ 'description' ])) {
$cluster_to_save [ 'description' ] = '' ;
}
$cluster_to_save [ 'distribution' ] = 3 ;
$cluster_to_save [ 'default' ] = true ;
$cluster_to_save [ 'published' ] = false ;
$cluster_to_save [ 'org_id' ] = 0 ;
$cluster_to_save [ 'orgc_id' ] = 0 ;
2021-10-30 23:05:11 +02:00
// We are already in transaction
$result = $this -> GalaxyCluster -> save ( $cluster_to_save , [ 'atomic' => false , 'validate' => false ]);
if ( ! $result ) {
$this -> log ( " Could not save galaxy cluster with UUID { $cluster_to_save [ 'uuid' ] } . " );
continue ;
}
2020-11-23 19:38:19 +01:00
$galaxyClusterId = $this -> GalaxyCluster -> id ;
if ( isset ( $cluster [ 'meta' ])) {
foreach ( $cluster [ 'meta' ] as $key => $value ) {
if ( ! is_array ( $value )) {
$value = [ $value ];
}
foreach ( $value as $v ) {
2021-04-26 13:26:29 +02:00
if ( is_array ( $v )) {
$this -> Log = ClassRegistry :: init ( 'Log' );
$this -> Log -> create ();
$this -> Log -> save ( array (
2021-04-26 13:44:12 +02:00
'org' => 'SYSTEM' ,
2021-04-26 13:26:29 +02:00
'model' => 'Galaxy' ,
'model_id' => 0 ,
'email' => 0 ,
'action' => 'error' ,
'title' => sprintf ( 'Found a malformed galaxy cluster (%s) during the update, skipping. Reason: Malformed meta field, embedded array found.' , $cluster [ 'uuid' ]),
'change' => ''
));
} else {
$elements [] = array (
$galaxyClusterId ,
$key ,
2021-10-30 23:05:11 +02:00
( string ) $v
2021-04-26 13:26:29 +02:00
);
}
2020-11-23 19:38:19 +01:00
}
}
}
if ( isset ( $cluster [ 'related' ])) {
2021-07-27 21:10:45 +02:00
foreach ( $cluster [ 'related' ] as $relation ) {
2020-11-23 19:38:19 +01:00
$relations [] = [
'galaxy_cluster_id' => $galaxyClusterId ,
'galaxy_cluster_uuid' => $cluster [ 'uuid' ],
'referenced_galaxy_cluster_uuid' => $relation [ 'dest-uuid' ],
'referenced_galaxy_cluster_type' => $relation [ 'type' ],
'default' => true ,
'distribution' => 3 ,
2021-10-30 23:05:11 +02:00
'tags' => $relation [ 'tags' ] ? ? []
2020-11-23 19:38:19 +01:00
];
}
}
}
2021-10-30 23:05:11 +02:00
// Commit transaction
$this -> getDataSource () -> commit ();
2020-11-23 19:38:19 +01:00
return [ $elements , $relations ];
}
2018-07-19 11:48:22 +02:00
public function update ( $force = false )
{
$galaxies = $this -> __load_galaxies ( $force );
2021-11-14 16:42:21 +01:00
$files = new GlobIterator ( APP . 'files' . DS . 'misp-galaxy' . DS . 'clusters' . DS . '*.json' );
2020-11-23 22:30:54 +01:00
$force = ( bool ) $force ;
2021-10-30 23:05:11 +02:00
$allRelations = [];
2018-07-19 11:48:22 +02:00
foreach ( $files as $file ) {
2021-11-14 16:42:21 +01:00
$cluster_package = FileAccessTool :: readJsonFromFile ( $file -> getPathname ());
2018-07-19 11:48:22 +02:00
if ( ! isset ( $galaxies [ $cluster_package [ 'type' ]])) {
continue ;
}
2020-11-23 19:38:19 +01:00
$template = $this -> __update_prepare_template ( $cluster_package , $galaxies );
$existingClusters = $this -> __getPreExistingClusters ( $galaxies , $cluster_package );
$cluster_package = $this -> __deleteOutdated ( $force , $cluster_package , $existingClusters );
2018-07-04 13:08:47 +02:00
2018-07-19 11:48:22 +02:00
// create all clusters
2020-11-23 19:38:19 +01:00
list ( $elements , $relations ) = $this -> __createClusters ( $cluster_package , $template );
2018-07-19 11:48:22 +02:00
if ( ! empty ( $elements )) {
2020-11-19 23:36:11 +01:00
$db = $this -> getDataSource ();
$fields = array ( 'galaxy_cluster_id' , 'key' , 'value' );
2018-07-19 11:48:22 +02:00
$db -> insertMulti ( 'galaxy_elements' , $fields , $elements );
}
2021-10-30 23:05:11 +02:00
$allRelations = array_merge ( $allRelations , $relations );
}
// Save relation as last part when all clusters are created
if ( ! empty ( $allRelations )) {
$this -> GalaxyCluster -> GalaxyClusterRelation -> bulkSaveRelations ( $allRelations );
2018-07-19 11:48:22 +02:00
}
2021-10-30 23:05:11 +02:00
// Probably unnecessary anymore
2020-11-23 19:38:19 +01:00
$this -> GalaxyCluster -> generateMissingRelations ();
2018-07-19 11:48:22 +02:00
return true ;
}
2018-07-04 13:08:47 +02:00
2020-05-20 10:33:33 +02:00
/**
* Capture the Galaxy
*
* @ param $user
2020-07-08 09:30:24 +02:00
* @ param array $user
* @ param array $galaxy The galaxy to be captured
2020-05-20 10:33:33 +02:00
* @ return array the captured galaxy
*/
2020-07-08 09:30:24 +02:00
public function captureGalaxy ( array $user , array $galaxy )
2020-05-20 10:33:33 +02:00
{
2020-07-08 09:30:24 +02:00
if ( empty ( $galaxy [ 'uuid' ])) {
return false ;
}
2020-05-20 10:33:33 +02:00
$existingGalaxy = $this -> find ( 'first' , array (
'recursive' => - 1 ,
'conditions' => array ( 'Galaxy.uuid' => $galaxy [ 'uuid' ])
));
if ( empty ( $existingGalaxy )) {
if ( $user [ 'Role' ][ 'perm_site_admin' ] || $user [ 'Role' ][ 'perm_galaxy_editor' ]) {
$this -> create ();
unset ( $galaxy [ 'id' ]);
$this -> save ( $galaxy );
$existingGalaxy = $this -> find ( 'first' , array (
'recursive' => - 1 ,
'conditions' => array ( 'Galaxy.id' => $this -> id )
));
} else {
return false ;
}
}
return $existingGalaxy ;
}
/**
2020-07-08 09:30:24 +02:00
* Import all clusters into the Galaxy they are shipped with , creating the galaxy if not existant .
2020-05-20 10:33:33 +02:00
*
2020-07-08 09:30:24 +02:00
* This function is meant to be used with manual import or push from remote instance
2020-05-20 10:33:33 +02:00
* @ param $user
* @ param array $clusters clusters to import
2020-07-08 09:30:24 +02:00
* @ return array The import result with errors if any
2020-05-20 10:33:33 +02:00
*/
2020-07-08 09:30:24 +02:00
public function importGalaxyAndClusters ( $user , array $clusters )
2020-05-20 10:33:33 +02:00
{
$results = array ( 'success' => false , 'imported' => 0 , 'ignored' => 0 , 'failed' => 0 , 'errors' => array ());
foreach ( $clusters as $k => $cluster ) {
$conditions = array ();
2020-06-09 11:45:59 +02:00
if ( ! empty ( $cluster [ 'GalaxyCluster' ][ 'Galaxy' ])) {
$existingGalaxy = $this -> captureGalaxy ( $user , $cluster [ 'GalaxyCluster' ][ 'Galaxy' ]);
2020-07-08 09:30:24 +02:00
} elseif ( ! empty ( $cluster [ 'GalaxyCluster' ][ 'type' ])) {
2020-05-20 10:33:33 +02:00
$existingGalaxy = $this -> find ( 'first' , array (
'recursive' => - 1 ,
'fields' => array ( 'id' , 'version' ),
2020-07-08 09:30:24 +02:00
'conditions' => array ( 'Galaxy.type' => $cluster [ 'GalaxyCluster' ][ 'type' ]),
2020-05-20 10:33:33 +02:00
));
if ( empty ( $existingGalaxy )) { // We don't have enough info to create the galaxy
$results [ 'failed' ] ++ ;
$results [ 'errors' ][] = __ ( 'Galaxy not found' );
continue ;
}
} else { // We don't have the galaxy nor can create it
$results [ 'failed' ] ++ ;
$results [ 'errors' ][] = __ ( 'Galaxy not found' );
continue ;
}
2020-06-08 11:10:59 +02:00
$cluster [ 'GalaxyCluster' ][ 'galaxy_id' ] = $existingGalaxy [ 'Galaxy' ][ 'id' ];
2020-06-08 11:53:15 +02:00
$cluster [ 'GalaxyCluster' ][ 'locked' ] = true ;
2020-06-15 14:37:37 +02:00
$saveResult = $this -> GalaxyCluster -> captureCluster ( $user , $cluster , $fromPull = false );
if ( empty ( $saveResult [ 'errors' ])) {
$results [ 'imported' ] += $saveResult [ 'imported' ];
2020-06-09 11:01:25 +02:00
} else {
2020-06-15 14:37:37 +02:00
$results [ 'ignored' ] += $saveResult [ 'ignored' ];
$results [ 'failed' ] += $saveResult [ 'failed' ];
$results [ 'errors' ] = array_merge ( $results [ 'errors' ], $saveResult [ 'errors' ]);
2020-06-09 11:01:25 +02:00
}
2020-05-20 10:33:33 +02:00
}
2020-06-09 11:01:25 +02:00
$results [ 'success' ] = ! ( $results [ 'failed' ] > 0 && $results [ 'imported' ] == 0 );
2020-05-20 10:33:33 +02:00
return $results ;
}
2022-04-24 14:53:43 +02:00
/**
* @ param array $user
* @ param string $target_type
* @ param int $target_id
* @ param int $cluster_id
* @ param bool $local
* @ return string
* @ throws Exception
*/
public function attachCluster ( array $user , $target_type , $target_id , $cluster_id , $local = false )
2018-07-19 11:48:22 +02:00
{
2018-12-28 12:54:22 +01:00
$connectorModel = Inflector :: camelize ( $target_type ) . 'Tag' ;
2022-04-24 14:53:43 +02:00
$local = $local == 1 || $local === true ? 1 : 0 ;
2021-10-28 11:59:06 +02:00
$cluster_alias = $this -> GalaxyCluster -> alias ;
$galaxy_alias = $this -> alias ;
2020-06-17 15:01:23 +02:00
$cluster = $this -> GalaxyCluster -> fetchGalaxyClusters ( $user , array (
'first' => true ,
2021-10-28 11:59:06 +02:00
'conditions' => array ( " ${ cluster_alias } .id " => $cluster_id ),
'contain' => array ( 'Galaxy' ),
'fields' => array ( 'tag_name' , 'id' , 'value' , " ${ galaxy_alias } .local_only " ),
2022-04-24 14:53:43 +02:00
));
2021-10-27 16:46:56 +02:00
2020-06-17 15:01:23 +02:00
if ( empty ( $cluster )) {
throw new NotFoundException ( __ ( 'Invalid Galaxy cluster' ));
}
2022-04-24 14:53:43 +02:00
$local_only = $cluster [ 'GalaxyCluster' ][ 'Galaxy' ][ 'local_only' ];
if ( $local_only && ! $local ) {
throw new MethodNotAllowedException ( __ ( " This Cluster can only be attached in a local scope " ));
}
2018-07-19 11:48:22 +02:00
$this -> Tag = ClassRegistry :: init ( 'Tag' );
2018-12-28 12:54:22 +01:00
if ( $target_type === 'event' ) {
2022-04-24 14:53:43 +02:00
$target = $this -> Tag -> EventTag -> Event -> fetchSimpleEvent ( $user , $target_id );
2018-12-28 12:54:22 +01:00
} elseif ( $target_type === 'attribute' ) {
2022-04-24 14:53:43 +02:00
$target = $this -> Tag -> AttributeTag -> Attribute -> fetchAttributeSimple ( $user , array ( 'conditions' => array ( 'Attribute.id' => $target_id )));
2018-12-28 12:54:22 +01:00
} elseif ( $target_type === 'tag_collection' ) {
$target = $this -> Tag -> TagCollectionTag -> TagCollection -> fetchTagCollection ( $user , array ( 'conditions' => array ( 'TagCollection.id' => $target_id )));
2022-04-24 14:53:43 +02:00
if ( ! empty ( $target )) {
$target = $target [ 0 ];
}
2018-12-28 12:54:22 +01:00
}
if ( empty ( $target )) {
throw new NotFoundException ( __ ( 'Invalid %s.' , $target_type ));
}
2021-10-27 16:46:56 +02:00
$tag_id = $this -> Tag -> captureTag ( array ( 'name' => $cluster [ 'GalaxyCluster' ][ 'tag_name' ], 'colour' => '#0088cc' , 'exportable' => 1 , 'local_only' => $local_only ), $user , true );
2022-04-24 14:53:43 +02:00
$existingTag = $this -> Tag -> $connectorModel -> hasAny ( array ( $target_type . '_id' => $target_id , 'tag_id' => $tag_id ));
if ( $existingTag ) {
2018-12-28 12:54:22 +01:00
return 'Cluster already attached.' ;
}
$this -> Tag -> $connectorModel -> create ();
2019-07-08 11:39:41 +02:00
$toSave = array ( $target_type . '_id' => $target_id , 'tag_id' => $tag_id , 'local' => $local );
2018-12-28 12:54:22 +01:00
if ( $target_type === 'attribute' ) {
2018-07-19 11:48:22 +02:00
$event = $this -> Tag -> EventTag -> Event -> find ( 'first' , array (
'conditions' => array (
2018-12-28 12:54:22 +01:00
'Event.id' => $target [ 'Attribute' ][ 'event_id' ]
2018-07-19 11:48:22 +02:00
),
'recursive' => - 1
));
2018-12-28 12:54:22 +01:00
$toSave [ 'event_id' ] = $target [ 'Attribute' ][ 'event_id' ];
2018-07-19 11:48:22 +02:00
}
2018-12-28 12:54:22 +01:00
$result = $this -> Tag -> $connectorModel -> save ( $toSave );
2018-07-19 11:48:22 +02:00
if ( $result ) {
2018-12-28 12:54:22 +01:00
if ( $target_type !== 'tag_collection' ) {
2021-02-03 14:52:47 +01:00
$date = new DateTime ();
2018-12-28 12:54:22 +01:00
if ( $target_type === 'event' ) {
$event = $target ;
2021-02-03 14:52:47 +01:00
} else if ( $target_type === 'attribute' ) {
$target [ 'Attribute' ][ 'timestamp' ] = $date -> getTimestamp ();
$this -> Tag -> AttributeTag -> Attribute -> save ( $target );
if ( ! empty ( $target [ 'Attribute' ][ 'object_id' ])) {
$container_object = $this -> Tag -> AttributeTag -> Attribute -> Object -> find ( 'first' , [
'recursive' => - 1 ,
'conditions' => [ 'id' => $target [ 'Attribute' ][ 'object_id' ]]
]);
$container_object [ 'Object' ][ 'timestamp' ] = $date -> getTimestamp ();
$this -> Tag -> AttributeTag -> Attribute -> Object -> save ( $container_object );
}
2018-12-28 12:54:22 +01:00
}
$this -> Tag -> EventTag -> Event -> insertLock ( $user , $event [ 'Event' ][ 'id' ]);
$event [ 'Event' ][ 'published' ] = 0 ;
$event [ 'Event' ][ 'timestamp' ] = $date -> getTimestamp ();
$this -> Tag -> EventTag -> Event -> save ( $event );
}
2022-04-24 14:53:43 +02:00
$logTitle = 'Attached ' . $cluster [ 'GalaxyCluster' ][ 'value' ] . ' (' . $cluster [ 'GalaxyCluster' ][ 'id' ] . ') to ' . $target_type . ' (' . $target_id . ')' ;
$this -> loadLog () -> createLogEntry ( $user , 'galaxy' , ucfirst ( $target_type ), $target_id , $logTitle );
2018-07-19 11:48:22 +02:00
return 'Cluster attached.' ;
}
return 'Could not attach the cluster' ;
}
2018-07-04 13:08:47 +02:00
2020-07-07 08:16:46 +02:00
public function detachCluster ( $user , $target_type , $target_id , $cluster_id )
{
2019-01-16 15:59:49 +01:00
$cluster = $this -> GalaxyCluster -> find ( 'first' , array (
'recursive' => - 1 ,
'conditions' => array ( 'id' => $cluster_id ),
'fields' => array ( 'tag_name' , 'id' , 'value' )
));
$this -> Tag = ClassRegistry :: init ( 'Tag' );
if ( $target_type === 'event' ) {
$target = $this -> Tag -> EventTag -> Event -> fetchEvent ( $user , array ( 'eventid' => $target_id , 'metadata' => 1 ));
if ( empty ( $target )) {
throw new NotFoundException ( __ ( 'Invalid %s.' , $target_type ));
}
$target = $target [ 0 ];
$event = $target ;
$org_id = $event [ 'Event' ][ 'org_id' ];
$orgc_id = $event [ 'Event' ][ 'orgc_id' ];
} elseif ( $target_type === 'attribute' ) {
$target = $this -> Tag -> AttributeTag -> Attribute -> fetchAttributes ( $user , array ( 'conditions' => array ( 'Attribute.id' => $target_id ), 'flatten' => 1 ));
if ( empty ( $target )) {
throw new NotFoundException ( __ ( 'Invalid %s.' , $target_type ));
}
$target = $target [ 0 ];
$event_id = $target [ 'Attribute' ][ 'event_id' ];
$event = $this -> Tag -> EventTag -> Event -> fetchEvent ( $user , array ( 'eventid' => $event_id , 'metadata' => 1 ));
if ( empty ( $event )) {
throw new NotFoundException ( __ ( 'Invalid event' ));
}
$event = $event [ 0 ];
$org_id = $event [ 'Event' ][ 'org_id' ];
$orgc_id = $event [ 'Event' ][ 'org_id' ];
} elseif ( $target_type === 'tag_collection' ) {
$target = $this -> Tag -> TagCollectionTag -> TagCollection -> fetchTagCollection ( $user , array ( 'conditions' => array ( 'TagCollection.id' => $target_id )));
if ( empty ( $target )) {
throw new NotFoundException ( __ ( 'Invalid %s.' , $target_type ));
}
$target = $target [ 0 ];
$org_id = $target [ 'org_id' ];
$orgc_id = $org_id ;
}
if ( ! $user [ 'Role' ][ 'perm_site_admin' ] && ! $user [ 'Role' ][ 'perm_sync' ]) {
2019-01-18 11:59:24 +01:00
if (
2022-04-24 13:38:19 +02:00
( $target_type === 'tag_collection' && ! $user [ 'Role' ][ 'perm_tag_editor' ]) ||
( $target_type !== 'tag_collection' && ! $user [ 'Role' ][ 'perm_tagger' ]) ||
2019-01-18 11:59:24 +01:00
( $user [ 'org_id' ] !== $org_id && $user [ 'org_id' ] !== $orgc_id )
) {
2022-04-24 13:38:19 +02:00
throw new MethodNotAllowedException ( 'Invalid ' . Inflector :: humanize ( $target_type ) . '.' );
2019-01-16 15:59:49 +01:00
}
}
$tag_id = $this -> Tag -> captureTag ( array ( 'name' => $cluster [ 'GalaxyCluster' ][ 'tag_name' ], 'colour' => '#0088cc' , 'exportable' => 1 ), $user );
if ( $target_type == 'attribute' ) {
$existingTargetTag = $this -> Tag -> AttributeTag -> find ( 'first' , array (
'conditions' => array ( 'AttributeTag.tag_id' => $tag_id , 'AttributeTag.attribute_id' => $target_id ),
'recursive' => - 1 ,
'contain' => array ( 'Tag' )
));
} elseif ( $target_type == 'event' ) {
$existingTargetTag = $this -> Tag -> EventTag -> find ( 'first' , array (
'conditions' => array ( 'EventTag.tag_id' => $tag_id , 'EventTag.event_id' => $target_id ),
'recursive' => - 1 ,
'contain' => array ( 'Tag' )
));
} elseif ( $target_type == 'tag_collection' ) {
$existingTargetTag = $this -> Tag -> TagCollectionTag -> TagCollection -> find ( 'first' , array (
'conditions' => array ( 'tag_id' => $tag_id , 'tag_collection_id' => $target_id ),
'recursive' => - 1 ,
'contain' => array ( 'Tag' )
));
}
if ( empty ( $existingTargetTag )) {
return 'Cluster not attached.' ;
} else {
if ( $target_type == 'event' ) {
$result = $this -> Tag -> EventTag -> delete ( $existingTargetTag [ 'EventTag' ][ 'id' ]);
} elseif ( $target_type == 'attribute' ) {
$result = $this -> Tag -> AttributeTag -> delete ( $existingTargetTag [ 'AttributeTag' ][ 'id' ]);
} elseif ( $target_type == 'tag_collection' ) {
$result = $this -> Tag -> TagCollectionTag -> delete ( $existingTargetTag [ 'TagCollectionTag' ][ 'id' ]);
}
if ( $result ) {
if ( $target_type !== 'tag_collection' ) {
$this -> Tag -> EventTag -> Event -> insertLock ( $user , $event [ 'Event' ][ 'id' ]);
$event [ 'Event' ][ 'published' ] = 0 ;
$date = new DateTime ();
$event [ 'Event' ][ 'timestamp' ] = $date -> getTimestamp ();
$this -> Tag -> EventTag -> Event -> save ( $event );
}
2022-04-24 12:57:26 +02:00
2022-04-24 13:38:19 +02:00
$logTitle = 'Detached ' . $cluster [ 'GalaxyCluster' ][ 'value' ] . ' (' . $cluster [ 'GalaxyCluster' ][ 'id' ] . ') to ' . $target_type . ' (' . $target_id . ')' ;
2022-04-24 12:57:26 +02:00
$this -> loadLog () -> createLogEntry ( $user , 'galaxy' , ucfirst ( $target_type ), $target_id , $logTitle );
2019-01-16 15:59:49 +01:00
return 'Cluster detached' ;
} else {
return 'Could not detach cluster' ;
}
}
}
2022-04-24 18:29:32 +02:00
/**
* @ param array $user
* @ param int $targetId
2022-04-25 10:31:39 +02:00
* @ param string $targetType Can be 'attribute' , 'event' or 'tag_collection'
2022-04-24 18:29:32 +02:00
* @ param int $tagId
* @ return void
* @ throws Exception
*/
public function detachClusterByTagId ( array $user , $targetId , $targetType , $tagId )
{
if ( $targetType === 'attribute' ) {
$attribute = $this -> GalaxyCluster -> Tag -> EventTag -> Event -> Attribute -> find ( 'first' , array (
'recursive' => - 1 ,
'fields' => array ( 'id' , 'event_id' ),
'conditions' => array ( 'Attribute.id' => $targetId )
));
if ( empty ( $attribute )) {
throw new NotFoundException ( 'Invalid Attribute.' );
}
$event_id = $attribute [ 'Attribute' ][ 'event_id' ];
} elseif ( $targetType === 'event' ) {
$event_id = $targetId ;
} elseif ( $targetType !== 'tag_collection' ) {
2022-04-25 10:31:39 +02:00
throw new InvalidArgumentException ( 'Invalid target type' );
2022-04-24 18:29:32 +02:00
}
if ( $targetType === 'tag_collection' ) {
$tag_collection = $this -> GalaxyCluster -> Tag -> TagCollectionTag -> TagCollection -> fetchTagCollection ( $user , array (
'conditions' => array ( 'TagCollection.id' => $targetId ),
2022-04-25 10:31:39 +02:00
'recursive' => - 1 ,
2022-04-24 18:29:32 +02:00
));
if ( empty ( $tag_collection )) {
throw new NotFoundException ( 'Invalid Tag Collection' );
}
$tag_collection = $tag_collection [ 0 ];
2022-04-25 10:31:39 +02:00
if ( ! $user [ 'Role' ][ 'perm_site_admin' ]) {
if ( ! $user [ 'Role' ][ 'perm_tag_editor' ] || $user [ 'org_id' ] !== $tag_collection [ 'TagCollection' ][ 'org_id' ]) {
2022-04-24 18:29:32 +02:00
throw new NotFoundException ( 'Invalid Tag Collection' );
}
}
} else {
$event = $this -> GalaxyCluster -> Tag -> EventTag -> Event -> fetchSimpleEvent ( $user , $event_id );
if ( empty ( $event )) {
throw new NotFoundException ( 'Invalid Event.' );
}
2022-04-25 10:31:39 +02:00
if ( ! $user [ 'Role' ][ 'perm_site_admin' ] && ! $user [ 'Role' ][ 'perm_sync' ]) {
if ( ! $user [ 'Role' ][ 'perm_tagger' ] || ( $user [ 'org_id' ] !== $event [ 'Event' ][ 'org_id' ] && $user [ 'org_id' ] !== $event [ 'Event' ][ 'orgc_id' ])) {
2022-04-24 18:29:32 +02:00
throw new NotFoundException ( 'Invalid Event.' );
}
}
}
if ( $targetType === 'attribute' ) {
$existingTargetTag = $this -> GalaxyCluster -> Tag -> AttributeTag -> find ( 'first' , array (
'conditions' => array ( 'AttributeTag.tag_id' => $tagId , 'AttributeTag.attribute_id' => $targetId ),
'recursive' => - 1 ,
'contain' => array ( 'Tag' )
));
} elseif ( $targetType === 'event' ) {
$existingTargetTag = $this -> GalaxyCluster -> Tag -> EventTag -> find ( 'first' , array (
'conditions' => array ( 'EventTag.tag_id' => $tagId , 'EventTag.event_id' => $targetId ),
'recursive' => - 1 ,
'contain' => array ( 'Tag' )
));
} elseif ( $targetType === 'tag_collection' ) {
$existingTargetTag = $this -> GalaxyCluster -> Tag -> TagCollectionTag -> find ( 'first' , array (
'conditions' => array ( 'TagCollectionTag.tag_id' => $tagId , 'TagCollectionTag.tag_collection_id' => $targetId ),
'recursive' => - 1 ,
'contain' => array ( 'Tag' )
));
}
if ( empty ( $existingTargetTag )) {
throw new NotFoundException ( 'Galaxy not attached.' );
}
$cluster = $this -> GalaxyCluster -> find ( 'first' , array (
'recursive' => - 1 ,
'conditions' => array ( 'GalaxyCluster.tag_name' => $existingTargetTag [ 'Tag' ][ 'name' ])
));
if ( empty ( $cluster )) {
2022-04-25 10:31:39 +02:00
throw new NotFoundException ( 'Tag is not cluster' );
2022-04-24 18:29:32 +02:00
}
if ( $targetType === 'event' ) {
$result = $this -> GalaxyCluster -> Tag -> EventTag -> delete ( $existingTargetTag [ 'EventTag' ][ 'id' ]);
} elseif ( $targetType === 'attribute' ) {
$result = $this -> GalaxyCluster -> Tag -> AttributeTag -> delete ( $existingTargetTag [ 'AttributeTag' ][ 'id' ]);
} elseif ( $targetType === 'tag_collection' ) {
$result = $this -> GalaxyCluster -> Tag -> TagCollectionTag -> delete ( $existingTargetTag [ 'TagCollectionTag' ][ 'id' ]);
}
if ( ! $result ) {
throw new RuntimeException ( 'Could not detach galaxy from event.' );
}
if ( $targetType !== 'tag_collection' ) {
$event [ 'Event' ][ 'published' ] = 0 ;
$event [ 'Event' ][ 'timestamp' ] = time ();
$this -> GalaxyCluster -> Tag -> EventTag -> Event -> save ( $event );
}
$logTitle = 'Detached ' . $cluster [ 'GalaxyCluster' ][ 'value' ] . ' (' . $cluster [ 'GalaxyCluster' ][ 'id' ] . ') from ' . $targetType . ' (' . $targetId . ')' ;
$this -> loadLog () -> createLogEntry ( $user , 'galaxy' , ucfirst ( $targetType ), $targetId , $logTitle );
}
2019-02-15 09:24:52 +01:00
public function getMitreAttackGalaxyId ( $type = " mitre-attack-pattern " , $namespace = " mitre-attack " )
2018-07-19 11:48:22 +02:00
{
$galaxy = $this -> find ( 'first' , array (
'recursive' => - 1 ,
2019-12-18 17:40:00 +01:00
'fields' => array ( 'MAX(Galaxy.version) as latest_version' , 'id' ),
'conditions' => array (
'Galaxy.type' => $type ,
'Galaxy.namespace' => $namespace
),
2019-12-19 09:27:44 +01:00
'group' => array ( 'name' , 'id' )
2018-07-19 11:48:22 +02:00
));
return empty ( $galaxy ) ? 0 : $galaxy [ 'Galaxy' ][ 'id' ];
}
2018-05-14 23:20:09 +02:00
2019-03-12 15:36:00 +01:00
public function getAllowedMatrixGalaxies ()
{
$conditions = array (
'NOT' => array (
'kill_chain_order' => ''
)
);
$galaxies = $this -> find ( 'all' , array (
'recursive' => - 1 ,
'conditions' => $conditions ,
));
return $galaxies ;
}
2019-05-13 15:07:38 +02:00
public function getMatrix ( $galaxy_id , $scores = array ())
2018-07-19 11:48:22 +02:00
{
2019-02-15 09:24:52 +01:00
$conditions = array ( 'Galaxy.id' => $galaxy_id );
2018-07-19 11:48:22 +02:00
$contains = array (
'GalaxyCluster' => array ( 'GalaxyElement' ),
);
2018-06-18 11:58:20 +02:00
2019-02-15 09:24:52 +01:00
$galaxy = $this -> find ( 'first' , array (
2018-07-19 11:48:22 +02:00
'recursive' => - 1 ,
'contain' => $contains ,
'conditions' => $conditions ,
));
2018-06-18 11:58:20 +02:00
2018-07-19 11:48:22 +02:00
$mispUUID = Configure :: read ( 'MISP' )[ 'uuid' ];
2018-06-07 16:43:04 +02:00
2019-02-15 09:24:52 +01:00
if ( ! isset ( $galaxy [ 'Galaxy' ][ 'kill_chain_order' ])) {
2020-06-17 15:01:23 +02:00
throw new MethodNotAllowedException ( __ ( " Galaxy cannot be represented as a matrix " ));
2019-02-11 16:15:52 +01:00
}
2019-02-15 09:24:52 +01:00
$matrixData = array (
2019-02-14 10:24:42 +01:00
'killChain' => $galaxy [ 'Galaxy' ][ 'kill_chain_order' ],
2019-02-15 09:24:52 +01:00
'tabs' => array (),
'matrixTags' => array (),
'instance-uuid' => $mispUUID ,
'galaxy' => $galaxy [ 'Galaxy' ]
2019-02-14 10:24:42 +01:00
);
2019-02-11 16:15:52 +01:00
$clusters = $galaxy [ 'GalaxyCluster' ];
2019-02-15 09:24:52 +01:00
$cols = array ();
2019-02-11 16:15:52 +01:00
foreach ( $clusters as $cluster ) {
if ( empty ( $cluster [ 'GalaxyElement' ])) {
continue ;
}
2019-02-15 09:24:52 +01:00
2019-02-11 16:15:52 +01:00
$toBeAdded = false ;
$clusterType = $cluster [ 'type' ];
$galaxyElements = $cluster [ 'GalaxyElement' ];
foreach ( $galaxyElements as $element ) {
// add cluster if kill_chain is present
if ( $element [ 'key' ] == 'kill_chain' ) {
$kc = explode ( " : " , $element [ 'value' ]);
$galaxyType = $kc [ 0 ];
$kc = $kc [ 1 ];
2019-02-15 09:24:52 +01:00
$cols [ $galaxyType ][ $kc ][] = $cluster ;
2019-02-11 16:15:52 +01:00
$toBeAdded = true ;
2018-07-19 11:48:22 +02:00
}
2019-02-11 16:15:52 +01:00
if ( $element [ 'key' ] == 'external_id' ) {
$cluster [ 'external_id' ] = $element [ 'value' ];
2018-07-19 11:48:22 +02:00
}
if ( $toBeAdded ) {
2019-02-15 14:41:55 +01:00
$matrixData [ 'matrixTags' ][ $cluster [ 'tag_name' ]] = 1 ;
2018-07-19 11:48:22 +02:00
}
}
2019-02-11 16:15:52 +01:00
}
2019-02-15 09:24:52 +01:00
$matrixData [ 'tabs' ] = $cols ;
2019-02-11 16:15:52 +01:00
2019-05-13 15:07:38 +02:00
$this -> sortMatrixByScore ( $matrixData [ 'tabs' ], $scores );
2019-10-04 13:02:59 +02:00
// #FIXME temporary fix: retrieve tag name of deprecated mitre galaxies (for the stats)
2019-02-15 14:41:55 +01:00
if ( $galaxy [ 'Galaxy' ][ 'id' ] == $this -> getMitreAttackGalaxyId ()) {
$names = array ( 'Enterprise Attack - Attack Pattern' , 'Pre Attack - Attack Pattern' , 'Mobile Attack - Attack Pattern' );
$tag_names = array ();
$gals = $this -> find ( 'all' , array (
'recursive' => - 1 ,
'contain' => array ( 'GalaxyCluster.tag_name' ),
'conditions' => array ( 'Galaxy.name' => $names )
));
foreach ( $gals as $gal => $temp ) {
foreach ( $temp [ 'GalaxyCluster' ] as $value ) {
$matrixData [ 'matrixTags' ][ $value [ 'tag_name' ]] = 1 ;
}
}
}
2019-02-15 14:48:15 +01:00
// end FIXME
2019-02-15 14:41:55 +01:00
2019-02-15 14:48:15 +01:00
$matrixData [ 'matrixTags' ] = array_keys ( $matrixData [ 'matrixTags' ]);
2019-02-15 09:24:52 +01:00
return $matrixData ;
2018-07-19 11:48:22 +02:00
}
2019-05-13 15:07:38 +02:00
public function sortMatrixByScore ( & $tabs , $scores )
{
foreach ( array_keys ( $tabs ) as $i ) {
foreach ( array_keys ( $tabs [ $i ]) as $j ) {
// major ordering based on score, minor based on alphabetical
2020-07-07 08:16:46 +02:00
usort ( $tabs [ $i ][ $j ], function ( $a , $b ) use ( $scores ) {
2019-05-13 15:07:38 +02:00
if ( $a [ 'tag_name' ] == $b [ 'tag_name' ]) {
return 0 ;
}
if ( isset ( $scores [ $a [ 'tag_name' ]]) && isset ( $scores [ $b [ 'tag_name' ]])) {
if ( $scores [ $a [ 'tag_name' ]] < $scores [ $b [ 'tag_name' ]]) {
$ret = 1 ;
2020-07-07 08:16:46 +02:00
} elseif ( $scores [ $a [ 'tag_name' ]] == $scores [ $b [ 'tag_name' ]]) {
2019-05-13 15:07:38 +02:00
$ret = strcmp ( $a [ 'value' ], $b [ 'value' ]);
} else {
$ret = - 1 ;
}
2020-07-07 08:16:46 +02:00
} elseif ( isset ( $scores [ $a [ 'tag_name' ]])) {
2019-05-13 15:07:38 +02:00
$ret = - 1 ;
2020-07-07 08:16:46 +02:00
} elseif ( isset ( $scores [ $b [ 'tag_name' ]])) {
2019-05-13 15:07:38 +02:00
$ret = 1 ;
2019-05-15 14:12:08 +02:00
} else { // none are set
2019-05-13 15:07:38 +02:00
$ret = strcmp ( $a [ 'value' ], $b [ 'value' ]);
}
return $ret ;
});
}
}
}
2020-11-23 19:38:19 +01:00
2020-07-08 09:30:24 +02:00
/**
* generateForkTree
*
* @ param mixed $clusters The accessible cluster for the user to be arranged into a fork tree
* @ param mixed $galaxy The galaxy for which the fork tree is generated
* @ param bool $pruneRootLeaves Should the nonforked clusters be removed from the tree
* @ return array The generated fork tree where the children of a node are contained in the `children` key
*/
public function generateForkTree ( array $clusters , array $galaxy , $pruneRootLeaves = true )
2020-04-21 08:30:07 +02:00
{
$tree = array ();
$lookup = array ();
2020-04-30 14:41:07 +02:00
$lastNodeAdded = array ();
2020-04-21 08:37:57 +02:00
// generate the lookup table used to immediatly get the correct cluster
2020-04-21 08:30:07 +02:00
foreach ( $clusters as $i => $cluster ) {
$clusters [ $i ][ 'children' ] = array ();
$lookup [ $cluster [ 'GalaxyCluster' ][ 'id' ]] = & $clusters [ $i ];
}
foreach ( $clusters as $i => $cluster ) {
if ( ! empty ( $cluster [ 'GalaxyCluster' ][ 'extended_from' ])) {
$parent = $cluster [ 'GalaxyCluster' ][ 'extended_from' ];
2020-04-29 16:03:01 +02:00
$clusterVersion = $cluster [ 'GalaxyCluster' ][ 'extends_version' ];
$parentVersion = $lookup [ $parent [ 'GalaxyCluster' ][ 'id' ]][ 'GalaxyCluster' ][ 'version' ];
if ( $clusterVersion == $parentVersion ) {
$lookup [ $parent [ 'GalaxyCluster' ][ 'id' ]][ 'children' ][] = & $clusters [ $i ];
} else {
// version differs, insert version node between child and parent
$lastVersionNode = array (
'isVersion' => true ,
'isLast' => true ,
'version' => $parentVersion ,
'parentUuid' => $parent [ 'GalaxyCluster' ][ 'uuid' ],
'children' => array ()
);
$versionNode = array (
'isVersion' => true ,
'isLast' => false ,
'version' => $clusterVersion ,
'parentUuid' => $parent [ 'GalaxyCluster' ][ 'uuid' ],
'children' => array ( & $clusters [ $i ])
);
$lookup [ $parent [ 'GalaxyCluster' ][ 'id' ]][ 'children' ][] = $versionNode ;
2020-04-30 14:41:07 +02:00
if ( ! isset ( $lastNodeAdded [ $parent [ 'GalaxyCluster' ][ 'id' ]])) {
$lookup [ $parent [ 'GalaxyCluster' ][ 'id' ]][ 'children' ][] = $lastVersionNode ;
$lastNodeAdded [ $parent [ 'GalaxyCluster' ][ 'id' ]] = true ;
}
2020-04-29 16:03:01 +02:00
}
2020-04-21 08:30:07 +02:00
} else {
$tree [] = & $clusters [ $i ];
}
}
if ( $pruneRootLeaves ) {
2020-07-07 08:16:46 +02:00
foreach ( $tree as $i => $node ) {
2020-04-21 08:30:07 +02:00
if ( empty ( $node [ 'children' ])) {
unset ( $tree [ $i ]);
}
}
}
$tree = array ( array (
'Galaxy' => $galaxy [ 'Galaxy' ],
'children' => array_values ( $tree )
));
return $tree ;
}
2020-11-23 19:38:19 +01:00
2020-11-10 10:16:20 +01:00
/**
* convertToMISPGalaxyFormat
*
* @ param array $galaxy
* @ param array $clusters
* @ return array the converted clusters into the misp - galaxy format
2020-11-23 19:38:19 +01:00
*
2020-11-11 09:55:09 +01:00
* Special cases :
* - authors : ( since all clusters have their own , takes all of them )
* - version : Takes the higher version number of all clusters
* - uuid : Is actually the collection_uuid . Takes the last one
* - source ( since all clusters have their own , takes the last one )
* - category ( not saved in MISP nor used )
2020-11-10 10:16:20 +01:00
* - description ( not used as the description in the galaxy . json is used instead )
*/
public function convertToMISPGalaxyFormat ( $galaxy , $clusters )
{
$converted = [];
$converted [ 'name' ] = $galaxy [ 'Galaxy' ][ 'name' ];
$converted [ 'type' ] = $galaxy [ 'Galaxy' ][ 'type' ];
2020-11-11 09:55:09 +01:00
$converted [ 'authors' ] = [];
$converted [ 'version' ] = 0 ;
2020-11-10 10:16:20 +01:00
$values = [];
2020-11-11 09:55:09 +01:00
$fieldsToSave = [ 'description' , 'uuid' , 'value' , 'extends_uuid' , 'extends_version' ];
2020-11-10 10:16:20 +01:00
foreach ( $clusters as $i => $cluster ) {
foreach ( $fieldsToSave as $field ) {
$values [ $i ][ $field ] = $cluster [ 'GalaxyCluster' ][ $field ];
}
2020-11-11 09:55:09 +01:00
$converted [ 'uuid' ] = $cluster [ 'GalaxyCluster' ][ 'collection_uuid' ];
$converted [ 'source' ] = $cluster [ 'GalaxyCluster' ][ 'source' ];
if ( ! empty ( $cluster [ 'GalaxyCluster' ][ 'authors' ])) {
foreach ( $cluster [ 'GalaxyCluster' ][ 'authors' ] as $author ) {
if ( ! is_null ( $author ) && $author != 'null' ) {
$converted [ 'authors' ][ $author ] = $author ;
}
}
}
$converted [ 'version' ] = $converted [ 'version' ] > $cluster [ 'GalaxyCluster' ][ 'version' ];
2020-11-10 10:16:20 +01:00
foreach ( $cluster [ 'GalaxyCluster' ][ 'GalaxyElement' ] as $element ) {
if ( isset ( $values [ $i ][ 'meta' ][ $element [ 'key' ]])) {
if ( is_array ( $values [ $i ][ 'meta' ][ $element [ 'key' ]])) {
$values [ $i ][ 'meta' ][ $element [ 'key' ]][] = $element [ 'value' ];
} else {
$values [ $i ][ 'meta' ][ $element [ 'key' ]] = [ $values [ $i ][ 'meta' ][ $element [ 'key' ]], $element [ 'value' ]];
}
} else {
$values [ $i ][ 'meta' ][ $element [ 'key' ]] = $element [ 'value' ];
}
}
foreach ( $cluster [ 'GalaxyCluster' ][ 'GalaxyClusterRelation' ] as $j => $relation ) {
$values [ $i ][ 'related' ][ $j ] = [
'dest-uuid' => $relation [ 'referenced_galaxy_cluster_uuid' ],
'type' => $relation [ 'referenced_galaxy_cluster_type' ],
];
if ( ! empty ( $relation [ 'Tag' ])) {
foreach ( $relation [ 'Tag' ] as $tag ) {
$values [ $i ][ 'related' ][ $j ][ 'tags' ][] = $tag [ 'name' ];
}
}
}
}
2020-11-11 09:55:09 +01:00
$converted [ 'authors' ] = array_values ( $converted [ 'authors' ]);
2020-11-10 10:16:20 +01:00
$converted [ 'values' ] = $values ;
return $converted ;
}
2016-12-05 00:47:34 +01:00
}