new: [feature] Built in REST client added to test / interact with the API directly from MISP

- no more shitty chrome extensions that crash during trainings, rejoice!
pull/3539/head
iglocska 2018-08-08 11:29:38 +02:00
parent 23a2611202
commit c8fcb16881
5 changed files with 154 additions and 0 deletions

View File

@ -323,6 +323,7 @@ class ACLComponent extends Component
'pull' => array(),
'purgeSessions' => array(),
'push' => array(),
'rest' => array('perm_auth'),
'restartWorkers' => array(),
'serverSettings' => array(),
'serverSettingsEdit' => array(),

View File

@ -1580,4 +1580,85 @@ class ServersController extends AppController
{
return $this->RestResponse->viewData(array('uuid' => Configure::read('MISP.uuid')), $this->response->type());
}
public function rest() {
if ($this->request->is('post')) {
$request = $this->request->data;
if (!empty($request['Server'])) {
$request = $this->request->data['Server'];
}
$result = $this->__doRestQuery($request);
if (!$result) {
$this->Flash->error('Something went wrong. Make sure you set the http method, body (when sending POST requests) and URL correctly.');
} else {
$this->set('data', $result);
}
}
$header =
'Authorization: ' . $this->Auth->user('authkey') . PHP_EOL .
'Accept: application/json' . PHP_EOL .
'Content-Type: application/json';
$this->set('header', $header);
}
private function __doRestQuery($request) {
App::uses('SyncTool', 'Tools');
$params = array(
);
if (!empty($request['url'])) {
$path = parse_url($request['url'], PHP_URL_PATH);
$query = parse_url($request['url'], PHP_URL_QUERY);
if (!empty($query)) {
$path .= '?' . $query;
}
$url = Configure::read('MISP.baseurl') . '/' . $path;
} else {
throw new InvalidArgumentException('Url not set.');
}
App::uses('HttpSocket', 'Network/Http');
$HttpSocket = new HttpSocket($params);
$view_data = array();
$temp_headers = explode("\n", $request['header']);
$request['header'] = array(
'Authorization' => $this->Auth->user('authkey'),
'Accept' => 'application/json',
'Content-Type' => 'application/json'
);
foreach ($temp_headers as $header) {
$header = explode(':', $header);
$header[0] = trim($header[0]);
$header[1] = trim($header[1]);
$request['header'][$header[0]] = $header[1];
}
$start = microtime(true);
if (
!empty($request['method']) &&
$request['method'] === 'GET'
) {
$response = $HttpSocket->get($url, false, array('header' => $request['header']));
} else if (
!empty($request['method']) &&
$request['method'] === 'POST' &&
!empty($request['body'])
) {
$response = $HttpSocket->post($url, $request['body'], array('header' => $request['header']));
} else {
return false;
}
$view_data['duration'] = microtime(true) - $start;
$view_data['duration'] = round($view_data['duration'] * 100, 2) . 'ms';
$view_data['code'] = $response->code;
$view_data['headers'] = $response->headers;
if (!empty($request['show_result'])) {
$view_data['data'] = $response->body;
} else {
if ($response->isOk()) {
$view_data['data'] = 'Success.';
} else {
$view_data['data'] = 'Something went wrong.';
}
}
return $view_data;
}
}

View File

@ -27,6 +27,7 @@
<?php endif; ?>
<li><a href="<?php echo $baseurl;?>/attributes/index"><?php echo __('List Attributes');?></a></li>
<li><a href="<?php echo $baseurl;?>/attributes/search"><?php echo __('Search Attributes');?></a></li>
<li><a href="<?php echo $baseurl;?>/servers/rest"><?php echo __('REST client');?></a></li>
<li class="divider"></li>
<li><a href="<?php echo $baseurl;?>/shadow_attributes/index"><?php echo __('View Proposals');?></a></li>
<li><a href="<?php echo $baseurl;?>/events/proposalEventIndex">Events with proposals</a></li>

View File

@ -200,6 +200,11 @@
),
'text' => __('Import from…')
));
echo $this->element('/side_menu_link', array(
'element_id' => 'rest',
'url' => '/servers/rest',
'text' => __('REST client')
));
}
echo $this->element('/side_menu_divider');
echo $this->element('/side_menu_link', array(

66
app/View/Servers/rest.ctp Normal file
View File

@ -0,0 +1,66 @@
<div class="servers form">
<?php echo $this->Form->create('Server');?>
<fieldset>
<legend><?php echo __('REST query tool');?></legend>
<?php
echo $this->Form->input('method', array(
'label' => __('Relative path to query'),
'options' => array(
'GET' => 'GET',
'POST' => 'POST'
)
));
?>
<div class="input clear" style="width:100%;">
<?php
echo $this->Form->input('url', array(
'label' => __('Relative path to query'),
'class' => 'input-xxlarge'
));
?>
<div class="input clear" style="width:100%;">
<?php
echo $this->Form->input('show_result', array(
'type' => 'checkbox'
));
?>
<div class="input clear" style="width:100%;">
<?php
echo $this->Form->input('header', array(
'type' => 'textarea',
'div' => 'input clear',
'class' => 'input-xxlarge',
'default' => !empty($this->request->data['Server']['header']) ? $this->request->data['Server']['header'] : $header
));
?>
<div class="input clear" style="width:100%;">
<?php
echo $this->Form->input('body', array(
'type' => 'textarea',
'div' => 'input clear',
'class' => 'input-xxlarge'
));
?>
<div class="input clear" style="width:100%;">
<?php
echo $this->Form->submit('Run query', array('class' => 'btn btn-primary'));
echo $this->Form->end();
?>
<hr />
</fieldset>
<?php
if (!empty($data['data'])) {
echo sprintf('<h3>%s</h3>', __('Response'));
echo sprintf('<div><span class="bold">%s</span>: %d</div>', __('Response code'), h($data['code']));
echo sprintf('<div><span class="bold">%s</span>: %s</div>', __('Request duration'), h($data['duration']));
echo sprintf('<div class="bold">%s</div>', __('Headers'));
foreach ($data['headers'] as $header => $value) {
echo sprintf('&nbsp;&nbsp;<span class="bold">%s</span>: %s<br />', h($header), h($value));
}
echo sprintf('<pre>%s</pre>', h($data['data']));
}
?>
</div>
<?php
echo $this->element('side_menu', array('menuList' => 'event-collection', 'menuItem' => 'rest'));
?>