mirror of https://github.com/MISP/MISP
Merge branch '2.4' of github.com:MISP/MISP into zoidberg-final
Not a simple merge. Needed to fix forms and simplified how form_seen_input workspull/5462/head
commit
7797aeed94
2
PyMISP
2
PyMISP
|
@ -1 +1 @@
|
|||
Subproject commit 36cc79ffb686430e02b382dfef85c29a5e27c39d
|
||||
Subproject commit 637a9668c0fe6a668fc92011d949a7049c588388
|
|
@ -221,7 +221,7 @@ class ServerShell extends AppShell
|
|||
$data = array(
|
||||
'worker' => 'default',
|
||||
'job_type' => 'cache_servers',
|
||||
'job_input' => 'Server: ' . $id,
|
||||
'job_input' => 'Server: ' . $scopeid,
|
||||
'status' => 0,
|
||||
'retries' => 0,
|
||||
'org' => $user['Organisation']['name'],
|
||||
|
|
|
@ -239,13 +239,8 @@ class AttributesController extends AppController
|
|||
$failed = 1;
|
||||
$message = sprintf('Attributes saved, however, %s attributes could not be saved. Click %s for more info', count($fails), '$flashErrorMessage');
|
||||
} else {
|
||||
if (!empty($fails["attribute_0"])) {
|
||||
$failed = 1;
|
||||
$message = '0: ' . $v[0];
|
||||
} else {
|
||||
$failed = 1;
|
||||
$message = 'Attribute could not be saved.';
|
||||
}
|
||||
$failed = 1;
|
||||
$message = 'Attribute could not be saved.';
|
||||
}
|
||||
}
|
||||
if (!empty($failKeys)) {
|
||||
|
@ -267,8 +262,14 @@ class AttributesController extends AppController
|
|||
$flashErrorMessage = implode('<br />', $flashErrorMessage);
|
||||
$this->Session->write('flashErrorMessage', $flashErrorMessage);
|
||||
}
|
||||
if (empty($failed)) {
|
||||
$this->Flash->success($message);
|
||||
} else {
|
||||
$this->Flash->error($message);
|
||||
}
|
||||
if ($this->request->is('ajax')) {
|
||||
$this->autoRender = false;
|
||||
$this->layout = false;
|
||||
$errors = ($attributeCount > 1) ? $message : $this->Attribute->validationErrors;
|
||||
if (!empty($successes)) {
|
||||
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => $message)),'status' => 200, 'type' => 'json'));
|
||||
|
@ -276,11 +277,6 @@ class AttributesController extends AppController
|
|||
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $errors)),'status' => 200, 'type' => 'json'));
|
||||
}
|
||||
} else {
|
||||
if (empty($failed)) {
|
||||
$this->Flash->success($message);
|
||||
} else {
|
||||
$this->Flash->error($message);
|
||||
}
|
||||
if ($successes > 0) {
|
||||
$this->redirect(array('controller' => 'events', 'action' => 'view', $eventId));
|
||||
}
|
||||
|
@ -311,25 +307,31 @@ class AttributesController extends AppController
|
|||
$this->loadModel('SharingGroup');
|
||||
$sgs = $this->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1);
|
||||
$this->set('sharingGroups', $sgs);
|
||||
$info = array();
|
||||
$initialDistribution = 5;
|
||||
$configuredDistribution = Configure::check('MISP.default_attribute_distribution');
|
||||
if ($configuredDistribution != null && $configuredDistribution != 'event') {
|
||||
$initialDistribution = $configuredDistribution;
|
||||
}
|
||||
$this->set('initialDistribution', $initialDistribution);
|
||||
$fieldDesc = array();
|
||||
$distributionLevels = $this->Attribute->distributionLevels;
|
||||
if (empty($sgs)) {
|
||||
unset($distributionLevels[4]);
|
||||
}
|
||||
$this->set('distributionLevels', $distributionLevels);
|
||||
foreach ($distributionLevels as $key => $value) {
|
||||
$fieldDesc['distribution'][$key] = $this->Attribute->distributionDescriptions[$key]['formdesc'];
|
||||
}
|
||||
foreach ($this->Attribute->categoryDefinitions as $key => $value) {
|
||||
$info['category'][$key] = array('key' => $key, 'desc' => isset($value['formdesc'])? $value['formdesc'] : $value['desc']);
|
||||
$fieldDesc['category'][$key] = isset($value['formdesc']) ? $value['formdesc'] : $value['desc'];
|
||||
}
|
||||
foreach ($this->Attribute->typeDefinitions as $key => $value) {
|
||||
$info['type'][$key] = array('key' => $key, 'desc' => isset($value['formdesc'])? $value['formdesc'] : $value['desc']);
|
||||
}
|
||||
foreach ($distributionLevels as $key => $value) {
|
||||
$info['distribution'][$key] = array('key' => $value, 'desc' => $this->Attribute->distributionDescriptions[$key]['formdesc']);
|
||||
$fieldDesc['type'][$key] = isset($value['formdesc']) ? $value['formdesc'] : $value['desc'];
|
||||
}
|
||||
$this->loadModel('Noticelist');
|
||||
$notice_list_triggers = $this->Noticelist->getTriggerData();
|
||||
$this->set('notice_list_triggers', json_encode($notice_list_triggers, true));
|
||||
$this->set('info', $info);
|
||||
$this->set('fieldDesc', $fieldDesc);
|
||||
$this->set('typeDefinitions', $this->Attribute->typeDefinitions);
|
||||
$this->set('categoryDefinitions', $this->Attribute->categoryDefinitions);
|
||||
$this->set('published', $events['Event']['published']);
|
||||
|
|
|
@ -591,7 +591,8 @@ class DecayingModelController extends AppController
|
|||
$filters['uuid'] = $filters['id'];
|
||||
} else {
|
||||
$attributes = $this->User->Event->Attribute->fetchAttributes($this->Auth->user(), array(
|
||||
'conditions' => array('Attribute.id' => $filters['id'])
|
||||
'conditions' => array('Attribute.id' => $filters['id']),
|
||||
'flatten' => 1
|
||||
));
|
||||
if (!empty($attributes)) {
|
||||
$filters['uuid'] = $attributes[0]['Attribute']['uuid'];
|
||||
|
|
|
@ -2082,7 +2082,6 @@ class EventsController extends AppController
|
|||
if (isset($this->params['named']['extends'])) {
|
||||
$this->set('extends_uuid', $this->params['named']['extends']);
|
||||
}
|
||||
$this->set('action', 'add');
|
||||
}
|
||||
|
||||
public function addIOC($id)
|
||||
|
@ -2420,11 +2419,9 @@ class EventsController extends AppController
|
|||
$fieldDesc['analysis'][$key] = $this->Event->analysisDescriptions[$key]['formdesc'];
|
||||
}
|
||||
$this->set('analysisLevels', $analysisLevels);
|
||||
|
||||
$this->set('fieldDesc', $fieldDesc);
|
||||
$this->set('eventDescriptions', $this->Event->fieldDescriptions);
|
||||
$this->set('event', $this->Event->data);
|
||||
$this->set('action', 'edit');
|
||||
$this->render('add');
|
||||
}
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ class ShadowAttributesController extends AppController
|
|||
$this->Attribute->delete($activeAttribute['Attribute']['id']);
|
||||
} else {
|
||||
// Update the live attribute with the shadow data
|
||||
$fieldsToUpdate = array('value1', 'value2', 'value', 'type', 'category', 'comment', 'to_ids');
|
||||
$fieldsToUpdate = array('value1', 'value2', 'value', 'type', 'category', 'comment', 'to_ids', 'first_seen', 'last_seen');
|
||||
foreach ($fieldsToUpdate as $f) {
|
||||
$activeAttribute['Attribute'][$f] = $shadow[$f];
|
||||
}
|
||||
|
|
|
@ -886,9 +886,9 @@ class UsersController extends AppController
|
|||
continue;
|
||||
}
|
||||
if ($field != 'confirm_password') {
|
||||
array_push($fieldsOldValues, $this->User->field($field));
|
||||
$fieldsOldValues[$field] = $this->User->field($field);
|
||||
} else {
|
||||
array_push($fieldsOldValues, $this->User->field('password'));
|
||||
$fieldsOldValues[$field] = $this->User->field('password');
|
||||
}
|
||||
}
|
||||
if (
|
||||
|
@ -929,31 +929,28 @@ class UsersController extends AppController
|
|||
}
|
||||
$cP++;
|
||||
}
|
||||
array_push($fieldsNewValues, $newValueStr);
|
||||
$fieldsNewValues[$field] = $newValueStr;
|
||||
} else {
|
||||
array_push($fieldsNewValues, $newValue);
|
||||
$fieldsNewValues[$field] = $newValue;
|
||||
}
|
||||
} else {
|
||||
array_push($fieldsNewValues, $this->data['User']['password']);
|
||||
$fieldsNewValues[$field] = $this->data['User']['password'];
|
||||
}
|
||||
}
|
||||
// compare
|
||||
$fieldsResultStr = '';
|
||||
$c = 0;
|
||||
$fieldsResult = array();
|
||||
foreach ($fields as $field) {
|
||||
if (isset($fieldsOldValues[$c]) && $fieldsOldValues[$c] != $fieldsNewValues[$c]) {
|
||||
if (isset($fieldsOldValues[$field]) && $fieldsOldValues[$field] != $fieldsNewValues[$field]) {
|
||||
if ($field != 'confirm_password' && $field != 'enable_password') {
|
||||
$fieldsResultStr = $fieldsResultStr . ', ' . $field . ' (' . $fieldsOldValues[$c] . ') => (' . $fieldsNewValues[$c] . ')';
|
||||
$fieldsResult[$field] = array($fieldsOldValues[$field], $fieldsNewValues[$field]);
|
||||
}
|
||||
}
|
||||
$c++;
|
||||
}
|
||||
$fieldsResultStr = substr($fieldsResultStr, 2);
|
||||
$user = $this->User->find('first', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('User.id' => $this->User->id)
|
||||
));
|
||||
$this->User->extralog($this->Auth->user(), "edit", "user", $fieldsResultStr, $user);
|
||||
$this->User->extralog($this->Auth->user(), "edit", "user", $fieldsResult, $user);
|
||||
if ($this->_isRest()) {
|
||||
$user['User']['password'] = '******';
|
||||
return $this->RestResponse->viewData($user, $this->response->type());
|
||||
|
|
|
@ -3346,6 +3346,8 @@ class Attribute extends AppModel
|
|||
if (empty($at['Tag'])) {
|
||||
unset($results[$k]['AttributeTag'][$k2]);
|
||||
$tagCulled = true;
|
||||
} else {
|
||||
$results[$k]['AttributeTag'][$k2]['Tag']['local'] = $results[$k]['AttributeTag'][$k2]['local'];
|
||||
}
|
||||
}
|
||||
if ($tagCulled) {
|
||||
|
@ -3355,6 +3357,7 @@ class Attribute extends AppModel
|
|||
if (isset($result['Event']['EventTag'])) {
|
||||
$results[$k]['Event']['Tag'] = array();
|
||||
foreach ($result['Event']['EventTag'] as $et) {
|
||||
$et['Tag']['local'] = $et['local'];
|
||||
$results[$k]['Event']['Tag'][] = $et['Tag'];
|
||||
}
|
||||
unset($results[$k]['Event']['EventTag']);
|
||||
|
|
|
@ -5851,6 +5851,7 @@ class Event extends AppModel
|
|||
unset($data[$dataType . 'Tag'][$k]);
|
||||
continue;
|
||||
}
|
||||
$dataTag['Tag']['local'] = $dataTag['local'];
|
||||
if (!isset($excludeGalaxy) || !$excludeGalaxy) {
|
||||
if (substr($dataTag['Tag']['name'], 0, strlen('misp-galaxy:')) === 'misp-galaxy:') {
|
||||
$cluster = $this->GalaxyCluster->getCluster($dataTag['Tag']['name']);
|
||||
|
|
|
@ -189,6 +189,7 @@ class Log extends AppModel
|
|||
* @param int $modelId
|
||||
* @param string $title
|
||||
* @param string|array $change
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function createLogEntry($user, $action, $model, $modelId = 0, $title = '', $change = '')
|
||||
|
@ -227,6 +228,8 @@ class Log extends AppModel
|
|||
if (!$result) {
|
||||
throw new Exception("Cannot save log because of validation errors: " . json_encode($this->validationErrors));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
// to combat a certain bug that causes the upgrade scripts to loop without being able to set the correct version
|
||||
|
|
|
@ -413,11 +413,28 @@ class Tag extends AppModel
|
|||
return ($this->saveAll($tags));
|
||||
}
|
||||
|
||||
public function getTagsByName($tag_names, $containTagConnectors = true)
|
||||
{
|
||||
$contain = array('EventTag', 'AttributeTag');
|
||||
$tag_params = array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('name' => $tag_names)
|
||||
);
|
||||
if ($containTagConnectors) {
|
||||
$tag_params['contain'] = $contain;
|
||||
}
|
||||
$tags_temp = $this->find('all', $tag_params);
|
||||
$tags = array();
|
||||
foreach ($tags_temp as $temp) {
|
||||
$tags[strtoupper($temp['Tag']['name'])] = $temp;
|
||||
}
|
||||
return $tags;
|
||||
}
|
||||
|
||||
public function getTagsForNamespace($namespace, $containTagConnectors = true)
|
||||
{
|
||||
|
||||
$contain = array('EventTag');
|
||||
$contain[] = 'AttributeTag';
|
||||
$contain = array('EventTag', 'AttributeTag');
|
||||
$tag_params = array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('UPPER(name) LIKE' => strtoupper($namespace) . '%'),
|
||||
|
|
|
@ -283,7 +283,8 @@ class Taxonomy extends AppModel
|
|||
if (empty($taxonomy)) {
|
||||
return false;
|
||||
}
|
||||
$tags = $this->Tag->getTagsForNamespace($taxonomy['Taxonomy']['namespace'], false);
|
||||
$tag_names = Hash::extract($taxonomy, 'entries.{n}.tag');
|
||||
$tags = $this->Tag->getTagsByName($tag_names, false);
|
||||
if (isset($taxonomy['entries'])) {
|
||||
foreach ($taxonomy['entries'] as $key => $temp) {
|
||||
$taxonomy['entries'][$key]['existing_tag'] = isset($tags[strtoupper($temp['tag'])]) ? $tags[strtoupper($temp['tag'])] : false;
|
||||
|
|
|
@ -3,6 +3,9 @@ App::uses('AppModel', 'Model');
|
|||
App::uses('AuthComponent', 'Controller/Component');
|
||||
App::uses('RandomTool', 'Tools');
|
||||
|
||||
/**
|
||||
* @property Log $Log
|
||||
*/
|
||||
class User extends AppModel
|
||||
{
|
||||
public $displayField = 'email';
|
||||
|
@ -1419,20 +1422,12 @@ class User extends AppModel
|
|||
|
||||
// query
|
||||
$this->Log = ClassRegistry::init('Log');
|
||||
$this->Log->create();
|
||||
$this->Log->save(array(
|
||||
'org' => $user['Organisation']['name'],
|
||||
'model' => $model,
|
||||
'model_id' => $modelId,
|
||||
'email' => $user['email'],
|
||||
'action' => $action,
|
||||
'title' => $description,
|
||||
'change' => isset($fieldsResult) ? $fieldsResult : ''));
|
||||
$result = $this->Log->createLogEntry($user, $action, $model, $modelId, $description, $fieldsResult);
|
||||
|
||||
// write to syslogd as well
|
||||
App::import('Lib', 'SysLog.SysLog');
|
||||
$syslog = new SysLog();
|
||||
$syslog->write('notice', $description . ' -- ' . $action . (empty($fieldResult) ? '' : '-- ' . $fieldResult));
|
||||
$syslog->write('notice', "$description -- $action" . (empty($fieldResult) ? '' : ' -- ' . $result['Log']['change']));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1500,7 +1495,7 @@ class User extends AppModel
|
|||
$endDate = time();
|
||||
}
|
||||
$dates = array();
|
||||
for ($d=$startDate; $d < $endDate; $d=$d+3600*24) {
|
||||
for ($d=$startDate; $d < $endDate; $d=$d+3600*24) {
|
||||
$dates[] = date('Y-m-d', $d);
|
||||
}
|
||||
$csv = 'Date,Close\n';
|
||||
|
|
|
@ -1,167 +1,131 @@
|
|||
<div class="attributes <?php if (!isset($ajax) || !$ajax) echo 'form';?>">
|
||||
<?php
|
||||
$url_params = $action == 'add' ? 'add/' . $event_id : 'edit/' . $attribute['Attribute']['id'];
|
||||
echo $this->Form->create('Attribute', array('id'=>'AttributeForm', 'url' => '/attributes/' . $url_params));
|
||||
?>
|
||||
<fieldset>
|
||||
<legend><?php echo $action == 'add' ? __('Add Attribute') : __('Edit Attribute'); ?></legend>
|
||||
<div id="formWarning" class="message ajaxMessage"></div>
|
||||
<div id="compositeWarning" class="message <?php echo !empty($ajax) ? 'ajaxMessage' : '';?>" style="display:none;">Did you consider adding an object instead of a composite attribute?</div>
|
||||
<div class="add_attribute_fields">
|
||||
<?php
|
||||
echo $this->Form->hidden('event_id');
|
||||
echo $this->Form->input('category', array(
|
||||
'empty' => __('(choose one)'),
|
||||
'label' => __('Category ') . $this->element('formInfo', array('type' => 'category')),
|
||||
));
|
||||
echo $this->Form->input('type', array(
|
||||
'empty' => __('(first choose category)'),
|
||||
'label' => __('Type ') . $this->element('formInfo', array('type' => 'type')),
|
||||
));
|
||||
|
||||
$initialDistribution = 5;
|
||||
if (Configure::read('MISP.default_attribute_distribution') != null) {
|
||||
if (Configure::read('MISP.default_attribute_distribution') === 'event') {
|
||||
$initialDistribution = 5;
|
||||
} else {
|
||||
$initialDistribution = Configure::read('MISP.default_attribute_distribution');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="input clear"></div>
|
||||
<?php
|
||||
$distArray = array(
|
||||
'options' => array($distributionLevels),
|
||||
'label' => __('Distribution ') . $this->element('formInfo', array('type' => 'distribution')),
|
||||
);
|
||||
|
||||
if ($action == 'add') {
|
||||
$distArray['selected'] = $initialDistribution;
|
||||
}
|
||||
|
||||
echo $this->Form->input('distribution', $distArray);
|
||||
?>
|
||||
<div id="SGContainer" style="display:none;">
|
||||
<?php
|
||||
if (!empty($sharingGroups)) {
|
||||
echo $this->Form->input('sharing_group_id', array(
|
||||
'options' => array($sharingGroups),
|
||||
'label' => __('Sharing Group'),
|
||||
));
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
echo $this->Form->input('value', array(
|
||||
'type' => 'textarea',
|
||||
'error' => array('escape' => false),
|
||||
'div' => 'input clear',
|
||||
'class' => 'input-xxlarge'
|
||||
));
|
||||
?>
|
||||
<div class="input clear"></div>
|
||||
<?php
|
||||
echo $this->Form->input('comment', array(
|
||||
$modelForForm = 'Attribute';
|
||||
echo $this->element('genericElements/Form/genericForm', array(
|
||||
'form' => $this->Form,
|
||||
'data' => array(
|
||||
'title' => $action === 'add' ? __('Add Attribute') : __('Edit Attribute'),
|
||||
'model' => $modelForForm,
|
||||
'fields' => array(
|
||||
array(
|
||||
'field' => 'event_id',
|
||||
'class' => 'org-id-picker-hidden-field',
|
||||
'type' => 'text',
|
||||
'label' => __('Contextual Comment'),
|
||||
'error' => array('escape' => false),
|
||||
'hidden' => true
|
||||
),
|
||||
array(
|
||||
'field' => 'category',
|
||||
'class' => 'input',
|
||||
'empty' => __('(choose one)'),
|
||||
'options' => $categories,
|
||||
'stayInLine' => 1
|
||||
),
|
||||
array(
|
||||
'field' => 'type',
|
||||
'class' => 'input',
|
||||
'empty' => __('(choose category first)'),
|
||||
'options' => $types
|
||||
),
|
||||
array(
|
||||
'field' => 'distribution',
|
||||
'class' => 'input',
|
||||
'options' => $distributionLevels,
|
||||
'default' => isset($attribute['Attribute']['distribution']) ? $attribute['Attribute']['distribution'] : $initialDistribution,
|
||||
'stayInLine' => 1
|
||||
),
|
||||
array(
|
||||
'field' => 'sharing_group_id',
|
||||
'class' => 'input',
|
||||
'options' => $sharingGroups,
|
||||
'label' => __("Sharing Group")
|
||||
),
|
||||
array(
|
||||
'field'=> 'value',
|
||||
'type' => 'textarea',
|
||||
'class' => 'input span6',
|
||||
'div' => 'input clear'
|
||||
),
|
||||
array(
|
||||
'field' => 'comment',
|
||||
'type' => 'text',
|
||||
'class' => 'input span6',
|
||||
'div' => 'input clear',
|
||||
'class' => 'input-xxlarge'
|
||||
));
|
||||
?>
|
||||
<div class="input clear"></div>
|
||||
<?php
|
||||
echo $this->Form->input('to_ids', array(
|
||||
'label' => __('for Intrusion Detection System'),
|
||||
'type' => 'checkbox'
|
||||
));
|
||||
echo $this->Form->input('batch_import', array(
|
||||
'label' => __("Contextual Comment")
|
||||
),
|
||||
array(
|
||||
'field' => 'to_ids',
|
||||
'type' => 'checkbox',
|
||||
'label' => __("for Intrusion Detection System"),
|
||||
//'stayInLine' => 1
|
||||
),
|
||||
array(
|
||||
'field' => 'batch_import',
|
||||
'type' => 'checkbox'
|
||||
));
|
||||
echo $this->element('form_seen_input');
|
||||
echo '<div class="input clear"></div>';
|
||||
echo $this->Form->input('disable_correlation', array(
|
||||
),
|
||||
array(
|
||||
'field' => 'disable_correlation',
|
||||
'type' => 'checkbox'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
</fieldset>
|
||||
<p id="notice_message" style="display:none;"></p>
|
||||
<?php if ($ajax): ?>
|
||||
<div class="overlay_spacing">
|
||||
<span id="submitButton" class="btn btn-primary" style="margin-bottom:5px;float:left;" title="<?php echo __('Submit'); ?>" role="button" tabindex="0" aria-label="<?php echo __('Submit'); ?>" onClick="submitPopoverForm('<?php echo $action == 'add' ? $event_id : $attribute['Attribute']['id'];?>', '<?php echo $action; ?>')"><?php echo __('Submit'); ?></span>
|
||||
<span class="btn btn-inverse" style="float:right;" title="<?php echo __('Cancel'); ?>" role="button" tabindex="0" aria-label="<?php echo __('Cancel'); ?>" id="cancel_attribute_add"><?php echo __('Cancel'); ?></span>
|
||||
</div>
|
||||
<?php
|
||||
else:
|
||||
?>
|
||||
<?php
|
||||
echo $this->Form->button('Submit', array('class' => 'btn btn-primary'));
|
||||
endif;
|
||||
echo $this->Form->end();
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
),
|
||||
array(
|
||||
'field' => 'first_seen',
|
||||
'type' => 'text',
|
||||
'stayInLine' => 1,
|
||||
'hidden' => true
|
||||
),
|
||||
array(
|
||||
'field' => 'last_seen',
|
||||
'type' => 'text',
|
||||
'hidden' => true
|
||||
),
|
||||
'<div id="extended_event_preview" style="width:446px;"></div>'
|
||||
),
|
||||
'submit' => array(
|
||||
'action' => $action,
|
||||
'ajaxSubmit' => sprintf(
|
||||
'submitPopoverForm(%s, %s, 0, 1)',
|
||||
"'" . ($action == 'add' ? h($event_id) : h($attribute['Attribute']['id'])) . "'",
|
||||
"'" . h($action) . "'"
|
||||
)
|
||||
),
|
||||
'metaFields' => array(
|
||||
'<div id="bothSeenSliderContainer"></div>'
|
||||
)
|
||||
)
|
||||
));
|
||||
if (!$ajax) {
|
||||
$event['Event']['id'] = $event_id;
|
||||
$event['Event']['published'] = $published;
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event', 'menuItem' => 'addAttribute', 'event' => $event));
|
||||
}
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
var notice_list_triggers = <?php echo $notice_list_triggers; ?>;
|
||||
var fieldsArray = new Array('AttributeCategory', 'AttributeType', 'AttributeValue', 'AttributeDistribution', 'AttributeComment', 'AttributeToIds', 'AttributeBatchImport', 'AttributeSharingGroupId');
|
||||
<?php
|
||||
$formInfoTypes = array('distribution' => 'Distribution', 'category' => 'Category', 'type' => 'Type');
|
||||
echo 'var formInfoFields = ' . json_encode($formInfoTypes) . PHP_EOL;
|
||||
foreach ($formInfoTypes as $formInfoType => $humanisedName) {
|
||||
echo 'var ' . $formInfoType . 'FormInfoValues = {' . PHP_EOL;
|
||||
foreach ($info[$formInfoType] as $key => $formInfoData) {
|
||||
echo '"' . $key . '": "<span class=\"blue bold\">' . h($formInfoData['key']) . '</span>: ' . h($formInfoData['desc']) . '<br />",' . PHP_EOL;
|
||||
}
|
||||
echo '}' . PHP_EOL;
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event-collection', 'menuItem' => $this->action === 'add' ? 'add' : 'editEvent'));
|
||||
}
|
||||
?>
|
||||
|
||||
//
|
||||
//Generate Category / Type filtering array
|
||||
//
|
||||
var category_type_mapping = new Array();
|
||||
<?php
|
||||
<script type="text/javascript">
|
||||
var notice_list_triggers = <?php echo $notice_list_triggers; ?>;
|
||||
var composite_types = <?php echo json_encode($compositeTypes); ?>;
|
||||
var category_type_mapping = new Array();
|
||||
|
||||
<?php
|
||||
foreach ($categoryDefinitions as $category => $def) {
|
||||
echo "category_type_mapping['" . addslashes($category) . "'] = {";
|
||||
$first = true;
|
||||
foreach ($def['types'] as $type) {
|
||||
if ($first) $first = false;
|
||||
else echo ', ';
|
||||
if ($first) {
|
||||
$first = false;
|
||||
} else {
|
||||
echo ', ';
|
||||
}
|
||||
echo "'" . addslashes($type) . "' : '" . addslashes($type) . "'";
|
||||
}
|
||||
echo "}; \n";
|
||||
}
|
||||
?>
|
||||
|
||||
var composite_types = <?php echo json_encode($compositeTypes); ?>;
|
||||
|
||||
$(document).ready(function() {
|
||||
<?php
|
||||
if ($action == 'edit'):
|
||||
?>
|
||||
checkNoticeList('attribute');
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
initPopoverContent('Attribute');
|
||||
|
||||
$('#AttributeDistribution').change(function() {
|
||||
if ($('#AttributeDistribution').val() == 4) $('#SGContainer').show();
|
||||
else $('#SGContainer').hide();
|
||||
checkSharingGroup('Attribute');
|
||||
});
|
||||
|
||||
$("#AttributeCategory").on('change', function(e) {
|
||||
$('#AttributeCategory').change(function() {
|
||||
formCategoryChanged('Attribute');
|
||||
if ($(this).val() === 'Internal reference') {
|
||||
$("#AttributeDistribution").val('0');
|
||||
$('#SGContainer').hide();
|
||||
checkSharingGroup('Attribute');
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -169,22 +133,16 @@ $(document).ready(function() {
|
|||
checkNoticeList('attribute');
|
||||
});
|
||||
|
||||
$("#AttributeCategory, #AttributeType, #AttributeDistribution").change(function() {
|
||||
var start = $("#AttributeType").val();
|
||||
initPopoverContent('Attribute');
|
||||
$("#AttributeType").val(start);
|
||||
if ($.inArray(start, composite_types) > -1) {
|
||||
$('#compositeWarning').show();
|
||||
} else {
|
||||
$('#compositeWarning').hide();
|
||||
}
|
||||
$(document).ready(function() {
|
||||
<?php
|
||||
if ($action == 'edit'):
|
||||
?>
|
||||
checkNoticeList('attribute');
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
checkSharingGroup('Attribute');
|
||||
});
|
||||
<?php if ($ajax): ?>
|
||||
$('#cancel_attribute_add').click(function() {
|
||||
cancelPopoverForm();
|
||||
});
|
||||
|
||||
<?php endif; ?>
|
||||
});
|
||||
</script>
|
||||
<?php echo $this->element('form_seen_input'); ?>
|
||||
<?php echo $this->Js->writeBuffer(); // Write cached scripts
|
||||
|
|
|
@ -32,18 +32,27 @@
|
|||
'type' => 'checkbox',
|
||||
'label' => __('Alternate Search Result (Events)')
|
||||
));
|
||||
echo $this->Form->input('first_seen', array(
|
||||
'type' => 'text',
|
||||
'div' => 'input hidden',
|
||||
'required' => false,
|
||||
));
|
||||
echo $this->Form->input('last_seen', array(
|
||||
'type' => 'text',
|
||||
'div' => 'input hidden',
|
||||
'required' => false,
|
||||
));
|
||||
?>
|
||||
<div class="clear">
|
||||
<h3><?php echo __('First seen and Last seen.'); ?></h3>
|
||||
<p><?php echo __('Attributes not having first seen or last seen set might not appear in the search'); ?></p>
|
||||
</div>
|
||||
<?php echo $this->element('form_seen_input'); ?>
|
||||
</fieldset>
|
||||
<?php
|
||||
echo $this->Form->button(__('Search'), array('class' => 'btn btn-primary'));
|
||||
echo $this->Form->end();
|
||||
?>
|
||||
<?php echo $this->Form->end(); ?>
|
||||
<div id="bothSeenSliderContainer"></div>
|
||||
<button onclick="$('#AttributeSearchForm').submit();" class="btn btn-primary">Submit</button>
|
||||
</div>
|
||||
<?php echo $this->element('form_seen_input'); ?>
|
||||
<script type="text/javascript">
|
||||
//
|
||||
// Generate Category / Type filtering array
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
if ($object['value'] == 'MERGE') debug($object);
|
||||
$tr_class = '';
|
||||
$linkClass = 'blue';
|
||||
$otherColour = 'blue';
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
if ($object['value'] == 'MERGE') debug($object);
|
||||
$tr_class = '';
|
||||
$linkClass = 'blue';
|
||||
$otherColour = 'blue';
|
||||
|
|
|
@ -49,10 +49,11 @@
|
|||
'children' => array(
|
||||
array(
|
||||
'id' => 'create-button',
|
||||
'title' => __('Add attribute'),
|
||||
'title' => $possibleAction === 'attribute' ? __('Add attribute') : __('Add proposal'),
|
||||
'fa-icon' => 'plus',
|
||||
'onClick' => 'clickCreateButton',
|
||||
'onClickParams' => array($event['Event']['id'], $possibleAction)
|
||||
//'onClick' => 'clickCreateButton',
|
||||
'onClick' => 'openGenericModal',
|
||||
'onClickParams' => array('/' . $possibleAction . 's/add/' . h($event['Event']['id']))
|
||||
),
|
||||
array(
|
||||
'id' => 'multi-edit-button',
|
||||
|
|
|
@ -1,23 +1,5 @@
|
|||
<?php echo $this->Html->script('moment-with-locales'); ?>
|
||||
|
||||
<div class="input-group">
|
||||
<?php
|
||||
echo $this->Form->input('first_seen', array(
|
||||
'type' => 'text',
|
||||
'div' => 'input hidden',
|
||||
'required' => false,
|
||||
));
|
||||
echo $this->Form->input('last_seen', array(
|
||||
'type' => 'text',
|
||||
'div' => 'input hidden',
|
||||
'required' => false,
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="input clear"></div>
|
||||
|
||||
|
||||
<script>
|
||||
<?php
|
||||
$temp = explode('_', $this->params->controller);
|
||||
|
@ -304,27 +286,7 @@ function reflect_change_on_form() {
|
|||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
<?php if ($this->params->controller === 'attributes'): ?>
|
||||
<?php if ($this->params->action === 'add'): ?>
|
||||
var sliders_container = "<?php echo '#AttributeForm fieldset'; ?>"
|
||||
<?php elseif ($this->params->action === 'search'): ?>
|
||||
var sliders_container = "<?php echo '#AttributeSearchForm fieldset'; ?>"
|
||||
<?php else: ?>
|
||||
var sliders_container = "<?php echo '#AttributeForm fieldset'; ?>"
|
||||
<?php endif; ?>
|
||||
<?php elseif ($this->params->controller === 'shadow_attributes'): ?>
|
||||
<?php if ($this->params->action === 'add'): ?>
|
||||
var sliders_container = "<?php echo '#ShadowAttributeAddForm fieldset'; ?>"
|
||||
<?php elseif ($this->params->action === 'edit'): ?>
|
||||
var sliders_container = "<?php echo '#ShadowAttributeEditForm fieldset'; ?>"
|
||||
<?php else: ?>
|
||||
var sliders_container = "<?php echo '#ShadowAttributeAddForm fieldset'; ?>"
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
var sliders_container = "<?php echo '#meta-div'; ?>"
|
||||
<?php endif; ?>
|
||||
|
||||
var sliders_container = "#bothSeenSliderContainer"
|
||||
var inputs_container = $('<div class="input-group input-daterange"></div>');
|
||||
// create separate date and time input
|
||||
var date_div_fs = $('<div class="input clear larger-input-field" style="margin-left: 10px;"></div>').append(
|
||||
|
@ -448,7 +410,7 @@ $(document).ready(function() {
|
|||
event.preventDefault();
|
||||
});
|
||||
|
||||
$('#date_fs').closest('form').submit(function( event ) {
|
||||
$('#'+controller+'FirstSeen').closest('form').submit(function( event ) {
|
||||
reflect_change_on_form();
|
||||
});
|
||||
|
||||
|
|
|
@ -16,8 +16,9 @@
|
|||
h($data['model']);
|
||||
$fieldsString = '';
|
||||
$simpleFieldWhitelist = array(
|
||||
'default', 'type', 'options', 'placeholder', 'label'
|
||||
'default', 'type', 'options', 'placeholder', 'label', 'empty'
|
||||
);
|
||||
$fieldsArrayForPersistence = array();
|
||||
$formCreate = $this->Form->create($modelForForm);
|
||||
if (!empty($data['fields'])) {
|
||||
foreach ($data['fields'] as $fieldData) {
|
||||
|
@ -51,6 +52,7 @@
|
|||
}
|
||||
}
|
||||
$temp = $this->Form->input($fieldData['field'], $params);
|
||||
$fieldsArrayForPersistence []= $modelForForm . Inflector::camelize($fieldData['field']);
|
||||
if (!empty($fieldData['hidden'])) {
|
||||
$temp = '<span class="hidden">' . $temp . '</span>';
|
||||
}
|
||||
|
@ -73,18 +75,55 @@
|
|||
if (!empty($data['submit'])) {
|
||||
$submitButtonData = array_merge($submitButtonData, $data['submit']);
|
||||
}
|
||||
if (!empty($data['ajaxSubmit'])) {
|
||||
$submitButtonData['ajaxSubmit'] = $ajaxSubmit;
|
||||
}
|
||||
$ajaxFlashMessage = '';
|
||||
if ($ajax) {
|
||||
$ajaxFlashMessage = sprintf(
|
||||
'<div id="flashContainer"><div id="main-view-container">%s</div></div>',
|
||||
$this->Flash->render()
|
||||
);
|
||||
}
|
||||
$formEnd = $this->Form->end();
|
||||
echo sprintf(
|
||||
'<div class="form">%s<fieldset><legend>%s</legend>%s</fieldset>%s%s%s</div>',
|
||||
$formCreate,
|
||||
empty($data['title']) ? h(Inflector::humanize($this->request->params['action'])) . ' ' . $modelForForm : h($data['title']),
|
||||
$fieldsString,
|
||||
$formEnd,
|
||||
$metaFieldString,
|
||||
$this->element('genericElements/Form/submitButton', $submitButtonData)
|
||||
);
|
||||
if (!empty($ajax)) {
|
||||
echo sprintf(
|
||||
'<div id="genericModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="genericModalLabel" aria-hidden="true">%s%s%s</div>',
|
||||
sprintf(
|
||||
'<div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button><h3 id="genericModalLabel">%s</h3></div>',
|
||||
empty($data['title']) ? h(Inflector::humanize($this->request->params['action'])) . ' ' . $modelForForm : h($data['title'])
|
||||
),
|
||||
sprintf(
|
||||
'<div class="modal-body modal-body-long">%s</div>',
|
||||
sprintf(
|
||||
'%s<fieldset>%s%s</fieldset>%s%s',
|
||||
$formCreate,
|
||||
$ajaxFlashMessage,
|
||||
$fieldsString,
|
||||
$formEnd,
|
||||
$metaFieldString
|
||||
)
|
||||
),
|
||||
sprintf(
|
||||
'<div class="modal-footer">%s</div>',
|
||||
$this->element('genericElements/Form/submitButton', $submitButtonData)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
echo sprintf(
|
||||
'<div class="form">%s<fieldset><legend>%s</legend>%s%s</fieldset>%s%s%s</div>',
|
||||
$formCreate,
|
||||
empty($data['title']) ? h(Inflector::humanize($this->request->params['action'])) . ' ' . $modelForForm : h($data['title']),
|
||||
$ajaxFlashMessage,
|
||||
$fieldsString,
|
||||
$formEnd,
|
||||
$metaFieldString,
|
||||
$this->element('genericElements/Form/submitButton', $submitButtonData)
|
||||
);
|
||||
}
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
var fieldsArray = <?php echo json_encode($fieldsArrayForPersistence); ?>;
|
||||
$(document).ready(function() {
|
||||
popoverStartup();
|
||||
});
|
||||
|
|
|
@ -1,12 +1,28 @@
|
|||
<?php
|
||||
echo sprintf(
|
||||
'<button onClick="%s" class="btn btn-%s">%s</button>',
|
||||
sprintf(
|
||||
"$('#%s%sForm').submit();",
|
||||
h($model),
|
||||
h(Inflector::classify($action))
|
||||
),
|
||||
empty($type) ? 'primary' : h($type),
|
||||
empty($text) ? __('Submit') : h($text)
|
||||
);
|
||||
if ($ajax) {
|
||||
echo sprintf(
|
||||
'%s%s',
|
||||
sprintf(
|
||||
'<button id="submitButton" class="btn btn-primary" onClick="%s">%s</button>',
|
||||
$ajaxSubmit,
|
||||
__('Submit')
|
||||
),
|
||||
sprintf(
|
||||
'<button class="btn" data-dismiss="modal" aria-hidden="true" onClick="%s">%s</button>',
|
||||
'cancelPopoverForm();',
|
||||
__('Cancel')
|
||||
)
|
||||
);
|
||||
} else {
|
||||
echo sprintf(
|
||||
'<button onClick="%s" class="btn btn-%s">%s</button>',
|
||||
sprintf(
|
||||
"$('#%s%sForm').submit();",
|
||||
h($model),
|
||||
h(Inflector::classify($action))
|
||||
),
|
||||
empty($type) ? 'primary' : h($type),
|
||||
empty($text) ? __('Submit') : h($text)
|
||||
);
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
$modelForForm = 'Event';
|
||||
$action = $this->request->params['action'];
|
||||
echo $this->element('genericElements/Form/genericForm', array(
|
||||
'form' => $this->Form,
|
||||
'data' => array(
|
||||
|
@ -60,11 +61,11 @@
|
|||
'<div id="extended_event_preview" style="width:446px;"></div>'
|
||||
),
|
||||
'submit' => array(
|
||||
'action' => $this->request->params['action']
|
||||
'action' => $action
|
||||
)
|
||||
)
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event-collection', 'menuItem' => $this->action === 'add' ? 'add' : 'editEvent'));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event-collection', 'menuItem' => $action === 'add' ? 'add' : 'editEvent'));
|
||||
?>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
|
|
@ -78,8 +78,18 @@
|
|||
?>
|
||||
</dd>
|
||||
<?php
|
||||
echo $this->element('form_seen_input');
|
||||
echo $this->Form->input('first_seen', array(
|
||||
'type' => 'text',
|
||||
'div' => 'input hidden',
|
||||
'required' => false,
|
||||
));
|
||||
echo $this->Form->input('last_seen', array(
|
||||
'type' => 'text',
|
||||
'div' => 'input hidden',
|
||||
'required' => false,
|
||||
));
|
||||
?>
|
||||
<div id="bothSeenSliderContainer"></div>
|
||||
</dl>
|
||||
</div>
|
||||
<?php
|
||||
|
@ -312,6 +322,7 @@
|
|||
|
||||
|
||||
<?php
|
||||
echo $this->element('form_seen_input');
|
||||
if (!$ajax) {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event', 'menuItem' => 'addObject', 'event' => $event));
|
||||
}
|
||||
|
|
|
@ -40,8 +40,18 @@
|
|||
echo $this->Form->input('batch_import', array(
|
||||
'type' => 'checkbox',
|
||||
));
|
||||
echo $this->element('form_seen_input');
|
||||
echo $this->Form->input('first_seen', array(
|
||||
'type' => 'text',
|
||||
'div' => 'input hidden',
|
||||
'required' => false,
|
||||
));
|
||||
echo $this->Form->input('last_seen', array(
|
||||
'type' => 'text',
|
||||
'div' => 'input hidden',
|
||||
'required' => false,
|
||||
));
|
||||
?>
|
||||
<div id="bothSeenSliderContainer"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<p style="color:red;font-weight:bold;display:none;<?php if ($ajax) echo 'text-align:center;'; ?>" id="warning-message"><?php echo __('Warning: You are about to share data that is of a classified nature (Attribution / targeting data). Make sure that you are authorised to share this.');?></p>
|
||||
|
@ -73,6 +83,8 @@
|
|||
if (!$ajax) {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event', 'menuItem' => 'proposeAttribute', 'event' => $event));
|
||||
}
|
||||
|
||||
echo $this->element('form_seen_input');
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
<?php
|
||||
|
|
|
@ -40,8 +40,18 @@
|
|||
echo $this->Form->input('to_ids', array(
|
||||
'label' => __('IDS Signature?'),
|
||||
));
|
||||
echo $this->element('form_seen_input');
|
||||
echo $this->Form->input('first_seen', array(
|
||||
'type' => 'text',
|
||||
'div' => 'input hidden',
|
||||
'required' => false,
|
||||
));
|
||||
echo $this->Form->input('last_seen', array(
|
||||
'type' => 'text',
|
||||
'div' => 'input hidden',
|
||||
'required' => false,
|
||||
));
|
||||
?>
|
||||
<div id="bothSeenSliderContainer"></div>
|
||||
</fieldset>
|
||||
<p style="color:red;font-weight:bold;display:none;<?php if (isset($ajax) && $ajax) echo "text-align:center;"?>" id="warning-message"><?php echo __('Warning: You are about to share data that is of a sensitive nature (Attribution / targeting data). Make sure that you are authorised to share this.');?></p>
|
||||
<?php if (isset($ajax) && $ajax): ?>
|
||||
|
@ -70,6 +80,8 @@
|
|||
<?php
|
||||
$event['Event']['id'] = $this->request->data['ShadowAttribute']['event_id'];
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event', 'menuItem' => 'proposeAttribute', 'event' => $event));
|
||||
|
||||
echo $this->element('form_seen_input');
|
||||
?>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit e88b1e07ead796ef3cece3e28dfe9c3e4e04598c
|
||||
Subproject commit c5a2d74ed6a7835d0b7e43fb6c3ee69bd8bcfa80
|
|
@ -1 +1 @@
|
|||
Subproject commit 54da7b5cc30aea83905bb23e94a25b75c055f022
|
||||
Subproject commit 33a7d6b574b7354ba8243ba461bfb30db0528023
|
|
@ -89,44 +89,44 @@ class StixBuilder(object):
|
|||
idgen.set_id_namespace(Namespace(self.baseurl, self.orgname, "MISP"))
|
||||
self.namespace_prefix = idgen.get_id_namespace_alias()
|
||||
## MAPPING FOR ATTRIBUTES
|
||||
self.simple_type_to_method = {"port": self.generate_port_observable, "domain|ip": self.generate_domain_ip_observable,
|
||||
"named pipe": self.generate_pipe_observable}
|
||||
self.simple_type_to_method.update(dict.fromkeys(list(hash_type_attributes["single"]) + list(hash_type_attributes["composite"]) + ["filename"], self.resolve_file_observable))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["ip-src", "ip-dst"], self.generate_ip_observable))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["ip-src|port", "ip-dst|port", "hostname|port"], self.generate_socket_address_observable))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["regkey", "regkey|value"], self.generate_regkey_observable))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["hostname", "domain", "url", "AS", "mutex", "named pipe", "link", "windows-service-name"], self.generate_simple_observable))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["email-src", "email-dst", "email-subject", "email-reply-to"], self.resolve_email_observable))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["http-method", "user-agent"], self.resolve_http_observable))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["pattern-in-file", "pattern-in-traffic", "pattern-in-memory"], self.resolve_pattern_observable))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["mac-address"], self.resolve_system_observable))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["attachment"], self.resolve_attachment))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["email-attachment"], self.generate_email_attachment_observable))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["malware-sample"], self.resolve_malware_sample))
|
||||
self.simple_type_to_method = {"port": 'generate_port_observable', "domain|ip": 'generate_domain_ip_observable',
|
||||
"named pipe": 'generate_pipe_observable'}
|
||||
self.simple_type_to_method.update(dict.fromkeys(list(hash_type_attributes["single"]) + list(hash_type_attributes["composite"]) + ["filename"], 'resolve_file_observable'))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["ip-src", "ip-dst"], 'generate_ip_observable'))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["ip-src|port", "ip-dst|port", "hostname|port"], 'generate_socket_address_observable'))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["regkey", "regkey|value"], 'generate_regkey_observable'))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["hostname", "domain", "url", "AS", "mutex", "named pipe", "link", "windows-service-name"], 'generate_simple_observable'))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["email-src", "email-dst", "email-subject", "email-reply-to"], 'resolve_email_observable'))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["http-method", "user-agent"], 'resolve_http_observable'))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["pattern-in-file", "pattern-in-traffic", "pattern-in-memory"], 'resolve_pattern_observable'))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["mac-address"], 'resolve_system_observable'))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["attachment"], 'resolve_attachment'))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["email-attachment"], 'generate_email_attachment_observable'))
|
||||
self.simple_type_to_method.update(dict.fromkeys(["malware-sample"], 'resolve_malware_sample'))
|
||||
## MAPPING FOR OBJECTS
|
||||
self.ttp_names = {'attack-pattern': self.parse_attack_pattern,
|
||||
'course-of-action': self.parse_course_of_action,
|
||||
'vulnerability': self.parse_vulnerability,
|
||||
'weakness': self.parse_weakness}
|
||||
self.ttp_names = {'attack-pattern': 'parse_attack_pattern',
|
||||
'course-of-action': 'parse_course_of_action',
|
||||
'vulnerability': 'parse_vulnerability',
|
||||
'weakness': 'parse_weakness'}
|
||||
self.types_mapping = {CourseOfAction: 'add_course_of_action',
|
||||
ThreatActor: 'add_threat_actor',
|
||||
TTP: 'add_ttp'}
|
||||
self.objects_mapping = {"asn": self.parse_asn_object,
|
||||
"credential": self.parse_credential_object,
|
||||
"domain-ip": self.parse_domain_ip_object,
|
||||
"email": self.parse_email_object,
|
||||
"file": self.parse_file_object,
|
||||
"ip-port": self.parse_ip_port_object,
|
||||
"network-connection": self.parse_network_connection_object,
|
||||
"network-socket": self.parse_network_socket_object,
|
||||
"pe": self.store_pe,
|
||||
"pe-section": self.store_pe,
|
||||
"process": self.parse_process_object,
|
||||
"registry-key": self.parse_regkey_object,
|
||||
"url": self.parse_url_object,
|
||||
"user-account": self.parse_user_account_object,
|
||||
"whois": self.parse_whois,
|
||||
"x509": self.parse_x509_object}
|
||||
self.objects_mapping = {"asn": 'parse_asn_object',
|
||||
"credential": 'parse_credential_object',
|
||||
"domain-ip": 'parse_domain_ip_object',
|
||||
"email": 'parse_email_object',
|
||||
"file": 'parse_file_object',
|
||||
"ip-port": 'parse_ip_port_object',
|
||||
"network-connection": 'parse_network_connection_object',
|
||||
"network-socket": 'parse_network_socket_object',
|
||||
"pe": 'store_pe',
|
||||
"pe-section": 'store_pe',
|
||||
"process": 'parse_process_object',
|
||||
"registry-key": 'parse_regkey_object',
|
||||
"url": 'parse_url_object',
|
||||
"user-account": 'parse_user_account_object',
|
||||
"whois": 'parse_whois',
|
||||
"x509": 'parse_x509_object'}
|
||||
|
||||
def loadEvent(self):
|
||||
pathname = os.path.dirname(self.args[0])
|
||||
|
@ -274,11 +274,11 @@ class StixBuilder(object):
|
|||
if name == 'original-imported-file':
|
||||
continue
|
||||
if name in self.ttp_names:
|
||||
self.ttp_names[name](misp_object)
|
||||
getattr(self, self.ttp_names[name])(misp_object)
|
||||
else:
|
||||
category = misp_object.get('meta-category')
|
||||
try:
|
||||
to_ids, observable = self.objects_mapping[name](misp_object)
|
||||
to_ids, observable = getattr(self, self.objects_mapping[name])(misp_object)
|
||||
except KeyError:
|
||||
to_ids, observable = self.create_custom_observable(name, misp_object['Attribute'], misp_object['uuid'])
|
||||
except TypeError:
|
||||
|
@ -525,7 +525,7 @@ class StixBuilder(object):
|
|||
attribute_type = attribute['type']
|
||||
attribute_uuid = attribute['uuid']
|
||||
try:
|
||||
observable_property = self.simple_type_to_method[attribute_type](attribute)
|
||||
observable_property = getattr(self, self.simple_type_to_method[attribute_type])(attribute)
|
||||
except KeyError:
|
||||
return False
|
||||
if isinstance(observable_property, Observable):
|
||||
|
|
|
@ -189,43 +189,43 @@ class StixBuilder():
|
|||
|
||||
def load_objects_mapping(self):
|
||||
self.objects_mapping = {
|
||||
'asn': {'observable': self.resolve_asn_observable,
|
||||
'pattern': self.resolve_asn_pattern},
|
||||
'credential': {'observable': self.resolve_credential_observable,
|
||||
'pattern': self.resolve_credential_pattern},
|
||||
'domain-ip': {'observable': self.resolve_domain_ip_observable,
|
||||
'pattern': self.resolve_domain_ip_pattern},
|
||||
'email': {'observable': self.resolve_email_object_observable,
|
||||
'pattern': self.resolve_email_object_pattern},
|
||||
'file': {'observable': self.resolve_file_observable,
|
||||
'pattern': self.resolve_file_pattern},
|
||||
'ip-port': {'observable': self.resolve_ip_port_observable,
|
||||
'pattern': self.resolve_ip_port_pattern},
|
||||
'network-connection': {'observable': self.resolve_network_connection_observable,
|
||||
'pattern': self.resolve_network_connection_pattern},
|
||||
'network-socket': {'observable': self.resolve_network_socket_observable,
|
||||
'pattern': self.resolve_network_socket_pattern},
|
||||
'process': {'observable': self.resolve_process_observable,
|
||||
'pattern': self.resolve_process_pattern},
|
||||
'registry-key': {'observable': self.resolve_regkey_observable,
|
||||
'pattern': self.resolve_regkey_pattern},
|
||||
'stix2-pattern': {'pattern': self.resolve_stix2_pattern},
|
||||
'url': {'observable': self.resolve_url_observable,
|
||||
'pattern': self.resolve_url_pattern},
|
||||
'user-account': {'observable': self.resolve_user_account_observable,
|
||||
'pattern': self.resolve_user_account_pattern},
|
||||
'x509': {'observable': self.resolve_x509_observable,
|
||||
'pattern': self.resolve_x509_pattern}
|
||||
'asn': {'observable': 'resolve_asn_observable',
|
||||
'pattern': 'resolve_asn_pattern'},
|
||||
'credential': {'observable': 'resolve_credential_observable',
|
||||
'pattern': 'resolve_credential_pattern'},
|
||||
'domain-ip': {'observable': 'resolve_domain_ip_observable',
|
||||
'pattern': 'resolve_domain_ip_pattern'},
|
||||
'email': {'observable': 'resolve_email_object_observable',
|
||||
'pattern': 'resolve_email_object_pattern'},
|
||||
'file': {'observable': 'resolve_file_observable',
|
||||
'pattern': 'resolve_file_pattern'},
|
||||
'ip-port': {'observable': 'resolve_ip_port_observable',
|
||||
'pattern': 'resolve_ip_port_pattern'},
|
||||
'network-connection': {'observable': 'resolve_network_connection_observable',
|
||||
'pattern': 'resolve_network_connection_pattern'},
|
||||
'network-socket': {'observable': 'resolve_network_socket_observable',
|
||||
'pattern': 'resolve_network_socket_pattern'},
|
||||
'process': {'observable': 'resolve_process_observable',
|
||||
'pattern': 'resolve_process_pattern'},
|
||||
'registry-key': {'observable': 'resolve_regkey_observable',
|
||||
'pattern': 'resolve_regkey_pattern'},
|
||||
'stix2-pattern': {'pattern': 'resolve_stix2_pattern'},
|
||||
'url': {'observable': 'resolve_url_observable',
|
||||
'pattern': 'resolve_url_pattern'},
|
||||
'user-account': {'observable': 'resolve_user_account_observable',
|
||||
'pattern': 'resolve_user_account_pattern'},
|
||||
'x509': {'observable': 'resolve_x509_observable',
|
||||
'pattern': 'resolve_x509_pattern'}
|
||||
}
|
||||
|
||||
def load_galaxy_mapping(self):
|
||||
self.galaxies_mapping = {'branded-vulnerability': ['vulnerability', self.add_vulnerability_from_galaxy]}
|
||||
self.galaxies_mapping.update(dict.fromkeys(attack_pattern_galaxies_list, ['attack-pattern', self.add_attack_pattern]))
|
||||
self.galaxies_mapping.update(dict.fromkeys(course_of_action_galaxies_list, ['course-of-action', self.add_course_of_action]))
|
||||
self.galaxies_mapping.update(dict.fromkeys(intrusion_set_galaxies_list, ['intrusion-set', self.add_intrusion_set]))
|
||||
self.galaxies_mapping.update(dict.fromkeys(malware_galaxies_list, ['malware', self.add_malware]))
|
||||
self.galaxies_mapping.update(dict.fromkeys(threat_actor_galaxies_list, ['threat-actor', self.add_threat_actor]))
|
||||
self.galaxies_mapping.update(dict.fromkeys(tool_galaxies_list, ['tool', self.add_tool]))
|
||||
self.galaxies_mapping = {'branded-vulnerability': ['vulnerability', 'add_vulnerability_from_galaxy']}
|
||||
self.galaxies_mapping.update(dict.fromkeys(attack_pattern_galaxies_list, ['attack-pattern', 'add_attack_pattern']))
|
||||
self.galaxies_mapping.update(dict.fromkeys(course_of_action_galaxies_list, ['course-of-action', 'add_course_of_action']))
|
||||
self.galaxies_mapping.update(dict.fromkeys(intrusion_set_galaxies_list, ['intrusion-set', 'add_intrusion_set']))
|
||||
self.galaxies_mapping.update(dict.fromkeys(malware_galaxies_list, ['malware', 'add_malware']))
|
||||
self.galaxies_mapping.update(dict.fromkeys(threat_actor_galaxies_list, ['threat-actor', 'add_threat_actor']))
|
||||
self.galaxies_mapping.update(dict.fromkeys(tool_galaxies_list, ['tool', 'add_tool']))
|
||||
|
||||
def get_object_by_uuid(self, uuid):
|
||||
for _object in self.misp_event['Object']:
|
||||
|
@ -373,7 +373,7 @@ class StixBuilder():
|
|||
except Exception:
|
||||
return
|
||||
if galaxy_uuid not in self.galaxies:
|
||||
to_call(galaxy)
|
||||
getattr(self, to_call)(galaxy)
|
||||
self.galaxies.append(galaxy_uuid)
|
||||
self.relationships['defined'][source_id].append("{}--{}".format(stix_type, galaxy_uuid))
|
||||
|
||||
|
@ -619,7 +619,7 @@ class StixBuilder():
|
|||
pattern = pattern_arg
|
||||
else:
|
||||
name = misp_object['name']
|
||||
pattern = self.objects_mapping[name]['pattern'](misp_object['Attribute'], indicator_id)
|
||||
pattern = getattr(self, self.objects_mapping[name]['pattern'])(misp_object['Attribute'], indicator_id)
|
||||
category = misp_object.get('meta-category')
|
||||
killchain = self.create_killchain(category)
|
||||
labels = self.create_object_labels(name, category, True)
|
||||
|
@ -638,7 +638,7 @@ class StixBuilder():
|
|||
observable_objects = observable_arg
|
||||
else:
|
||||
name = misp_object['name']
|
||||
observable_objects = self.objects_mapping[name]['observable'](misp_object['Attribute'], observed_data_id)
|
||||
observable_objects = getattr(self, self.objects_mapping[name]['observable'])(misp_object['Attribute'], observed_data_id)
|
||||
category = misp_object.get('meta-category')
|
||||
labels = self.create_object_labels(name, category, False)
|
||||
timestamp = self.get_datetime_from_timestamp(misp_object['timestamp'])
|
||||
|
|
|
@ -49,13 +49,14 @@ class StixParser():
|
|||
self.filename = filename
|
||||
self.stix_version = version
|
||||
self.event = defaultdict(dict)
|
||||
self.relationship = defaultdict(list)
|
||||
self.event['relationship'] = defaultdict(list)
|
||||
mapping = {'custom_object': self.__load_custom,
|
||||
'marking-definition': self.__load_marking,
|
||||
'relationship': self.__load_relationship,
|
||||
'report': self.__load_report}
|
||||
mapping.update({object_type: self.__load_usual_object for object_type in ('indicator', 'observed-data', 'vulnerability', 'course-of-action')})
|
||||
mapping.update({galaxy_type: self.__load_galaxy for galaxy_type in galaxy_types})
|
||||
mapping = {'custom_object': '_load_custom',
|
||||
'marking-definition': '_load_marking',
|
||||
'relationship': '_load_relationship',
|
||||
'report': '_load_report'}
|
||||
mapping.update({object_type: '_load_usual_object' for object_type in ('indicator', 'observed-data', 'vulnerability', 'course-of-action')})
|
||||
mapping.update({galaxy_type: '_load_galaxy' for galaxy_type in galaxy_types})
|
||||
for parsed_object in event.objects:
|
||||
try:
|
||||
object_type = parsed_object._type
|
||||
|
@ -64,9 +65,9 @@ class StixParser():
|
|||
if object_type.startswith('x-misp-object'):
|
||||
object_type = 'custom_object'
|
||||
try:
|
||||
mapping[object_type](parsed_object)
|
||||
getattr(self, mapping[object_type])(parsed_object)
|
||||
except KeyError:
|
||||
self.__load_usual_object(parsed_object)
|
||||
self._load_usual_object(parsed_object)
|
||||
try:
|
||||
event_distribution = args[0]
|
||||
if not isinstance(event_distribution, int):
|
||||
|
@ -84,35 +85,31 @@ class StixParser():
|
|||
self.misp_event.distribution = event_distribution
|
||||
self._attribute_distribution = attribute_distribution
|
||||
|
||||
def __load_custom(self, parsed_object):
|
||||
def _load_custom(self, parsed_object):
|
||||
self.event['custom_object'][parsed_object['id'].split('--')[1]] = parsed_object
|
||||
|
||||
def __load_galaxy(self, parsed_object):
|
||||
def _load_galaxy(self, parsed_object):
|
||||
try:
|
||||
self.galaxy[parsed_object['id'].split('--')[1]] = {'object': parsed_object, 'used': False}
|
||||
except AttributeError:
|
||||
self.galaxy = {parsed_object['id'].split('--')[1]: {'object': parsed_object, 'used': False}}
|
||||
|
||||
def __load_marking(self, parsed_object):
|
||||
def _load_marking(self, parsed_object):
|
||||
try:
|
||||
self.marking_definition[parsed_object['id'].split('--')[1]] = {'object': parsed_object, 'used': False}
|
||||
except AttributeError:
|
||||
self.marking_definition = {parsed_object['id'].split('--')[1]: {'object': parsed_object, 'used': False}}
|
||||
|
||||
def __load_relationship(self, parsed_object):
|
||||
try:
|
||||
self.relationship[parsed_object.source_ref.split('--')[1]].append(parsed_object)
|
||||
except AttributeError:
|
||||
self.relationship = defaultdict(list)
|
||||
self.relationship[parsed_object.source_ref.split('--')[1]].append(parsed_object)
|
||||
def _load_relationship(self, parsed_object):
|
||||
self.relationship[parsed_object.source_ref.split('--')[1]].append(parsed_object)
|
||||
|
||||
def __load_report(self, parsed_object):
|
||||
def _load_report(self, parsed_object):
|
||||
try:
|
||||
self.report[parsed_object['id'].split('--')[1]] = parsed_object
|
||||
except AttributeError:
|
||||
self.report = {parsed_object['id'].split('--')[1]: parsed_object}
|
||||
|
||||
def __load_usual_object(self, parsed_object):
|
||||
def _load_usual_object(self, parsed_object):
|
||||
self.event[parsed_object._type][parsed_object['id'].split('--')[1]] = parsed_object
|
||||
|
||||
def general_handler(self):
|
||||
|
@ -558,34 +555,34 @@ class StixParser():
|
|||
class StixFromMISPParser(StixParser):
|
||||
def __init__(self):
|
||||
super(StixFromMISPParser, self).__init__()
|
||||
self.objects_mapping = {'asn': {'observable': self.attributes_from_asn_observable, 'pattern': self.pattern_asn},
|
||||
'credential': {'observable': self.observable_credential, 'pattern': self.pattern_credential},
|
||||
'domain-ip': {'observable': self.attributes_from_domain_ip_observable, 'pattern': self.pattern_domain_ip},
|
||||
'email': {'observable': self.observable_email, 'pattern': self.pattern_email},
|
||||
'file': {'observable': self.observable_file, 'pattern': self.pattern_file},
|
||||
'ip-port': {'observable': self.observable_ip_port, 'pattern': self.pattern_ip_port},
|
||||
'network-connection': {'observable': self.observable_connection, 'pattern': self.pattern_connection},
|
||||
'network-socket': {'observable': self.observable_socket, 'pattern': self.pattern_socket},
|
||||
'process': {'observable': self.attributes_from_process_observable, 'pattern': self.pattern_process},
|
||||
'registry-key': {'observable': self.attributes_from_regkey_observable, 'pattern': self.pattern_regkey},
|
||||
'url': {'observable': self.attributes_from_url_observable, 'pattern': self.pattern_url},
|
||||
'user-account': {'observable': self.attributes_from_user_account_observable,
|
||||
'pattern': self.attributes_from_user_account_pattern},
|
||||
'WindowsPEBinaryFile': {'observable': self.observable_pe, 'pattern': self.pattern_pe},
|
||||
'x509': {'observable': self.attributes_from_x509_observable, 'pattern': self.pattern_x509}}
|
||||
self.object_from_refs = {'course-of-action': self.parse_MISP_course_of_action, 'vulnerability': self.parse_vulnerability,
|
||||
'custom_object': self.parse_custom}
|
||||
self.object_from_refs.update(dict.fromkeys(['indicator', 'observed-data'], self.parse_usual_object))
|
||||
self.attributes_fetcher_mapping = {'indicator': self.fetch_attributes_from_indicator,
|
||||
'observed-data': self.fetch_attributes_from_observable,
|
||||
'vulnerability': self.fetch_attributes_from_vulnerability}
|
||||
self.objects_mapping = {'asn': {'observable': 'attributes_from_asn_observable', 'pattern': 'pattern_asn'},
|
||||
'credential': {'observable': 'observable_credential', 'pattern': 'pattern_credential'},
|
||||
'domain-ip': {'observable': 'attributes_from_domain_ip_observable', 'pattern': 'pattern_domain_ip'},
|
||||
'email': {'observable': 'observable_email', 'pattern': 'pattern_email'},
|
||||
'file': {'observable': 'observable_file', 'pattern': 'pattern_file'},
|
||||
'ip-port': {'observable': 'observable_ip_port', 'pattern': 'pattern_ip_port'},
|
||||
'network-connection': {'observable': 'observable_connection', 'pattern': 'pattern_connection'},
|
||||
'network-socket': {'observable': 'observable_socket', 'pattern': 'pattern_socket'},
|
||||
'process': {'observable': 'attributes_from_process_observable', 'pattern': 'pattern_process'},
|
||||
'registry-key': {'observable': 'attributes_from_regkey_observable', 'pattern': 'pattern_regkey'},
|
||||
'url': {'observable': 'attributes_from_url_observable', 'pattern': 'pattern_url'},
|
||||
'user-account': {'observable': 'attributes_from_user_account_observable',
|
||||
'pattern': 'attributes_from_user_account_pattern'},
|
||||
'WindowsPEBinaryFile': {'observable': 'observable_pe', 'pattern': 'pattern_pe'},
|
||||
'x509': {'observable': 'attributes_from_x509_observable', 'pattern': 'pattern_x509'}}
|
||||
self.object_from_refs = {'course-of-action': 'parse_MISP_course_of_action', 'vulnerability': 'parse_vulnerability',
|
||||
'custom_object': 'parse_custom'}
|
||||
self.object_from_refs.update(dict.fromkeys(['indicator', 'observed-data'], 'parse_usual_object'))
|
||||
self.attributes_fetcher_mapping = {'indicator': 'fetch_attributes_from_indicator',
|
||||
'observed-data': 'fetch_attributes_from_observable',
|
||||
'vulnerability': 'fetch_attributes_from_vulnerability'}
|
||||
|
||||
def handler(self):
|
||||
self.general_handler()
|
||||
|
||||
def parsing_process(self, object2parse, object_type):
|
||||
labels = object2parse.get('labels')
|
||||
self.object_from_refs[object_type](object2parse, labels)
|
||||
getattr(self, self.object_from_refs[object_type])(object2parse, labels)
|
||||
|
||||
################################################################################
|
||||
## PARSING FUNCTIONS. ##
|
||||
|
@ -665,7 +662,7 @@ class StixFromMISPParser(StixParser):
|
|||
misp_object.uuid = uuid
|
||||
misp_object['meta-category'] = object_category
|
||||
try:
|
||||
attributes = self.attributes_fetcher_mapping[stix_type](o, object_type)
|
||||
attributes = getattr(self, self.attributes_fetcher_mapping[stix_type])(o, object_type)
|
||||
except KeyError:
|
||||
print("Unable to map {} object:\n{}".format(stix_type, o), file=sys.stderr)
|
||||
return
|
||||
|
@ -683,11 +680,11 @@ class StixFromMISPParser(StixParser):
|
|||
pattern = indicator.pattern.replace('\\\\', '\\').split(' AND ')
|
||||
pattern[0] = pattern[0][1:]
|
||||
pattern[-1] = pattern[-1][:-1]
|
||||
return self.objects_mapping[object_type]['pattern'](pattern)
|
||||
return getattr(self, self.objects_mapping[object_type]['pattern'])(pattern)
|
||||
|
||||
def fetch_attributes_from_observable(self, observable, object_type):
|
||||
observable = observable.objects
|
||||
return self.objects_mapping[object_type]['observable'](observable)
|
||||
return getattr(self, self.objects_mapping[object_type]['observable'])(observable)
|
||||
|
||||
def fetch_attributes_from_vulnerability(self, vulnerability, _):
|
||||
attributes = []
|
||||
|
@ -1102,52 +1099,52 @@ class StixFromMISPParser(StixParser):
|
|||
class ExternalStixParser(StixParser):
|
||||
def __init__(self):
|
||||
super(ExternalStixParser, self).__init__()
|
||||
self.object_from_refs = {'course-of-action': self.parse_course_of_action, 'vulnerability': self.parse_external_vulnerability,
|
||||
'indicator': self.parse_external_indicator, 'observed-data': self.parse_external_observable}
|
||||
self.observable_mapping = {('artifact', 'file'): self.parse_file_object_observable,
|
||||
('autonomous-system',): self.parse_asn_observable,
|
||||
('autonomous-system', 'ipv4-addr'): self.parse_asn_observable,
|
||||
('autonomous-system', 'ipv6-addr'): self.parse_asn_observable,
|
||||
('autonomous-system', 'ipv4-addr', 'ipv6-addr'): self.parse_asn_observable,
|
||||
('domain-name',): self.parse_domain_ip_observable,
|
||||
('domain-name', 'ipv4-addr'): self.parse_domain_ip_observable,
|
||||
('domain-name', 'ipv6-addr'): self.parse_domain_ip_observable,
|
||||
('domain-name', 'ipv4-addr', 'network-traffic'): self.parse_ip_port_or_network_socket_observable,
|
||||
('domain-name', 'ipv6-addr', 'network-traffic'): self.parse_ip_port_or_network_socket_observable,
|
||||
('domain-name', 'ipv4-addr', 'ipv6-addr', 'network-traffic'): self.parse_ip_port_or_network_socket_observable,
|
||||
('domain-name', 'network-traffic'): self.parse_network_socket_observable,
|
||||
('domain-name', 'network-traffic', 'url'): self.parse_url_object_observable,
|
||||
('email-addr',): self.parse_email_address_observable,
|
||||
('email-addr', 'email-message'): self.parse_email_observable,
|
||||
('email-addr', 'email-message', 'file'): self.parse_email_observable,
|
||||
('email-message',): self.parse_email_observable,
|
||||
('file',): self.parse_file_observable,
|
||||
('ipv4-addr',): self.parse_ip_address_observable,
|
||||
('ipv6-addr',): self.parse_ip_address_observable,
|
||||
('ipv4-addr', 'network-traffic'): self.parse_ip_network_traffic_observable,
|
||||
('ipv6-addr', 'network-traffic'): self.parse_ip_network_traffic_observable,
|
||||
('mac-addr',): self.parse_mac_address_observable,
|
||||
('mutex',): self.parse_mutex_observable,
|
||||
('process',): self.parse_process_observable,
|
||||
('x509-certificate',): self.parse_x509_observable,
|
||||
('url',): self.parse_url_observable,
|
||||
('user-account',): self.parse_user_account_observable,
|
||||
('windows-registry-key',): self.parse_regkey_observable}
|
||||
self.pattern_mapping = {('directory',): self.parse_file_pattern,
|
||||
('directory', 'file'): self.parse_file_pattern,
|
||||
('domain-name',): self.parse_domain_ip_port_pattern,
|
||||
('domain-name', 'ipv4-addr', 'url'): self.parse_domain_ip_port_pattern,
|
||||
('domain-name', 'ipv6-addr', 'url'): self.parse_domain_ip_port_pattern,
|
||||
('email-addr',): self.parse_email_address_pattern,
|
||||
('file',): self.parse_file_pattern,
|
||||
('ipv4-addr',): self.parse_ip_address_pattern,
|
||||
('ipv6-addr',): self.parse_ip_address_pattern,
|
||||
('network-traffic',): self.parse_network_traffic_pattern,
|
||||
('process',): self.parse_process_pattern,
|
||||
('url',): self.parse_url_pattern,
|
||||
('user-account',): self.parse_user_account_pattern,
|
||||
('windows-registry-key',): self.parse_regkey_pattern,
|
||||
('x509-certificate',): self.parse_x509_pattern}
|
||||
self.object_from_refs = {'course-of-action': 'parse_course_of_action', 'vulnerability': 'parse_external_vulnerability',
|
||||
'indicator': 'parse_external_indicator', 'observed-data': 'parse_external_observable'}
|
||||
self.observable_mapping = {('artifact', 'file'): 'parse_file_object_observable',
|
||||
('autonomous-system',): 'parse_asn_observable',
|
||||
('autonomous-system', 'ipv4-addr'): 'parse_asn_observable',
|
||||
('autonomous-system', 'ipv6-addr'): 'parse_asn_observable',
|
||||
('autonomous-system', 'ipv4-addr', 'ipv6-addr'): 'parse_asn_observable',
|
||||
('domain-name',): 'parse_domain_ip_observable',
|
||||
('domain-name', 'ipv4-addr'): 'parse_domain_ip_observable',
|
||||
('domain-name', 'ipv6-addr'): 'parse_domain_ip_observable',
|
||||
('domain-name', 'ipv4-addr', 'network-traffic'): 'parse_ip_port_or_network_socket_observable',
|
||||
('domain-name', 'ipv6-addr', 'network-traffic'): 'parse_ip_port_or_network_socket_observable',
|
||||
('domain-name', 'ipv4-addr', 'ipv6-addr', 'network-traffic'): 'parse_ip_port_or_network_socket_observable',
|
||||
('domain-name', 'network-traffic'): 'parse_network_socket_observable',
|
||||
('domain-name', 'network-traffic', 'url'): 'parse_url_object_observable',
|
||||
('email-addr',): 'parse_email_address_observable',
|
||||
('email-addr', 'email-message'): 'parse_email_observable',
|
||||
('email-addr', 'email-message', 'file'): 'parse_email_observable',
|
||||
('email-message',): 'parse_email_observable',
|
||||
('file',): 'parse_file_observable',
|
||||
('ipv4-addr',): 'parse_ip_address_observable',
|
||||
('ipv6-addr',): 'parse_ip_address_observable',
|
||||
('ipv4-addr', 'network-traffic'): 'parse_ip_network_traffic_observable',
|
||||
('ipv6-addr', 'network-traffic'): 'parse_ip_network_traffic_observable',
|
||||
('mac-addr',): 'parse_mac_address_observable',
|
||||
('mutex',): 'parse_mutex_observable',
|
||||
('process',): 'parse_process_observable',
|
||||
('x509-certificate',): 'parse_x509_observable',
|
||||
('url',): 'parse_url_observable',
|
||||
('user-account',): 'parse_user_account_observable',
|
||||
('windows-registry-key',): 'parse_regkey_observable'}
|
||||
self.pattern_mapping = {('directory',): 'parse_file_pattern',
|
||||
('directory', 'file'): 'parse_file_pattern',
|
||||
('domain-name',): 'parse_domain_ip_port_pattern',
|
||||
('domain-name', 'ipv4-addr', 'url'): 'parse_domain_ip_port_pattern',
|
||||
('domain-name', 'ipv6-addr', 'url'): 'parse_domain_ip_port_pattern',
|
||||
('email-addr',): 'parse_email_address_pattern',
|
||||
('file',): 'parse_file_pattern',
|
||||
('ipv4-addr',): 'parse_ip_address_pattern',
|
||||
('ipv6-addr',): 'parse_ip_address_pattern',
|
||||
('network-traffic',): 'parse_network_traffic_pattern',
|
||||
('process',): 'parse_process_pattern',
|
||||
('url',): 'parse_url_pattern',
|
||||
('user-account',): 'parse_user_account_pattern',
|
||||
('windows-registry-key',): 'parse_regkey_pattern',
|
||||
('x509-certificate',): 'parse_x509_pattern'}
|
||||
self.pattern_forbidden_relations = (' LIKE ', ' FOLLOWEDBY ', ' MATCHES ', ' ISSUBSET ', ' ISSUPERSET ', ' REPEATS ')
|
||||
self.single_attribute_fields = ('type', 'value', 'to_ids')
|
||||
|
||||
|
@ -1157,7 +1154,7 @@ class ExternalStixParser(StixParser):
|
|||
|
||||
def parsing_process(self, object2parse, object_type):
|
||||
try:
|
||||
self.object_from_refs[object_type](object2parse)
|
||||
getattr(self, self.object_from_refs[object_type])(object2parse)
|
||||
except KeyError:
|
||||
print("Unknown {} type: {}".format(self.stix_version, object_type), file=sys.stderr)
|
||||
|
||||
|
@ -1198,9 +1195,9 @@ class ExternalStixParser(StixParser):
|
|||
to_call = self.observable_mapping[types]
|
||||
observable_id = observable.id.split('--')[1]
|
||||
if hasattr(observable, 'object_marking_refs'):
|
||||
to_call(objects, observable_id, marking=observable.object_marking_refs)
|
||||
getattr(self, to_call)(objects, observable_id, marking=observable.object_marking_refs)
|
||||
else:
|
||||
to_call(objects, observable_id)
|
||||
getattr(self, to_call)(objects, observable_id)
|
||||
except KeyError:
|
||||
print('{} not parsed at the moment'.format(types), file=sys.stderr)
|
||||
# deeper analyse to come, as well as for indicators
|
||||
|
@ -1222,7 +1219,7 @@ class ExternalStixParser(StixParser):
|
|||
for p in pattern:
|
||||
type_ = tuple([p.split(' = ')[0].split(':')[0]])
|
||||
try:
|
||||
self.pattern_mapping[type_]([p.strip()], marking)
|
||||
getattr(self, self.pattern_mapping[type_])([p.strip()], marking)
|
||||
except KeyError:
|
||||
print('{} not parsed at the moment'.format(type_), file=sys.stderr)
|
||||
raise Exception
|
||||
|
@ -1230,7 +1227,7 @@ class ExternalStixParser(StixParser):
|
|||
pattern = [p.strip() for p in pattern.split(' AND ')]
|
||||
types = self.parse_external_pattern_types(pattern)
|
||||
try:
|
||||
self.pattern_mapping[types](pattern, marking, uuid=uuid)
|
||||
getattr(self, self.pattern_mapping[types])(pattern, marking, uuid=uuid)
|
||||
except KeyError:
|
||||
print('{} not parsed at the moment'.format(types), file=sys.stderr)
|
||||
raise Exception
|
||||
|
@ -1268,7 +1265,7 @@ class ExternalStixParser(StixParser):
|
|||
## PARSING FUNCTIONS. ##
|
||||
################################################################################
|
||||
|
||||
def add_attributes_from_observable(self, objects, attribute_type, identifier, marking, uuid):
|
||||
def add_attributes_from_observable(self, objects, attribute_type, identifier, uuid, marking):
|
||||
attribute = {'to_ids': False}
|
||||
if len(objects) == 1:
|
||||
attribute['uuid'] = uuid
|
||||
|
@ -1321,11 +1318,11 @@ class ExternalStixParser(StixParser):
|
|||
file_object.add_reference(pe_uuid, 'includes')
|
||||
self.misp_event.add_object(**file_object)
|
||||
|
||||
def parse_asn_observable(self, objects, marking, uuid):
|
||||
def parse_asn_observable(self, objects, uuid, marking=None):
|
||||
attributes = self.attributes_from_asn_observable(objects)
|
||||
self.handle_import_case(attributes, 'asn', marking, uuid)
|
||||
|
||||
def parse_domain_ip_observable(self, objects, marking, uuid):
|
||||
def parse_domain_ip_observable(self, objects, uuid, marking=None):
|
||||
attributes = self.attributes_from_domain_ip_observable(objects)
|
||||
self.handle_import_case(attributes, 'domain-ip', marking, uuid)
|
||||
|
||||
|
@ -1337,7 +1334,7 @@ class ExternalStixParser(StixParser):
|
|||
attributes = self.attributes_from_dict(values, domain_ip_mapping, True)
|
||||
self.handle_import_case(attributes, 'domain-ip', marking, uuid)
|
||||
|
||||
def parse_email_observable(self, objects, marking, uuid):
|
||||
def parse_email_observable(self, objects, uuid, marking=None):
|
||||
to_ids = False
|
||||
attributes, message = self.parse_complex_fields_observable_email(objects, to_ids)
|
||||
for m_key, m_value in message.items():
|
||||
|
@ -1345,7 +1342,7 @@ class ExternalStixParser(StixParser):
|
|||
attributes.append(self.append_email_attribute(m_key, m_value, to_ids))
|
||||
self.handle_import_case(attributes, 'email', marking, uuid)
|
||||
|
||||
def parse_email_address_observable(self, objects, marking, uuid):
|
||||
def parse_email_address_observable(self, objects, uuid, marking=None):
|
||||
mapping = to_attribute_mapping
|
||||
attributes = [{'type': 'email-dst', 'object_relation': 'to', 'to_ids': True, 'value': _object.value} for _object in objects.values()]
|
||||
self.handle_import_case(attributes, 'email', marking, uuid)
|
||||
|
@ -1355,7 +1352,7 @@ class ExternalStixParser(StixParser):
|
|||
attributes = self.fill_pattern_attributes(pattern_types, pattern_values, email_mapping)
|
||||
self.handle_import_case(attributes, 'email', marking, uuid)
|
||||
|
||||
def parse_file_observable(self, objects, marking, uuid):
|
||||
def parse_file_observable(self, objects, uuid, marking=None):
|
||||
file, directory = self.split_file_observable(objects)
|
||||
attributes = self.attributes_from_file_observable(file)
|
||||
if directory is not None and directory.path:
|
||||
|
@ -1375,7 +1372,7 @@ class ExternalStixParser(StixParser):
|
|||
else:
|
||||
self.handle_import_case(attributes, 'file', marking, uuid)
|
||||
|
||||
def parse_file_object_observable(self, objects, marking, uuid):
|
||||
def parse_file_object_observable(self, objects, uuid, marking=None):
|
||||
file, data = self.split_file_observable(objects)
|
||||
attributes = self.attributes_from_file_observable(file, data)
|
||||
if hasattr(file, 'extensions') and 'windows-pebinary-ext' in file.extensions:
|
||||
|
@ -1383,27 +1380,27 @@ class ExternalStixParser(StixParser):
|
|||
else:
|
||||
self.handle_import_case(attributes, file._type, marking, uuid)
|
||||
|
||||
def parse_ip_address_observable(self, objects, marking, uuid):
|
||||
self.add_attributes_from_observable(objects, 'ip-dst', 'value', marking, uuid)
|
||||
def parse_ip_address_observable(self, objects, uuid, marking=None):
|
||||
self.add_attributes_from_observable(objects, 'ip-dst', 'value', uuid, marking)
|
||||
|
||||
def parse_ip_address_pattern(self, pattern, marking=None, uuid=None):
|
||||
self.add_attributes_from_pattern('ip-dst', pattern, marking, uuid)
|
||||
|
||||
def parse_ip_network_traffic_observable(self, objects, marking, uuid):
|
||||
def parse_ip_network_traffic_observable(self, objects, uuid, marking=None):
|
||||
attributes, name = self.attributes_from_network_traffic(objects)
|
||||
self.handle_import_case(attributes, name, marking, uuid)
|
||||
|
||||
def parse_ip_port_or_network_socket_observable(self, objects, marking, uuid):
|
||||
def parse_ip_port_or_network_socket_observable(self, objects, uuid, marking=None):
|
||||
attributes, name = self.attributes_from_network_traffic(objects)
|
||||
self.handle_import_case(attributes, name, marking, uuid)
|
||||
|
||||
def parse_mac_address_observable(self, objects, marking, uuid):
|
||||
self.add_attributes_from_observable(objects, 'mac-address', 'value', marking, uuid)
|
||||
def parse_mac_address_observable(self, objects, uuid, marking=None):
|
||||
self.add_attributes_from_observable(objects, 'mac-address', 'value', uuid, marking)
|
||||
|
||||
def parse_mutex_observable(self, objects, marking, uuid):
|
||||
self.add_attributes_from_observable(objects, 'mutex', 'name', marking, uuid)
|
||||
def parse_mutex_observable(self, objects, uuid, marking=None):
|
||||
self.add_attributes_from_observable(objects, 'mutex', 'name', uuid, marking)
|
||||
|
||||
def parse_network_socket_observable(self, objects, marking, uuid):
|
||||
def parse_network_socket_observable(self, objects, uuid, marking=None):
|
||||
attributes, name = self.attributes_from_network_traffic(objects)
|
||||
self.handle_import_case(attributes, name, marking, uuid)
|
||||
|
||||
|
@ -1412,7 +1409,7 @@ class ExternalStixParser(StixParser):
|
|||
attributes = self.fill_pattern_attributes(pattern_types, pattern_values, network_traffic_mapping)
|
||||
self.handle_import_case(attributes, 'ip-port', marking, uuid)
|
||||
|
||||
def parse_process_observable(self, objects, marking, uuid):
|
||||
def parse_process_observable(self, objects, uuid, marking=None):
|
||||
attributes = self.attributes_from_process_observable(objects)
|
||||
self.handle_import_case(attributes, 'process', marking, uuid)
|
||||
|
||||
|
@ -1421,7 +1418,7 @@ class ExternalStixParser(StixParser):
|
|||
attributes = self.fill_pattern_attributes(pattern_types, pattern_values, process_mapping)
|
||||
self.handle_import_case(attributes, 'process', marking, uuid)
|
||||
|
||||
def parse_regkey_observable(self, objects, marking, uuid):
|
||||
def parse_regkey_observable(self, objects, uuid, marking=None):
|
||||
_object = objects['0']
|
||||
attributes = self.attributes_from_regkey_observable(_object)
|
||||
self.handle_import_case(attributes, 'registry-key', marking, uuid)
|
||||
|
@ -1431,17 +1428,17 @@ class ExternalStixParser(StixParser):
|
|||
attributes = self.fill_pattern_attributes(pattern_types, pattern_values, regkey_mapping)
|
||||
self.handle_import_case(attributes, 'registry-key', marking, uuid)
|
||||
|
||||
def parse_url_observable(self, objects, marking, uuid):
|
||||
self.add_attributes_from_observable(objects, 'url', 'value', marking, uuid)
|
||||
def parse_url_observable(self, objects, uuid, marking=None):
|
||||
self.add_attributes_from_observable(objects, 'url', 'value', uuid, marking)
|
||||
|
||||
def parse_url_pattern(self, pattern, marking=None, uuid=None):
|
||||
self.add_attributes_from_pattern('url', pattern, marking, uuid)
|
||||
|
||||
def parse_url_object_observable(self, objects, marking, uuid):
|
||||
def parse_url_object_observable(self, objects, uuid, marking=None):
|
||||
attributes = self.attributes_from_url_observable(objects)
|
||||
self.handle_import_case(attributes, 'url', marking, uuid)
|
||||
|
||||
def parse_user_account_observable(self, observable, marking, uuid):
|
||||
def parse_user_account_observable(self, observable, uuid, marking=None):
|
||||
attributes = self.attributes_from_user_account_observable(observable)
|
||||
name = self.__define_user_account_name(attributes)
|
||||
self.handle_import_case(attributes, name, marking, uuid)
|
||||
|
@ -1451,7 +1448,7 @@ class ExternalStixParser(StixParser):
|
|||
name = self.__define_user_account_name(attributes)
|
||||
self.handle_import_case(attributes, name, marking, uuid)
|
||||
|
||||
def parse_x509_observable(self, objects, marking, uuid):
|
||||
def parse_x509_observable(self, objects, uuid, marking=None):
|
||||
attributes = self.attributes_from_x509_observable(objects)
|
||||
self.handle_import_case(attributes, 'x509', marking, uuid)
|
||||
|
||||
|
@ -1533,7 +1530,7 @@ class ExternalStixParser(StixParser):
|
|||
values.append(value.strip().strip('\''))
|
||||
return types, values
|
||||
|
||||
def handle_import_case(self, attributes, name, marking=None, uuid=None):
|
||||
def handle_import_case(self, attributes, name, marking, uuid):
|
||||
if len(attributes) == 1:
|
||||
attribute = attributes[0]
|
||||
attribute = {field: attribute[field] for field in self.single_attribute_fields if attribute.get(field)}
|
||||
|
|
|
@ -100,42 +100,42 @@ class StixParser():
|
|||
# Load the mapping dictionary for STIX object types
|
||||
def load_mapping(self):
|
||||
self.attribute_types_mapping = {
|
||||
"AccountObjectType": self.handle_credential,
|
||||
'AddressObjectType': self.handle_address,
|
||||
"ArtifactObjectType": self.handle_attachment,
|
||||
"ASObjectType": self.handle_as,
|
||||
"CustomObjectType": self.handle_custom,
|
||||
"DNSRecordObjectType": self.handle_dns,
|
||||
'DomainNameObjectType': self.handle_domain_or_url,
|
||||
'EmailMessageObjectType': self.handle_email_attribute,
|
||||
'FileObjectType': self.handle_file,
|
||||
'HostnameObjectType': self.handle_hostname,
|
||||
'HTTPSessionObjectType': self.handle_http,
|
||||
'LinkObjectType': self.handle_link,
|
||||
'MutexObjectType': self.handle_mutex,
|
||||
'NetworkConnectionObjectType': self.handle_network_connection,
|
||||
'NetworkSocketObjectType': self.handle_network_socket,
|
||||
'PDFFileObjectType': self.handle_file,
|
||||
'PipeObjectType': self.handle_pipe,
|
||||
'PortObjectType': self.handle_port,
|
||||
'ProcessObjectType': self.handle_process,
|
||||
'SocketAddressObjectType': self.handle_socket_address,
|
||||
'SystemObjectType': self.handle_system,
|
||||
'UnixUserAccountObjectType': self.handle_unix_user,
|
||||
'URIObjectType': self.handle_domain_or_url,
|
||||
'UserAccountObjectType': self.handle_user,
|
||||
"WhoisObjectType": self.handle_whois,
|
||||
"WindowsFileObjectType": self.handle_file,
|
||||
'WindowsRegistryKeyObjectType': self.handle_regkey,
|
||||
"WindowsExecutableFileObjectType": self.handle_pe,
|
||||
"WindowsServiceObjectType": self.handle_windows_service,
|
||||
'WindowsUserAccountObjectType': self.handle_windows_user,
|
||||
"X509CertificateObjectType": self.handle_x509
|
||||
"AccountObjectType": 'handle_credential',
|
||||
'AddressObjectType': 'handle_address',
|
||||
"ArtifactObjectType": 'handle_attachment',
|
||||
"ASObjectType": 'handle_as',
|
||||
"CustomObjectType": 'handle_custom',
|
||||
"DNSRecordObjectType": 'handle_dns',
|
||||
'DomainNameObjectType': 'handle_domain_or_url',
|
||||
'EmailMessageObjectType': 'handle_email_attribute',
|
||||
'FileObjectType': 'handle_file',
|
||||
'HostnameObjectType': 'handle_hostname',
|
||||
'HTTPSessionObjectType': 'handle_http',
|
||||
'LinkObjectType': 'handle_link',
|
||||
'MutexObjectType': 'handle_mutex',
|
||||
'NetworkConnectionObjectType': 'handle_network_connection',
|
||||
'NetworkSocketObjectType': 'handle_network_socket',
|
||||
'PDFFileObjectType': 'handle_file',
|
||||
'PipeObjectType': 'handle_pipe',
|
||||
'PortObjectType': 'handle_port',
|
||||
'ProcessObjectType': 'handle_process',
|
||||
'SocketAddressObjectType': 'handle_socket_address',
|
||||
'SystemObjectType': 'handle_system',
|
||||
'UnixUserAccountObjectType': 'handle_unix_user',
|
||||
'URIObjectType': 'handle_domain_or_url',
|
||||
'UserAccountObjectType': 'handle_user',
|
||||
"WhoisObjectType": 'handle_whois',
|
||||
"WindowsFileObjectType": 'handle_file',
|
||||
'WindowsRegistryKeyObjectType': 'handle_regkey',
|
||||
"WindowsExecutableFileObjectType": 'handle_pe',
|
||||
"WindowsServiceObjectType": 'handle_windows_service',
|
||||
'WindowsUserAccountObjectType': 'handle_windows_user',
|
||||
"X509CertificateObjectType": 'handle_x509'
|
||||
}
|
||||
|
||||
self.marking_mapping = {
|
||||
'AIS:AISMarkingStructure': self.parse_AIS_marking,
|
||||
'tlpMarking:TLPMarkingStructureType': self.parse_TLP_marking
|
||||
'AIS:AISMarkingStructure': 'parse_AIS_marking',
|
||||
'tlpMarking:TLPMarkingStructureType': 'parse_TLP_marking'
|
||||
}
|
||||
|
||||
def parse_marking(self, handling):
|
||||
|
@ -143,7 +143,7 @@ class StixParser():
|
|||
if hasattr(handling, 'marking_structures') and handling.marking_structures:
|
||||
for marking in handling.marking_structures:
|
||||
try:
|
||||
tags.extend(self.marking_mapping[marking._XSI_TYPE](marking))
|
||||
tags.extend(getattr(self, self.marking_mapping[marking._XSI_TYPE])(marking))
|
||||
except KeyError:
|
||||
print(marking._XSI_TYPE, file=sys.stderr)
|
||||
continue
|
||||
|
@ -226,7 +226,7 @@ class StixParser():
|
|||
args.append(is_object)
|
||||
elif xsi_type == "ArtifactObjectType":
|
||||
args.append(title)
|
||||
return self.attribute_types_mapping[xsi_type](*args)
|
||||
return getattr(self, self.attribute_types_mapping[xsi_type])(*args)
|
||||
# except AttributeError:
|
||||
# # ATM USED TO TEST TYPES
|
||||
# print("Unparsed type: {}".format(xsi_type))
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit d7e067bf5b2889c43699c86f66c56b4139ac42dc
|
||||
Subproject commit 6179f6bb4adb02c99c9a0b133d2b0756758d0585
|
|
@ -1 +1 @@
|
|||
Subproject commit baa25888c98a44b96cf50716e5bc51219e57b33a
|
||||
Subproject commit 260171d89b494f4e8c84fa80ac263d296b43a2f9
|
|
@ -931,6 +931,10 @@ a.proposal_link_red:hover {
|
|||
float: left;
|
||||
}
|
||||
|
||||
.modal-body-long {
|
||||
max-height: 600px;
|
||||
}
|
||||
|
||||
.ajax_popover_form {
|
||||
display:none;
|
||||
width: 700px;
|
||||
|
@ -993,7 +997,7 @@ a.proposal_link_red:hover {
|
|||
border-radius: 10px 10px 0px 0px;
|
||||
padding-left:10px;
|
||||
margin-bottom:0px;
|
||||
width:690px;
|
||||
width:calc(100% - 10px);
|
||||
background-color:black;
|
||||
color:white;
|
||||
font-size: 21px;
|
||||
|
@ -1027,8 +1031,9 @@ a.proposal_link_red:hover {
|
|||
height:120px !important;
|
||||
}
|
||||
|
||||
.ajax_popover_form .add_attribute_fields {
|
||||
.ajax_fieldset, .ajax_popover_form .add_attribute_fields {
|
||||
padding-left:10px;
|
||||
padding-right:10px;
|
||||
}
|
||||
|
||||
.hover_enrichment_text {
|
||||
|
@ -2509,4 +2514,4 @@ table tr:hover .down-expand-button {
|
|||
background-color: #3b3b3b;
|
||||
color: white;
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1170,62 +1170,56 @@ function clickCreateButton(event, type) {
|
|||
simplePopup("/" + destination + "/add/" + event);
|
||||
}
|
||||
|
||||
function submitPopoverForm(context_id, referer, update_context_id, popover_dissmis_id_to_close) {
|
||||
function openGenericModal(url) {
|
||||
$.ajax({
|
||||
type: "get",
|
||||
url: url,
|
||||
success: function (data) {
|
||||
$('#genericModal').remove();
|
||||
$('body').append(data);
|
||||
$('#genericModal').modal();
|
||||
},
|
||||
error: function (data, textStatus, errorThrown) {
|
||||
showMessage('fail', textStatus + ": " + errorThrown);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// function submitPopoverForm(context_id, referer, update_context_id, popover_dissmis_id_to_close) {
|
||||
function submitPopoverForm(context_id, referer, update_context_id, modal) {
|
||||
var url = null;
|
||||
var context = 'event';
|
||||
var contextNamingConvention = 'Attribute';
|
||||
var closePopover = true;
|
||||
switch (referer) {
|
||||
case 'add':
|
||||
url = "/attributes/add/" + context_id;
|
||||
break;
|
||||
case 'edit':
|
||||
url = "/attributes/edit/" + context_id;
|
||||
break;
|
||||
case 'propose':
|
||||
url = "/shadow_attributes/add/" + context_id;
|
||||
break;
|
||||
case 'massEdit':
|
||||
url = "/attributes/editSelected/" + context_id;
|
||||
break;
|
||||
case 'addTextElement':
|
||||
url = "/templateElements/add/text/" + context_id;
|
||||
context = 'template';
|
||||
contextNamingConvention = 'TemplateElementText';
|
||||
break;
|
||||
case 'editTextElement':
|
||||
url = "/templateElements/edit/text/" + context_id;
|
||||
context = 'template';
|
||||
context_id = update_context_id;
|
||||
contextNamingConvention = 'TemplateElementText';
|
||||
break;
|
||||
case 'addAttributeElement':
|
||||
url = "/templateElements/add/attribute/" + context_id;
|
||||
context = 'template';
|
||||
contextNamingConvention = 'TemplateElementAttribute';
|
||||
break;
|
||||
case 'editAttributeElement':
|
||||
url = "/templateElements/edit/attribute/" + context_id;
|
||||
context = 'template';
|
||||
context_id = update_context_id;
|
||||
contextNamingConvention = 'TemplateElementAttribute';
|
||||
break;
|
||||
case 'addFileElement':
|
||||
url = "/templateElements/add/file/" + context_id;
|
||||
context = 'template';
|
||||
contextNamingConvention = 'TemplateElementFile';
|
||||
break;
|
||||
case 'editFileElement':
|
||||
url = "/templateElements/edit/file/" + context_id;
|
||||
context = 'template';
|
||||
context_id = update_context_id;
|
||||
contextNamingConvention = 'TemplateElementFile';
|
||||
break;
|
||||
case 'replaceAttributes':
|
||||
url = "/attributes/attributeReplace/" + context_id;
|
||||
break;
|
||||
case 'addSighting':
|
||||
url = "/sightings/add/" + context_id;
|
||||
closePopover = false;
|
||||
break;
|
||||
case 'addObjectReference':
|
||||
|
@ -1235,44 +1229,101 @@ function submitPopoverForm(context_id, referer, update_context_id, popover_dissm
|
|||
url = "/objects/quickAddAttributeForm/" + context_id;
|
||||
break;
|
||||
}
|
||||
if (url !== null) {
|
||||
url = baseurl + url;
|
||||
$.ajax({
|
||||
beforeSend: function (XMLHttpRequest) {
|
||||
$(".loading").show();
|
||||
if ($("#submitButton").parent().hasClass('modal-footer')) {
|
||||
var $form = $("#submitButton").parent().parent().find('.modal-body form');
|
||||
url = baseurl + $form.attr('action');
|
||||
} else {
|
||||
var $form = $("#submitButton").closest("form");
|
||||
url = baseurl + $form.attr('action');
|
||||
}
|
||||
$.ajax({
|
||||
beforeSend: function (XMLHttpRequest) {
|
||||
if (modal) {
|
||||
if (closePopover) {
|
||||
$('#genericModal').modal('hide');
|
||||
}
|
||||
} else {
|
||||
if (closePopover) {
|
||||
$("#gray_out").fadeOut();
|
||||
$("#popover_form").fadeOut();
|
||||
if (popover_dissmis_id_to_close !== undefined) {
|
||||
$('[data-dismissid="' + popover_dissmis_id_to_close + '"]').popover('destroy');
|
||||
}
|
||||
// if (popover_dissmis_id_to_close !== undefined) {
|
||||
// $('[data-dismissid="' + popover_dissmis_id_to_close + '"]').popover('destroy');
|
||||
// }
|
||||
$(".loading").show();
|
||||
}
|
||||
},
|
||||
data: $("#submitButton").closest("form").serialize(),
|
||||
success:function (data, textStatus) {
|
||||
var result;
|
||||
if (closePopover) {
|
||||
}
|
||||
},
|
||||
data: $form.serialize(),
|
||||
success:function (data, textStatus) {
|
||||
var result;
|
||||
if (closePopover) {
|
||||
if (modal) {
|
||||
result = handleAjaxModalResponse(data, context_id, url, referer, context, contextNamingConvention);
|
||||
} else {
|
||||
result = handleAjaxPopoverResponse(data, context_id, url, referer, context, contextNamingConvention);
|
||||
}
|
||||
if (referer == 'addSighting') {
|
||||
updateIndex(update_context_id, 'event');
|
||||
$.get( "/sightings/listSightings/" + id + "/attribute", function(data) {
|
||||
$("#sightingsData").html(data);
|
||||
});
|
||||
$('.sightingsToggle').removeClass('btn-primary');
|
||||
$('.sightingsToggle').addClass('btn-inverse');
|
||||
$('#sightingsListAllToggle').removeClass('btn-inverse');
|
||||
$('#sightingsListAllToggle').addClass('btn-primary');
|
||||
}
|
||||
if (
|
||||
(
|
||||
context == 'event' &&
|
||||
(referer == 'add' || referer == 'massEdit' || referer == 'replaceAttributes' || referer == 'addObjectReference')
|
||||
) ||
|
||||
referer == 'quickAddAttributeForm'
|
||||
){
|
||||
eventUnpublish();
|
||||
}
|
||||
if (referer == 'addSighting') {
|
||||
updateIndex(update_context_id, 'event');
|
||||
$.get( "/sightings/listSightings/" + id + "/attribute", function(data) {
|
||||
$("#sightingsData").html(data);
|
||||
});
|
||||
$('.sightingsToggle').removeClass('btn-primary');
|
||||
$('.sightingsToggle').addClass('btn-inverse');
|
||||
$('#sightingsListAllToggle').removeClass('btn-inverse');
|
||||
$('#sightingsListAllToggle').addClass('btn-primary');
|
||||
}
|
||||
if (
|
||||
(
|
||||
context == 'event' &&
|
||||
(referer == 'add' || referer == 'massEdit' || referer == 'replaceAttributes' || referer == 'addObjectReference')
|
||||
) ||
|
||||
referer == 'quickAddAttributeForm' // FIXME: Why no inline with the others?
|
||||
){
|
||||
eventUnpublish();
|
||||
}
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
showMessage('fail', textStatus + ": " + errorThrown);
|
||||
},
|
||||
complete: function () {
|
||||
$(".loading").hide();
|
||||
},
|
||||
type: "post",
|
||||
url: url,
|
||||
});
|
||||
return false;
|
||||
};
|
||||
|
||||
function handleAjaxModalResponse(response, context_id, url, referer, context, contextNamingConvention) {
|
||||
responseArray = response;
|
||||
var message = null;
|
||||
var result = "fail";
|
||||
if (responseArray.saved) {
|
||||
updateIndex(context_id, context);
|
||||
if (responseArray.success) {
|
||||
showMessage("success", responseArray.success);
|
||||
result = "success";
|
||||
}
|
||||
if (responseArray.errors) {
|
||||
showMessage("fail", responseArray.errors);
|
||||
}
|
||||
} else {
|
||||
var savedArray = saveValuesForPersistance();
|
||||
$.ajax({
|
||||
async:true,
|
||||
dataType:"html",
|
||||
success:function (data, textStatus) {
|
||||
$('#genericModal').remove();
|
||||
$('body').append(data);
|
||||
$('#genericModal').modal();
|
||||
var error_context = context.charAt(0).toUpperCase() + context.slice(1);
|
||||
handleValidationErrors(responseArray.errors, context, contextNamingConvention);
|
||||
result = "success";
|
||||
if (!$.isEmptyObject(responseArray)) {
|
||||
result = "fail";
|
||||
}
|
||||
recoverValuesFromPersistance(savedArray);
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
showMessage('fail', textStatus + ": " + errorThrown);
|
||||
|
@ -1280,13 +1331,11 @@ function submitPopoverForm(context_id, referer, update_context_id, popover_dissm
|
|||
complete: function () {
|
||||
$(".loading").hide();
|
||||
},
|
||||
type: "post",
|
||||
url: url,
|
||||
url:url
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
function handleAjaxPopoverResponse(response, context_id, url, referer, context, contextNamingConvention) {
|
||||
responseArray = response;
|
||||
|
|
Loading…
Reference in New Issue