Adding a local_only option for Tags and Galaxies

pull/7892/head
Loic Fortemps 2021-10-27 16:46:56 +02:00 committed by Golbark
parent 2a33f27842
commit a1ba1c053e
No known key found for this signature in database
GPG Key ID: 98878A7B36234F0D
11 changed files with 87 additions and 6 deletions

View File

@ -339,6 +339,11 @@ class GalaxiesController extends AppController
$conditions[] = [
'enabled' => true
];
if(!$local) {
$conditions[] = [
'local_only' => 0
];
}
$galaxies = $this->Galaxy->find('all', array(
'recursive' => -1,
'fields' => array('MAX(Galaxy.version) as latest_version', 'id', 'kill_chain_order', 'name', 'icon', 'description'),

View File

@ -505,6 +505,7 @@ class TagsController extends AppController
$this->loadModel('Taxonomy');
$expanded = array();
$this->set('taxonomy_id', $taxonomy_id);
$local_tag = !empty($this->params['named']['local']);
if ($taxonomy_id === 'collections') {
$this->loadModel('TagCollection');
// This method removes banned and hidden tags
@ -528,7 +529,7 @@ class TagsController extends AppController
}
} else {
if ($taxonomy_id === '0') {
$temp = $this->Taxonomy->getAllTaxonomyTags(true, $this->Auth->user(), true);
$temp = $this->Taxonomy->getAllTaxonomyTags(true, $this->Auth->user(), true, true, $local_tag);
$tags = array();
foreach ($temp as $tag) {
$tags[$tag['Tag']['id']] = $tag['Tag'];
@ -543,6 +544,9 @@ class TagsController extends AppController
'Tag.user_id' => array(0, $this->Auth->user('id')),
'Tag.hide_tag' => 0,
);
if (!$local_tag) {
$conditions['Tag.local_only'] = 0;
}
$favTags = $this->Tag->FavouriteTag->find('all', array(
'conditions' => $conditions,
'recursive' => -1,
@ -562,6 +566,9 @@ class TagsController extends AppController
$conditions['Tag.org_id'] = array(0, $this->Auth->user('org_id'));
$conditions['Tag.user_id'] = array(0, $this->Auth->user('id'));
}
if (!$local_tag) {
$conditions['Tag.local_only'] = 0;
}
$allTags = $this->Tag->find('all', array(
'conditions' => $conditions,
'recursive' => -1,
@ -585,6 +592,9 @@ class TagsController extends AppController
if ($tag['hide_tag']) {
continue; // do not include hidden tags
}
if ($tag['local_only'] && !$local_tag) {
continue; // we skip the local tags for global entries
}
if (!$isSiteAdmin) {
// Skip all tags that this user cannot use for tagging, determined by the org restriction on tags
if ($tag['org_id'] != '0' && $tag['org_id'] != $this->Auth->user('org_id')) {
@ -835,6 +845,10 @@ class TagsController extends AppController
continue;
}
}
if ($existingTag['Tag']['local_only'] && !$local) {
$fails[] = __('Invalid Tag. This tag can only be set as a local tag.');
continue;
}
$this->loadModel($objectType);
$connectorObject = $objectType . 'Tag';
$conditions = array(

View File

@ -83,7 +83,7 @@ class AppModel extends Model
51 => false, 52 => false, 53 => false, 54 => false, 55 => false, 56 => false,
57 => false, 58 => false, 59 => false, 60 => false, 61 => false, 62 => false,
63 => true, 64 => false, 65 => false, 66 => false, 67 => false, 68 => false,
69 => false, 70 => false, 71 => true, 72 => true,
69 => false, 70 => false, 71 => true, 72 => true, 73 => true,
);
public $advanced_updates_description = array(
@ -1578,6 +1578,10 @@ class AppModel extends Model
case 72:
$sqlArray[] = "ALTER TABLE `auth_keys` ADD `read_only` tinyint(1) NOT NULL DEFAULT 0 AFTER `expiration`;";
break;
case 73:
$sqlArray[] = "ALTER TABLE `tags` ADD `local_only` tinyint(1) NOT NULL DEFAULT 0 AFTER `is_custom_galaxy`;";
$sqlArray[] = "ALTER TABLE `galaxies` ADD `local_only` tinyint(1) NOT NULL DEFAULT 0 AFTER `enabled`;";
break;
case 'fixNonEmptySharingGroupID':
$sqlArray[] = 'UPDATE `events` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';
$sqlArray[] = 'UPDATE `attributes` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';

View File

@ -353,6 +353,7 @@ class Galaxy extends AppModel
'conditions' => array('id' => $cluster_id),
'fields' => array('tag_name', 'id', 'value'),
), $full=false);
if (empty($cluster)) {
throw new NotFoundException(__('Invalid Galaxy cluster'));
}
@ -368,7 +369,11 @@ class Galaxy extends AppModel
throw new NotFoundException(__('Invalid %s.', $target_type));
}
$target = $target[0];
$tag_id = $this->Tag->captureTag(array('name' => $cluster['GalaxyCluster']['tag_name'], 'colour' => '#0088cc', 'exportable' => 1), $user, true);
$local_only = $cluster['GalaxyCluster']['Galaxy']['local_only'];
if ($local_only && !$local) {
return __("This Cluster can only be attached in a local scope");
}
$tag_id = $this->Tag->captureTag(array('name' => $cluster['GalaxyCluster']['tag_name'], 'colour' => '#0088cc', 'exportable' => 1, 'local_only' => $local_only), $user, true);
$existingTag = $this->Tag->$connectorModel->find('first', array('conditions' => array($target_type . '_id' => $target_id, 'tag_id' => $tag_id)));
if (!empty($existingTag)) {
return 'Cluster already attached.';

View File

@ -96,6 +96,9 @@ class Tag extends AppModel
if (!isset($this->data['Tag']['exportable'])) {
$this->data['Tag']['exportable'] = 1;
}
if (!isset($this->data['Tag']['local_only'])) {
$this->data['Tag']['local_only'] = 0;
}
if (isset($this->data['Tag']['name']) && strlen($this->data['Tag']['name']) >= 255) {
$this->data['Tag']['name'] = substr($this->data['Tag']['name'], 0, 255);
}
@ -354,6 +357,7 @@ class Tag extends AppModel
'name' => $tag['name'],
'colour' => $tag['colour'],
'exportable' => isset($tag['exportable']) ? $tag['exportable'] : 1,
'local_only' => $tag['local_only'] ?? 0,
'org_id' => 0,
'user_id' => 0,
'hide_tag' => Configure::read('MISP.incoming_tags_disabled_by_default') ? 1 : 0
@ -409,11 +413,14 @@ class Tag extends AppModel
return ($this->save($data));
}
public function quickEdit($tag, $name, $colour, $hide = false, $numerical_value = null)
public function quickEdit($tag, $name, $colour, $hide = false, $numerical_value = null, $local_only = -1)
{
if ($tag['Tag']['colour'] !== $colour || $tag['Tag']['name'] !== $name || $hide !== false || $tag['Tag']['numerical_value'] !== $numerical_value) {
if ($tag['Tag']['colour'] !== $colour || $tag['Tag']['name'] !== $name || $hide !== false || $tag['Tag']['numerical_value'] !== $numerical_value || ($tag['Tag']['local_only'] !== $local_only && $local_only !== -1)) {
$tag['Tag']['name'] = $name;
$tag['Tag']['colour'] = $colour;
if ($tag['Tag']['local_only'] !== -1) {
$tag['Tag']['local_only'] = $local_only;
}
if ($hide !== false) {
$tag['Tag']['hide_tag'] = $hide;
}

View File

@ -242,7 +242,7 @@ class Taxonomy extends AppModel
// returns all tags associated to a taxonomy
// returns all tags not associated to a taxonomy if $inverse is true
public function getAllTaxonomyTags($inverse = false, $user = false, $full = false, $hideUnselectable = true)
public function getAllTaxonomyTags($inverse = false, $user = false, $full = false, $hideUnselectable = true, $local_tag = false)
{
$this->Tag = ClassRegistry::init('Tag');
$taxonomyIdList = $this->find('column', array('fields' => array('Taxonomy.id')));
@ -260,6 +260,10 @@ class Taxonomy extends AppModel
if (Configure::read('MISP.incoming_tags_disabled_by_default') || $hideUnselectable) {
$conditions['Tag.hide_tag'] = 0;
}
// If the tag is to be added as global, we filter out the local_only tags
if (!$local_tag) {
$conditions['Tag.local_only'] = 0;
}
if ($full) {
$allTags = $this->Tag->find(
'all',

View File

@ -80,6 +80,13 @@
'class' => 'short',
'data_path' => 'Galaxy.enabled',
),
array(
'name' => __('Local Only'),
'element' => 'boolean',
'sort' => 'local_only',
'class' => 'short',
'data_path' => 'Galaxy.local_only',
),
),
'title' => __('Galaxy index'),
'actions' => array(

View File

@ -8,6 +8,7 @@
$table_data[] = array('key' => __('UUID'), 'value' => $galaxy['Galaxy']['uuid']);
$table_data[] = array('key' => __('Description'), 'value' => $galaxy['Galaxy']['description']);
$table_data[] = array('key' => __('Version'), 'value' => $galaxy['Galaxy']['version']);
$table_data[] = array('key' => __('Local Only'), 'value' => ($galaxy['Galaxy']['local_only'] ? __("Yes. It can only be added in the local context.") : __("No")));
$kco = '';
if (isset($galaxy['Galaxy']['kill_chain_order'])) {
$kco = '<strong>' . __('Kill chain order') . '</strong> <span class="useCursorPointer fa fa-expand" onclick="$(\'#killChainOrder\').toggle(\'blind\')"></span>';

View File

@ -33,6 +33,11 @@ echo $this->element('genericElements/Form/genericForm', [
[
'field' => 'hide_tag',
'type' => 'checkbox'
],
[
'field' => 'local_only',
'label' => __('Enforce this tag to be used as local only'),
'type' => 'checkbox'
]
],
'submit' => [

View File

@ -50,6 +50,13 @@
'class' => 'short',
'data_path' => 'Tag.hide_tag',
],
[
'name' => __('Local Only'),
'sort' => 'Tag.local_only',
'element' => 'boolean',
'class' => 'short',
'data_path' => 'Tag.local_only',
],
[
'name' => __('Name'),
'sort' => 'Tag.name',

View File

@ -2460,6 +2460,17 @@
"column_default": "1",
"extra": ""
},
{
"column_name": "local_only",
"is_nullable": "NO",
"data_type": "tinyint",
"character_maximum_length": null,
"numeric_precision": "3",
"collation_name": null,
"column_type": "tinyint(1)",
"column_default": "0",
"extra": ""
},
{
"column_name": "kill_chain_order",
"is_nullable": "YES",
@ -6254,6 +6265,17 @@
"column_type": "tinyint(1)",
"column_default": "0",
"extra": ""
},
{
"column_name": "local_only",
"is_nullable": "NO",
"data_type": "tinyint",
"character_maximum_length": null,
"numeric_precision": "3",
"collation_name": null,
"column_type": "tinyint(1)",
"column_default": "0",
"extra": ""
}
],
"tag_collections": [