mirror of https://github.com/MISP/MISP
new: [diagnostic] Check if database index is unique
parent
99d910fe75
commit
6f12dfc7df
|
@ -4752,9 +4752,9 @@ class Server extends AppModel
|
||||||
$dbActualIndexes = array();
|
$dbActualIndexes = array();
|
||||||
$dataSource = $this->getDataSource()->config['datasource'];
|
$dataSource = $this->getDataSource()->config['datasource'];
|
||||||
if ($dataSource == 'Database/Mysql' || $dataSource == 'Database/MysqlObserver') {
|
if ($dataSource == 'Database/Mysql' || $dataSource == 'Database/MysqlObserver') {
|
||||||
$sqlGetTable = sprintf('SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = %s;', "'" . $this->getDataSource()->config['database'] . "'");
|
$sqlGetTable = sprintf('SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = %s ORDER BY TABLE_NAME;', "'" . $this->getDataSource()->config['database'] . "'");
|
||||||
$sqlResult = $this->query($sqlGetTable);
|
$sqlResult = $this->query($sqlGetTable);
|
||||||
$tables = HASH::extract($sqlResult, '{n}.tables.TABLE_NAME');
|
$tables = Hash::extract($sqlResult, '{n}.tables.TABLE_NAME');
|
||||||
foreach ($tables as $table) {
|
foreach ($tables as $table) {
|
||||||
$sqlSchema = sprintf(
|
$sqlSchema = sprintf(
|
||||||
"SELECT %s
|
"SELECT %s
|
||||||
|
@ -4878,53 +4878,120 @@ class Server extends AppModel
|
||||||
return $dbDiff;
|
return $dbDiff;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function compareDBIndexes($actualIndex, $expectedIndex, $dbExpectedSchema)
|
/**
|
||||||
|
* Returns `true` if given column for given table contains just unique values.
|
||||||
|
*
|
||||||
|
* @param string $tableName
|
||||||
|
* @param string $columnName
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function checkIfColumnContainsJustUniqueValues($tableName, $columnName)
|
||||||
|
{
|
||||||
|
$db = $this->getDataSource();
|
||||||
|
$duplicates = $this->query(
|
||||||
|
sprintf('SELECT %s, COUNT(*) c FROM %s GROUP BY %s HAVING c > 1;',
|
||||||
|
$db->name($columnName), $db->name($tableName), $db->name($columnName))
|
||||||
|
);
|
||||||
|
return empty($duplicates);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function generateSqlDropIndexQuery($tableName, $columnName)
|
||||||
|
{
|
||||||
|
return sprintf('DROP INDEX `%s` ON %s;',
|
||||||
|
$columnName,
|
||||||
|
$tableName
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function generateSqlIndexQuery(array $dbExpectedSchema, $tableName, $columnName, $shouldBeUnique = false, $defaultIndexKeylength = 255)
|
||||||
|
{
|
||||||
|
$columnData = Hash::extract($dbExpectedSchema['schema'][$tableName], "{n}[column_name=$columnName]");
|
||||||
|
if (empty($columnData)) {
|
||||||
|
throw new Exception("Index in db_schema.json is defined for `$tableName.$columnName`, but this column is not defined.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$columnData = $columnData[0];
|
||||||
|
if ($columnData['data_type'] === 'varchar') {
|
||||||
|
$keyLength = sprintf('(%s)', $columnData['character_maximum_length'] < $defaultIndexKeylength ? $columnData['character_maximum_length'] : $defaultIndexKeylength);
|
||||||
|
} elseif ($columnData['data_type'] === 'text') {
|
||||||
|
$keyLength = sprintf('(%s)', $defaultIndexKeylength);
|
||||||
|
} else {
|
||||||
|
$keyLength = '';
|
||||||
|
}
|
||||||
|
return sprintf('CREATE%s INDEX `%s` ON `%s` (`%s`%s);',
|
||||||
|
$shouldBeUnique ? ' UNIQUE' : '',
|
||||||
|
$columnName,
|
||||||
|
$tableName,
|
||||||
|
$columnName,
|
||||||
|
$keyLength
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function compareDBIndexes(array $actualIndex, array $expectedIndex, array $dbExpectedSchema)
|
||||||
{
|
{
|
||||||
$defaultIndexKeylength = 255;
|
|
||||||
$allowedlistTables = array();
|
$allowedlistTables = array();
|
||||||
$indexDiff = array();
|
$indexDiff = array();
|
||||||
foreach($expectedIndex as $tableName => $indexes) {
|
foreach ($expectedIndex as $tableName => $indexes) {
|
||||||
if (!array_key_exists($tableName, $actualIndex)) {
|
if (!array_key_exists($tableName, $actualIndex)) {
|
||||||
continue; // If table does not exists, it is covered by the schema diagnostic
|
continue; // If table does not exists, it is covered by the schema diagnostic
|
||||||
} elseif(in_array($tableName, $allowedlistTables)) {
|
} elseif(in_array($tableName, $allowedlistTables)) {
|
||||||
continue; // Ignore allowedlisted tables
|
continue; // Ignore allowedlisted tables
|
||||||
} else {
|
} else {
|
||||||
$tableIndexDiff = array_diff($indexes, $actualIndex[$tableName]); // check for missing indexes
|
$tableIndexDiff = array_diff(array_keys($indexes), array_keys($actualIndex[$tableName])); // check for missing indexes
|
||||||
if (count($tableIndexDiff) > 0) {
|
foreach ($tableIndexDiff as $columnDiff) {
|
||||||
foreach($tableIndexDiff as $columnDiff) {
|
$shouldBeUnique = $indexes[$columnDiff];
|
||||||
$columnData = Hash::extract($dbExpectedSchema['schema'][$tableName], sprintf('{n}[column_name=%s]', $columnDiff))[0];
|
if ($shouldBeUnique && !$this->checkIfColumnContainsJustUniqueValues($tableName, $columnDiff)) {
|
||||||
$message = sprintf(__('Column `%s` should be indexed'), $columnDiff);
|
|
||||||
if ($columnData['data_type'] == 'varchar') {
|
|
||||||
$keyLength = sprintf('(%s)', $columnData['character_maximum_length'] < $defaultIndexKeylength ? $columnData['character_maximum_length'] : $defaultIndexKeylength);
|
|
||||||
} elseif ($columnData['data_type'] == 'text') {
|
|
||||||
$keyLength = sprintf('(%s)', $defaultIndexKeylength);
|
|
||||||
} else {
|
|
||||||
$keyLength = '';
|
|
||||||
}
|
|
||||||
$sql = sprintf('CREATE INDEX `%s` ON `%s` (`%s`%s);',
|
|
||||||
$columnDiff,
|
|
||||||
$tableName,
|
|
||||||
$columnDiff,
|
|
||||||
$keyLength
|
|
||||||
);
|
|
||||||
$indexDiff[$tableName][$columnDiff] = array(
|
$indexDiff[$tableName][$columnDiff] = array(
|
||||||
'message' => $message,
|
'message' => __('Column `%s` should be unique indexed, but contains duplicate values', $columnDiff),
|
||||||
'sql' => $sql
|
'sql' => '',
|
||||||
);
|
);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$message = __('Column `%s` should be indexed', $columnDiff);
|
||||||
|
$indexDiff[$tableName][$columnDiff] = array(
|
||||||
|
'message' => $message,
|
||||||
|
'sql' => $this->generateSqlIndexQuery($dbExpectedSchema, $tableName, $columnDiff, $shouldBeUnique),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
$tableIndexDiff = array_diff($actualIndex[$tableName], $indexes); // check for additional indexes
|
$tableIndexDiff = array_diff(array_keys($actualIndex[$tableName]), array_keys($indexes)); // check for additional indexes
|
||||||
if (count($tableIndexDiff) > 0) {
|
foreach ($tableIndexDiff as $columnDiff) {
|
||||||
foreach($tableIndexDiff as $columnDiff) {
|
$message = __('Column `%s` is indexed but should not', $columnDiff);
|
||||||
$message = sprintf(__('Column `%s` is indexed but should not'), $columnDiff);
|
$indexDiff[$tableName][$columnDiff] = array(
|
||||||
$sql = sprintf('DROP INDEX `%s` ON %s;',
|
'message' => $message,
|
||||||
$columnDiff,
|
'sql' => $this->generateSqlDropIndexQuery($tableName, $columnDiff),
|
||||||
$tableName
|
);
|
||||||
);
|
}
|
||||||
$indexDiff[$tableName][$columnDiff] = array(
|
foreach ($indexes as $column => $unique) {
|
||||||
'message' => $message,
|
if (isset($actualIndex[$tableName][$column]) && $actualIndex[$tableName][$column] != $unique) {
|
||||||
'sql' => $sql
|
if ($actualIndex[$tableName][$column]) {
|
||||||
);
|
$sql = $this->generateSqlDropIndexQuery($tableName, $column);
|
||||||
|
$sql .= '<br>' . $this->generateSqlIndexQuery($dbExpectedSchema, $tableName, $column, false);
|
||||||
|
|
||||||
|
$message = __('Column `%s` has unique index, but should be non unique', $column);
|
||||||
|
$indexDiff[$tableName][$column] = array(
|
||||||
|
'message' => $message,
|
||||||
|
'sql' => $sql,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
if (!$this->checkIfColumnContainsJustUniqueValues($tableName, $column)) {
|
||||||
|
$message = __('Column `%s` should be unique index, but contains duplicate values', $column);
|
||||||
|
$indexDiff[$tableName][$column] = array(
|
||||||
|
'message' => $message,
|
||||||
|
'sql' => '',
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = $this->generateSqlDropIndexQuery($tableName, $column);
|
||||||
|
$sql .= '<br>' . $this->generateSqlIndexQuery($dbExpectedSchema, $tableName, $column, true);
|
||||||
|
|
||||||
|
$message = __('Column `%s` should be unique index', $column);
|
||||||
|
$indexDiff[$tableName][$column] = array(
|
||||||
|
'message' => $message,
|
||||||
|
'sql' => $sql,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4932,16 +4999,27 @@ class Server extends AppModel
|
||||||
return $indexDiff;
|
return $indexDiff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns indexes for given schema and table in array, where key is column name and value is `true` if
|
||||||
|
* index is index is unique, `false` otherwise.
|
||||||
|
*
|
||||||
|
* @param string $database
|
||||||
|
* @param string $table
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
public function getDatabaseIndexes($database, $table)
|
public function getDatabaseIndexes($database, $table)
|
||||||
{
|
{
|
||||||
$sqlTableIndex = sprintf(
|
$sqlTableIndex = sprintf(
|
||||||
"SELECT DISTINCT TABLE_NAME, COLUMN_NAME FROM information_schema.statistics WHERE TABLE_SCHEMA = '%s' AND TABLE_NAME = '%s';",
|
"SELECT DISTINCT TABLE_NAME, COLUMN_NAME, NON_UNIQUE FROM information_schema.statistics WHERE TABLE_SCHEMA = '%s' AND TABLE_NAME = '%s';",
|
||||||
$database,
|
$database,
|
||||||
$table
|
$table
|
||||||
);
|
);
|
||||||
$sqlTableIndexResult = $this->query($sqlTableIndex);
|
$sqlTableIndexResult = $this->query($sqlTableIndex);
|
||||||
$tableIndex = Hash::extract($sqlTableIndexResult, '{n}.statistics.COLUMN_NAME');
|
$output = [];
|
||||||
return $tableIndex;
|
foreach ($sqlTableIndexResult as $index) {
|
||||||
|
$output[$index['statistics']['COLUMN_NAME']] = $index['statistics']['NON_UNIQUE'] == 0;
|
||||||
|
}
|
||||||
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function writeableDirsDiagnostics(&$diagnostic_errors)
|
public function writeableDirsDiagnostics(&$diagnostic_errors)
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<div>
|
<div>
|
||||||
<label for="toggleTableDBIndexes" style="display: inline-block;">
|
<label for="toggleTableDBIndexes" style="display: inline-block;">
|
||||||
<input type="checkbox" id="toggleTableDBIndexes" class="form-input" checked></input>
|
<input type="checkbox" id="toggleTableDBIndexes" class="form-input" checked>
|
||||||
<?php echo __('Show database indexes') ?>
|
<?php echo __('Show database indexes') ?>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div id="containerDBIndexes" class="" style="max-height: 800px; overflow-y: auto; padding: 5px;">
|
<div id="containerDBIndexes" class="" style="max-height: 800px; overflow-y: auto; padding: 5px;">
|
||||||
<?php if(empty($diagnostic)): ?>
|
<?php if(empty($diagnostic)): ?>
|
||||||
<span class="label label-success"><?php echo __('Index diagnostic:'); ?><i class="fa fa-check"></i></span>
|
<span class="label label-success"><?php echo __('Index diagnostic:'); ?> <i class="fa fa-check"></i></span>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<div class="alert alert-warning">
|
<div class="alert alert-warning">
|
||||||
<strong><?php echo __('Notice'); ?></strong>
|
<strong><?php echo __('Notice'); ?></strong>
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
?>
|
?>
|
||||||
<?php foreach($columnArray as $columnName): ?>
|
<?php foreach($columnArray as $columnName): ?>
|
||||||
<?php
|
<?php
|
||||||
$columnIndexed = !empty($indexes[$tableName]) && in_array($columnName, $indexes[$tableName]);
|
$columnIndexed = isset($indexes[$tableName][$columnName]);
|
||||||
$warningArray = isset($diagnostic[$tableName][$columnName]);
|
$warningArray = isset($diagnostic[$tableName][$columnName]);
|
||||||
if ($warningArray) {
|
if ($warningArray) {
|
||||||
$columnCount++;
|
$columnCount++;
|
||||||
|
@ -74,4 +74,4 @@
|
||||||
message += "<div class=\"well\"><kbd>" + sqlQuery + "</kbd></div>"
|
message += "<div class=\"well\"><kbd>" + sqlQuery + "</kbd></div>"
|
||||||
openPopover(clicked, message, undefined, 'left');
|
openPopover(clicked, message, undefined, 'left');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
798
db_schema.json
798
db_schema.json
|
@ -6775,397 +6775,415 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"indexes": {
|
"indexes": {
|
||||||
"admin_settings": [
|
"admin_settings": {
|
||||||
"id"
|
"id": true
|
||||||
],
|
},
|
||||||
"attribute_tags": [
|
"attributes": {
|
||||||
"id",
|
"id": true,
|
||||||
"attribute_id",
|
"uuid": true,
|
||||||
"event_id",
|
"event_id": false,
|
||||||
"tag_id"
|
"sharing_group_id": false,
|
||||||
],
|
"type": false,
|
||||||
"attributes": [
|
"category": false,
|
||||||
"id",
|
"value1": false,
|
||||||
"uuid",
|
"value2": false,
|
||||||
"event_id",
|
"object_id": false,
|
||||||
"sharing_group_id",
|
"object_relation": false,
|
||||||
"type",
|
"deleted": false,
|
||||||
"category",
|
"first_seen": false,
|
||||||
"value1",
|
"last_seen": false
|
||||||
"value2",
|
},
|
||||||
"object_id",
|
"attribute_tags": {
|
||||||
"object_relation",
|
"id": true,
|
||||||
"deleted",
|
"attribute_id": false,
|
||||||
"first_seen",
|
"event_id": false,
|
||||||
"last_seen"
|
"tag_id": false
|
||||||
],
|
},
|
||||||
"bruteforces": [],
|
"bruteforces": [],
|
||||||
"cake_sessions": [
|
"cake_sessions": {
|
||||||
"id",
|
"id": true,
|
||||||
"expires"
|
"expires": false
|
||||||
],
|
},
|
||||||
"correlations": [
|
"correlations": {
|
||||||
"id",
|
"id": true,
|
||||||
"event_id",
|
"event_id": false,
|
||||||
"1_event_id",
|
"1_event_id": false,
|
||||||
"attribute_id",
|
"attribute_id": false,
|
||||||
"1_attribute_id"
|
"1_attribute_id": false
|
||||||
],
|
},
|
||||||
"dashboards": [
|
"dashboards": {
|
||||||
"id",
|
"id": true,
|
||||||
"name",
|
"name": false,
|
||||||
"uuid",
|
"uuid": false,
|
||||||
"user_id",
|
"user_id": false,
|
||||||
"restrict_to_org_id",
|
"restrict_to_org_id": false,
|
||||||
"restrict_to_permission_flag"
|
"restrict_to_permission_flag": false
|
||||||
],
|
},
|
||||||
"decaying_model_mappings": [
|
"decaying_models": {
|
||||||
"id",
|
"id": true,
|
||||||
"model_id"
|
"uuid": false,
|
||||||
],
|
"name": false,
|
||||||
"decaying_models": [
|
"org_id": false,
|
||||||
"id",
|
"enabled": false,
|
||||||
"uuid",
|
"all_orgs": false,
|
||||||
"name",
|
"version": false
|
||||||
"org_id",
|
},
|
||||||
"enabled",
|
"decaying_model_mappings": {
|
||||||
"all_orgs",
|
"id": true,
|
||||||
"version"
|
"model_id": false
|
||||||
],
|
},
|
||||||
"event_blacklists": [
|
"events": {
|
||||||
"id",
|
"id": true,
|
||||||
"event_uuid",
|
"uuid": true,
|
||||||
"event_orgc"
|
"info": false,
|
||||||
],
|
"sharing_group_id": false,
|
||||||
"event_delegations": [
|
"org_id": false,
|
||||||
"id",
|
"orgc_id": false,
|
||||||
"org_id",
|
"extends_uuid": false
|
||||||
"event_id"
|
},
|
||||||
],
|
"event_blacklists": {
|
||||||
"event_graph": [
|
"id": true,
|
||||||
"id",
|
"event_uuid": false,
|
||||||
"event_id",
|
"event_orgc": false
|
||||||
"user_id",
|
},
|
||||||
"org_id",
|
"event_delegations": {
|
||||||
"timestamp"
|
"id": true,
|
||||||
],
|
"org_id": false,
|
||||||
"event_locks": [
|
"event_id": false
|
||||||
"id",
|
},
|
||||||
"event_id",
|
"event_graph": {
|
||||||
"user_id",
|
"id": true,
|
||||||
"timestamp"
|
"event_id": false,
|
||||||
],
|
"user_id": false,
|
||||||
"event_tags": [
|
"org_id": false,
|
||||||
"id",
|
"timestamp": false
|
||||||
"event_id",
|
},
|
||||||
"tag_id"
|
"event_locks": {
|
||||||
],
|
"id": true,
|
||||||
"events": [
|
"event_id": false,
|
||||||
"id",
|
"user_id": false,
|
||||||
"uuid",
|
"timestamp": false
|
||||||
"info",
|
},
|
||||||
"sharing_group_id",
|
"event_tags": {
|
||||||
"org_id",
|
"id": true,
|
||||||
"orgc_id",
|
"event_id": false,
|
||||||
"extends_uuid"
|
"tag_id": false
|
||||||
],
|
},
|
||||||
"favourite_tags": [
|
"favourite_tags": {
|
||||||
"id",
|
"id": true,
|
||||||
"user_id",
|
"user_id": false,
|
||||||
"tag_id"
|
"tag_id": false
|
||||||
],
|
},
|
||||||
"feeds": [
|
"feeds": {
|
||||||
"id",
|
"id": true,
|
||||||
"input_source",
|
"input_source": false
|
||||||
"orgc_id"
|
},
|
||||||
],
|
"fuzzy_correlate_ssdeep": {
|
||||||
"fuzzy_correlate_ssdeep": [
|
"id": true,
|
||||||
"id",
|
"chunk": false,
|
||||||
"chunk",
|
"attribute_id": false
|
||||||
"attribute_id"
|
},
|
||||||
],
|
"galaxies": {
|
||||||
"galaxies": [
|
"id": true,
|
||||||
"id",
|
"name": false,
|
||||||
"name",
|
"uuid": false,
|
||||||
"uuid",
|
"type": false,
|
||||||
"type",
|
"namespace": false
|
||||||
"namespace"
|
},
|
||||||
],
|
"galaxy_clusters": {
|
||||||
"galaxy_clusters": [
|
"id": true,
|
||||||
"id",
|
"value": false,
|
||||||
"value",
|
"uuid": false,
|
||||||
"uuid",
|
"collection_uuid": false,
|
||||||
"collection_uuid",
|
"galaxy_id": false,
|
||||||
"galaxy_id",
|
"version": false,
|
||||||
"version",
|
"tag_name": false,
|
||||||
"tag_name",
|
"type": false
|
||||||
"type"
|
},
|
||||||
],
|
"galaxy_cluster_blocklists": {
|
||||||
"galaxy_elements": [
|
"id": true,
|
||||||
"id",
|
"cluster_uuid": false,
|
||||||
"key",
|
"cluster_orgc": false
|
||||||
"value",
|
},
|
||||||
"galaxy_cluster_id"
|
"galaxy_cluster_relations": {
|
||||||
],
|
"id": true,
|
||||||
"galaxy_reference": [
|
"galaxy_cluster_id": false,
|
||||||
"id",
|
"referenced_galaxy_cluster_id": false,
|
||||||
"galaxy_cluster_id",
|
"referenced_galaxy_cluster_type": false,
|
||||||
"referenced_galaxy_cluster_id",
|
"galaxy_cluster_uuid": false,
|
||||||
"referenced_galaxy_cluster_value",
|
"sharing_group_id": false,
|
||||||
"referenced_galaxy_cluster_type"
|
"default": false
|
||||||
],
|
},
|
||||||
"inbox": [
|
"galaxy_cluster_relation_tags": {
|
||||||
"id",
|
"id": true,
|
||||||
"title",
|
"galaxy_cluster_relation_id": false,
|
||||||
"type",
|
"tag_id": false
|
||||||
"uuid",
|
},
|
||||||
"user_agent_sha256",
|
"galaxy_elements": {
|
||||||
"ip",
|
"id": true,
|
||||||
"timestamp"
|
"key": false,
|
||||||
],
|
"value": false,
|
||||||
"jobs": [
|
"galaxy_cluster_id": false
|
||||||
"id"
|
},
|
||||||
],
|
"galaxy_reference": {
|
||||||
"logs": [
|
"id": true,
|
||||||
"id"
|
"referenced_galaxy_cluster_id": false,
|
||||||
],
|
"referenced_galaxy_cluster_value": false,
|
||||||
"news": [
|
"referenced_galaxy_cluster_type": false
|
||||||
"id"
|
},
|
||||||
],
|
"inbox": {
|
||||||
"noticelist_entries": [
|
"id": true,
|
||||||
"id",
|
"title": false,
|
||||||
"noticelist_id"
|
"type": false,
|
||||||
],
|
"uuid": false,
|
||||||
"noticelists": [
|
"user_agent_sha256": false,
|
||||||
"id",
|
"ip": false,
|
||||||
"name",
|
"timestamp": false
|
||||||
"geographical_area"
|
},
|
||||||
],
|
"jobs": {
|
||||||
"notification_logs": [
|
"id": true
|
||||||
"id",
|
},
|
||||||
"org_id",
|
"logs": {
|
||||||
"type"
|
"id": true
|
||||||
],
|
},
|
||||||
"object_references": [
|
"news": {
|
||||||
"id",
|
"id": true
|
||||||
"source_uuid",
|
},
|
||||||
"referenced_uuid",
|
"noticelists": {
|
||||||
"timestamp",
|
"id": true,
|
||||||
"object_id",
|
"name": false,
|
||||||
"referenced_id",
|
"geographical_area": false
|
||||||
"relationship_type"
|
},
|
||||||
],
|
"noticelist_entries": {
|
||||||
"object_relationships": [
|
"id": true,
|
||||||
"id",
|
"noticelist_id": false
|
||||||
"name"
|
},
|
||||||
],
|
"notification_logs": {
|
||||||
"object_template_elements": [
|
"id": true,
|
||||||
"id",
|
"org_id": false,
|
||||||
"object_relation",
|
"type": false
|
||||||
"type"
|
},
|
||||||
],
|
"objects": {
|
||||||
"object_templates": [
|
"id": true,
|
||||||
"id",
|
"name": false,
|
||||||
"user_id",
|
"template_uuid": false,
|
||||||
"org_id",
|
"template_version": false,
|
||||||
"uuid",
|
"meta-category": false,
|
||||||
"name",
|
"event_id": false,
|
||||||
"meta-category"
|
"uuid": false,
|
||||||
],
|
"timestamp": false,
|
||||||
"objects": [
|
"distribution": false,
|
||||||
"id",
|
"sharing_group_id": false,
|
||||||
"name",
|
"first_seen": false,
|
||||||
"template_uuid",
|
"last_seen": false
|
||||||
"template_version",
|
},
|
||||||
"meta-category",
|
"object_references": {
|
||||||
"event_id",
|
"id": true,
|
||||||
"uuid",
|
"source_uuid": false,
|
||||||
"timestamp",
|
"referenced_uuid": false,
|
||||||
"distribution",
|
"timestamp": false,
|
||||||
"sharing_group_id",
|
"object_id": false,
|
||||||
"first_seen",
|
"referenced_id": false,
|
||||||
"last_seen"
|
"relationship_type": false
|
||||||
],
|
},
|
||||||
"org_blacklists": [
|
"object_relationships": {
|
||||||
"id"
|
"id": true,
|
||||||
],
|
"name": false
|
||||||
"organisations": [
|
},
|
||||||
"id",
|
"object_templates": {
|
||||||
"uuid",
|
"id": true,
|
||||||
"name"
|
"user_id": false,
|
||||||
],
|
"org_id": false,
|
||||||
"posts": [
|
"uuid": false,
|
||||||
"id",
|
"name": false,
|
||||||
"post_id",
|
"meta-category": false
|
||||||
"thread_id"
|
},
|
||||||
],
|
"object_template_elements": {
|
||||||
"regexp": [
|
"id": true,
|
||||||
"id"
|
"object_relation": false,
|
||||||
],
|
"type": false
|
||||||
"rest_client_histories": [
|
},
|
||||||
"id",
|
"organisations": {
|
||||||
"org_id",
|
"id": true,
|
||||||
"user_id",
|
"uuid": false,
|
||||||
"timestamp"
|
"name": false
|
||||||
],
|
},
|
||||||
"roles": [
|
"org_blacklists": {
|
||||||
"id"
|
"id": true
|
||||||
],
|
},
|
||||||
"servers": [
|
"posts": {
|
||||||
"id",
|
"id": true,
|
||||||
"org_id",
|
"post_id": false,
|
||||||
"priority",
|
"thread_id": false
|
||||||
"remote_org_id"
|
},
|
||||||
],
|
"regexp": {
|
||||||
"shadow_attribute_correlations": [
|
"id": true
|
||||||
"id",
|
},
|
||||||
"org_id",
|
"rest_client_histories": {
|
||||||
"attribute_id",
|
"id": true,
|
||||||
"a_sharing_group_id",
|
"org_id": false,
|
||||||
"event_id",
|
"user_id": false,
|
||||||
"1_event_id",
|
"timestamp": false
|
||||||
"sharing_group_id",
|
},
|
||||||
"1_shadow_attribute_id"
|
"roles": {
|
||||||
],
|
"id": true
|
||||||
"shadow_attributes": [
|
},
|
||||||
"id",
|
"servers": {
|
||||||
"event_id",
|
"id": true,
|
||||||
"event_uuid",
|
"org_id": false,
|
||||||
"event_org_id",
|
"priority": false,
|
||||||
"uuid",
|
"remote_org_id": false
|
||||||
"old_id",
|
},
|
||||||
"value1",
|
"shadow_attributes": {
|
||||||
"value2",
|
"id": true,
|
||||||
"type",
|
"event_id": false,
|
||||||
"category",
|
"event_uuid": false,
|
||||||
"first_seen",
|
"event_org_id": false,
|
||||||
"last_seen"
|
"uuid": false,
|
||||||
],
|
"old_id": false,
|
||||||
"sharing_group_orgs": [
|
"value1": false,
|
||||||
"id",
|
"value2": false,
|
||||||
"org_id",
|
"type": false,
|
||||||
"sharing_group_id"
|
"category": false,
|
||||||
],
|
"first_seen": false,
|
||||||
"sharing_group_servers": [
|
"last_seen": false
|
||||||
"id",
|
},
|
||||||
"server_id",
|
"shadow_attribute_correlations": {
|
||||||
"sharing_group_id"
|
"id": true,
|
||||||
],
|
"org_id": false,
|
||||||
"sharing_groups": [
|
"attribute_id": false,
|
||||||
"id",
|
"a_sharing_group_id": false,
|
||||||
"uuid",
|
"event_id": false,
|
||||||
"org_id",
|
"1_event_id": false,
|
||||||
"sync_user_id",
|
"sharing_group_id": false,
|
||||||
"organisation_uuid"
|
"1_shadow_attribute_id": false
|
||||||
],
|
},
|
||||||
"sightingdb_orgs": [
|
"sharing_groups": {
|
||||||
"id",
|
"id": true,
|
||||||
"sightingdb_id",
|
"uuid": true,
|
||||||
"org_id"
|
"org_id": false,
|
||||||
],
|
"sync_user_id": false,
|
||||||
"sightingdbs": [
|
"organisation_uuid": false
|
||||||
"id",
|
},
|
||||||
"name",
|
"sharing_group_orgs": {
|
||||||
"owner",
|
"id": true,
|
||||||
"host",
|
"org_id": false,
|
||||||
"port"
|
"sharing_group_id": false
|
||||||
],
|
},
|
||||||
"sightings": [
|
"sharing_group_servers": {
|
||||||
"id",
|
"id": true,
|
||||||
"attribute_id",
|
"server_id": false,
|
||||||
"event_id",
|
"sharing_group_id": false
|
||||||
"org_id",
|
},
|
||||||
"uuid",
|
"sightingdbs": {
|
||||||
"source",
|
"id": true,
|
||||||
"type"
|
"name": false,
|
||||||
],
|
"owner": false,
|
||||||
"tag_collection_tags": [
|
"host": false,
|
||||||
"id",
|
"port": false
|
||||||
"tag_collection_id",
|
},
|
||||||
"tag_id"
|
"sightingdb_orgs": {
|
||||||
],
|
"id": true,
|
||||||
"tag_collections": [
|
"sightingdb_id": false,
|
||||||
"id",
|
"org_id": false
|
||||||
"uuid",
|
},
|
||||||
"user_id",
|
"sightings": {
|
||||||
"org_id"
|
"id": true,
|
||||||
],
|
"attribute_id": false,
|
||||||
"tags": [
|
"event_id": false,
|
||||||
"id",
|
"org_id": false,
|
||||||
"name",
|
"uuid": false,
|
||||||
"org_id",
|
"source": false,
|
||||||
"user_id",
|
"type": false
|
||||||
"numerical_value"
|
},
|
||||||
],
|
"tags": {
|
||||||
"tasks": [
|
"id": true,
|
||||||
"id"
|
"name": false,
|
||||||
],
|
"org_id": false,
|
||||||
"taxonomies": [
|
"user_id": false,
|
||||||
"id"
|
"numerical_value": false
|
||||||
],
|
},
|
||||||
"taxonomy_entries": [
|
"tag_collections": {
|
||||||
"id",
|
"id": true,
|
||||||
"taxonomy_predicate_id",
|
"uuid": false,
|
||||||
"numerical_value"
|
"user_id": false,
|
||||||
],
|
"org_id": false
|
||||||
"taxonomy_predicates": [
|
},
|
||||||
"id",
|
"tag_collection_tags": {
|
||||||
"taxonomy_id",
|
"id": true,
|
||||||
"numerical_value"
|
"tag_collection_id": false,
|
||||||
],
|
"tag_id": false
|
||||||
"template_element_attributes": [
|
},
|
||||||
"id"
|
"tasks": {
|
||||||
],
|
"id": true
|
||||||
"template_element_files": [
|
},
|
||||||
"id"
|
"taxonomies": {
|
||||||
],
|
"id": true,
|
||||||
"template_element_texts": [
|
"enabled": false
|
||||||
"id"
|
},
|
||||||
],
|
"taxonomy_entries": {
|
||||||
"template_elements": [
|
"id": true,
|
||||||
"id"
|
"taxonomy_predicate_id": false,
|
||||||
],
|
"numerical_value": false
|
||||||
"template_tags": [
|
},
|
||||||
"id"
|
"taxonomy_predicates": {
|
||||||
],
|
"id": true,
|
||||||
"templates": [
|
"taxonomy_id": false,
|
||||||
"id"
|
"numerical_value": false
|
||||||
],
|
},
|
||||||
"threads": [
|
"templates": {
|
||||||
"id",
|
"id": true
|
||||||
"user_id",
|
},
|
||||||
"event_id",
|
"template_elements": {
|
||||||
"org_id",
|
"id": true
|
||||||
"sharing_group_id"
|
},
|
||||||
],
|
"template_element_attributes": {
|
||||||
"threat_levels": [
|
"id": true
|
||||||
"id"
|
},
|
||||||
],
|
"template_element_files": {
|
||||||
"user_settings": [
|
"id": true
|
||||||
"id",
|
},
|
||||||
"setting",
|
"template_element_texts": {
|
||||||
"user_id",
|
"id": true
|
||||||
"timestamp"
|
},
|
||||||
],
|
"template_tags": {
|
||||||
"users": [
|
"id": true
|
||||||
"id",
|
},
|
||||||
"email",
|
"threads": {
|
||||||
"org_id",
|
"id": true,
|
||||||
"server_id"
|
"user_id": false,
|
||||||
],
|
"event_id": false,
|
||||||
"warninglist_entries": [
|
"org_id": false,
|
||||||
"id",
|
"sharing_group_id": false
|
||||||
"warninglist_id"
|
},
|
||||||
],
|
"threat_levels": {
|
||||||
"warninglist_types": [
|
"id": true
|
||||||
"id"
|
},
|
||||||
],
|
"users": {
|
||||||
"warninglists": [
|
"id": true,
|
||||||
"id"
|
"email": false,
|
||||||
],
|
"org_id": false,
|
||||||
"whitelist": [
|
"server_id": false
|
||||||
"id"
|
},
|
||||||
]
|
"user_settings": {
|
||||||
|
"id": true,
|
||||||
|
"setting": false,
|
||||||
|
"user_id": false,
|
||||||
|
"timestamp": false
|
||||||
|
},
|
||||||
|
"warninglists": {
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"warninglist_entries": {
|
||||||
|
"id": true,
|
||||||
|
"warninglist_id": false
|
||||||
|
},
|
||||||
|
"warninglist_types": {
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"whitelist": {
|
||||||
|
"id": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"db_version": "55"
|
"db_version": "55"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue