2021-04-30 23:59:53 +02:00
< ? php
namespace MispConnector ;
require_once ( ROOT . '/src/Lib/default/local_tool_connectors/CommonConnectorTools.php' );
use CommonConnectorTools\CommonConnectorTools ;
use Cake\Http\Client ;
2021-06-01 07:48:06 +02:00
use Cake\Http\Exception\NotFoundException ;
use Cake\Http\Exception\MethodNotAllowedException ;
use Cake\Http\Client\Response ;
2021-04-30 23:59:53 +02:00
class MispConnector extends CommonConnectorTools
{
public $description = 'MISP connector, handling diagnostics, organisation and sharing group management of your instance. Synchronisation requests can also be managed through the connector.' ;
2021-06-01 07:48:06 +02:00
2021-06-17 14:13:10 +02:00
public $connectorName = 'MispConnector' ;
2021-04-30 23:59:53 +02:00
public $name = 'MISP' ;
2021-06-01 07:48:06 +02:00
2021-04-30 23:59:53 +02:00
public $exposedFunctions = [
2021-06-01 07:48:06 +02:00
'serverSettingsAction' => [
'type' => 'index' ,
'scope' => 'child' ,
'params' => [
'quickFilter' ,
'sort' ,
'direction' ,
'page' ,
'limit'
]
],
'organisationsAction' => [
'type' => 'index' ,
'scope' => 'child' ,
'params' => [
'quickFilter' ,
'limit' ,
'page' ,
'sort' ,
'direction'
]
],
'sharingGroupsAction' => [
'type' => 'index' ,
'scope' => 'child' ,
'params' => [
'quickFilter' ,
'limit' ,
'page' ,
'sort' ,
'direction'
]
],
'fetchOrganisationAction' => [
'type' => 'formAction' ,
'scope' => 'childAction' ,
'params' => [
'uuid'
],
'redirect' => 'organisationsAction'
],
'fetchSharingGroupAction' => [
'type' => 'formAction' ,
'scope' => 'childAction' ,
'params' => [
'uuid'
],
'redirect' => 'sharingGroupsAction'
],
'modifySettingAction' => [
'type' => 'formAction' ,
'scope' => 'childAction' ,
'params' => [
'setting' ,
'value'
],
'redirect' => 'serverSettingsAction'
2021-06-14 08:37:00 +02:00
],
'serversAction' => [
'type' => 'index' ,
'scope' => 'child' ,
'params' => [
'quickFilter' ,
'limit' ,
'page' ,
'sort' ,
'direction'
]
2021-06-28 10:45:23 +02:00
],
'usersAction' => [
'type' => 'index' ,
'scope' => 'child' ,
'params' => [
'quickFilter' ,
'limit' ,
'page' ,
'sort' ,
'direction'
]
2021-07-07 15:05:32 +02:00
],
'batchAPIAction' => [
'type' => 'batchAction' ,
'scope' => 'childAction' ,
'params' => [
'method' ,
'url' ,
'body' ,
],
'ui' => [
'text' => 'Batch API' ,
'icon' => 'terminal' ,
'variant' => 'primary' ,
]
2021-06-01 07:48:06 +02:00
]
2021-04-30 23:59:53 +02:00
];
public $version = '0.1' ;
2021-07-05 17:15:21 +02:00
public $settings = [
2021-07-05 14:14:17 +02:00
'url' => [
2021-07-05 17:15:21 +02:00
'type' => 'text'
2021-07-05 14:14:17 +02:00
],
'authkey' => [
2021-07-05 17:15:21 +02:00
'type' => 'text'
2021-07-05 14:14:17 +02:00
],
'skip_ssl' => [
2021-07-05 17:15:21 +02:00
'type' => 'boolean'
2021-07-05 14:14:17 +02:00
],
];
2021-04-30 23:59:53 +02:00
2021-07-05 17:15:21 +02:00
public function addSettingValidatorRules ( $validator )
{
return $validator
-> requirePresence ( 'url' )
-> notEmpty ( 'url' , __ ( 'An URL must be provided' ))
-> requirePresence ( 'authkey' )
-> notEmpty ( 'authkey' , __ ( 'An Authkey must be provided' ))
-> lengthBetween ( 'authkey' , [ 40 , 40 ], __ ( 'The authkey must be 40 character long' ))
-> boolean ( 'skip_ssl' );
}
2021-04-30 23:59:53 +02:00
public function addExposedFunction ( string $functionName ) : void
{
$this -> exposedFunctions [] = $functionName ;
}
2021-06-01 07:48:06 +02:00
public function getExposedFunction ( string $functionName ) : array
{
if ( ! empty ( $this -> exposedFunctions [ $functionName ])) {
return $exposedFunctions [ $functionName ];
} else {
throw new NotFoundException ( __ ( 'Invalid action requested.' ));
}
}
2021-06-28 10:18:49 +02:00
private function genHTTPClient ( Object $connection , array $options = []) : Object
2021-06-17 14:13:10 +02:00
{
$settings = json_decode ( $connection -> settings , true );
2021-06-28 10:18:49 +02:00
$defaultOptions = [
'headers' => [
'Authorization' => $settings [ 'authkey' ],
],
];
if ( empty ( $options [ 'type' ])) {
$options [ 'type' ] = 'json' ;
}
2021-06-16 09:48:07 +02:00
if ( ! empty ( $settings [ 'skip_ssl' ])) {
$options [ 'ssl_verify_peer' ] = false ;
$options [ 'ssl_verify_host' ] = false ;
$options [ 'ssl_verify_peer_name' ] = false ;
$options [ 'ssl_allow_self_signed' ] = true ;
}
2021-06-28 10:18:49 +02:00
$options = array_merge ( $defaultOptions , $options );
2021-06-16 09:48:07 +02:00
$http = new Client ( $options );
return $http ;
}
2021-06-28 10:18:49 +02:00
public function HTTPClientGET ( String $relativeURL , Object $connection , array $data = [], array $options = []) : Object
2021-04-30 23:59:53 +02:00
{
$settings = json_decode ( $connection -> settings , true );
2021-06-28 10:18:49 +02:00
$http = $this -> genHTTPClient ( $connection , $options );
$url = sprintf ( '%s%s' , $settings [ 'url' ], $relativeURL );
return $http -> get ( $url , $data , $options );
}
public function HTTPClientPOST ( String $relativeURL , Object $connection , $data , array $options = []) : Object
{
$settings = json_decode ( $connection -> settings , true );
$http = $this -> genHTTPClient ( $connection , $options );
$url = sprintf ( '%s%s' , $settings [ 'url' ], $relativeURL );
return $http -> post ( $url , $data , $options );
}
2021-06-16 09:48:07 +02:00
2021-06-28 10:18:49 +02:00
public function health ( Object $connection ) : array
{
2021-06-14 10:02:16 +02:00
try {
2021-06-28 10:18:49 +02:00
$response = $this -> HTTPClientPOST ( '/users/view/me.json' , $connection , '{}' );
2021-06-14 10:02:16 +02:00
} catch ( \Exception $e ) {
return [
'status' => 0 ,
'message' => __ ( 'Connection issue.' )
];
}
2021-04-30 23:59:53 +02:00
$responseCode = $response -> getStatusCode ();
if ( $response -> isOk ()) {
$status = 1 ;
$message = __ ( 'OK' );
} else if ( $responseCode == 403 ){
$status = 3 ;
$message = __ ( 'Unauthorized' );
} else {
$status = 0 ;
$message = __ ( 'Something went wrong.' );
}
return [
'status' => $status ,
'message' => $message
];
}
2021-06-01 07:48:06 +02:00
private function getData ( string $url , array $params ) : Response
2021-04-30 23:59:53 +02:00
{
if ( empty ( $params [ 'connection' ])) {
2021-06-01 07:48:06 +02:00
throw new NotFoundException ( __ ( 'No connection object received.' ));
2021-04-30 23:59:53 +02:00
}
2021-06-01 07:48:06 +02:00
if ( ! empty ( $params [ 'sort' ])) {
$list = explode ( '.' , $params [ 'sort' ]);
$params [ 'sort' ] = end ( $list );
2021-04-30 23:59:53 +02:00
}
2021-06-01 07:48:06 +02:00
if ( ! isset ( $params [ 'limit' ])) {
$params [ 'limit' ] = 50 ;
2021-04-30 23:59:53 +02:00
}
2021-06-01 07:48:06 +02:00
$url = $this -> urlAppendParams ( $url , $params );
2021-06-28 10:18:49 +02:00
$response = $this -> HTTPClientGET ( $url , $params [ 'connection' ]);
2021-04-30 23:59:53 +02:00
if ( $response -> isOk ()) {
2021-06-01 07:48:06 +02:00
return $response ;
} else {
2021-06-10 13:45:46 +02:00
if ( ! empty ( $params [ 'softError' ])) {
return $response ;
}
2021-06-01 07:48:06 +02:00
throw new NotFoundException ( __ ( 'Could not retrieve the requested resource.' ));
}
}
private function postData ( string $url , array $params ) : Response
{
if ( empty ( $params [ 'connection' ])) {
throw new NotFoundException ( __ ( 'No connection object received.' ));
}
$url = $this -> urlAppendParams ( $url , $params );
2021-07-07 15:05:32 +02:00
if ( ! is_string ( $params [ 'body' ])) {
$params [ 'body' ] = json_encode ( $params [ 'body' ]);
}
$response = $this -> HTTPClientPOST ( $url , $params [ 'connection' ], $params [ 'body' ]);
2021-06-01 07:48:06 +02:00
if ( $response -> isOk ()) {
return $response ;
} else {
2021-06-17 14:13:10 +02:00
throw new NotFoundException ( __ ( 'Could not post to the requested resource. Remote returned:' ) . PHP_EOL . $response -> getStringBody ());
2021-06-01 07:48:06 +02:00
}
}
public function urlAppendParams ( string $url , array $params ) : string
{
if ( ! isset ( $params [ 'validParams' ])) {
$validParams = [
'quickFilter' => 'searchall' ,
'sort' => 'sort' ,
'page' => 'page' ,
'direction' => 'direction' ,
'limit' => 'limit'
];
} else {
$validParams = $params [ 'validParams' ];
}
foreach ( $validParams as $param => $remoteParam ) {
if ( ! empty ( $params [ $param ])) {
$url .= sprintf ( '/%s:%s' , $remoteParam , $params [ $param ]);
}
}
return $url ;
}
public function diagnosticsAction ( array $params ) : array
{
}
public function serverSettingsAction ( array $params ) : array
{
$params [ 'validParams' ] = [
'limit' => 'limit' ,
'page' => 'page' ,
'quickFilter' => 'searchall'
];
$urlParams = h ( $params [ 'connection' ][ 'id' ]) . '/serverSettingsAction' ;
$response = $this -> getData ( '/servers/serverSettings' , $params );
$data = $response -> getJson ();
if ( ! empty ( $data [ 'finalSettings' ])) {
$finalSettings = [
2021-04-30 23:59:53 +02:00
'type' => 'index' ,
'data' => [
2021-06-01 07:48:06 +02:00
'data' => $data [ 'finalSettings' ],
'skip_pagination' => 1 ,
2021-04-30 23:59:53 +02:00
'top_bar' => [
'children' => [
[
'type' => 'search' ,
2021-11-10 15:31:09 +01:00
'button' => __ ( 'Search' ),
2021-04-30 23:59:53 +02:00
'placeholder' => __ ( 'Enter value to search' ),
'data' => '' ,
2021-06-01 07:48:06 +02:00
'searchKey' => 'value' ,
'additionalUrlParams' => $urlParams
2021-04-30 23:59:53 +02:00
]
]
],
'fields' => [
[
2021-06-01 07:48:06 +02:00
'name' => 'Setting' ,
'sort' => 'setting' ,
'data_path' => 'setting' ,
],
[
'name' => 'Criticality' ,
'sort' => 'level' ,
'data_path' => 'level' ,
'arrayData' => [
0 => 'Critical' ,
1 => 'Recommended' ,
2 => 'Optional'
],
'element' => 'array_lookup_field'
],
[
'name' => __ ( 'Value' ),
'sort' => 'value' ,
'data_path' => 'value' ,
2021-06-14 08:37:00 +02:00
'options' => 'options'
2021-06-01 07:48:06 +02:00
],
[
'name' => __ ( 'Type' ),
'sort' => 'type' ,
'data_path' => 'type' ,
2021-04-30 23:59:53 +02:00
],
[
2021-06-01 07:48:06 +02:00
'name' => __ ( 'Error message' ),
'sort' => 'errorMessage' ,
'data_path' => 'errorMessage' ,
]
],
'title' => false ,
'description' => false ,
'pull' => 'right' ,
'actions' => [
[
'open_modal' => '/localTools/action/' . h ( $params [ 'connection' ][ 'id' ]) . '/modifySettingAction?setting={{0}}' ,
'modal_params_data_path' => [ 'setting' ],
'icon' => 'download' ,
'reload_url' => '/localTools/action/' . h ( $params [ 'connection' ][ 'id' ]) . '/ServerSettingsAction'
]
]
]
];
if ( ! empty ( $params [ 'quickFilter' ])) {
$needle = strtolower ( $params [ 'quickFilter' ]);
foreach ( $finalSettings [ 'data' ][ 'data' ] as $k => $v ) {
if ( strpos ( strtolower ( $v [ 'setting' ]), $needle ) === false ) {
unset ( $finalSettings [ 'data' ][ 'data' ][ $k ]);
}
}
$finalSettings [ 'data' ][ 'data' ] = array_values ( $finalSettings [ 'data' ][ 'data' ]);
}
return $finalSettings ;
} else {
return [];
}
}
2021-06-14 08:37:00 +02:00
public function serversAction ( array $params ) : array
{
$params [ 'validParams' ] = [
'limit' => 'limit' ,
'page' => 'page' ,
'quickFilter' => 'searchall'
];
$urlParams = h ( $params [ 'connection' ][ 'id' ]) . '/serversAction' ;
$response = $this -> getData ( '/servers/index' , $params );
$data = $response -> getJson ();
if ( ! empty ( $data )) {
return [
'type' => 'index' ,
'data' => [
'data' => $data ,
'skip_pagination' => 1 ,
'top_bar' => [
'children' => [
[
'type' => 'search' ,
2021-11-10 15:31:09 +01:00
'button' => __ ( 'Search' ),
2021-06-14 08:37:00 +02:00
'placeholder' => __ ( 'Enter value to search' ),
'data' => '' ,
'searchKey' => 'value' ,
'additionalUrlParams' => $urlParams ,
'quickFilter' => 'value'
]
]
],
'fields' => [
[
'name' => 'Id' ,
'sort' => 'Server.id' ,
'data_path' => 'Server.id' ,
],
[
'name' => 'Name' ,
'sort' => 'Server.name' ,
'data_path' => 'Server.name' ,
],
[
'name' => 'Url' ,
'sort' => 'Server.url' ,
'data_path' => 'Server.url'
],
[
'name' => 'Pull' ,
'sort' => 'Server.pull' ,
'element' => 'function' ,
'function' => function ( $row , $context ) {
$pull = $context -> Hash -> extract ( $row , 'Server.pull' )[ 0 ];
$pull_rules = $context -> Hash -> extract ( $row , 'Server.pull_rules' )[ 0 ];
$pull_rules = json_encode ( json_decode ( $pull_rules , true ), JSON_PRETTY_PRINT );
echo sprintf (
'<span title="%s" class="fa fa-%s"></span>' ,
h ( $pull_rules ),
$pull ? 'check' : 'times'
);
}
],
[
'name' => 'Push' ,
'element' => 'function' ,
'function' => function ( $row , $context ) {
$push = $context -> Hash -> extract ( $row , 'Server.push' )[ 0 ];
$push_rules = $context -> Hash -> extract ( $row , 'Server.push_rules' )[ 0 ];
$push_rules = json_encode ( json_decode ( $push_rules , true ), JSON_PRETTY_PRINT );
echo sprintf (
'<span title="%s" class="fa fa-%s"></span>' ,
h ( $push_rules ),
$push ? 'check' : 'times'
);
}
],
[
'name' => 'Caching' ,
'element' => 'boolean' ,
'data_path' => 'Server.caching_enabled'
]
],
'title' => false ,
'description' => false ,
'pull' => 'right'
]
];
} else {
return [];
}
}
2021-06-28 10:45:23 +02:00
public function usersAction ( array $params ) : array
{
$params [ 'validParams' ] = [
'limit' => 'limit' ,
'page' => 'page' ,
'quickFilter' => 'searchall'
];
$urlParams = h ( $params [ 'connection' ][ 'id' ]) . '/usersAction' ;
$response = $this -> getData ( '/admin/users/index' , $params );
$data = $response -> getJson ();
if ( ! empty ( $data )) {
return [
'type' => 'index' ,
'data' => [
'data' => $data ,
'skip_pagination' => 1 ,
'top_bar' => [
'children' => [
[
'type' => 'search' ,
2021-11-10 15:31:09 +01:00
'button' => __ ( 'Search' ),
2021-06-28 10:45:23 +02:00
'placeholder' => __ ( 'Enter value to search' ),
'data' => '' ,
'searchKey' => 'value' ,
'additionalUrlParams' => $urlParams ,
'quickFilter' => 'value'
]
]
],
'fields' => [
[
'name' => 'Id' ,
'sort' => 'User.id' ,
'data_path' => 'User.id' ,
],
[
'name' => 'Organisation' ,
'sort' => 'Organisation.name' ,
'data_path' => 'Organisation.name' ,
],
[
'name' => 'Email' ,
'sort' => 'User.email' ,
'data_path' => 'User.email' ,
],
[
'name' => 'Role' ,
'sort' => 'Role.name' ,
'data_path' => 'Role.name'
]
],
'actions' => [
[
'open_modal' => '/localTools/action/' . h ( $params [ 'connection' ][ 'id' ]) . '/editUser?id={{0}}' ,
'modal_params_data_path' => [ 'User.id' ],
'icon' => 'edit' ,
'reload_url' => '/localTools/action/' . h ( $params [ 'connection' ][ 'id' ]) . '/editAction'
],
[
'open_modal' => '/localTools/action/' . h ( $params [ 'connection' ][ 'id' ]) . '/deleteUser?id={{0}}' ,
'modal_params_data_path' => [ 'User.id' ],
'icon' => 'trash' ,
'reload_url' => '/localTools/action/' . h ( $params [ 'connection' ][ 'id' ]) . '/serversAction'
]
],
'title' => false ,
'description' => false ,
'pull' => 'right'
]
];
} else {
return [];
}
}
2021-06-01 07:48:06 +02:00
public function organisationsAction ( array $params ) : array
{
$params [ 'validParams' ] = [
'limit' => 'limit' ,
'page' => 'page' ,
'quickFilter' => 'searchall'
];
$urlParams = h ( $params [ 'connection' ][ 'id' ]) . '/organisationsAction' ;
$response = $this -> getData ( '/organisations/index' , $params );
$data = $response -> getJson ();
if ( ! empty ( $data )) {
return [
'type' => 'index' ,
'data' => [
'data' => $data ,
'skip_pagination' => 1 ,
'top_bar' => [
'children' => [
[
'type' => 'search' ,
2021-11-10 15:31:09 +01:00
'button' => __ ( 'Search' ),
2021-06-01 07:48:06 +02:00
'placeholder' => __ ( 'Enter value to search' ),
'data' => '' ,
'searchKey' => 'value' ,
'additionalUrlParams' => $urlParams
]
]
],
'fields' => [
[
'name' => 'Name' ,
'sort' => 'Organisation.name' ,
2021-04-30 23:59:53 +02:00
'data_path' => 'Organisation.name' ,
],
[
2021-06-01 07:48:06 +02:00
'name' => 'uuid' ,
'sort' => 'Organisation.uuid' ,
'data_path' => 'Organisation.uuid'
],
[
'name' => 'nationality' ,
'sort' => 'Organisation.nationality' ,
'data_path' => 'Organisation.nationality'
],
[
'name' => 'sector' ,
'sort' => 'Organisation.sector' ,
'data_path' => 'Organisation.sector'
2021-04-30 23:59:53 +02:00
]
],
'title' => false ,
'description' => false ,
'pull' => 'right' ,
'actions' => [
[
2021-06-01 07:48:06 +02:00
'open_modal' => '/localTools/action/' . h ( $params [ 'connection' ][ 'id' ]) . '/fetchOrganisationAction?uuid={{0}}' ,
'modal_params_data_path' => [ 'Organisation.uuid' ],
'icon' => 'download' ,
'reload_url' => '/localTools/action/' . h ( $params [ 'connection' ][ 'id' ]) . '/organisationsAction'
2021-04-30 23:59:53 +02:00
]
]
]
];
} else {
2021-06-01 07:48:06 +02:00
return [];
2021-04-30 23:59:53 +02:00
}
}
2021-06-01 07:48:06 +02:00
public function sharingGroupsAction ( array $params ) : array
{
$params [ 'validParams' ] = [
'limit' => 'limit' ,
'page' => 'page' ,
'quickFilter' => 'searchall'
];
$urlParams = h ( $params [ 'connection' ][ 'id' ]) . '/sharingGroupsAction' ;
$response = $this -> getData ( '/sharing_groups/index' , $params );
$data = $response -> getJson ();
if ( ! empty ( $data )) {
return [
'type' => 'index' ,
'data' => [
'data' => $data [ 'response' ],
'skip_pagination' => 1 ,
'top_bar' => [
'children' => [
[
'type' => 'search' ,
2021-11-10 15:31:09 +01:00
'button' => __ ( 'Search' ),
2021-06-01 07:48:06 +02:00
'placeholder' => __ ( 'Enter value to search' ),
'data' => '' ,
'searchKey' => 'value' ,
'additionalUrlParams' => $urlParams
]
]
],
'fields' => [
[
'name' => 'Name' ,
'sort' => 'SharingGroup.name' ,
'data_path' => 'SharingGroup.name' ,
],
[
'name' => 'uuid' ,
'sort' => 'SharingGroup.uuid' ,
'data_path' => 'SharingGroup.uuid'
],
[
'name' => 'Organisations' ,
'sort' => 'Organisation' ,
'data_path' => 'Organisation' ,
'element' => 'count_summary'
],
[
'name' => 'Roaming' ,
'sort' => 'SharingGroup.roaming' ,
'data_path' => 'SharingGroup.roaming' ,
'element' => 'boolean'
],
[
'name' => 'External servers' ,
'sort' => 'Server' ,
'data_path' => 'Server' ,
'element' => 'count_summary'
]
],
'title' => false ,
'description' => false ,
'pull' => 'right' ,
'actions' => [
[
'open_modal' => '/localTools/action/' . h ( $params [ 'connection' ][ 'id' ]) . '/fetchSharingGroupAction?uuid={{0}}' ,
'modal_params_data_path' => [ 'SharingGroup.uuid' ],
'icon' => 'download' ,
'reload_url' => '/localTools/action/' . h ( $params [ 'connection' ][ 'id' ]) . '/SharingGroupsAction'
]
]
]
];
} else {
return [];
}
}
public function fetchOrganisationAction ( array $params ) : array
{
if ( $params [ 'request' ] -> is ([ 'get' ])) {
return [
'data' => [
'title' => __ ( 'Fetch organisation' ),
'description' => __ ( 'Fetch and create/update organisation ({0}) from MISP.' , $params [ 'uuid' ]),
'submit' => [
'action' => $params [ 'request' ] -> getParam ( 'action' )
],
'url' => [ 'controller' => 'localTools' , 'action' => 'action' , $params [ 'connection' ][ 'id' ], 'fetchOrganisationAction' , $params [ 'uuid' ]]
]
];
} elseif ( $params [ 'request' ] -> is ([ 'post' ])) {
$response = $this -> getData ( '/organisations/view/' . $params [ 'uuid' ], $params );
if ( $response -> getStatusCode () == 200 ) {
$result = $this -> captureOrganisation ( $response -> getJson ()[ 'Organisation' ]);
if ( $result ) {
return [ 'success' => 1 , 'message' => __ ( 'Organisation created/modified.' )];
} else {
return [ 'success' => 0 , 'message' => __ ( 'Could not save the changes to the organisation.' )];
}
} else {
return [ 'success' => 0 , 'message' => __ ( 'Could not fetch the remote organisation.' )];
}
}
throw new MethodNotAllowedException ( __ ( 'Invalid http request type for the given action.' ));
}
public function fetchSharingGroupAction ( array $params ) : array
{
if ( $params [ 'request' ] -> is ([ 'get' ])) {
return [
'data' => [
'title' => __ ( 'Fetch sharing group' ),
'description' => __ ( 'Fetch and create/update sharing group ({0}) from MISP.' , $params [ 'uuid' ]),
'submit' => [
'action' => $params [ 'request' ] -> getParam ( 'action' )
],
'url' => [ 'controller' => 'localTools' , 'action' => 'action' , $params [ 'connection' ][ 'id' ], 'fetchSharingGroupAction' , $params [ 'uuid' ]]
]
];
} elseif ( $params [ 'request' ] -> is ([ 'post' ])) {
$response = $this -> getData ( '/sharing_groups/view/' . $params [ 'uuid' ], $params );
if ( $response -> getStatusCode () == 200 ) {
$mispSG = $response -> getJson ();
$sg = [
'uuid' => $mispSG [ 'SharingGroup' ][ 'uuid' ],
'name' => $mispSG [ 'SharingGroup' ][ 'name' ],
'releasability' => $mispSG [ 'SharingGroup' ][ 'releasability' ],
'description' => $mispSG [ 'SharingGroup' ][ 'description' ],
'organisation' => $mispSG [ 'Organisation' ],
'sharing_group_orgs' => []
];
foreach ( $mispSG [ 'SharingGroupOrg' ] as $sgo ) {
$sg [ 'sharing_group_orgs' ][] = $sgo [ 'Organisation' ];
}
$result = $this -> captureSharingGroup ( $sg , $params [ 'user_id' ]);
if ( $result ) {
return [ 'success' => 1 , 'message' => __ ( 'Sharing group created/modified.' )];
} else {
return [ 'success' => 0 , 'message' => __ ( 'Could not save the changes to the sharing group.' )];
}
} else {
return [ 'success' => 0 , 'message' => __ ( 'Could not fetch the remote sharing group.' )];
}
}
throw new MethodNotAllowedException ( __ ( 'Invalid http request type for the given action.' ));
}
public function modifySettingAction ( array $params ) : array
{
if ( $params [ 'request' ] -> is ([ 'get' ])) {
$response = $this -> getData ( '/servers/getSetting/' . $params [ 'setting' ], $params );
if ( $response -> getStatusCode () != 200 ) {
throw new NotFoundException ( __ ( 'Setting could not be fetched from the remote.' ));
}
$response = $response -> getJson ();
$types = [
'string' => 'text' ,
'boolean' => 'checkbox' ,
'numeric' => 'number'
];
2021-06-14 08:37:00 +02:00
if ( ! empty ( $response [ 'options' ])) {
$fields = [
[
'field' => 'value' ,
'label' => __ ( 'Value' ),
'default' => h ( $response [ 'value' ]),
'type' => 'dropdown' ,
2021-06-28 10:45:23 +02:00
'options' => $response [ 'options' ]
2021-06-14 08:37:00 +02:00
]
];
} else {
$fields = [
[
'field' => 'value' ,
'label' => __ ( 'Value' ),
'default' => h ( $response [ 'value' ]),
'type' => $types [ $response [ 'type' ]]
]
];
}
2021-06-01 07:48:06 +02:00
return [
'data' => [
'title' => __ ( 'Modify server setting' ),
2021-06-28 10:45:23 +02:00
'description' => __ ( 'Modify setting ({0}) on selected MISP instance(s).' , $params [ 'setting' ]),
2021-06-01 07:48:06 +02:00
'fields' => $fields ,
'submit' => [
'action' => $params [ 'request' ] -> getParam ( 'action' )
],
'url' => [ 'controller' => 'localTools' , 'action' => 'action' , $params [ 'connection' ][ 'id' ], 'modifySettingAction' , $params [ 'setting' ]]
]
];
} elseif ( $params [ 'request' ] -> is ([ 'post' ])) {
$params [ 'body' ] = [ 'value' => $params [ 'value' ]];
$response = $this -> postData ( '/servers/serverSettingsEdit/' . $params [ 'setting' ], $params );
if ( $response -> getStatusCode () == 200 ) {
return [ 'success' => 1 , 'message' => __ ( 'Setting saved.' )];
} else {
2021-06-11 10:44:24 +02:00
return [ 'success' => 0 , 'message' => __ ( 'Could not update.' )];
2021-06-01 07:48:06 +02:00
}
}
throw new MethodNotAllowedException ( __ ( 'Invalid http request type for the given action.' ));
2021-06-10 13:45:46 +02:00
}
2021-07-07 15:05:32 +02:00
public function batchAPIAction ( array $params ) : array
{
if ( $params [ 'request' ] -> is ([ 'get' ])) {
return [
'data' => [
'title' => __ ( 'Execute API Request' ),
'description' => __ ( 'Perform an API Request on the list of selected connections' ),
'fields' => [
[
'field' => 'connection_ids' ,
'type' => 'hidden' ,
2021-12-21 12:34:37 +01:00
'value' => json_encode ( $params [ 'connection_ids' ])
2021-07-07 15:05:32 +02:00
],
[
'field' => 'method' ,
'label' => __ ( 'Method' ),
'type' => 'dropdown' ,
'options' => [ 'GET' => 'GET' , 'POST' => 'POST' ]
],
[
'field' => 'url' ,
'label' => __ ( 'Relative URL' ),
'type' => 'text' ,
],
[
'field' => 'body' ,
'label' => __ ( 'POST Body' ),
'type' => 'codemirror' ,
],
],
'submit' => [
'action' => $params [ 'request' ] -> getParam ( 'action' )
],
'url' => [ 'controller' => 'localTools' , 'action' => 'batchAction' , 'batchAPIAction' ]
]
];
} else if ( $params [ 'request' ] -> is ([ 'post' ])) {
if ( $params [ 'method' ] == 'GET' ) {
$response = $this -> getData ( $params [ 'url' ], $params );
} else {
$response = $this -> postData ( $params [ 'url' ], $params );
}
if ( $response -> getStatusCode () == 200 ) {
return [ 'success' => 1 , 'message' => __ ( 'API query successful' ), 'data' => $response -> getJson ()];
} else {
return [ 'success' => 0 , 'message' => __ ( 'API query failed' ), 'data' => $response -> getJson ()];
}
}
throw new MethodNotAllowedException ( __ ( 'Invalid http request type for the given action.' ));
}
2021-06-11 10:44:24 +02:00
public function initiateConnection ( array $params ) : array
2021-06-10 13:45:46 +02:00
{
2021-06-11 10:44:24 +02:00
$params [ 'connection_settings' ] = json_decode ( $params [ 'connection' ][ 'settings' ], true );
$params [ 'misp_organisation' ] = $this -> getSetOrg ( $params );
2021-06-28 08:52:39 +02:00
$params [ 'sync_user' ] = $this -> createSyncUser ( $params , true );
2021-06-11 10:44:24 +02:00
return [
'email' => $params [ 'sync_user' ][ 'email' ],
2021-06-28 08:50:33 +02:00
'user_id' => $params [ 'sync_user' ][ 'id' ],
2021-06-11 10:44:24 +02:00
'authkey' => $params [ 'sync_user' ][ 'authkey' ],
2021-06-28 08:50:33 +02:00
'url' => $params [ 'connection_settings' ][ 'url' ],
2021-06-11 10:44:24 +02:00
];
}
public function acceptConnection ( array $params ) : array
{
$params [ 'sync_user_enabled' ] = true ;
$params [ 'connection_settings' ] = json_decode ( $params [ 'connection' ][ 'settings' ], true );
$params [ 'misp_organisation' ] = $this -> getSetOrg ( $params );
2021-06-28 08:52:39 +02:00
$params [ 'sync_user' ] = $this -> createSyncUser ( $params , false );
2021-06-17 14:13:10 +02:00
$serverParams = $params ;
$serverParams [ 'body' ] = [
'authkey' => $params [ 'remote_tool_data' ][ 'authkey' ],
'url' => $params [ 'remote_tool_data' ][ 'url' ],
2021-06-28 08:53:16 +02:00
'name' => ! empty ( $params [ 'remote_tool_data' ][ 'tool_name' ]) ? $params [ 'remote_tool_data' ][ 'tool_name' ] : sprintf ( 'MISP for %s' , $params [ 'remote_tool_data' ][ 'url' ]),
2021-06-11 10:44:24 +02:00
'remote_org_id' => $params [ 'misp_organisation' ][ 'id' ]
2021-06-17 14:13:10 +02:00
];
$params [ 'sync_connection' ] = $this -> addServer ( $serverParams );
2021-06-11 10:44:24 +02:00
return [
'email' => $params [ 'sync_user' ][ 'email' ],
'authkey' => $params [ 'sync_user' ][ 'authkey' ],
2021-06-28 08:50:33 +02:00
'url' => $params [ 'connection_settings' ][ 'url' ],
'reflected_user_id' => $params [ 'remote_tool_data' ][ 'user_id' ] // request initiator Cerebrate to enable the MISP user
2021-06-11 10:44:24 +02:00
];
}
public function finaliseConnection ( array $params ) : bool
{
2021-06-17 14:13:10 +02:00
$params [ 'misp_organisation' ] = $this -> getSetOrg ( $params );
2021-06-28 08:52:39 +02:00
$user = $this -> enableUser ( $params , intval ( $params [ 'remote_tool_data' ][ 'reflected_user_id' ]));
2021-06-17 14:13:10 +02:00
$serverParams = $params ;
$serverParams [ 'body' ] = [
'authkey' => $params [ 'remote_tool_data' ][ 'authkey' ],
'url' => $params [ 'remote_tool_data' ][ 'url' ],
2021-06-28 08:53:16 +02:00
'name' => ! empty ( $params [ 'remote_tool_data' ][ 'tool_name' ]) ? $params [ 'remote_tool_data' ][ 'tool_name' ] : sprintf ( 'MISP for %s' , $params [ 'remote_tool_data' ][ 'url' ]),
2021-06-11 14:27:22 +02:00
'remote_org_id' => $params [ 'misp_organisation' ][ 'id' ]
2021-06-17 14:13:10 +02:00
];
$params [ 'sync_connection' ] = $this -> addServer ( $serverParams );
2021-06-11 10:44:24 +02:00
return true ;
2021-06-10 13:45:46 +02:00
}
private function getSetOrg ( array $params ) : array
{
$params [ 'softError' ] = 1 ;
$response = $this -> getData ( '/organisations/view/' . $params [ 'remote_org' ][ 'uuid' ], $params );
if ( $response -> isOk ()) {
$organisation = $response -> getJson ()[ 'Organisation' ];
if ( ! $organisation [ 'local' ]) {
$organisation [ 'local' ] = 1 ;
2021-06-17 14:13:10 +02:00
$params [ 'body' ] = $organisation ;
2021-06-10 13:45:46 +02:00
$response = $this -> postData ( '/admin/organisations/edit/' . $organisation [ 'id' ], $params );
if ( ! $response -> isOk ()) {
throw new MethodNotAllowedException ( __ ( 'Could not update the organisation in MISP.' ));
}
}
} else {
$params [ 'body' ] = [
'uuid' => $params [ 'remote_org' ][ 'uuid' ],
'name' => $params [ 'remote_org' ][ 'name' ],
'local' => 1
];
$response = $this -> postData ( '/admin/organisations/add' , $params );
if ( $response -> isOk ()) {
$organisation = $response -> getJson ()[ 'Organisation' ];
} else {
throw new MethodNotAllowedException ( __ ( 'Could not create the organisation in MISP.' ));
}
}
return $organisation ;
}
2021-06-01 07:48:06 +02:00
2021-06-28 08:52:39 +02:00
private function createSyncUser ( array $params , $disabled = true ) : array
2021-06-10 13:45:46 +02:00
{
$params [ 'softError' ] = 1 ;
2021-06-11 10:44:24 +02:00
$user = [
'email' => 'sync_%s@' . parse_url ( $params [ 'remote_cerebrate' ][ 'url' ])[ 'host' ],
2021-06-10 13:45:46 +02:00
'org_id' => $params [ 'misp_organisation' ][ 'id' ],
'role_id' => empty ( $params [ 'connection_settings' ][ 'role_id' ]) ? 5 : $params [ 'connection_settings' ][ 'role_id' ],
2021-06-28 08:52:39 +02:00
'disabled' => $disabled ,
2021-06-10 13:45:46 +02:00
'change_pw' => 0 ,
'termsaccepted' => 1
];
2021-06-11 10:44:24 +02:00
return $this -> createUser ( $user , $params );
}
2021-06-28 08:52:39 +02:00
private function enableUser ( array $params , int $userID ) : array
{
$params [ 'softError' ] = 1 ;
$user = [
'disabled' => false ,
];
return $this -> updateUser ( $userID , $user , $params );
}
2021-06-11 10:44:24 +02:00
private function addServer ( array $params ) : array
{
if (
2021-06-17 14:13:10 +02:00
empty ( $params [ 'body' ][ 'authkey' ]) ||
empty ( $params [ 'body' ][ 'url' ]) ||
empty ( $params [ 'body' ][ 'remote_org_id' ]) ||
empty ( $params [ 'body' ][ 'name' ])
2021-06-11 10:44:24 +02:00
) {
throw new MethodNotAllowedException ( __ ( 'Required data missing from the sync connection object. The following fields are required: [name, url, authkey, org_id].' ));
}
$response = $this -> postData ( '/servers/add' , $params );
2021-06-10 13:45:46 +02:00
if ( ! $response -> isOk ()) {
2021-06-11 10:44:24 +02:00
throw new MethodNotAllowedException ( __ ( 'Could not add Server in MISP.' ));
2021-06-10 13:45:46 +02:00
}
2021-06-11 10:44:24 +02:00
return $response -> getJson ()[ 'Server' ];
2021-06-10 13:45:46 +02:00
}
2021-06-11 10:44:24 +02:00
private function createUser ( array $user , array $params ) : array
2021-06-10 13:45:46 +02:00
{
2021-06-11 10:44:24 +02:00
if ( strpos ( $user [ 'email' ], '%s' ) !== false ) {
$user [ 'email' ] = sprintf (
$user [ 'email' ],
\Cake\Utility\Security :: randomString ( 8 )
);
}
$params [ 'body' ] = $user ;
$response = $this -> postData ( '/admin/users/add' , $params );
if ( ! $response -> isOk ()) {
throw new MethodNotAllowedException ( __ ( 'Could not add the user in MISP.' ));
}
return $response -> getJson ()[ 'User' ];
2021-06-01 07:48:06 +02:00
}
2021-06-28 08:52:39 +02:00
private function updateUser ( int $userID , array $user , array $params ) : array
{
$params [ 'body' ] = $user ;
$response = $this -> postData ( sprintf ( '/admin/users/edit/%s' , $userID ), $params );
if ( ! $response -> isOk ()) {
throw new MethodNotAllowedException ( __ ( 'Could not edit the user in MISP.' ));
}
return $response -> getJson ()[ 'User' ];
}
2021-04-30 23:59:53 +02:00
}
?>