chg: [galaxyCluster] Added drafty version of restSearch

pull/6120/head
mokaddem 2020-05-26 11:17:58 +02:00
parent 2937066a71
commit 51391f8e57
No known key found for this signature in database
GPG Key ID: 164C473F627A06FA
4 changed files with 196 additions and 4 deletions

View File

@ -104,6 +104,16 @@ class RestResponseComponent extends Component
'http_method' => 'GET'
)
),
'GalaxyCluster' => array(
// 'add' => array(),
// 'edit' => array(),
'restSearch' => array(
'description' => "Search MISP using a list of filter parameters and return the data in the selected format. This API allows pagination via the page and limit parameters.",
'mandatory' => array('returnFormat'),
'optional' => array('page', 'limit', 'id', 'uuid', 'galaxy_id', 'galaxy_uuid', 'version', 'distribution', 'org', 'orgc', 'tag', 'custom', 'minimal',),
'params' => array()
),
),
'Log' => array(
'admin_index' => array(
'description' => "POST a filter object to receive a JSON with the log entries matching the query. A simple get request will return the entire DB. You can use the filter parameters as url parameters with a GET request such as: https://path.to.my.misp/admin/logs/page:1/limit:200 - to run substring queries simply append/prepend/encapsulate the search term with %. All restSearch rules apply.",

View File

@ -26,6 +26,9 @@ class RestSearchComponent extends Component
),
'Sighting' => array(
'context', 'returnFormat', 'id', 'type', 'from', 'to', 'last', 'org_id', 'source', 'includeAttribute', 'includeEvent'
),
'GalaxyCluster' => array(
'page', 'limit', 'id', 'uuid', 'galaxy_id', 'galaxy_uuid', 'version', 'distribution', 'org', 'orgc', 'tag', 'custom', 'sgReferenceOnly', 'minimal',
)
);

View File

@ -15,6 +15,8 @@ class JsonExport
return $this->__eventHandler($data, $options);
} else if($options['scope'] === 'Sighting') {
return $this->__sightingsHandler($data, $options);
} else if($options['scope'] === 'GalaxyCluster') {
return $this->__galaxyClusterHandler($data, $options);
}
}
@ -59,10 +61,15 @@ class JsonExport
return json_encode($attribute);
}
private function __sightingsHandler($sighting, $options = array())
{
return json_encode($sighting);
}
private function __sightingsHandler($sighting, $options = array())
{
return json_encode($sighting);
}
private function __galaxyClusterHandler($cluster, $options = array())
{
return json_encode($cluster);
}
public function header($options = array())
{

View File

@ -77,6 +77,10 @@ class GalaxyCluster extends AppModel
),
);
public $validFormats = array(
'json' => array('json', 'JsonExport', 'json'),
);
public function beforeValidate($options = array())
{
parent::beforeValidate();
@ -574,6 +578,12 @@ class GalaxyCluster extends AppModel
if (isset($options['group'])) {
$params['group'] = empty($options['group']) ? $options['group'] : false;
}
if (isset($options['page'])) {
$params['page'] = $options['page'];
}
if (isset($options['limit'])) {
$params['limit'] = $options['limit'];
}
$clusters = $this->find('all', $params);
foreach ($clusters as $i => $cluster) {
$clusters[$i] = $this->GalaxyClusterRelation->massageRelationTag($clusters[$i]);
@ -581,6 +591,168 @@ class GalaxyCluster extends AppModel
return $clusters;
}
public function restSearch($user, $returnFormat, $filters, $paramsOnly=false)
{
if (!isset($this->validFormats[$returnFormat][1])) {
throw new NotFoundException('Invalid output format.');
}
App::uses($this->validFormats[$returnFormat][1], 'Export');
$exportTool = new $this->validFormats[$returnFormat][1]();
$conditions = $this->buildFilterConditions($user, $filters);
$params = array(
'conditions' => $conditions,
);
if (isset($filters['limit'])) {
$params['limit'] = $filters['limit'];
if (!isset($filters['page'])) {
$filters['page'] = 1;
}
}
if (isset($filters['page'])) {
$params['page'] = $filters['page'];
}
$default_cluster_memory_coefficient = 80;
$params['full'] = false;
if (!empty($filters['full'])) {
$params['full'] = $filters['full'];
$filters['minimal'] = false;
$default_cluster_memory_coefficient = 1;
}
if (!empty($filters['minimal'])) {
$default_cluster_memory_coefficient = 100;
$params['fields'] = array('uuid', 'version');
}
if ($paramsOnly) {
return $params;
}
if (method_exists($exportTool, 'modify_params')) {
$params = $exportTool->modify_params($user, $params);
}
$exportToolParams = array(
'user' => $user,
'params' => $params,
'returnFormat' => $returnFormat,
'scope' => 'GalaxyCluster',
'filters' => $filters
);
if (!empty($exportTool->additional_params)) {
$params = array_merge_recursive(
$params,
$exportTool->additional_params
);
}
$tmpfile = tmpfile();
fwrite($tmpfile, $exportTool->header($exportToolParams));
if (empty($params['limit'])) {
$memory_in_mb = $this->convert_to_memory_limit_to_mb(ini_get('memory_limit'));
$memory_scaling_factor = $default_cluster_memory_coefficient / 10;
$params['limit'] = intval($memory_in_mb * $memory_scaling_factor);
$params['page'] = 1;
}
$this->__iteratedFetch($user, $params, $tmpfile, $exportTool, $exportToolParams, $elementCounter);
fwrite($tmpfile, $exportTool->footer($exportToolParams));
fseek($tmpfile, 0);
if (fstat($tmpfile)['size']) {
$final = fread($tmpfile, fstat($tmpfile)['size']);
} else {
$final = '';
}
fclose($tmpfile);
return $final;
}
private function __iteratedFetch($user, &$params, &$tmpfile, $exportTool, $exportToolParams, &$elementCounter = 0)
{
$params['limit'] = 10; // FIXME: Actually use an interated fetch
$results = $this->fetchGalaxyClusters($user, $params, $full=$params['full']);
$params['page'] += 1;
$i = 0;
$temp = '';
foreach ($results as $cluster) {
$elementCounter++;
$handlerResult = $exportTool->handler($cluster, $exportToolParams);
$temp .= $handlerResult;
if ($handlerResult !== '') {
if ($i != count($results) -1) {
$temp .= $exportTool->separator($exportToolParams);
}
}
$i++;
}
fwrite($tmpfile, $temp);
return true;
}
public function buildFilterConditions($user, $filters)
{
$conditions = array();
if (isset($filters['org_id'])) {
$this->Organisation = ClassRegistry::init('Organisation');
if (!is_array($filters['org_id'])) {
$filters['org_id'] = array($filters['org_id']);
}
foreach ($filters['org_id'] as $k => $org_id) {
if (Validation::uuid($org_id)) {
$org = $this->Organisation->find('first', array('conditions' => array('Organisation.uuid' => $org_id), 'recursive' => -1, 'fields' => array('Organisation.id')));
if (empty($org)) {
$filters['org_id'][$k] = -1;
} else {
$filters['org_id'][$k] = $org['Organisation']['id'];
}
}
}
$conditions['GalaxyCluster.org_id'] = $filters['org_id'];
}
if (isset($filters['orgc_id'])) {
$this->Organisation = ClassRegistry::init('Organisation');
if (!is_array($filters['orgc_id'])) {
$filters['orgc_id'] = array($filters['orgc_id']);
}
foreach ($filters['orgc_id'] as $k => $orgc_id) {
if (Validation::uuid($orgc_id)) {
$org = $this->Organisation->find('first', array('conditions' => array('Organisation.uuid' => $orgc_id), 'recursive' => -1, 'fields' => array('Organisation.id')));
if (empty($org)) {
$filters['orgc_id'][$k] = -1;
} else {
$filters['orgc_id'][$k] = $org['Organisation']['id'];
}
}
}
$conditions['GalaxyCluster.orgc_id'] = $filters['orgc_id'];
}
if (isset($filters['galaxy_uuid'])) {
$galaxy = $this->Galaxy->find('first', array(
'recursive' => -1,
'conditions' => array('Galaxy.uuid' => $filters['galaxy_uuid']),
'fields' => array('uuid', 'id')
));
if (!empty($galaxy)) {
$filters['galaxy_id'] = $galaxy[0]['id'];
} else {
$filters['galaxy_id'] = -1;
}
}
$simpleParams = array(
'id', 'uuid', 'galaxy_id', 'version', 'distribution', 'tag',
);
foreach ($simpleParams as $k => $simpleParam) {
if (isset($filters[$simpleParam])) {
$conditions["GalaxyCluster.${$simpleParam}"] = $filters[$simpleParam];
}
}
if (isset($filters['custom'])) {
$conditions['GalaxyCluster.default'] = !$filters['custom'];
}
return $conditions;
}
/**
* @param array $events
* @param bool $replace