Merge branch 'develop' of github.com:cerebrate-project/cerebrate into inbox-misp-sync
commit
5e0a4b155e
|
@ -205,10 +205,45 @@ class LocalToolsController extends AppController
|
||||||
{
|
{
|
||||||
$this->loadModel('Broods');
|
$this->loadModel('Broods');
|
||||||
$tools = $this->Broods->queryLocalTools($id);
|
$tools = $this->Broods->queryLocalTools($id);
|
||||||
|
foreach ($tools as $k => $tool) {
|
||||||
|
$tools[$k]['local_tools'] = $this->LocalTools->appendLocalToolConnections($id, $tool);
|
||||||
|
}
|
||||||
if ($this->ParamHandler->isRest()) {
|
if ($this->ParamHandler->isRest()) {
|
||||||
return $this->RestResponse->viewData($tools, 'json');
|
return $this->RestResponse->viewData($tools, 'json');
|
||||||
}
|
}
|
||||||
|
$this->set('id', $id);
|
||||||
$this->set('data', $tools);
|
$this->set('data', $tools);
|
||||||
$this->set('metaGroup', 'Administration');
|
$this->set('metaGroup', 'Administration');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function connectionRequest($cerebrate_id, $remote_tool_id)
|
||||||
|
{
|
||||||
|
$params = [
|
||||||
|
'cerebrate_id' => $cerebrate_id,
|
||||||
|
'remote_tool_id' => $remote_tool_id
|
||||||
|
];
|
||||||
|
if ($this->request->is(['post', 'put'])) {
|
||||||
|
$postParams = $this->ParamHandler->harvestParams(['local_tool_id']);
|
||||||
|
if (empty($postParams['local_tool_id'])) {
|
||||||
|
throw new MethodNotAllowedException(__('No local tool ID supplied.'));
|
||||||
|
}
|
||||||
|
$params['local_tool_id'] = $postParams['local_tool_id'];
|
||||||
|
$result = $this->LocalTools->encodeConnection($params);
|
||||||
|
// Send message to remote inbox
|
||||||
|
debug($result);
|
||||||
|
} else {
|
||||||
|
$this->loadModel('Broods');
|
||||||
|
$remoteCerebrate = $this->Broods->find()->where(['id' => $params['cerebrate_id']])->first();
|
||||||
|
$remoteTool = $this->LocalTools->getRemoteToolById($params);
|
||||||
|
$local_tools = $this->LocalTools->encodeConnectionChoice($params);
|
||||||
|
if (empty($local_tools)) {
|
||||||
|
throw new NotFoundException(__('No local equivalent tool found.'));
|
||||||
|
}
|
||||||
|
$this->set('data', [
|
||||||
|
'remoteCerebrate' => $remoteCerebrate,
|
||||||
|
'remoteTool' => $remoteTool,
|
||||||
|
'local_tools' => $local_tools
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,10 @@ class CommonConnectorTools
|
||||||
];
|
];
|
||||||
public $version = '???';
|
public $version = '???';
|
||||||
|
|
||||||
|
const STATE_INITIAL = 'Request issued';
|
||||||
|
const STATE_ACCEPT = 'Request accepted';
|
||||||
|
const STATE_CONNECTED = 'Connected';
|
||||||
|
|
||||||
public function addExposedFunction(string $functionName): void
|
public function addExposedFunction(string $functionName): void
|
||||||
{
|
{
|
||||||
$this->exposedFunctions[] = $functionName;
|
$this->exposedFunctions[] = $functionName;
|
||||||
|
@ -48,6 +52,57 @@ class CommonConnectorTools
|
||||||
$sharing_groups->captureSharingGroup($input);
|
$sharing_groups->captureSharingGroup($input);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function remoteToolConnectionStatus(array $params, string $status): void
|
||||||
|
{
|
||||||
|
$remoteToolConnections = \Cake\ORM\TableRegistry::getTableLocator()->get('RemoteToolConnections');
|
||||||
|
$remoteToolConnection = $remoteToolConnections->find()->where(
|
||||||
|
[
|
||||||
|
'local_tool_id' => $params['connection']['id'],
|
||||||
|
'remote_tool_id' => $params['remote_tool']['id'],
|
||||||
|
'brood_id' => $params['remote_cerebrate']['id']
|
||||||
|
]
|
||||||
|
)->first();
|
||||||
|
if (empty($remoteToolConnection)) {
|
||||||
|
$data = $remoteToolConnections->newEmptyEntity();
|
||||||
|
$entry = [
|
||||||
|
'local_tool_id' => $params['connection']['id'],
|
||||||
|
'remote_tool_id' => $params['remote_tool']['id'],
|
||||||
|
'remote_tool_name' => $params['remote_tool']['name'],
|
||||||
|
'brood_id' => $params['remote_cerebrate']['id'],
|
||||||
|
'name' => '',
|
||||||
|
'settings' => '',
|
||||||
|
'status' => $status,
|
||||||
|
'created' => time(),
|
||||||
|
'modified' => time()
|
||||||
|
];
|
||||||
|
$data = $remoteToolConnections->patchEntity($data, $entry);
|
||||||
|
$remoteToolConnections->save($data);
|
||||||
|
} else {
|
||||||
|
$data = $remoteToolConnections->patchEntity($remoteToolConnection, ['status' => $status, 'modified' => time()]);
|
||||||
|
$remoteToolConnections->save($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function initiateConnectionWrapper(array $params): array
|
||||||
|
{
|
||||||
|
$result = $this->initiateConnection($params);
|
||||||
|
$this->remoteToolConnectionStatus($params, self::STATE_INITIAL);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function acceptConnectionWrapper(array $params): array
|
||||||
|
{
|
||||||
|
$result = $this->acceptConnection($params);
|
||||||
|
$this->remoteToolConnectionStatus($params, self::STATE_ACCEPT);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function finaliseConnectionWrapper(array $params): bool
|
||||||
|
{
|
||||||
|
$this->remoteToolConnectionStatus($params, self::STATE_CONNECTED);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -143,6 +143,9 @@ class MispConnector extends CommonConnectorTools
|
||||||
if ($response->isOk()) {
|
if ($response->isOk()) {
|
||||||
return $response;
|
return $response;
|
||||||
} else {
|
} else {
|
||||||
|
if (!empty($params['softError'])) {
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
throw new NotFoundException(__('Could not retrieve the requested resource.'));
|
throw new NotFoundException(__('Could not retrieve the requested resource.'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -537,11 +540,128 @@ class MispConnector extends CommonConnectorTools
|
||||||
if ($response->getStatusCode() == 200) {
|
if ($response->getStatusCode() == 200) {
|
||||||
return ['success' => 1, 'message' => __('Setting saved.')];
|
return ['success' => 1, 'message' => __('Setting saved.')];
|
||||||
} else {
|
} else {
|
||||||
return ['success' => 0, 'message' => __('Could not fetch the remote sharing group.')];
|
return ['success' => 0, 'message' => __('Could not update.')];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new MethodNotAllowedException(__('Invalid http request type for the given action.'));
|
throw new MethodNotAllowedException(__('Invalid http request type for the given action.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function initiateConnection(array $params): array
|
||||||
|
{
|
||||||
|
$params['connection_settings'] = json_decode($params['connection']['settings'], true);
|
||||||
|
$params['misp_organisation'] = $this->getSetOrg($params);
|
||||||
|
$params['sync_user'] = $this->createSyncUser($params);
|
||||||
|
return [
|
||||||
|
'email' => $params['sync_user']['email'],
|
||||||
|
'authkey' => $params['sync_user']['authkey'],
|
||||||
|
'url' => $params['connection_settings']['url']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
$params['sync_user'] = $this->createSyncUser($params);
|
||||||
|
$params['sync_connection'] = $this->addServer([
|
||||||
|
'authkey' => $params['remote_tool']['authkey'],
|
||||||
|
'url' => $params['remote_tool']['url'],
|
||||||
|
'name' => $params['remote_tool']['name'],
|
||||||
|
'remote_org_id' => $params['misp_organisation']['id']
|
||||||
|
]);
|
||||||
|
return [
|
||||||
|
'email' => $params['sync_user']['email'],
|
||||||
|
'authkey' => $params['sync_user']['authkey'],
|
||||||
|
'url' => $params['connection_settings']['url']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function finaliseConnection(array $params): bool
|
||||||
|
{
|
||||||
|
$params['sync_connection'] = $this->addServer([
|
||||||
|
'authkey' => $params['remote_tool']['authkey'],
|
||||||
|
'url' => $params['remote_tool']['url'],
|
||||||
|
'name' => $params['remote_tool']['name'],
|
||||||
|
'remote_org_id' => $params['misp_organisation']['id']
|
||||||
|
]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createSyncUser(array $params): array
|
||||||
|
{
|
||||||
|
$params['softError'] = 1;
|
||||||
|
$user = [
|
||||||
|
'email' => 'sync_%s@' . parse_url($params['remote_cerebrate']['url'])['host'],
|
||||||
|
'org_id' => $params['misp_organisation']['id'],
|
||||||
|
'role_id' => empty($params['connection_settings']['role_id']) ? 5 : $params['connection_settings']['role_id'],
|
||||||
|
'disabled' => 1,
|
||||||
|
'change_pw' => 0,
|
||||||
|
'termsaccepted' => 1
|
||||||
|
];
|
||||||
|
return $this->createUser($user, $params);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addServer(array $params): array
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
empty($params['authkey']) ||
|
||||||
|
empty($params['url']) ||
|
||||||
|
empty($params['remote_org_id']) ||
|
||||||
|
empty($params['name'])
|
||||||
|
) {
|
||||||
|
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);
|
||||||
|
if (!$response->isOk()) {
|
||||||
|
throw new MethodNotAllowedException(__('Could not add Server in MISP.'));
|
||||||
|
}
|
||||||
|
return $response->getJson()['Server'];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createUser(array $user, array $params): array
|
||||||
|
{
|
||||||
|
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'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Model\Entity;
|
||||||
|
|
||||||
|
use App\Model\Entity\AppModel;
|
||||||
|
use Cake\ORM\Entity;
|
||||||
|
|
||||||
|
class RemoteToolConnection extends AppModel
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -166,4 +166,74 @@ class LocalToolsTable extends AppTable
|
||||||
}
|
}
|
||||||
return $children;
|
return $children;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getRemoteToolById($params) {
|
||||||
|
$broods = \Cake\ORM\TableRegistry::getTableLocator()->get('Broods');
|
||||||
|
$tools = $broods->queryLocalTools($params['cerebrate_id']);
|
||||||
|
$remoteTool = [];
|
||||||
|
foreach ($tools as $tool) {
|
||||||
|
if ($tool['id'] === intval($params['remote_tool_id'])) {
|
||||||
|
$remoteTool = $tool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (empty($remoteTool)) {
|
||||||
|
throw new NotFoundException(__('Invalid remote tool specified.'));
|
||||||
|
}
|
||||||
|
return $remoteTool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function encodeConnectionChoice(array $params): array
|
||||||
|
{
|
||||||
|
$remoteTool = $this->getRemoteToolById($params);
|
||||||
|
$connections = $this->find()->where(['connector' => $remoteTool['connector']])->toArray();
|
||||||
|
$results = [];
|
||||||
|
foreach ($connections as $connection) {
|
||||||
|
$results[] = [
|
||||||
|
'id' => $connection->id,
|
||||||
|
'name' => $connection->name
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function encodeConnection(array $params): array
|
||||||
|
{
|
||||||
|
$params = $this->buildConnectionParams($params);
|
||||||
|
$result = $params['connector'][$params['remote_tool']['connector']]->initiateConnectionWrapper($params);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildConnectionParams(array $params): array
|
||||||
|
{
|
||||||
|
$remote_tool = $this->getRemoteToolById($params);
|
||||||
|
$broods = \Cake\ORM\TableRegistry::getTableLocator()->get('Broods');
|
||||||
|
$remote_cerebrate = $broods->find()->where(['id' => $params['cerebrate_id']])->first();
|
||||||
|
$connector = $this->getConnectors($remote_tool['connector']);
|
||||||
|
$connection = $this->find()->where(['id' => $params['local_tool_id']])->first();
|
||||||
|
$remote_org = $broods->Organisations->find()->where(['id' => $remote_cerebrate['organisation_id']])->first();
|
||||||
|
if (empty($connector[$remote_tool['connector']])) {
|
||||||
|
throw new NotFoundException(__('No valid connector found for the remote tool.'));
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
'remote_cerebrate' => $remote_cerebrate,
|
||||||
|
'remote_org' => $remote_org,
|
||||||
|
'remote_tool' => $remote_tool,
|
||||||
|
'connector' => $connector,
|
||||||
|
'connection' => $connection,
|
||||||
|
//'message' =>
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function appendLocalToolConnections(int $brood_id, array $tool): array
|
||||||
|
{
|
||||||
|
$remoteToolConnections = \Cake\ORM\TableRegistry::getTableLocator()->get('RemoteToolConnections');
|
||||||
|
$connections = $remoteToolConnections->find()->where(['remote_tool_id' => $tool['id'], 'brood_id' => $brood_id])->toArray();
|
||||||
|
$local_tools = [];
|
||||||
|
foreach ($connections as $k => $connection) {
|
||||||
|
$temp = $this->find()->where(['id' => $connection['local_tool_id']])->select(['id', 'name'])->enableHydration(false)->first();
|
||||||
|
$temp['status'] = $connection['status'];
|
||||||
|
$local_tools[] = $temp;
|
||||||
|
}
|
||||||
|
return $local_tools;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Model\Table;
|
||||||
|
|
||||||
|
use App\Model\Table\AppTable;
|
||||||
|
use Cake\ORM\Table;
|
||||||
|
use Cake\Validation\Validator;
|
||||||
|
use Cake\Http\Client;
|
||||||
|
use Cake\ORM\TableRegistry;
|
||||||
|
use Cake\Error\Debugger;
|
||||||
|
|
||||||
|
class RemoteToolConnectionsTable extends AppTable
|
||||||
|
{
|
||||||
|
public function initialize(array $config): void
|
||||||
|
{
|
||||||
|
parent::initialize($config);
|
||||||
|
$this->BelongsTo(
|
||||||
|
'LocalTools'
|
||||||
|
);
|
||||||
|
$this->setDisplayField('id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validationDefault(Validator $validator): Validator
|
||||||
|
{
|
||||||
|
return $validator;
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,11 @@ echo $this->element('genericElements/IndexTable/index_table', [
|
||||||
[
|
[
|
||||||
'name' => __('Description'),
|
'name' => __('Description'),
|
||||||
'data_path' => 'description',
|
'data_path' => 'description',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => __('Connected Local Tools'),
|
||||||
|
'data_path' => 'local_tool',
|
||||||
|
'element' => 'local_tools_status'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'title' => __('Local tools made available by the remote Cerebrate'),
|
'title' => __('Local tools made available by the remote Cerebrate'),
|
||||||
|
@ -37,8 +42,8 @@ echo $this->element('genericElements/IndexTable/index_table', [
|
||||||
'skip_pagination' => 1,
|
'skip_pagination' => 1,
|
||||||
'actions' => [
|
'actions' => [
|
||||||
[
|
[
|
||||||
'url' => '/localTools/connectionRequest',
|
'open_modal' => sprintf('/localTools/connectionRequest/%s/[onclick_params_data_path]', h($id)),
|
||||||
'url_params_data_paths' => ['id'],
|
'modal_params_data_path' => 'id',
|
||||||
'title' => 'Issue a connection request',
|
'title' => 'Issue a connection request',
|
||||||
'icon' => 'plug'
|
'icon' => 'plug'
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
$dropdown = [];
|
||||||
|
foreach ($data['local_tools'] as $local_tool) {
|
||||||
|
$dropdown[$local_tool['id']] = $local_tool['name'];
|
||||||
|
}
|
||||||
|
echo $this->element('genericElements/Form/genericForm', [
|
||||||
|
'data' => [
|
||||||
|
'description' => __(
|
||||||
|
'Connect the remote tool ({0}) on remote brood ({1}) using the local tool selected below.',
|
||||||
|
h($data['remoteTool']['name']),
|
||||||
|
h($data['remoteCerebrate']['name'])
|
||||||
|
),
|
||||||
|
'model' => 'LocalTools',
|
||||||
|
'fields' => [
|
||||||
|
[
|
||||||
|
'field' => 'local_tool_id',
|
||||||
|
'options' => $dropdown,
|
||||||
|
'type' => 'dropdown'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'submit' => [
|
||||||
|
'action' => $this->request->getParam('action')
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
?>
|
||||||
|
</div>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
$tools = $this->Hash->extract($row, 'local_tools');
|
||||||
|
$output = [];
|
||||||
|
foreach ($tools as $tool) {
|
||||||
|
$output[] = sprintf(
|
||||||
|
'<span class="text-nowrap"><a href="/localTools/view/%s">%s</a>: %s</span>',
|
||||||
|
h($tool['id']),
|
||||||
|
h($tool['name']),
|
||||||
|
h($tool['status'])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
echo implode('<br />', $output);
|
||||||
|
?>
|
Loading…
Reference in New Issue