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,
|
||||
'unpublishedprivate' => false,
|
||||
'disable_emailing' => false,
|
||||
'Attributes_Values_Filter_In_Event' => 'id, uuid, value, comment, type, category, Tag.name',
|
||||
),
|
||||
'GnuPG' =>
|
||||
array(
|
||||
|
|
|
@ -46,7 +46,7 @@ class AppController extends Controller {
|
|||
|
||||
public $helpers = array('Utility');
|
||||
|
||||
private $__queryVersion = '20';
|
||||
private $__queryVersion = '21';
|
||||
public $pyMispVersion = '2.4.80';
|
||||
public $phpmin = '5.6.5';
|
||||
public $phprec = '7.0.16';
|
||||
|
|
|
@ -714,6 +714,51 @@ class EventsController extends AppController {
|
|||
$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) {
|
||||
if (isset($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);
|
||||
if (empty($results)) throw new NotFoundException('Invalid event');
|
||||
$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']));
|
||||
$this->set('emptyEvent', $emptyEvent);
|
||||
$params = $this->Event->rearrangeEventForView($event, $this->passedArgs, $all);
|
||||
|
|
|
@ -792,6 +792,14 @@ class Server extends AppModel {
|
|||
'test' => null,
|
||||
'type' => 'string',
|
||||
'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(
|
||||
|
|
|
@ -33,6 +33,12 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
$filtered = false;
|
||||
if(isset($passedArgsArray)){
|
||||
if (count($passedArgsArray) > 0) {
|
||||
$filtered = true;
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div class="pagination">
|
||||
<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>
|
||||
<?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 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>
|
||||
|
||||
<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');
|
||||
});
|
||||
});
|
||||
$('#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() {
|
||||
var val = $(this).parent().children(':first-child').text();
|
||||
if ($(this).parent().children(':first-child').attr('data-original-title') == 'Hexadecimal representation') {
|
||||
|
|
|
@ -2558,6 +2558,10 @@ function syncUserSelected() {
|
|||
|
||||
function filterAttributes(filter, id) {
|
||||
url = "/events/viewEventAttributes/" + id + "/attributeFilter:" + filter;
|
||||
if(filter === 'value'){
|
||||
filter = $('#attributesFilterField').val().trim();
|
||||
url += "/searchFor:" + filter;
|
||||
}
|
||||
if (deleted) url += '/deleted:true';
|
||||
$.ajax({
|
||||
type:"get",
|
||||
|
@ -3218,7 +3222,6 @@ $('.add_object_attribute_row').click(function() {
|
|||
|
||||
$('.quickToggleCheckbox').toggle(function() {
|
||||
var url = $(this).data('checkbox-url');
|
||||
|
||||
});
|
||||
|
||||
(function(){
|
||||
|
|
Loading…
Reference in New Issue