Merge branch 'local_only' into develop

pull/7946/head
iglocska 2021-11-08 14:15:18 +01:00
commit 952a98dba8
No known key found for this signature in database
GPG Key ID: BEA224F1FEF113AC
13 changed files with 124 additions and 14 deletions

View File

@ -3488,7 +3488,7 @@ class EventsController extends AppController
$tag = $this->Event->EventTag->Tag->find('first', array(
'conditions' => $conditions,
'recursive' => -1,
'fields' => array('Tag.name')
'fields' => array('Tag.name', 'Tag.local_only')
));
if (!$tag) {
$fails[$tag_id] = __('Tag not found.');
@ -3519,6 +3519,10 @@ class EventsController extends AppController
$fails[$tag_id] = __('Tag is not allowed due to taxonomy exclusivity settings');
continue;
}
if ($tag['Tag']['local_only'] && !$local) {
$fails[$tag_id] = __('Invalid Tag. This tag can only be set as a local tag.');
continue;
}
$this->Event->EventTag->create();
if ($this->Event->EventTag->save(array('event_id' => $id, 'tag_id' => $tag_id, 'local' => $local))) {
if (!$local) {

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'),
@ -528,8 +533,9 @@ class GalaxiesController extends AppController
public function attachCluster($target_id, $target_type = 'event')
{
$local = !empty($this->params['named']['local']);
$cluster_id = $this->request->data['Galaxy']['target_id'];
$result = $this->Galaxy->attachCluster($this->Auth->user(), $target_type, $target_id, $cluster_id);
$result = $this->Galaxy->attachCluster($this->Auth->user(), $target_type, $target_id, $cluster_id, $local);
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => $result, 'check_publish' => true)), 'status'=>200, 'type' => 'json'));
}

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')) {
@ -829,6 +839,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

@ -84,7 +84,7 @@ class AppModel extends Model
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, 73 => false, 74 => false,
75 => false,
75 => false, 76 => false
);
public $advanced_updates_description = array(
@ -1593,6 +1593,10 @@ class AppModel extends Model
$this->__dropIndex('object_references', 'relationship_type');
$this->__dropIndex('object_references', 'referenced_uuid');
break;
case 76:
$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

@ -365,11 +365,15 @@ class Galaxy extends AppModel
} else {
$local = 0;
}
$cluster_alias = $this->GalaxyCluster->alias;
$galaxy_alias = $this->alias;
$cluster = $this->GalaxyCluster->fetchGalaxyClusters($user, array(
'first' => true,
'conditions' => array('id' => $cluster_id),
'fields' => array('tag_name', 'id', 'value'),
'conditions' => array("${cluster_alias}.id" => $cluster_id),
'contain' => array('Galaxy'),
'fields' => array('tag_name', 'id', 'value', "${galaxy_alias}.local_only"),
), $full=false);
if (empty($cluster)) {
throw new NotFoundException(__('Invalid Galaxy cluster'));
}
@ -385,7 +389,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['Galaxy']['local_only'];
if ($local_only && !$local) {
throw new MethodNotAllowedException(__("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

@ -98,6 +98,9 @@ class Tag extends AppModel
if (!isset($tag['exportable'])) {
$tag['exportable'] = 1;
}
if (!isset($tag['local_only'])) {
$tag['local_only'] = 0;
}
if (isset($tag['name']) && strlen($tag['name']) >= 255) {
$tag['name'] = substr($tag['name'], 0, 255);
}
@ -315,6 +318,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
@ -380,11 +384,14 @@ class Tag extends AppModel
}
}
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

@ -212,7 +212,7 @@ paths:
default:
$ref: "#/components/responses/ApiErrorResponse"
/attributes/addTag/{attributeId}/{tagId}:
/attributes/addTag/{attributeId}/{tagId}/local:{local}:
post:
summary: "Add a tag to an attribute"
operationId: tagAttribute
@ -221,6 +221,7 @@ paths:
parameters:
- $ref: "#/components/parameters/attributeIdParameter"
- $ref: "#/components/parameters/tagIdParameter"
- $ref: "#/components/parameters/localParameter"
responses:
"200":
$ref: "#/components/responses/AddAttributeTagResponse"
@ -457,7 +458,7 @@ paths:
default:
$ref: "#/components/responses/ApiErrorResponse"
/events/addTag/{eventId}/{tagId}:
/events/addTag/{eventId}/{tagId}/local:{local}:
post:
summary: "Add event tag"
operationId: tagEvent
@ -466,6 +467,7 @@ paths:
parameters:
- $ref: "#/components/parameters/eventIdParameter"
- $ref: "#/components/parameters/tagIdParameter"
- $ref: "#/components/parameters/localParameter"
responses:
"200":
$ref: "#/components/responses/AddEventTagResponse"
@ -607,7 +609,7 @@ paths:
default:
$ref: "#/components/responses/ApiErrorResponse"
/galaxies/attachCluster/{attachTargetId}/{attachTargetType}:
/galaxies/attachCluster/{attachTargetId}/{attachTargetType}/local:{local}:
post:
summary: "Attach the galaxy cluster tag a given entity"
operationId: attachGalaxyCluster
@ -616,6 +618,7 @@ paths:
parameters:
- $ref: "#/components/parameters/attachTargetIdParameter"
- $ref: "#/components/parameters/attachTargetTypeParameter"
- $ref: "#/components/parameters/localParameter"
requestBody:
$ref: "#/components/requestBodies/AttachGalaxyClusterRequest"
responses:
@ -5302,6 +5305,16 @@ components:
IsLocal:
type: boolean
Local:
type: integer
format: int32
maxLength: 1
default: 0
nullable: false
enum:
- 0
- 1
IsReadOnly:
type: boolean
@ -5692,6 +5705,14 @@ components:
schema:
$ref: "#/components/schemas/TagId"
localParameter:
name: local
in: path
description: "Whether the object should be attached locally or not to the target"
required: false
schema:
$ref: "#/components/schemas/Local"
tagSearchTermParameter:
name: tagSearchTerm
in: path

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": [
@ -8180,5 +8202,5 @@
"id": true
}
},
"db_version": "75"
"db_version": "76"
}