Merge branch 'develop' of github.com:MISP/MISP into develop

pull/8673/head
Sami Mokaddem 2022-10-17 11:31:48 +02:00
commit e41a9d2bb7
No known key found for this signature in database
GPG Key ID: 164C473F627A06FA
11 changed files with 109 additions and 58 deletions

View File

@ -35,7 +35,7 @@ class AppController extends Controller
public $helpers = array('OrgImg', 'FontAwesome', 'UserName'); public $helpers = array('OrgImg', 'FontAwesome', 'UserName');
private $__queryVersion = '145'; private $__queryVersion = '146';
public $pyMispVersion = '2.4.162'; public $pyMispVersion = '2.4.162';
public $phpmin = '7.2'; public $phpmin = '7.2';
public $phprec = '7.4'; public $phprec = '7.4';

View File

@ -488,6 +488,7 @@ class RestResponseComponent extends Component
* @param mixed $data * @param mixed $data
* @return CakeResponse * @return CakeResponse
* @throws Exception * @throws Exception
* @deprecated Use failResponse instead
*/ */
public function saveFailResponse($controller, $action, $id, $validationErrors, $format = false, $data = null) public function saveFailResponse($controller, $action, $id, $validationErrors, $format = false, $data = null)
{ {
@ -514,6 +515,18 @@ class RestResponseComponent extends Component
return $this->__sendResponse($response, 403, $format); return $this->__sendResponse($response, 403, $format);
} }
/**
* @param int|null $id
* @param array|string $validationErrors
* @param mixed $additionalData
* @return CakeResponse|CakeResponseFile
* @throws Exception
*/
public function failResponse($id = null, $validationErrors = null, $additionalData = null)
{
return $this->saveFailResponse($this->Controller->name, $this->Controller->action, $id, $validationErrors, 'json', $additionalData);
}
/** /**
* @param string $controller * @param string $controller
* @param string $action * @param string $action
@ -523,6 +536,7 @@ class RestResponseComponent extends Component
* @param mixed $data * @param mixed $data
* @return CakeResponse * @return CakeResponse
* @throws Exception * @throws Exception
* @deprecated Use successResponse instead
*/ */
public function saveSuccessResponse($controller, $action, $id = false, $format = false, $message = false, $data = null) public function saveSuccessResponse($controller, $action, $id = false, $format = false, $message = false, $data = null)
{ {
@ -546,6 +560,18 @@ class RestResponseComponent extends Component
return $this->__sendResponse($response, 200, $format); return $this->__sendResponse($response, 200, $format);
} }
/**
* @param int|null $id
* @param string|null $message
* @param mixed $additionalData
* @return CakeResponse|CakeResponseFile
* @throws Exception
*/
public function successResponse($id = null, $message = null, $additionalData = null)
{
return $this->saveSuccessResponse($this->Controller->name, $this->Controller->action, $id, 'json', $message, $additionalData);
}
/** /**
* @param mixed $response * @param mixed $response
* @param int $code * @param int $code

View File

@ -1064,36 +1064,47 @@ class TagsController extends AppController
return $this->RestResponse->viewData($tags, $this->response->type()); return $this->RestResponse->viewData($tags, $this->response->type());
} }
public function modifyTagRelationship($scope, $id) { public function modifyTagRelationship($scope, $id)
{
$validScopes = ['event', 'attribute']; $validScopes = ['event', 'attribute'];
if (!in_array($scope, $validScopes)) { if (!in_array($scope, $validScopes, true)) {
throw new InvalidArgumentException(__('Invalid scope. Valid options: %s', implode(', ', $validScopes))); throw new InvalidArgumentException(__('Invalid scope. Valid options: %s', implode(', ', $validScopes)));
} }
$model_name = Inflector::classify($scope) . 'Tag'; $model_name = Inflector::classify($scope) . 'Tag';
$tagConnector = $this->Tag->$model_name->find('first', [ $tagConnector = $this->Tag->$model_name->find('first', [
'conditions' => [$model_name . '.id' => $id], 'conditions' => [$model_name . '.id' => $id],
'recursive' => -1, 'recursive' => -1,
'contain' => 'Tag' 'contain' => ['Tag'],
]); ]);
if (empty($tagConnector)) {
throw new NotFoundException(__('Tag not found.'));
}
$event = $this->Tag->EventTag->Event->fetchSimpleEvent($this->Auth->user(), $tagConnector[$model_name]['event_id']);
if (empty($event)) {
throw new NotFoundException(__('Event not found.'));
}
if (!$this->__canModifyTag($event, $tagConnector[$model_name]['local'])) {
throw new ForbiddenException(__('You dont have permission to modify this tag.'));
}
if ($this->request->is('post')) { if ($this->request->is('post')) {
if (isset($this->request->data['Tag']['relationship_type'])) { if (isset($this->request->data['Tag']['relationship_type'])) {
$tagConnector[$model_name]['relationship_type'] = $this->request->data['Tag']['relationship_type']; $tagConnector[$model_name]['relationship_type'] = $this->request->data['Tag']['relationship_type'];
} else { } else {
$tagConnector[$model_name]['relationship_type'] = ''; $tagConnector[$model_name]['relationship_type'] = '';
} }
$result = $this->Tag->$model_name->save($tagConnector); $result = $this->Tag->$model_name->save($tagConnector, true, ['relationship_type']);
if ($result) { if ($result) {
$message = __('Relationship updated.'); $message = __('Relationship updated.');
if ($this->_isRest()) { if ($this->_isRest() || $this->request->is('ajax')) {
return $this->RestResponse->successResponse($id, $message, ["{$scope}_id" => $tagConnector[$model_name]["{$scope}_id"]]);
} else { } else {
$this->Flash->success($message); $this->Flash->success($message);
$this->redirect($this->referer()); $this->redirect($this->referer());
} }
} else { } else {
$message = __('Relationship could not be updated.'); $message = __('Relationship could not be updated.');
if ($this->_isRest()) { if ($this->_isRest() || $this->request->is('ajax')) {
return $this->RestResponse->failResponse($id, $this->Tag->$model_name->validationErrors);
} else { } else {
$this->Flash->error($message); $this->Flash->error($message);
$this->redirect($this->referer()); $this->redirect($this->referer());
@ -1110,6 +1121,7 @@ class TagsController extends AppController
$relationships['custom'] = 'custom'; $relationships['custom'] = 'custom';
$relationships[null] = 'Unspecified'; $relationships[null] = 'Unspecified';
ksort($relationships); ksort($relationships);
$this->set('title', __('Modify Tag Relationship')); $this->set('title', __('Modify Tag Relationship'));
$this->set( $this->set(
'description', 'description',
@ -1124,6 +1136,7 @@ class TagsController extends AppController
$this->set('options', $relationships); $this->set('options', $relationships);
$this->set('default', $tagConnector[$model_name]['relationship_type']); $this->set('default', $tagConnector[$model_name]['relationship_type']);
$this->set('model', 'Tag'); $this->set('model', 'Tag');
$this->set('onsubmit', 'modifyTagRelationship()');
$this->set('field', 'relationship_type'); $this->set('field', 'relationship_type');
$this->layout = false; $this->layout = false;
$this->render('/genericTemplates/select'); $this->render('/genericTemplates/select');

View File

@ -5992,7 +5992,15 @@ class Event extends AppModel
return $attributes_added; return $attributes_added;
} }
public function massageTags($user, $data, $dataType = 'Event', $excludeGalaxy = false, $cullGalaxyTags = false) /**
* @param array $user
* @param array $data
* @param string $dataType
* @param bool $excludeGalaxy
* @param bool $cullGalaxyTags
* @return array
*/
public function massageTags(array $user, array $data, $dataType = 'Event', $excludeGalaxy = false, $cullGalaxyTags = false)
{ {
$data['Galaxy'] = array(); $data['Galaxy'] = array();
@ -6012,14 +6020,15 @@ class Event extends AppModel
$cluster = $this->GalaxyCluster->getCluster($dataTag['Tag']['name'], $user); $cluster = $this->GalaxyCluster->getCluster($dataTag['Tag']['name'], $user);
if ($cluster) { if ($cluster) {
$found = false; $found = false;
$cluster['GalaxyCluster']['local'] = isset($dataTag['local']) ? $dataTag['local'] : false; $cluster['GalaxyCluster']['local'] = $dataTag['local'] ?? false;
$cluster['GalaxyCluster'][strtolower($dataType) . '_tag_id'] = $dataTag['id'];
foreach ($data['Galaxy'] as $j => $galaxy) { foreach ($data['Galaxy'] as $j => $galaxy) {
if ($galaxy['id'] == $cluster['GalaxyCluster']['Galaxy']['id']) { if ($galaxy['id'] == $cluster['GalaxyCluster']['Galaxy']['id']) {
$found = true; $found = true;
$temp = $cluster; $temp = $cluster;
unset($temp['GalaxyCluster']['Galaxy']); unset($temp['GalaxyCluster']['Galaxy']);
$data['Galaxy'][$j]['GalaxyCluster'][] = $temp['GalaxyCluster']; $data['Galaxy'][$j]['GalaxyCluster'][] = $temp['GalaxyCluster'];
continue; break;
} }
} }
if (!$found) { if (!$found) {

View File

@ -89,14 +89,12 @@
$span_relationship = ''; $span_relationship = '';
if ($full || ($fullLocal && $tag['Tag']['local'])) { if ($full || ($fullLocal && $tag['Tag']['local'])) {
$span_relationship = sprintf( $span_relationship = sprintf(
'<span class="%s" title="%s" role="%s" tabindex="%s" aria-label="%s" onclick="%s"><i class="fas fa-project-diagram"></i></span>', '<a class="%s" title="%s" role="button" tabindex="0" aria-label="%s" href="%s"><i class="fas fa-project-diagram"></i></a>',
'black-white tag useCursorPointer noPrint', 'black-white tag noPrint modal-open',
__('Modify Tag Relationship'), __('Modify Tag Relationship'),
"button",
"0",
__('Modify relationship for tag %s', h($tag['Tag']['name'])), __('Modify relationship for tag %s', h($tag['Tag']['name'])),
sprintf( sprintf(
'openGenericModal(\'%s/tags/modifyTagRelationship/%s/%s\');', '%s/tags/modifyTagRelationship/%s/%s',
$baseurl, $baseurl,
h($scope), h($scope),
h($tag['id']) h($tag['id'])

View File

@ -12,16 +12,9 @@
<?= $this->Form->postLink( <?= $this->Form->postLink(
h($actionName), h($actionName),
$this->request->here(), $this->request->here(),
['class' => 'btn btn-primary button-execute'] ['class' => 'btn btn-primary']
) )
?> ?>
<button type="button" class="btn btn-secondary cancel-button" data-dismiss="modal"><?= __('Cancel') ?></button> <button type="button" class="btn btn-secondary cancel-button" data-dismiss="modal"><?= __('Cancel') ?></button>
</div> </div>
</div> </div>
<script type="text/javascript">
$(document).keydown(function(e) {
if(e.which === 13 && e.ctrlKey) {
$('.button-execute').click();
}
});
</script>

View File

@ -12,16 +12,9 @@
<?= $this->Form->postLink( <?= $this->Form->postLink(
h($actionName), h($actionName),
$this->request->here(), $this->request->here(),
['class' => 'btn btn-primary button-execute'] ['class' => 'btn btn-primary']
) )
?> ?>
<button type="button" class="btn btn-secondary cancel-button" data-dismiss="modal"><?= __('Cancel') ?></button> <button type="button" class="btn btn-secondary cancel-button" data-dismiss="modal"><?= __('Cancel') ?></button>
</div> </div>
</div> </div>
<script type="text/javascript">
$(document).keydown(function(e) {
if(e.which === 13 && e.ctrlKey) {
$('.button-execute').click();
}
});
</script>

View File

@ -23,17 +23,10 @@ $title = Inflector::singularize(Inflector::humanize(Inflector::underscore($this-
<?= $this->Form->postLink( <?= $this->Form->postLink(
'Delete', 'Delete',
$this->request->here(), $this->request->here(),
['class' => 'btn btn-primary button-execute'] ['class' => 'btn btn-primary']
) )
?> ?>
<button type="button" class="btn btn-secondary cancel-button" data-dismiss="modal"><?= __('Cancel') ?></button> <button type="button" class="btn btn-secondary cancel-button" data-dismiss="modal"><?= __('Cancel') ?></button>
</div> </div>
<?php endif; ?> <?php endif; ?>
</div> </div>
<script type="text/javascript">
$(document).keydown(function(e) {
if (e.which === 13 && e.ctrlKey) {
$('.button-execute').click();
}
});
</script>

View File

@ -5,27 +5,20 @@
</button> </button>
<h3 id="genericModalLabel"><?= h($title) ?></h3> <h3 id="genericModalLabel"><?= h($title) ?></h3>
</div> </div>
<?= $this->Form->create($model, ['onsubmit' => $onsubmit ?? null, 'style' => 'margin:0']) ?>
<div class="modal-body modal-body-long"> <div class="modal-body modal-body-long">
<p><?= h($description) ?></p> <p><?= h($description) ?></p>
<?php <?php
$randomNumber = rand();
echo $this->Form->create($model, ['id' => $randomNumber . 'Form']);
echo $this->Form->input('relationship_type', [ echo $this->Form->input('relationship_type', [
'type' => 'select', 'type' => 'select',
'options' => $options 'options' => $options,
'default' => $default ?? null,
]); ]);
echo $this->Form->end();
?> ?>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-primary button-execute" onclick="$('#<?= $randomNumber . 'Form' ?>').submit();"><?= __('Submit') ?></button> <button type="submit" class="btn btn-primary"><?= __('Submit') ?></button>
<button type="button" class="btn btn-secondary cancel-button" data-dismiss="modal"><?= __('Cancel') ?></button> <button type="button" class="btn btn-secondary cancel-button" data-dismiss="modal"><?= __('Cancel') ?></button>
</div> </div>
<?= $this->Form->end() ?>
</div> </div>
<script type="text/javascript">
$(document).keydown(function(e) {
if(e.which === 13 && e.ctrlKey) {
$('.button-execute').click();
}
});
</script>

View File

@ -867,6 +867,10 @@ a.proposal_link_red:hover {
color:white; color:white;
} }
a.black-white:hover {
color: white;
}
.tagFirstHalf { .tagFirstHalf {
display: inline-block; display: inline-block;
padding: 2px 4px; padding: 2px 4px;

View File

@ -799,6 +799,35 @@ function refreshTagCollectionRow(tag_collection_id) {
}); });
} }
function modifyTagRelationship() {
event.preventDefault();
var $form = $(event.target);
var action = $form.attr("action");
$.ajax({
type: "post",
url: action,
data: $form.serialize(),
error: xhrFailCallback,
success: function (data) {
if (data.saved) {
$('#genericModal').modal('hide');
if ("attribute_id" in data.data) {
var attribute_id = data.data.attribute_id;
loadAttributeTags(attribute_id);
loadGalaxies(attribute_id, 'attribute');
} else {
var event_id = data.data.event_id;
loadEventTags(event_id);
loadGalaxies(event_id, 'event');
}
}
}
});
return false;
}
function handleAjaxEditResponse($td, data, type, id, field) { function handleAjaxEditResponse($td, data, type, id, field) {
var responseArray = data; var responseArray = data;
if (type === 'Attribute') { if (type === 'Attribute') {
@ -1084,9 +1113,9 @@ function getSelectedTaxonomyNames() {
function loadEventTags(id) { function loadEventTags(id) {
$.ajax({ $.ajax({
dataType:"html", dataType: "html",
cache: false, cache: false,
success:function (data) { success: function (data) {
$(".eventTagContainer").html(data); $(".eventTagContainer").html(data);
}, },
url: baseurl + "/tags/showEventTag/" + id, url: baseurl + "/tags/showEventTag/" + id,
@ -4849,8 +4878,8 @@ $(document.body).on('keyup', '#quickFilterField', function(e) {
} }
}); });
// Send textarea form on CMD+ENTER or CTRL+ENTER // Send textarea or select form on CMD+ENTER or CTRL+ENTER
$(document.body).on('keydown', 'textarea', function(e) { $(document.body).on('keydown', 'textarea, select', function(e) {
if (e.keyCode === 13 && (e.metaKey || e.ctrlKey)) { // CMD+ENTER or CTRL+ENTER key if (e.keyCode === 13 && (e.metaKey || e.ctrlKey)) { // CMD+ENTER or CTRL+ENTER key
if (e.target.form) { if (e.target.form) {
$(e.target.form).submit(); $(e.target.form).submit();