mirror of https://github.com/MISP/MISP
Merge branch 'attributefiltering' into 2.4
commit
bbbdea72e3
|
@ -36,6 +36,7 @@ $config = array(
|
||||||
'take_ownership_xml_import' => false,
|
'take_ownership_xml_import' => false,
|
||||||
'unpublishedprivate' => false,
|
'unpublishedprivate' => false,
|
||||||
'disable_emailing' => false,
|
'disable_emailing' => false,
|
||||||
|
'Attributes_Values_Filter_In_Event' => 'id, uuid, value, comment, type, category, Tag.name',
|
||||||
),
|
),
|
||||||
'GnuPG' =>
|
'GnuPG' =>
|
||||||
array(
|
array(
|
||||||
|
|
|
@ -46,7 +46,7 @@ class AppController extends Controller {
|
||||||
|
|
||||||
public $helpers = array('Utility');
|
public $helpers = array('Utility');
|
||||||
|
|
||||||
private $__queryVersion = '20';
|
private $__queryVersion = '21';
|
||||||
public $pyMispVersion = '2.4.80';
|
public $pyMispVersion = '2.4.80';
|
||||||
public $phpmin = '5.6.5';
|
public $phpmin = '5.6.5';
|
||||||
public $phprec = '7.0.16';
|
public $phprec = '7.0.16';
|
||||||
|
|
|
@ -714,6 +714,51 @@ class EventsController extends AppController {
|
||||||
$this->layout = 'ajax';
|
$this->layout = 'ajax';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Search for a value on an attribute level for a specific field.
|
||||||
|
* $attribute : (array) an attribute
|
||||||
|
* $fields : (array) list of keys in attribute to search in
|
||||||
|
* $searchValue : Value to search
|
||||||
|
* returns true on match
|
||||||
|
*/
|
||||||
|
private function __valueInFieldAttribute($attribute, $fields, $searchValue) {
|
||||||
|
foreach ($attribute as $k => $v){ // look in attributes line
|
||||||
|
if (is_string($v)) {
|
||||||
|
foreach ($fields as $field){
|
||||||
|
if (strpos(".", $field) === false) { // check sub array after
|
||||||
|
// check for key in attribut
|
||||||
|
if (isset($attribute[$field])) {
|
||||||
|
$temp_value = strtolower($attribute[$field]);
|
||||||
|
$temp_search = strtolower($searchValue);
|
||||||
|
if(strpos($temp_value, $temp_search) !==false) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// check for tag in attribut maybe for other thing later
|
||||||
|
if($k === 'AttributeTag'){
|
||||||
|
foreach ($v as $tag) {
|
||||||
|
foreach ($fields as $field) {
|
||||||
|
if (strpos(strtolower($field), "tag.") !== false) { // check sub array
|
||||||
|
$tagKey = explode('tag.', strtolower($field))[1];
|
||||||
|
if (isset($tag['Tag'][$tagKey])) {
|
||||||
|
$temp_value = strtolower($tag['Tag'][$tagKey]);
|
||||||
|
$temp_search = strtolower($searchValue);
|
||||||
|
if (strpos($temp_value, $temp_search) !==false) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function viewEventAttributes($id, $all = false) {
|
public function viewEventAttributes($id, $all = false) {
|
||||||
if (isset($this->params['named']['focus'])) {
|
if (isset($this->params['named']['focus'])) {
|
||||||
$this->set('focus', $this->params['named']['focus']);
|
$this->set('focus', $this->params['named']['focus']);
|
||||||
|
@ -725,6 +770,50 @@ class EventsController extends AppController {
|
||||||
$results = $this->Event->fetchEvent($this->Auth->user(), $conditions);
|
$results = $this->Event->fetchEvent($this->Auth->user(), $conditions);
|
||||||
if (empty($results)) throw new NotFoundException('Invalid event');
|
if (empty($results)) throw new NotFoundException('Invalid event');
|
||||||
$event = $results[0];
|
$event = $results[0];
|
||||||
|
|
||||||
|
if (!empty($this->params['named']['searchFor'])) {
|
||||||
|
$filterColumns = empty(Configure::read('MISP.event_view_filter_fields')) ? 'id, uuid, value, comment, type, category, Tag.name' : Configure::read('MISP.event_view_filter_fields');
|
||||||
|
$filterValue = array_map('trim', explode(",", $filterColumns));
|
||||||
|
$validFilters = array('id', 'uuid', 'value', 'comment', 'type', 'category', 'Tag.name');
|
||||||
|
foreach ($filterValue as $k => $v) {
|
||||||
|
if (!in_array($v, $validFilters)) {
|
||||||
|
unset($filterValue[$k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// search in all attributes
|
||||||
|
foreach ($event['Attribute'] as $k => $attribute) {
|
||||||
|
if (!$this->__valueInFieldAttribute($attribute, $filterValue, $this->params['named']['searchFor'])) {
|
||||||
|
unset($event['Attribute'][$k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$event['Attribute'] = array_values($event['Attribute']);
|
||||||
|
|
||||||
|
// search in all attributes
|
||||||
|
foreach ($event['ShadowAttribute'] as $k => $proposals) {
|
||||||
|
if (!$this->__valueInFieldAttribute($proposals, $filterValue, $this->params['named']['searchFor'])) {
|
||||||
|
unset($event['ShadowAttribute'][$k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$event['ShadowAttribute'] = array_values($event['ShadowAttribute']);
|
||||||
|
|
||||||
|
// search for all attributes in object
|
||||||
|
foreach ($event['Object'] as $k => $object) {
|
||||||
|
foreach ($object['Attribute'] as $k2 => $attribute){
|
||||||
|
if (!$this->__valueInFieldAttribute($attribute, $filterValue, $this->params['named']['searchFor'])) {
|
||||||
|
unset($event['Object'][$k]['Attribute'][$k2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count($event['Object'][$k]['Attribute']) == 0){
|
||||||
|
// remove object if empty
|
||||||
|
unset($event['Object'][$k]);
|
||||||
|
} else {
|
||||||
|
$event['Object'][$k]['Attribute'] = array_values($event['Object'][$k]['Attribute']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$event['Object'] = array_values($event['Object']);
|
||||||
|
$this->set('passedArgsArray', array('all' => $this->params['named']['searchFor']));
|
||||||
|
}
|
||||||
$emptyEvent = (empty($event['Object']) && empty($event['Attribute']));
|
$emptyEvent = (empty($event['Object']) && empty($event['Attribute']));
|
||||||
$this->set('emptyEvent', $emptyEvent);
|
$this->set('emptyEvent', $emptyEvent);
|
||||||
$params = $this->Event->rearrangeEventForView($event, $this->passedArgs, $all);
|
$params = $this->Event->rearrangeEventForView($event, $this->passedArgs, $all);
|
||||||
|
|
|
@ -792,6 +792,14 @@ class Server extends AppModel {
|
||||||
'test' => null,
|
'test' => null,
|
||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
'redacted' => true
|
'redacted' => true
|
||||||
|
),
|
||||||
|
'event_view_filter_fields' => array(
|
||||||
|
'level' => 2,
|
||||||
|
'description' => 'Specify which fields to filter on when you search on the event view. Default values are : "id, uuid, value, comment, type, category, Tag.name"',
|
||||||
|
'value' => 'id, uuid, value, comment, type, category, Tag.name',
|
||||||
|
'errorMessage' => '',
|
||||||
|
'test' => null,
|
||||||
|
'type' => 'string',
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
'GnuPG' => array(
|
'GnuPG' => array(
|
||||||
|
|
|
@ -33,6 +33,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$filtered = false;
|
||||||
|
if(isset($passedArgsArray)){
|
||||||
|
if (count($passedArgsArray) > 0) {
|
||||||
|
$filtered = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
<div class="pagination">
|
<div class="pagination">
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -132,6 +138,13 @@
|
||||||
<div id="filter_deleted" title="Include deleted attributes" role="button" tabindex="0" aria-label="Include deleted attributes" class="attribute_filter_text<?php if ($deleted) echo '_active'; ?>" onClick="toggleDeletedAttributes('<?php echo Router::url( $this->here, true );?>');">Include deleted attributes</div>
|
<div id="filter_deleted" title="Include deleted attributes" role="button" tabindex="0" aria-label="Include deleted attributes" class="attribute_filter_text<?php if ($deleted) echo '_active'; ?>" onClick="toggleDeletedAttributes('<?php echo Router::url( $this->here, true );?>');">Include deleted attributes</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<div id="show_context" title="Show attribute context fields" role="button" tabindex="0" aria-label="Show attribute context fields" class="attribute_filter_text" onClick="toggleContextFields();">Show context fields</div>
|
<div id="show_context" title="Show attribute context fields" role="button" tabindex="0" aria-label="Show attribute context fields" class="attribute_filter_text" onClick="toggleContextFields();">Show context fields</div>
|
||||||
|
<div title="input filter" tabindex="0" aria-label="input filter" class="attribute_filter_text" style="padding-top:0px;">
|
||||||
|
<input type="text" id="attributesFilterField" style="height:20px;padding:0px;margin:0px;" class="form-control" data-eventid="<?php echo h($event['Event']['id']); ?>"></input>
|
||||||
|
<span id="attributesFilterButton" role="button" class="icon-search" tabindex="0" aria-label="Filter on attributes value" onClick="filterAttributes('value', '<?php echo h($event['Event']['id']); ?>');"></span>
|
||||||
|
<?php if ($filtered):?>
|
||||||
|
<span tabindex="0" aria-label="Show all attributes" title="Remove filters" role="button" onClick="filterAttributes('all', '<?php echo h($event['Event']['id']); ?>');" class='icon-remove'></span>
|
||||||
|
<?php endif;?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table class="table table-striped table-condensed">
|
<table class="table table-striped table-condensed">
|
||||||
|
@ -319,6 +332,12 @@ attributes or the appropriate distribution level. If you think there is a mistak
|
||||||
genericPopup(url, '#screenshot_box');
|
genericPopup(url, '#screenshot_box');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
$('#attributesFilterField').bind("keydown", function(e) {
|
||||||
|
var eventid = $('#attributesFilterField').data("eventid");
|
||||||
|
if ((e.keyCode == 13 || e.keyCode == 10)) {
|
||||||
|
filterAttributes('value', eventid);
|
||||||
|
}
|
||||||
|
});
|
||||||
$('.hex-value-convert').click(function() {
|
$('.hex-value-convert').click(function() {
|
||||||
var val = $(this).parent().children(':first-child').text();
|
var val = $(this).parent().children(':first-child').text();
|
||||||
if ($(this).parent().children(':first-child').attr('data-original-title') == 'Hexadecimal representation') {
|
if ($(this).parent().children(':first-child').attr('data-original-title') == 'Hexadecimal representation') {
|
||||||
|
|
|
@ -2558,6 +2558,10 @@ function syncUserSelected() {
|
||||||
|
|
||||||
function filterAttributes(filter, id) {
|
function filterAttributes(filter, id) {
|
||||||
url = "/events/viewEventAttributes/" + id + "/attributeFilter:" + filter;
|
url = "/events/viewEventAttributes/" + id + "/attributeFilter:" + filter;
|
||||||
|
if(filter === 'value'){
|
||||||
|
filter = $('#attributesFilterField').val().trim();
|
||||||
|
url += "/searchFor:" + filter;
|
||||||
|
}
|
||||||
if (deleted) url += '/deleted:true';
|
if (deleted) url += '/deleted:true';
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type:"get",
|
type:"get",
|
||||||
|
@ -3218,7 +3222,6 @@ $('.add_object_attribute_row').click(function() {
|
||||||
|
|
||||||
$('.quickToggleCheckbox').toggle(function() {
|
$('.quickToggleCheckbox').toggle(function() {
|
||||||
var url = $(this).data('checkbox-url');
|
var url = $(this).data('checkbox-url');
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
(function(){
|
(function(){
|
||||||
|
|
Loading…
Reference in New Issue