mirror of
https://github.com/valitydev/wazuh-kibana-app.git
synced 2024-11-06 01:45:18 +00:00
Code quality(eslint, mocha, tslint)
This commit is contained in:
parent
513b134c0a
commit
9dd02ea153
@ -11,17 +11,19 @@
|
|||||||
"jsx": true
|
"jsx": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"globals": {
|
||||||
|
"XPACK_RBAC_ENABLED": true
|
||||||
|
},
|
||||||
"parser": "babel-eslint",
|
"parser": "babel-eslint",
|
||||||
"rules": {
|
"rules": {
|
||||||
"node/exports-style": ["error", "module.exports"],
|
"node/exports-style": ["error", "module.exports"],
|
||||||
"semi": 0,
|
"no-console": "warn",
|
||||||
"no-console": 0,
|
"semi": "off",
|
||||||
"no-process-exit": 0,
|
"no-process-exit": "error",
|
||||||
|
"no-extra-boolean-cast": "off",
|
||||||
"node/no-unpublished-require": 0,
|
"node/no-unpublished-require": 0,
|
||||||
"node/no-unsupported-features": 0,
|
"node/no-unsupported-features": 0,
|
||||||
"node/no-unsupported-features/es-syntax": 0,
|
"node/no-unsupported-features/es-syntax": 0
|
||||||
"no-extra-boolean-cast": 0,
|
|
||||||
"no-cond-assign": 0
|
|
||||||
},
|
},
|
||||||
"plugins": ["node", "async-await"],
|
"plugins": ["node", "async-await"],
|
||||||
"extends": ["eslint:recommended", "plugin:node/recommended"]
|
"extends": ["eslint:recommended", "plugin:node/recommended"]
|
||||||
|
2
.tslint.yml
Normal file
2
.tslint.yml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
extends:
|
||||||
|
- tslint:recommended
|
5
index.js
5
index.js
@ -11,7 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Imports the init module
|
// Imports the init module
|
||||||
import init from './init';
|
import { initApp } from './init';
|
||||||
|
|
||||||
export default kibana => new kibana.Plugin({
|
export default kibana => new kibana.Plugin({
|
||||||
id: 'wazuh',
|
id: 'wazuh',
|
||||||
@ -26,6 +26,5 @@ export default kibana => new kibana.Plugin({
|
|||||||
main: 'plugins/wazuh/app'
|
main: 'plugins/wazuh/app'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
init: (server,options) => init(server,options)
|
init(server,options) { return initApp(server,options) }
|
||||||
|
|
||||||
});
|
});
|
28
init.js
28
init.js
@ -11,18 +11,18 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Imports all server modules
|
// Imports all server modules
|
||||||
import initialize from './server/initialize';
|
import { Initialize } from './server/initialize';
|
||||||
import wazuhElastic from './server/routes/wazuh-elastic';
|
import { WazuhElasticRouter } from './server/routes/wazuh-elastic';
|
||||||
import wazuhApiElastic from './server/routes/wazuh-api-elastic';
|
import { WazuhApiElasticRoutes } from './server/routes/wazuh-api-elastic';
|
||||||
import monitoring from './server/monitoring';
|
import { Monitoring } from './server/monitoring';
|
||||||
import wazuhApi from './server/routes/wazuh-api';
|
import { WazuhApiRoutes } from './server/routes/wazuh-api';
|
||||||
import wazuhReporting from './server/routes/wazuh-reporting';
|
import { WazuhReportingRoutes } from './server/routes/wazuh-reporting';
|
||||||
|
|
||||||
export default (server, options) => {
|
export function initApp (server) {
|
||||||
initialize(server, options);
|
Initialize(server);
|
||||||
wazuhElastic(server, options);
|
WazuhElasticRouter(server);
|
||||||
wazuhApiElastic(server, options);
|
WazuhApiElasticRoutes(server);
|
||||||
monitoring(server, false);
|
Monitoring(server, false);
|
||||||
wazuhApi(server, options);
|
WazuhApiRoutes(server);
|
||||||
wazuhReporting(server, options);
|
WazuhReportingRoutes(server);
|
||||||
};
|
}
|
@ -26,9 +26,11 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://www.wazuh.com/",
|
"homepage": "https://www.wazuh.com/",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"tslint": "tslint -c .tslint.yml server/**/*.ts server/**/*.tsx public/**/*.ts public/**/*.tsx",
|
||||||
"lint": "eslint server/** server/*.js *.js public/**/*.js public/*.js util/*.js -c .eslintrc.json --color",
|
"lint": "eslint server/** server/*.js *.js public/**/*.js public/*.js util/*.js -c .eslintrc.json --color",
|
||||||
"prebuild": "tsc; find . -name \"*.ts*\" -type f -not -path \"./node_modules/*\" -delete",
|
"prebuild": "tsc; find . -name \"*.ts*\" -type f -not -path \"./node_modules/*\" -delete",
|
||||||
"build": "plugin-helpers build"
|
"build": "plugin-helpers build",
|
||||||
|
"test": "_mocha test/**/*"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"angular-animate": "1.6.5",
|
"angular-animate": "1.6.5",
|
||||||
@ -53,6 +55,8 @@
|
|||||||
"eslint-plugin-async-await": "^0.0.0",
|
"eslint-plugin-async-await": "^0.0.0",
|
||||||
"eslint-plugin-import": "^2.14.0",
|
"eslint-plugin-import": "^2.14.0",
|
||||||
"eslint-plugin-node": "^7.0.1",
|
"eslint-plugin-node": "^7.0.1",
|
||||||
|
"mocha": "^5.2.0",
|
||||||
|
"chai": "^3.5.0",
|
||||||
"tslint": "^5.11.0",
|
"tslint": "^5.11.0",
|
||||||
"typescript": "^3.0.1",
|
"typescript": "^3.0.1",
|
||||||
"typescript-eslint-parser": "^18.0.0"
|
"typescript-eslint-parser": "^18.0.0"
|
||||||
|
@ -80,12 +80,12 @@ app.controller('agentsPreviewController', function ($scope, $routeParams, generi
|
|||||||
genericReq.request('GET', '/api/wazuh-api/agents-unique/' + api, {}),
|
genericReq.request('GET', '/api/wazuh-api/agents-unique/' + api, {}),
|
||||||
genericReq.request('GET', `/api/wazuh-elastic/top/${firstUrlParam}/${secondUrlParam}/agent.name/${pattern}`)
|
genericReq.request('GET', `/api/wazuh-elastic/top/${firstUrlParam}/${secondUrlParam}/agent.name/${pattern}`)
|
||||||
]);
|
]);
|
||||||
|
const [agentsUnique,agentsTop] = data;
|
||||||
const unique = data[0].data.result;
|
const unique = agentsUnique.data.result;
|
||||||
|
|
||||||
$scope.groups = unique.groups;
|
$scope.groups = unique.groups;
|
||||||
$scope.nodes = unique.nodes.map(item => { return {id: item} });
|
$scope.nodes = unique.nodes.map(item => ({id: item}));
|
||||||
$scope.versions = unique.versions.map(item => { return {id: item} });
|
$scope.versions = unique.versions.map(item => ({id: item}));
|
||||||
$scope.osPlatforms = unique.osPlatforms;
|
$scope.osPlatforms = unique.osPlatforms;
|
||||||
$scope.lastAgent = unique.lastAgent;
|
$scope.lastAgent = unique.lastAgent;
|
||||||
$scope.agentsCountActive = unique.summary.agentsCountActive;
|
$scope.agentsCountActive = unique.summary.agentsCountActive;
|
||||||
@ -94,11 +94,11 @@ app.controller('agentsPreviewController', function ($scope, $routeParams, generi
|
|||||||
$scope.agentsCountTotal = unique.summary.agentsCountTotal;
|
$scope.agentsCountTotal = unique.summary.agentsCountTotal;
|
||||||
$scope.agentsCoverity = unique.summary.agentsCoverity;
|
$scope.agentsCoverity = unique.summary.agentsCoverity;
|
||||||
|
|
||||||
if (data[1].data.data === '') {
|
if (agentsTop.data.data === '') {
|
||||||
$scope.mostActiveAgent.name = appState.getClusterInfo().manager;
|
$scope.mostActiveAgent.name = appState.getClusterInfo().manager;
|
||||||
$scope.mostActiveAgent.id = '000';
|
$scope.mostActiveAgent.id = '000';
|
||||||
} else {
|
} else {
|
||||||
$scope.mostActiveAgent.name = data[1].data.data;
|
$scope.mostActiveAgent.name = agentsTop.data.data;
|
||||||
const info = await genericReq.request('GET', `/api/wazuh-elastic/top/${firstUrlParam}/${secondUrlParam}/agent.id/${pattern}`);
|
const info = await genericReq.request('GET', `/api/wazuh-elastic/top/${firstUrlParam}/${secondUrlParam}/agent.id/${pattern}`);
|
||||||
if (info.data.data === '' && $scope.mostActiveAgent.name !== '') {
|
if (info.data.data === '' && $scope.mostActiveAgent.name !== '') {
|
||||||
$scope.mostActiveAgent.id = '000';
|
$scope.mostActiveAgent.id = '000';
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
import beautifier from '../../utils/json-beautifier';
|
import beautifier from '../../utils/json-beautifier';
|
||||||
import { uiModules } from 'ui/modules';
|
import { uiModules } from 'ui/modules';
|
||||||
import FilterHandler from '../../utils/filter-handler';
|
import { FilterHandler } from '../../utils/filter-handler';
|
||||||
import generateMetric from '../../utils/generate-metric';
|
import generateMetric from '../../utils/generate-metric';
|
||||||
import TabNames from '../../utils/tab-names';
|
import TabNames from '../../utils/tab-names';
|
||||||
import * as FileSaver from '../../services/file-saver';
|
import * as FileSaver from '../../services/file-saver';
|
||||||
|
@ -95,7 +95,7 @@ class Logs {
|
|||||||
try{
|
try{
|
||||||
const data = await this.apiReq.request('GET', '/manager/logs/summary', {});
|
const data = await this.apiReq.request('GET', '/manager/logs/summary', {});
|
||||||
const daemons = data.data.data;
|
const daemons = data.data.data;
|
||||||
this.$scope.daemons = Object.keys(daemons).map(item => { return { title: item } })
|
this.$scope.daemons = Object.keys(daemons).map(item => ({ title: item }))
|
||||||
if(!this.$scope.$$phase) this.$scope.$digest();
|
if(!this.$scope.$$phase) this.$scope.$digest();
|
||||||
return;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* Find more information about this on the LICENSE file.
|
* Find more information about this on the LICENSE file.
|
||||||
*/
|
*/
|
||||||
import FilterHandler from '../../utils/filter-handler'
|
import { FilterHandler } from '../../utils/filter-handler'
|
||||||
import { uiModules } from 'ui/modules'
|
import { uiModules } from 'ui/modules'
|
||||||
|
|
||||||
const app = uiModules.get('app/wazuh', []);
|
const app = uiModules.get('app/wazuh', []);
|
||||||
|
@ -51,22 +51,26 @@ class StatusController {
|
|||||||
this.apiReq.request('GET', '/decoders', { offset: 0, limit: 1 })
|
this.apiReq.request('GET', '/decoders', { offset: 0, limit: 1 })
|
||||||
])
|
])
|
||||||
|
|
||||||
|
const parsedData = data.map(item => item.data.data);
|
||||||
|
const [stats, daemons, managerInfo, totalRules, totalDecoders] = parsedData;
|
||||||
|
|
||||||
// Once Wazuh core fixes agent 000 issues, this should be adjusted
|
// Once Wazuh core fixes agent 000 issues, this should be adjusted
|
||||||
const active = data[0].data.data.Active - 1;
|
const active = stats.Active - 1;
|
||||||
const total = data[0].data.data.Total - 1;
|
const total = stats.Total - 1;
|
||||||
this.$scope.agentsCountActive = active;
|
this.$scope.agentsCountActive = active;
|
||||||
this.$scope.agentsCountDisconnected = data[0].data.data.Disconnected;
|
this.$scope.agentsCountDisconnected = stats.Disconnected;
|
||||||
this.$scope.agentsCountNeverConnected = data[0].data.data['Never connected'];
|
this.$scope.agentsCountNeverConnected = stats['Never connected'];
|
||||||
this.$scope.agentsCountTotal = total;
|
this.$scope.agentsCountTotal = total;
|
||||||
this.$scope.agentsCoverity = (active / total) * 100;
|
this.$scope.agentsCoverity = (active / total) * 100;
|
||||||
|
|
||||||
this.$scope.daemons = data[1].data.data;
|
this.$scope.daemons = daemons;
|
||||||
this.$scope.managerInfo = data[2].data.data;
|
this.$scope.managerInfo = managerInfo;
|
||||||
this.$scope.totalRules = data[3].data.data.totalItems;
|
this.$scope.totalRules = totalRules.totalItems;
|
||||||
this.$scope.totalDecoders = data[4].data.data.totalItems;
|
this.$scope.totalDecoders = totalDecoders.totalItems;
|
||||||
|
|
||||||
const lastAgent = await this.apiReq.request('GET', '/agents', { limit: 1, sort: '-dateAdd' });
|
const lastAgentRaw = await this.apiReq.request('GET', '/agents', { limit: 1, sort: '-dateAdd' });
|
||||||
const agentInfo = await this.apiReq.request('GET', `/agents/${lastAgent.data.data.items[0].id}`, {});
|
const [lastAgent] = lastAgentRaw.data.data.items;
|
||||||
|
const agentInfo = await this.apiReq.request('GET', `/agents/${lastAgent.id}`, {});
|
||||||
|
|
||||||
this.$scope.agentInfo = agentInfo.data.data;
|
this.$scope.agentInfo = agentInfo.data.data;
|
||||||
this.$scope.load = false;
|
this.$scope.load = false;
|
||||||
|
@ -9,14 +9,23 @@
|
|||||||
*
|
*
|
||||||
* Find more information about this on the LICENSE file.
|
* Find more information about this on the LICENSE file.
|
||||||
*/
|
*/
|
||||||
import { uiModules } from 'ui/modules'
|
import { uiModules } from 'ui/modules';
|
||||||
import FilterHandler from '../../utils/filter-handler'
|
import { FilterHandler } from '../../utils/filter-handler';
|
||||||
import generateMetric from '../../utils/generate-metric'
|
import generateMetric from '../../utils/generate-metric';
|
||||||
import TabNames from '../../utils/tab-names'
|
import TabNames from '../../utils/tab-names';
|
||||||
import { metricsGeneral, metricsFim, metricsAudit, metricsVulnerability, metricsScap, metricsCiscat, metricsVirustotal, metricsAws } from '../../utils/overview-metrics'
|
|
||||||
|
|
||||||
import TabDescription from '../../../server/reporting/tab-description';
|
import TabDescription from '../../../server/reporting/tab-description';
|
||||||
|
|
||||||
|
import {
|
||||||
|
metricsGeneral,
|
||||||
|
metricsFim,
|
||||||
|
metricsAudit,
|
||||||
|
metricsVulnerability,
|
||||||
|
metricsScap,
|
||||||
|
metricsCiscat,
|
||||||
|
metricsVirustotal,
|
||||||
|
metricsAws
|
||||||
|
} from '../../utils/overview-metrics'
|
||||||
|
|
||||||
const app = uiModules.get('app/wazuh', []);
|
const app = uiModules.get('app/wazuh', []);
|
||||||
|
|
||||||
app.controller('overviewController',
|
app.controller('overviewController',
|
||||||
|
@ -17,7 +17,7 @@ app.directive('wzDynamic', function($compile) {
|
|||||||
return {
|
return {
|
||||||
restrict: 'A',
|
restrict: 'A',
|
||||||
replace: true,
|
replace: true,
|
||||||
link: function(scope, ele, attrs) {
|
link(scope, ele, attrs) {
|
||||||
scope.$watch(attrs.wzDynamic, function(html) {
|
scope.$watch(attrs.wzDynamic, function(html) {
|
||||||
ele.html(html);
|
ele.html(html);
|
||||||
$compile(ele.contents())(scope);
|
$compile(ele.contents())(scope);
|
||||||
|
@ -29,7 +29,7 @@ app.directive('wzTable', function() {
|
|||||||
rowSizes: '=rowSizes',
|
rowSizes: '=rowSizes',
|
||||||
extraLimit: '=extraLimit'
|
extraLimit: '=extraLimit'
|
||||||
},
|
},
|
||||||
controller: function($scope, apiReq, $timeout, shareAgent, $location, errorHandler, wzTableFilter, $window) {
|
controller($scope, apiReq, $timeout, shareAgent, $location, errorHandler, wzTableFilter, $window) {
|
||||||
/**
|
/**
|
||||||
* Calculate number of table rows depending on the screen height
|
* Calculate number of table rows depending on the screen height
|
||||||
*/
|
*/
|
||||||
@ -322,13 +322,13 @@ app.directive('wzTable', function() {
|
|||||||
checkIfArray(item[key.value || key]) || '---';
|
checkIfArray(item[key.value || key]) || '---';
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
template: template
|
template
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.service('wzTableFilter',() => {
|
.service('wzTableFilter',() => {
|
||||||
const filters = [];
|
const filters = [];
|
||||||
return {
|
return {
|
||||||
set: array => { if(Array.isArray(array)) { filters.length = 0; filters.push(...array); } },
|
set (array) { if(Array.isArray(array)) { filters.length = 0; filters.push(...array); } },
|
||||||
get: () => filters
|
get () { return filters }
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -69,14 +69,13 @@ import { BasicResponseHandlerProvider } from 'ui/vis/response_handlers/basic';
|
|||||||
import { DocTitleProvider } from 'ui/doc_title';
|
import { DocTitleProvider } from 'ui/doc_title';
|
||||||
import PluginsKibanaDiscoverHitSortFnProvider from 'plugins/kibana/discover/_hit_sort_fn';
|
import PluginsKibanaDiscoverHitSortFnProvider from 'plugins/kibana/discover/_hit_sort_fn';
|
||||||
import { FilterBarQueryFilterProvider } from 'ui/filter_bar/query_filter';
|
import { FilterBarQueryFilterProvider } from 'ui/filter_bar/query_filter';
|
||||||
import { intervalOptions } from 'ui/agg_types/buckets/_interval_options';
|
|
||||||
import { stateMonitorFactory } from 'ui/state_management/state_monitor_factory';
|
import { stateMonitorFactory } from 'ui/state_management/state_monitor_factory';
|
||||||
import { migrateLegacyQuery } from 'ui/utils/migrateLegacyQuery';
|
import { migrateLegacyQuery } from 'ui/utils/migrateLegacyQuery';
|
||||||
import { FilterManagerProvider } from 'ui/filter_manager';
|
import { FilterManagerProvider } from 'ui/filter_manager';
|
||||||
import { visualizationLoader } from 'ui/visualize/loader/visualization_loader';
|
import { visualizationLoader } from 'ui/visualize/loader/visualization_loader';
|
||||||
import { getDocLink } from 'ui/documentation_links';
|
import { getDocLink } from 'ui/documentation_links';
|
||||||
|
|
||||||
import 'ui/courier/search_strategy/default_search_strategy'
|
import 'ui/courier/search_strategy/default_search_strategy';
|
||||||
|
|
||||||
const app = uiModules.get('apps/discover', [
|
const app = uiModules.get('apps/discover', [
|
||||||
'kibana/notify',
|
'kibana/notify',
|
||||||
@ -413,7 +412,7 @@ $scope.toggleRefresh = () => {
|
|||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
$state.save();
|
$state.save();
|
||||||
}).catch(console.error);
|
}).catch(console.error); // eslint-disable-line
|
||||||
});
|
});
|
||||||
|
|
||||||
// update data source when hitting forward/back and the query changes
|
// update data source when hitting forward/back and the query changes
|
||||||
@ -689,7 +688,7 @@ $scope.toggleRefresh = () => {
|
|||||||
const fields = _.keys(indexPattern.flattenHit(hit));
|
const fields = _.keys(indexPattern.flattenHit(hit));
|
||||||
let n = fields.length;
|
let n = fields.length;
|
||||||
let field;
|
let field;
|
||||||
while (field = fields[--n]) {
|
while (field = fields[--n]) { // eslint-disable-line
|
||||||
if (counts[field]) counts[field] += 1;
|
if (counts[field]) counts[field] += 1;
|
||||||
else counts[field] = 1;
|
else counts[field] = 1;
|
||||||
}
|
}
|
||||||
@ -921,7 +920,7 @@ $scope.toggleRefresh = () => {
|
|||||||
|
|
||||||
queryFilter.addFilters(wzCurrentFilters)
|
queryFilter.addFilters(wzCurrentFilters)
|
||||||
.then(() => { })
|
.then(() => { })
|
||||||
.catch(error => console.log(error.message || error));
|
.catch(error => console.log(error.message || error)); // eslint-disable-line
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12,17 +12,18 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { uiModules } from 'ui/modules';
|
import { uiModules } from 'ui/modules';
|
||||||
import { getVisualizeLoader } from './loader';
|
import { getVisualizeLoader } from './loader';
|
||||||
import { timefilter } from 'ui/timefilter'
|
import { timefilter } from 'ui/timefilter';
|
||||||
|
|
||||||
const app = uiModules.get('apps/webinar_app', []);
|
const app = uiModules.get('apps/webinar_app', []);
|
||||||
|
|
||||||
app.directive('kbnVis', [function () {
|
app.directive('kbnVis', function () {
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
scope: {
|
scope: {
|
||||||
visID: '=visId',
|
visID: '=visId',
|
||||||
specificTimeRange: '=specificTimeRange'
|
specificTimeRange: '=specificTimeRange'
|
||||||
},
|
},
|
||||||
controller: function VisController($scope, $rootScope, wzsavedVisualizations, errorHandler, rawVisualizations, loadedVisualizations, tabVisualizations, discoverPendingUpdates, visHandlers) {
|
controller($scope, $rootScope, wzsavedVisualizations, errorHandler, rawVisualizations, loadedVisualizations, tabVisualizations, discoverPendingUpdates, visHandlers) {
|
||||||
|
|
||||||
let implicitFilter = '';
|
let implicitFilter = '';
|
||||||
let rawFilters = [];
|
let rawFilters = [];
|
||||||
@ -143,4 +144,4 @@ app.directive('kbnVis', [function () {
|
|||||||
let loader = null;
|
let loader = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}]);
|
});
|
@ -2,7 +2,7 @@ import _ from 'lodash'
|
|||||||
import { Scanner } from 'ui/utils/scanner';
|
import { Scanner } from 'ui/utils/scanner';
|
||||||
import { StringUtils } from 'ui/utils/string_utils';
|
import { StringUtils } from 'ui/utils/string_utils';
|
||||||
import { SavedObjectsClient } from 'ui/saved_objects';
|
import { SavedObjectsClient } from 'ui/saved_objects';
|
||||||
import { SavedObjectProvider } from './saved-objects';
|
|
||||||
export class SavedObjectLoader {
|
export class SavedObjectLoader {
|
||||||
constructor(SavedObjectClass, kbnIndex, kbnUrl, $http, chrome ) {
|
constructor(SavedObjectClass, kbnIndex, kbnUrl, $http, chrome ) {
|
||||||
this.type = SavedObjectClass.type;
|
this.type = SavedObjectClass.type;
|
||||||
@ -52,7 +52,7 @@ export class SavedObjectLoader {
|
|||||||
// just assign the defaults and be done
|
// just assign the defaults and be done
|
||||||
_.assign(instance, instance.defaults);
|
_.assign(instance, instance.defaults);
|
||||||
return instance.hydrateIndexPattern().then(() => {
|
return instance.hydrateIndexPattern().then(() => {
|
||||||
return afterESResp.call(instance);
|
return afterESResp.call(instance); // eslint-disable-line
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return this.processFunc()
|
return this.processFunc()
|
||||||
|
@ -1,399 +0,0 @@
|
|||||||
/**
|
|
||||||
* @name SavedObject
|
|
||||||
*
|
|
||||||
* NOTE: SavedObject seems to track a reference to an object in ES,
|
|
||||||
* and surface methods for CRUD functionality (save and delete). This seems
|
|
||||||
* similar to how Backbone Models work.
|
|
||||||
*
|
|
||||||
* This class seems to interface with ES primarily through the es Angular
|
|
||||||
* service and the saved object api.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import angular from 'angular';
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
import { SavedObjectNotFound } from 'ui/errors';
|
|
||||||
import MappingSetupProvider from 'ui/utils/mapping_setup';
|
|
||||||
|
|
||||||
import { SearchSourceProvider } from 'ui/courier';
|
|
||||||
import { SavedObjectsClientProvider, findObjectByTitle } from 'ui/saved_objects';
|
|
||||||
import { migrateLegacyQuery } from 'ui/utils/migrateLegacyQuery.js';
|
|
||||||
import { recentlyAccessed } from 'ui/persisted_log';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An error message to be used when the user rejects a confirm overwrite.
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
const OVERWRITE_REJECTED = 'Overwrite confirmation was rejected';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An error message to be used when the user rejects a confirm save with duplicate title.
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
const SAVE_DUPLICATE_REJECTED = 'Save with duplicate title confirmation was rejected';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param error {Error} the error
|
|
||||||
* @return {boolean}
|
|
||||||
*/
|
|
||||||
function isErrorNonFatal(error) {
|
|
||||||
if (!error) return false;
|
|
||||||
return error.message === OVERWRITE_REJECTED || error.message === SAVE_DUPLICATE_REJECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function SavedObjectProvider(Promise, Private, Notifier, confirmModalPromise, indexPatterns) {
|
|
||||||
const savedObjectsClient = Private(SavedObjectsClientProvider);
|
|
||||||
const SearchSource = Private(SearchSourceProvider);
|
|
||||||
const mappingSetup = Private(MappingSetupProvider);
|
|
||||||
|
|
||||||
function SavedObject(config) {
|
|
||||||
if (!_.isObject(config)) config = {};
|
|
||||||
|
|
||||||
/************
|
|
||||||
* Initialize config vars
|
|
||||||
************/
|
|
||||||
|
|
||||||
// type name for this object, used as the ES-type
|
|
||||||
const esType = config.type;
|
|
||||||
|
|
||||||
this.getDisplayName = function () {
|
|
||||||
return esType;
|
|
||||||
};
|
|
||||||
|
|
||||||
// NOTE: this.type (not set in this file, but somewhere else) is the sub type, e.g. 'area' or
|
|
||||||
// 'data table', while esType is the more generic type - e.g. 'visualization' or 'saved search'.
|
|
||||||
this.getEsType = function () {
|
|
||||||
return esType;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flips to true during a save operation, and back to false once the save operation
|
|
||||||
* completes.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
this.isSaving = false;
|
|
||||||
this.defaults = config.defaults || {};
|
|
||||||
|
|
||||||
// mapping definition for the fields that this object will expose
|
|
||||||
const mapping = mappingSetup.expandShorthand(config.mapping);
|
|
||||||
|
|
||||||
const afterESResp = config.afterESResp || _.noop;
|
|
||||||
const customInit = config.init || _.noop;
|
|
||||||
|
|
||||||
// optional search source which this object configures
|
|
||||||
this.searchSource = config.searchSource ? new SearchSource() : undefined;
|
|
||||||
|
|
||||||
// the id of the document
|
|
||||||
this.id = config.id || void 0;
|
|
||||||
|
|
||||||
// Whether to create a copy when the object is saved. This should eventually go away
|
|
||||||
// in favor of a better rename/save flow.
|
|
||||||
this.copyOnSave = false;
|
|
||||||
|
|
||||||
const parseSearchSource = (searchSourceJson) => {
|
|
||||||
if (!this.searchSource) return;
|
|
||||||
|
|
||||||
// if we have a searchSource, set its values based on the searchSourceJson field
|
|
||||||
let searchSourceValues;
|
|
||||||
try {
|
|
||||||
searchSourceValues = JSON.parse(searchSourceJson);
|
|
||||||
} catch (e) {
|
|
||||||
searchSourceValues = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const searchSourceFields = this.searchSource.getFields();
|
|
||||||
const fnProps = _.transform(searchSourceFields, function (dynamic, val, name) {
|
|
||||||
if (_.isFunction(val)) dynamic[name] = val;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
this.searchSource.setFields(_.defaults(searchSourceValues, fnProps));
|
|
||||||
|
|
||||||
if (!_.isUndefined(this.searchSource.getOwnField('query'))) {
|
|
||||||
this.searchSource.setField('query', migrateLegacyQuery(this.searchSource.getOwnField('query')));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* After creation or fetching from ES, ensure that the searchSources index indexPattern
|
|
||||||
* is an bonafide IndexPattern object.
|
|
||||||
*
|
|
||||||
* @return {Promise<IndexPattern | null>}
|
|
||||||
*/
|
|
||||||
this.hydrateIndexPattern = (id) => {
|
|
||||||
if (!this.searchSource) {
|
|
||||||
return Promise.resolve(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.clearSavedIndexPattern) {
|
|
||||||
this.searchSource.setField('index', null);
|
|
||||||
return Promise.resolve(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
let index = id || config.indexPattern || this.searchSource.getOwnField('index');
|
|
||||||
|
|
||||||
if (!index) {
|
|
||||||
return Promise.resolve(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If index is not an IndexPattern object at this point, then it's a string id of an index.
|
|
||||||
if (!(index instanceof indexPatterns.IndexPattern)) {
|
|
||||||
index = indexPatterns.get(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// At this point index will either be an IndexPattern, if cached, or a promise that
|
|
||||||
// will return an IndexPattern, if not cached.
|
|
||||||
return Promise.resolve(index).then(indexPattern => {
|
|
||||||
this.searchSource.setField('index', indexPattern);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Asynchronously initialize this object - will only run
|
|
||||||
* once even if called multiple times.
|
|
||||||
*
|
|
||||||
* @return {Promise}
|
|
||||||
* @resolved {SavedObject}
|
|
||||||
*/
|
|
||||||
this.init = _.once(() => {
|
|
||||||
// ensure that the esType is defined
|
|
||||||
if (!esType) throw new Error('You must define a type name to use SavedObject objects.');
|
|
||||||
|
|
||||||
return Promise.resolve()
|
|
||||||
.then(() => {
|
|
||||||
// If there is not id, then there is no document to fetch from elasticsearch
|
|
||||||
if (!this.id) {
|
|
||||||
// just assign the defaults and be done
|
|
||||||
_.assign(this, this.defaults);
|
|
||||||
return this.hydrateIndexPattern().then(() => {
|
|
||||||
return afterESResp.call(this);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// fetch the object from ES
|
|
||||||
return savedObjectsClient.get(esType, this.id)
|
|
||||||
.then(resp => {
|
|
||||||
// temporary compatability for savedObjectsClient
|
|
||||||
|
|
||||||
return {
|
|
||||||
_id: resp.id,
|
|
||||||
_type: resp.type,
|
|
||||||
_source: _.cloneDeep(resp.attributes),
|
|
||||||
found: resp._version ? true : false
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.then(this.applyESResp)
|
|
||||||
.catch(this.applyEsResp);
|
|
||||||
})
|
|
||||||
.then(() => customInit.call(this))
|
|
||||||
.then(() => this);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
this.applyESResp = (resp) => {
|
|
||||||
this._source = _.cloneDeep(resp._source);
|
|
||||||
|
|
||||||
if (resp.found != null && !resp.found) {
|
|
||||||
throw new SavedObjectNotFound(esType, this.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
const meta = resp._source.kibanaSavedObjectMeta || {};
|
|
||||||
delete resp._source.kibanaSavedObjectMeta;
|
|
||||||
|
|
||||||
if (!config.indexPattern && this._source.indexPattern) {
|
|
||||||
config.indexPattern = this._source.indexPattern;
|
|
||||||
delete this._source.indexPattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
// assign the defaults to the response
|
|
||||||
_.defaults(this._source, this.defaults);
|
|
||||||
|
|
||||||
// transform the source using _deserializers
|
|
||||||
_.forOwn(mapping, (fieldMapping, fieldName) => {
|
|
||||||
if (fieldMapping._deserialize) {
|
|
||||||
this._source[fieldName] = fieldMapping._deserialize(this._source[fieldName], resp, fieldName, fieldMapping);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Give obj all of the values in _source.fields
|
|
||||||
_.assign(this, this._source);
|
|
||||||
this.lastSavedTitle = this.title;
|
|
||||||
|
|
||||||
return Promise.try(() => {
|
|
||||||
parseSearchSource(meta.searchSourceJSON);
|
|
||||||
return this.hydrateIndexPattern();
|
|
||||||
}).then(() => {
|
|
||||||
return Promise.cast(afterESResp.call(this, resp));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Serialize this object
|
|
||||||
*
|
|
||||||
* @return {Object}
|
|
||||||
*/
|
|
||||||
this.serialize = () => {
|
|
||||||
const body = {};
|
|
||||||
|
|
||||||
_.forOwn(mapping, (fieldMapping, fieldName) => {
|
|
||||||
if (this[fieldName] != null) {
|
|
||||||
body[fieldName] = (fieldMapping._serialize)
|
|
||||||
? fieldMapping._serialize(this[fieldName])
|
|
||||||
: this[fieldName];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (this.searchSource) {
|
|
||||||
const searchSourceFields = _.omit(this.searchSource.getFields(), ['sort', 'size']);
|
|
||||||
body.kibanaSavedObjectMeta = {
|
|
||||||
searchSourceJSON: angular.toJson(searchSourceFields)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return body;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the object's original title has been changed. New objects return false.
|
|
||||||
* @return {boolean}
|
|
||||||
*/
|
|
||||||
this.isTitleChanged = () => {
|
|
||||||
return this._source && this._source.title !== this.title;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempts to create the current object using the serialized source. If an object already
|
|
||||||
* exists, a warning message requests an overwrite confirmation.
|
|
||||||
* @param source - serialized version of this object (return value from this.serialize())
|
|
||||||
* What will be indexed into elasticsearch.
|
|
||||||
* @returns {Promise} - A promise that is resolved with the objects id if the object is
|
|
||||||
* successfully indexed. If the overwrite confirmation was rejected, an error is thrown with
|
|
||||||
* a confirmRejected = true parameter so that case can be handled differently than
|
|
||||||
* a create or index error.
|
|
||||||
* @resolved {SavedObject}
|
|
||||||
*/
|
|
||||||
const createSource = (source) => {
|
|
||||||
return savedObjectsClient.create(esType, source, { id: this.id })
|
|
||||||
.catch(err => {
|
|
||||||
// record exists, confirm overwriting
|
|
||||||
if (_.get(err, 'res.status') === 409) {
|
|
||||||
const confirmMessage = `Are you sure you want to overwrite ${this.title}?`;
|
|
||||||
|
|
||||||
return confirmModalPromise(confirmMessage, { confirmButtonText: `Overwrite ${this.getDisplayName()}` })
|
|
||||||
.then(() => savedObjectsClient.create(esType, source, { id: this.id, overwrite: true }))
|
|
||||||
.catch(() => Promise.reject(new Error(OVERWRITE_REJECTED)));
|
|
||||||
}
|
|
||||||
return Promise.reject(err);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const displayDuplicateTitleConfirmModal = () => {
|
|
||||||
const confirmMessage =
|
|
||||||
`A ${this.getDisplayName()} with the title '${this.title}' already exists. Would you like to save anyway?`;
|
|
||||||
|
|
||||||
return confirmModalPromise(confirmMessage, { confirmButtonText: `Save ${this.getDisplayName()}` })
|
|
||||||
.catch(() => Promise.reject(new Error(SAVE_DUPLICATE_REJECTED)));
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkForDuplicateTitle = (isTitleDuplicateConfirmed, onTitleDuplicate) => {
|
|
||||||
// Don't check for duplicates if user has already confirmed save with duplicate title
|
|
||||||
if (isTitleDuplicateConfirmed) {
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't check if the user isn't updating the title, otherwise that would become very annoying to have
|
|
||||||
// to confirm the save every time, except when copyOnSave is true, then we do want to check.
|
|
||||||
if (this.title === this.lastSavedTitle && !this.copyOnSave) {
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
return findObjectByTitle(savedObjectsClient, this.getEsType(), this.title)
|
|
||||||
.then(duplicate => {
|
|
||||||
if (!duplicate) return true;
|
|
||||||
if (duplicate.id === this.id) return true;
|
|
||||||
|
|
||||||
if (onTitleDuplicate) {
|
|
||||||
onTitleDuplicate();
|
|
||||||
return Promise.reject(new Error(SAVE_DUPLICATE_REJECTED));
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: make onTitleDuplicate a required prop and remove UI components from this class
|
|
||||||
// Need to leave here until all users pass onTitleDuplicate.
|
|
||||||
return displayDuplicateTitleConfirmModal();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves this object.
|
|
||||||
*
|
|
||||||
* @param {object} [options={}]
|
|
||||||
* @property {boolean} [options.confirmOverwrite=false] - If true, attempts to create the source so it
|
|
||||||
* can confirm an overwrite if a document with the id already exists.
|
|
||||||
* @property {boolean} [options.isTitleDuplicateConfirmed=false] - If true, save allowed with duplicate title
|
|
||||||
* @property {func} [options.onTitleDuplicate] - function called if duplicate title exists.
|
|
||||||
* When not provided, confirm modal will be displayed asking user to confirm or cancel save.
|
|
||||||
* @return {Promise}
|
|
||||||
* @resolved {String} - The id of the doc
|
|
||||||
*/
|
|
||||||
this.save = ({ confirmOverwrite = false, isTitleDuplicateConfirmed = false, onTitleDuplicate } = {}) => {
|
|
||||||
// Save the original id in case the save fails.
|
|
||||||
const originalId = this.id;
|
|
||||||
// Read https://github.com/elastic/kibana/issues/9056 and
|
|
||||||
// https://github.com/elastic/kibana/issues/9012 for some background into why this copyOnSave variable
|
|
||||||
// exists.
|
|
||||||
// The goal is to move towards a better rename flow, but since our users have been conditioned
|
|
||||||
// to expect a 'save as' flow during a rename, we are keeping the logic the same until a better
|
|
||||||
// UI/UX can be worked out.
|
|
||||||
if (this.copyOnSave) {
|
|
||||||
this.id = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const source = this.serialize();
|
|
||||||
|
|
||||||
this.isSaving = true;
|
|
||||||
|
|
||||||
return checkForDuplicateTitle(isTitleDuplicateConfirmed, onTitleDuplicate)
|
|
||||||
.then(() => {
|
|
||||||
if (confirmOverwrite) {
|
|
||||||
return createSource(source);
|
|
||||||
} else {
|
|
||||||
return savedObjectsClient.create(esType, source, { id: this.id, overwrite: true });
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((resp) => {
|
|
||||||
this.id = resp.id;
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
if (this.showInRecentlyAccessed && this.getFullPath) {
|
|
||||||
recentlyAccessed.add(this.getFullPath(), this.title, this.id);
|
|
||||||
}
|
|
||||||
this.isSaving = false;
|
|
||||||
this.lastSavedTitle = this.title;
|
|
||||||
return this.id;
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
this.isSaving = false;
|
|
||||||
this.id = originalId;
|
|
||||||
if (isErrorNonFatal(err)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return Promise.reject(err);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.destroy = () => {
|
|
||||||
if (this.searchSource) {
|
|
||||||
this.searchSource.cancelQueued();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete this object from Elasticsearch
|
|
||||||
* @return {promise}
|
|
||||||
*/
|
|
||||||
this.delete = () => {
|
|
||||||
return savedObjectsClient.delete(esType, this.id);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return SavedObject;
|
|
||||||
}
|
|
@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable */
|
||||||
/* FileSaver.js
|
/* FileSaver.js
|
||||||
* A saveAs() FileSaver implementation.
|
* A saveAs() FileSaver implementation.
|
||||||
* 1.3.8
|
* 1.3.8
|
||||||
|
@ -18,20 +18,20 @@ app
|
|||||||
.service('regionmapsConfig', function () {
|
.service('regionmapsConfig', function () {
|
||||||
return {
|
return {
|
||||||
// Intended noop function and empty array
|
// Intended noop function and empty array
|
||||||
noop: () => {},
|
noop() {},
|
||||||
layers: []
|
layers: []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.service('mapConfig', function () {
|
.service('mapConfig', function () {
|
||||||
return {
|
return {
|
||||||
// Intended noop function
|
// Intended noop function
|
||||||
noop: () => {}
|
noop() {}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.service('tilemapsConfig', function () {
|
.service('tilemapsConfig', function () {
|
||||||
return {
|
return {
|
||||||
// Intended noop function and false properties
|
// Intended noop function and false properties
|
||||||
noop: () => {},
|
noop() {},
|
||||||
deprecated: {
|
deprecated: {
|
||||||
config: {
|
config: {
|
||||||
options: false
|
options: false
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
encode: text => {
|
encode: text => {
|
||||||
|
const textRegex = /([^\u0000-\u00ff])/; // eslint-disable-line
|
||||||
if (/([^\u0000-\u00ff])/.test(text)){
|
if (textRegex.test(text)){
|
||||||
throw new Error("Can't base64 encode non-ASCII characters.");
|
throw new Error("Can't base64 encode non-ASCII characters.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,8 +46,8 @@ export default {
|
|||||||
decode: text => {
|
decode: text => {
|
||||||
|
|
||||||
text = text.replace(/\s/g,"");
|
text = text.replace(/\s/g,"");
|
||||||
|
const textRegex = /^[a-z0-9\-_\s]+\={0,2}$/i; // eslint-disable-line
|
||||||
if(!(/^[a-z0-9\-_\s]+\={0,2}$/i.test(text)) || text.length % 4 > 0){
|
if(!(textRegex.test(text)) || text.length % 4 > 0){
|
||||||
throw new Error("Not a base64-encoded string.");
|
throw new Error("Not a base64-encoded string.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* Find more information about this on the LICENSE file.
|
* Find more information about this on the LICENSE file.
|
||||||
*/
|
*/
|
||||||
export default class FilterHandler {
|
export class FilterHandler {
|
||||||
constructor(pattern) {
|
constructor(pattern) {
|
||||||
this.pattern = pattern;
|
this.pattern = pattern;
|
||||||
}
|
}
|
||||||
@ -36,7 +36,7 @@ export default class FilterHandler {
|
|||||||
$state: {
|
$state: {
|
||||||
store: 'appState'
|
store: 'appState'
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
agentQuery(agent) {
|
agentQuery(agent) {
|
||||||
@ -110,7 +110,7 @@ export default class FilterHandler {
|
|||||||
result.meta.key = 'rule.pci_dss';
|
result.meta.key = 'rule.pci_dss';
|
||||||
result.exists = {
|
result.exists = {
|
||||||
field: 'rule.pci_dss'
|
field: 'rule.pci_dss'
|
||||||
}
|
};
|
||||||
delete result.query;
|
delete result.query;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -122,7 +122,7 @@ export default class FilterHandler {
|
|||||||
result.meta.key = 'rule.gdpr';
|
result.meta.key = 'rule.gdpr';
|
||||||
result.exists = {
|
result.exists = {
|
||||||
field: 'rule.gdpr'
|
field: 'rule.gdpr'
|
||||||
}
|
};
|
||||||
delete result.query;
|
delete result.query;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ export default id => {
|
|||||||
html.split('ng-non-bindable')[1].split('>')[1].split('</') &&
|
html.split('ng-non-bindable')[1].split('>')[1].split('</') &&
|
||||||
html.split('ng-non-bindable')[1].split('>')[1].split('</')[0]) {
|
html.split('ng-non-bindable')[1].split('>')[1].split('</')[0]) {
|
||||||
|
|
||||||
return html.split('ng-non-bindable')[1].split('>')[1].split('</')[0]
|
return html.split('ng-non-bindable')[1].split('>')[1].split('</')[0];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,4 +40,4 @@ export default id => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
}
|
};
|
@ -18,7 +18,7 @@
|
|||||||
* wazuh-reporting 50XX
|
* wazuh-reporting 50XX
|
||||||
* unknown 1000
|
* unknown 1000
|
||||||
*/
|
*/
|
||||||
export default (message = null, code = null, statusCode = null, reply) => {
|
export function ErrorResponse (message = null, code = null, statusCode = null, reply) {
|
||||||
let filteredMessage = '';
|
let filteredMessage = '';
|
||||||
if(code) {
|
if(code) {
|
||||||
const isString = typeof message === 'string';
|
const isString = typeof message === 'string';
|
||||||
@ -48,4 +48,4 @@ export default (message = null, code = null, statusCode = null, reply) => {
|
|||||||
statusCode: statusCode ? statusCode : 500
|
statusCode: statusCode ? statusCode : 500
|
||||||
})
|
})
|
||||||
.code(statusCode ? statusCode : 500);
|
.code(statusCode ? statusCode : 500);
|
||||||
};
|
}
|
@ -9,9 +9,9 @@
|
|||||||
*
|
*
|
||||||
* Find more information about this on the LICENSE file.
|
* Find more information about this on the LICENSE file.
|
||||||
*/
|
*/
|
||||||
import WazuhElastic from './wazuh-elastic';
|
import { WazuhElasticCtrl } from './wazuh-elastic';
|
||||||
import WazuhApiElastic from './wazuh-api-elastic';
|
import { WazuhApiElasticCtrl } from './wazuh-api-elastic';
|
||||||
import WazuhApi from './wazuh-api';
|
import { WazuhApiCtrl } from './wazuh-api';
|
||||||
import WazuhReportingCtrl from './wazuh-reporting';
|
import { WazuhReportingCtrl } from './wazuh-reporting';
|
||||||
|
|
||||||
export { WazuhElastic, WazuhApiElastic, WazuhApi, WazuhReportingCtrl };
|
export { WazuhElasticCtrl, WazuhApiElasticCtrl, WazuhApiCtrl, WazuhReportingCtrl };
|
@ -10,9 +10,9 @@
|
|||||||
* Find more information about this on the LICENSE file.
|
* Find more information about this on the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ElasticWrapper from '../lib/elastic-wrapper';
|
import { ElasticWrapper } from '../lib/elastic-wrapper';
|
||||||
import ErrorResponse from './error-response';
|
import { ErrorResponse } from './error-response';
|
||||||
import log from '../logger';
|
import { log } from '../logger';
|
||||||
|
|
||||||
const userRegEx = new RegExp(/^.{3,100}$/);
|
const userRegEx = new RegExp(/^.{3,100}$/);
|
||||||
const passRegEx = new RegExp(/^.{3,100}$/);
|
const passRegEx = new RegExp(/^.{3,100}$/);
|
||||||
@ -20,7 +20,7 @@ const urlRegEx = new RegExp(/^https?:\/\/[a-zA-Z0-9-.]{1,300}$/);
|
|||||||
const urlRegExIP = new RegExp(/^https?:\/\/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/);
|
const urlRegExIP = new RegExp(/^https?:\/\/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/);
|
||||||
const portRegEx = new RegExp(/^[0-9]{2,5}$/);
|
const portRegEx = new RegExp(/^[0-9]{2,5}$/);
|
||||||
|
|
||||||
export default class WazuhApiElastic {
|
export class WazuhApiElasticCtrl {
|
||||||
constructor(server) {
|
constructor(server) {
|
||||||
this.wzWrapper = new ElasticWrapper(server);
|
this.wzWrapper = new ElasticWrapper(server);
|
||||||
}
|
}
|
||||||
|
@ -14,23 +14,23 @@
|
|||||||
import needle from 'needle';
|
import needle from 'needle';
|
||||||
import pciRequirementsFile from '../integration-files/pci-requirements';
|
import pciRequirementsFile from '../integration-files/pci-requirements';
|
||||||
import gdprRequirementsFile from '../integration-files/gdpr-requirements';
|
import gdprRequirementsFile from '../integration-files/gdpr-requirements';
|
||||||
import ElasticWrapper from '../lib/elastic-wrapper';
|
import { ElasticWrapper } from '../lib/elastic-wrapper';
|
||||||
import getPath from '../../util/get-path';
|
import { getPath } from '../../util/get-path';
|
||||||
import packageInfo from '../../package.json';
|
import packageInfo from '../../package.json';
|
||||||
import monitoring from '../monitoring';
|
import { Monitoring } from '../monitoring';
|
||||||
import ErrorResponse from './error-response';
|
import { ErrorResponse } from './error-response';
|
||||||
import { Parser } from 'json2csv';
|
import { Parser } from 'json2csv';
|
||||||
import getConfiguration from '../lib/get-configuration';
|
import { getConfiguration } from '../lib/get-configuration';
|
||||||
import { totalmem } from 'os';
|
import { totalmem } from 'os';
|
||||||
import simpleTail from 'simple-tail';
|
import simpleTail from 'simple-tail';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import log from '../logger';
|
import { log } from '../logger';
|
||||||
import CsvKeys from '../../util/csv-key-equivalence';
|
import CsvKeys from '../../util/csv-key-equivalence';
|
||||||
|
|
||||||
export default class WazuhApi {
|
export class WazuhApiCtrl {
|
||||||
constructor(server){
|
constructor(server){
|
||||||
this.wzWrapper = new ElasticWrapper(server);
|
this.wzWrapper = new ElasticWrapper(server);
|
||||||
this.fetchAgentsExternal = monitoring(server,{disableCron:true})
|
this.fetchAgentsExternal = Monitoring(server,{disableCron:true})
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkStoredAPI (req, reply) {
|
async checkStoredAPI (req, reply) {
|
||||||
|
@ -9,9 +9,9 @@
|
|||||||
*
|
*
|
||||||
* Find more information about this on the LICENSE file.
|
* Find more information about this on the LICENSE file.
|
||||||
*/
|
*/
|
||||||
import ElasticWrapper from '../lib/elastic-wrapper';
|
import { ElasticWrapper } from '../lib/elastic-wrapper';
|
||||||
import ErrorResponse from './error-response';
|
import { ErrorResponse } from './error-response';
|
||||||
import log from '../logger';
|
import { log } from '../logger';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AgentsVisualizations,
|
AgentsVisualizations,
|
||||||
@ -20,7 +20,7 @@ import {
|
|||||||
} from '../integration-files/visualizations';
|
} from '../integration-files/visualizations';
|
||||||
|
|
||||||
|
|
||||||
export default class WazuhElastic {
|
export class WazuhElasticCtrl {
|
||||||
constructor(server){
|
constructor(server){
|
||||||
this.wzWrapper = new ElasticWrapper(server);
|
this.wzWrapper = new ElasticWrapper(server);
|
||||||
}
|
}
|
||||||
|
@ -15,25 +15,29 @@ import descriptions from '../reporting/tab-description';
|
|||||||
import * as TimSort from 'timsort';
|
import * as TimSort from 'timsort';
|
||||||
import rawParser from '../reporting/raw-parser';
|
import rawParser from '../reporting/raw-parser';
|
||||||
import PdfPrinter from 'pdfmake/src/printer';
|
import PdfPrinter from 'pdfmake/src/printer';
|
||||||
import ErrorResponse from './error-response';
|
import { ErrorResponse } from './error-response';
|
||||||
import VulnerabilityRequest from '../reporting/vulnerability-request';
|
import { VulnerabilityRequest } from '../reporting/vulnerability-request';
|
||||||
import OverviewRequest from '../reporting/overview-request';
|
import { OverviewRequest } from '../reporting/overview-request';
|
||||||
import RootcheckRequest from '../reporting/rootcheck-request';
|
import { RootcheckRequest } from '../reporting/rootcheck-request';
|
||||||
import PciRequest from '../reporting/pci-request';
|
import { PciRequest } from '../reporting/pci-request';
|
||||||
import GdprRequest from '../reporting/gdpr-request';
|
import { GdprRequest } from '../reporting/gdpr-request';
|
||||||
import AuditRequest from '../reporting/audit-request';
|
import { AuditRequest } from '../reporting/audit-request';
|
||||||
import SyscheckRequest from '../reporting/syscheck-request';
|
import { SyscheckRequest } from '../reporting/syscheck-request';
|
||||||
import PCI from '../integration-files/pci-requirements-pdfmake';
|
import PCI from '../integration-files/pci-requirements-pdfmake';
|
||||||
import GDPR from '../integration-files/gdpr-requirements-pdfmake';
|
import GDPR from '../integration-files/gdpr-requirements-pdfmake';
|
||||||
import PdfTable from '../reporting/generic-table';
|
import PdfTable from '../reporting/generic-table';
|
||||||
import WazuhApi from './wazuh-api';
|
import { WazuhApiCtrl } from './wazuh-api';
|
||||||
import clockIconRaw from '../reporting/clock-icon-raw';
|
import clockIconRaw from '../reporting/clock-icon-raw';
|
||||||
import filterIconRaw from '../reporting/filter-icon-raw';
|
import filterIconRaw from '../reporting/filter-icon-raw';
|
||||||
import { AgentsVisualizations, OverviewVisualizations } from '../integration-files/visualizations';
|
|
||||||
|
import {
|
||||||
|
AgentsVisualizations,
|
||||||
|
OverviewVisualizations
|
||||||
|
} from '../integration-files/visualizations';
|
||||||
|
|
||||||
const REPORTING_PATH = '../../../../optimize/wazuh-reporting';
|
const REPORTING_PATH = '../../../../optimize/wazuh-reporting';
|
||||||
|
|
||||||
export default class WazuhReportingCtrl {
|
export class WazuhReportingCtrl {
|
||||||
constructor(server) {
|
constructor(server) {
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.fonts = {
|
this.fonts = {
|
||||||
@ -103,7 +107,7 @@ export default class WazuhReportingCtrl {
|
|||||||
content: [
|
content: [
|
||||||
|
|
||||||
],
|
],
|
||||||
footer: function (currentPage, pageCount) {
|
footer (currentPage, pageCount) {
|
||||||
return {
|
return {
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
@ -115,7 +119,7 @@ export default class WazuhReportingCtrl {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
pageBreakBefore: function (currentNode, followingNodesOnPage, nodesOnNextPage, previousNodesOnPage) {
|
pageBreakBefore (currentNode, followingNodesOnPage) {
|
||||||
if (currentNode.id && currentNode.id.includes('splitvis')) {
|
if (currentNode.id && currentNode.id.includes('splitvis')) {
|
||||||
return followingNodesOnPage.length === 6 || followingNodesOnPage.length === 7;
|
return followingNodesOnPage.length === 6 || followingNodesOnPage.length === 7;
|
||||||
}
|
}
|
||||||
@ -129,7 +133,7 @@ export default class WazuhReportingCtrl {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.apiRequest = new WazuhApi(server);
|
this.apiRequest = new WazuhApiCtrl(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTables(tables) {
|
renderTables(tables) {
|
||||||
@ -151,19 +155,14 @@ export default class WazuhReportingCtrl {
|
|||||||
|
|
||||||
const modifiedRows = [];
|
const modifiedRows = [];
|
||||||
for (const row of rows) {
|
for (const row of rows) {
|
||||||
modifiedRows.push(row.map(cell => {
|
modifiedRows.push(row.map(cell => ({ text: cell, style: 'standard' })));
|
||||||
return { text: cell, style: 'standard' };
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const widths = Array(table.columns.length - 1).fill('auto');
|
const widths = Array(table.columns.length - 1).fill('auto');
|
||||||
widths.push('*');
|
widths.push('*');
|
||||||
|
|
||||||
full_body.push(
|
full_body.push(
|
||||||
table.columns.map(col => {
|
table.columns.map(col => ({ text: col, style: 'whiteColor', border: [0, 0, 0, 0]})), ...modifiedRows);
|
||||||
return { text: col, style: 'whiteColor', border: [0, 0, 0, 0] };
|
|
||||||
})
|
|
||||||
, ...modifiedRows);
|
|
||||||
this.dd.content.push({
|
this.dd.content.push({
|
||||||
fontSize: 8,
|
fontSize: 8,
|
||||||
table: {
|
table: {
|
||||||
@ -586,7 +585,7 @@ export default class WazuhReportingCtrl {
|
|||||||
|
|
||||||
if (section === 'agents' && tab === 'pm') {
|
if (section === 'agents' && tab === 'pm') {
|
||||||
const database = await this.apiRequest.makeGenericRequest('GET', `/rootcheck/${agent}`, { limit: 15 }, apiId);
|
const database = await this.apiRequest.makeGenericRequest('GET', `/rootcheck/${agent}`, { limit: 15 }, apiId);
|
||||||
const cis = await this.apiRequest.makeGenericRequest('GET', `/rootcheck/${agent}/cis`, {}, apiId);
|
//const cis = await this.apiRequest.makeGenericRequest('GET', `/rootcheck/${agent}/cis`, {}, apiId);
|
||||||
const pci = await this.apiRequest.makeGenericRequest('GET', `/rootcheck/${agent}/pci`, {}, apiId);
|
const pci = await this.apiRequest.makeGenericRequest('GET', `/rootcheck/${agent}/pci`, {}, apiId);
|
||||||
const lastScan = await this.apiRequest.makeGenericRequest('GET', `/rootcheck/${agent}/last_scan`, {}, apiId);
|
const lastScan = await this.apiRequest.makeGenericRequest('GET', `/rootcheck/${agent}/last_scan`, {}, apiId);
|
||||||
|
|
||||||
@ -727,7 +726,7 @@ export default class WazuhReportingCtrl {
|
|||||||
for (const critical of topCriticalPackages) {
|
for (const critical of topCriticalPackages) {
|
||||||
customul.push({ text: critical.package, style: 'standard' });
|
customul.push({ text: critical.package, style: 'standard' });
|
||||||
customul.push({
|
customul.push({
|
||||||
ul: critical.references.map(item => { return { text: item, color: '#1EA5C8' }; })
|
ul: critical.references.map(item => ({ text: item, color: '#1EA5C8' }))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.dd.content.push({ ul: customul })
|
this.dd.content.push({ ul: customul })
|
||||||
@ -744,7 +743,7 @@ export default class WazuhReportingCtrl {
|
|||||||
for (const critical of topHighPackages) {
|
for (const critical of topHighPackages) {
|
||||||
customul.push({ text: critical.package, style: 'standard' });
|
customul.push({ text: critical.package, style: 'standard' });
|
||||||
customul.push({
|
customul.push({
|
||||||
ul: critical.references.map(item => { return { text: item, color: '#1EA5C8' }; })
|
ul: critical.references.map(item => ({ text: item, color: '#1EA5C8' }))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
customul && customul.length && this.dd.content.push({ ul: customul });
|
customul && customul.length && this.dd.content.push({ ul: customul });
|
||||||
|
@ -11,15 +11,15 @@
|
|||||||
*/
|
*/
|
||||||
import needle from 'needle'
|
import needle from 'needle'
|
||||||
import colors from 'ansicolors'
|
import colors from 'ansicolors'
|
||||||
import log from './logger'
|
import { log } from './logger'
|
||||||
import ElasticWrapper from './lib/elastic-wrapper'
|
import { ElasticWrapper } from './lib/elastic-wrapper'
|
||||||
import packageJSON from '../package.json'
|
import packageJSON from '../package.json'
|
||||||
import kibana_template from './integration-files/kibana-template'
|
import kibana_template from './integration-files/kibana-template'
|
||||||
import getConfiguration from './lib/get-configuration'
|
import { getConfiguration } from './lib/get-configuration'
|
||||||
import defaultExt from './lib/default-ext'
|
import defaultExt from './lib/default-ext'
|
||||||
import { BuildBody } from './lib/replicas-shards-helper'
|
import { BuildBody } from './lib/replicas-shards-helper'
|
||||||
|
|
||||||
export default (server, options) => {
|
export function Initialize(server) {
|
||||||
const blueWazuh = colors.blue('wazuh');
|
const blueWazuh = colors.blue('wazuh');
|
||||||
|
|
||||||
// Elastic JS Client
|
// Elastic JS Client
|
||||||
@ -674,4 +674,4 @@ export default (server, options) => {
|
|||||||
// Check Kibana index and if it is prepared, start the initialization of Wazuh App.
|
// Check Kibana index and if it is prepared, start the initialization of Wazuh App.
|
||||||
checkStatus();
|
checkStatus();
|
||||||
|
|
||||||
};
|
}
|
@ -11,7 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
import knownFields from '../integration-files/known-fields';
|
import knownFields from '../integration-files/known-fields';
|
||||||
|
|
||||||
export default class ElasticWrapper {
|
export class ElasticWrapper {
|
||||||
constructor(server){
|
constructor(server){
|
||||||
this.elasticRequest = server.plugins.elasticsearch.getCluster('data');
|
this.elasticRequest = server.plugins.elasticsearch.getCluster('data');
|
||||||
this.WZ_KIBANA_INDEX = server &&
|
this.WZ_KIBANA_INDEX = server &&
|
||||||
@ -437,7 +437,7 @@ export default class ElasticWrapper {
|
|||||||
} catch(error){
|
} catch(error){
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Usually used to save a new Wazuh API entry
|
* Usually used to save a new Wazuh API entry
|
||||||
@ -526,7 +526,7 @@ export default class ElasticWrapper {
|
|||||||
} catch(error){
|
} catch(error){
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as curling the templates from Elasticsearch
|
* Same as curling the templates from Elasticsearch
|
||||||
|
@ -13,7 +13,7 @@ import fs from 'fs'
|
|||||||
import yml from 'js-yaml'
|
import yml from 'js-yaml'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
|
||||||
export default () => {
|
export function getConfiguration() {
|
||||||
try {
|
try {
|
||||||
const customPath = path.join(__dirname, '../../config.yml');
|
const customPath = path.join(__dirname, '../../config.yml');
|
||||||
const raw = fs.readFileSync(customPath, { encoding: 'utf-8' })
|
const raw = fs.readFileSync(customPath, { encoding: 'utf-8' })
|
||||||
|
@ -9,10 +9,10 @@
|
|||||||
*
|
*
|
||||||
* Find more information about this on the LICENSE file.
|
* Find more information about this on the LICENSE file.
|
||||||
*/
|
*/
|
||||||
import log from '../logger'
|
import { log } from '../logger'
|
||||||
import cron from 'node-cron'
|
import cron from 'node-cron'
|
||||||
|
|
||||||
export default interval => {
|
export function parseCron(interval) {
|
||||||
try {
|
try {
|
||||||
if(!interval) throw new Error('Interval not found');
|
if(!interval) throw new Error('Interval not found');
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ const checkFiles = () => {
|
|||||||
* @param {*} message Message to show
|
* @param {*} message Message to show
|
||||||
* @param {*} level Optional, default is 'error'
|
* @param {*} level Optional, default is 'error'
|
||||||
*/
|
*/
|
||||||
export default (location, message, level) => {
|
export function log(location, message, level) {
|
||||||
initDirectory()
|
initDirectory()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if(allowed){
|
if(allowed){
|
||||||
@ -110,5 +110,5 @@ export default (location, message, level) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => console.error(`Cannot create the logs directory due to:\n${error.message || error}`));
|
.catch(error => console.error(`Cannot create the logs directory due to:\n${error.message || error}`)); // eslint-disable-line
|
||||||
};
|
}
|
@ -11,17 +11,17 @@
|
|||||||
*/
|
*/
|
||||||
import cron from 'node-cron'
|
import cron from 'node-cron'
|
||||||
import needle from 'needle'
|
import needle from 'needle'
|
||||||
import getPath from'../util/get-path'
|
import { getPath } from'../util/get-path'
|
||||||
import colors from 'ansicolors'
|
import colors from 'ansicolors'
|
||||||
import log from './logger'
|
import { log } from './logger'
|
||||||
import ElasticWrapper from './lib/elastic-wrapper'
|
import { ElasticWrapper } from './lib/elastic-wrapper'
|
||||||
import monitoringTemplate from './integration-files/monitoring-template'
|
import monitoringTemplate from './integration-files/monitoring-template'
|
||||||
import packageJSON from '../package.json'
|
import packageJSON from '../package.json'
|
||||||
import getConfiguration from './lib/get-configuration'
|
import { getConfiguration } from './lib/get-configuration'
|
||||||
import parseCron from './lib/parse-cron'
|
import { parseCron } from './lib/parse-cron'
|
||||||
import { BuildBody } from './lib/replicas-shards-helper'
|
import { BuildBody } from './lib/replicas-shards-helper'
|
||||||
|
|
||||||
export default (server, options) => {
|
export function Monitoring (server, options) {
|
||||||
const blueWazuh = colors.blue('wazuh');
|
const blueWazuh = colors.blue('wazuh');
|
||||||
|
|
||||||
let ENABLED = true;
|
let ENABLED = true;
|
||||||
@ -280,7 +280,7 @@ export default (server, options) => {
|
|||||||
}
|
}
|
||||||
if (body === '') return;
|
if (body === '') return;
|
||||||
|
|
||||||
const response = await wzWrapper.pushBulkAnyIndex(todayIndex,body);
|
await wzWrapper.pushBulkAnyIndex(todayIndex,body);
|
||||||
|
|
||||||
agentsArray.length = 0;
|
agentsArray.length = 0;
|
||||||
}
|
}
|
||||||
@ -341,7 +341,7 @@ export default (server, options) => {
|
|||||||
try {
|
try {
|
||||||
log('[monitoring][checkTemplate]', 'Updating wazuh-monitoring template...', 'info');
|
log('[monitoring][checkTemplate]', 'Updating wazuh-monitoring template...', 'info');
|
||||||
server.log([blueWazuh, 'monitoring', 'info'], "Updating wazuh-monitoring template...");
|
server.log([blueWazuh, 'monitoring', 'info'], "Updating wazuh-monitoring template...");
|
||||||
const data = await wzWrapper.putMonitoringTemplate(monitoringTemplate);
|
await wzWrapper.putMonitoringTemplate(monitoringTemplate);
|
||||||
return;
|
return;
|
||||||
} catch(error){
|
} catch(error){
|
||||||
log('[monitoring][checkTemplate]', `Something went wrong updating wazuh-monitoring template... ${error.message || error}`);
|
log('[monitoring][checkTemplate]', `Something went wrong updating wazuh-monitoring template... ${error.message || error}`);
|
||||||
@ -452,4 +452,4 @@ export default (server, options) => {
|
|||||||
// Cron tab for getting agent status.
|
// Cron tab for getting agent status.
|
||||||
if(!options && ENABLED) cron.schedule(CRON_FREQ, cronTask, true);
|
if(!options && ENABLED) cron.schedule(CRON_FREQ, cronTask, true);
|
||||||
return fetchAgentsExternal;
|
return fetchAgentsExternal;
|
||||||
};
|
}
|
@ -9,11 +9,11 @@
|
|||||||
*
|
*
|
||||||
* Find more information about this on the LICENSE file.
|
* Find more information about this on the LICENSE file.
|
||||||
*/
|
*/
|
||||||
import ElasticWrapper from '../lib/elastic-wrapper';
|
import { ElasticWrapper } from '../lib/elastic-wrapper';
|
||||||
import Base from './base-query';
|
import Base from './base-query';
|
||||||
import AuditMap from './audit-map';
|
import AuditMap from './audit-map';
|
||||||
|
|
||||||
export default class PciRequest {
|
export class AuditRequest {
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param {*} server Hapi.js server object provided by Kibana
|
* @param {*} server Hapi.js server object provided by Kibana
|
||||||
@ -176,7 +176,7 @@ export default class PciRequest {
|
|||||||
const response = await this.wzWrapper.searchWazuhAlertsWithPayload(base);
|
const response = await this.wzWrapper.searchWazuhAlertsWithPayload(base);
|
||||||
const { buckets } = response.aggregations['2'];
|
const { buckets } = response.aggregations['2'];
|
||||||
|
|
||||||
return buckets.map(item => { return { id:item.key, syscall:AuditMap[item.key] };});
|
return buckets.map(item => ({ id:item.key, syscall:AuditMap[item.key] }));
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
|
@ -9,10 +9,10 @@
|
|||||||
*
|
*
|
||||||
* Find more information about this on the LICENSE file.
|
* Find more information about this on the LICENSE file.
|
||||||
*/
|
*/
|
||||||
import ElasticWrapper from '../lib/elastic-wrapper';
|
import { ElasticWrapper } from '../lib/elastic-wrapper';
|
||||||
import Base from './base-query';
|
import Base from './base-query';
|
||||||
|
|
||||||
export default class GdprRequest {
|
export class GdprRequest {
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param {*} server Hapi.js server object provided by Kibana
|
* @param {*} server Hapi.js server object provided by Kibana
|
||||||
|
@ -9,10 +9,10 @@
|
|||||||
*
|
*
|
||||||
* Find more information about this on the LICENSE file.
|
* Find more information about this on the LICENSE file.
|
||||||
*/
|
*/
|
||||||
import ElasticWrapper from '../lib/elastic-wrapper';
|
import { ElasticWrapper } from '../lib/elastic-wrapper';
|
||||||
import Base from './base-query';
|
import Base from './base-query';
|
||||||
|
|
||||||
export default class VulnerabilityRequest {
|
export class OverviewRequest {
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param {*} server Hapi.js server object provided by Kibana
|
* @param {*} server Hapi.js server object provided by Kibana
|
||||||
|
@ -9,10 +9,10 @@
|
|||||||
*
|
*
|
||||||
* Find more information about this on the LICENSE file.
|
* Find more information about this on the LICENSE file.
|
||||||
*/
|
*/
|
||||||
import ElasticWrapper from '../lib/elastic-wrapper';
|
import { ElasticWrapper } from '../lib/elastic-wrapper';
|
||||||
import Base from './base-query';
|
import Base from './base-query';
|
||||||
|
|
||||||
export default class PciRequest {
|
export class PciRequest {
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param {*} server Hapi.js server object provided by Kibana
|
* @param {*} server Hapi.js server object provided by Kibana
|
||||||
|
@ -9,10 +9,10 @@
|
|||||||
*
|
*
|
||||||
* Find more information about this on the LICENSE file.
|
* Find more information about this on the LICENSE file.
|
||||||
*/
|
*/
|
||||||
import ElasticWrapper from '../lib/elastic-wrapper';
|
import { ElasticWrapper } from '../lib/elastic-wrapper';
|
||||||
import Base from './base-query';
|
import Base from './base-query';
|
||||||
|
|
||||||
export default class RootcheckRequest {
|
export class RootcheckRequest {
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param {*} server Hapi.js server object provided by Kibana
|
* @param {*} server Hapi.js server object provided by Kibana
|
||||||
|
@ -9,10 +9,10 @@
|
|||||||
*
|
*
|
||||||
* Find more information about this on the LICENSE file.
|
* Find more information about this on the LICENSE file.
|
||||||
*/
|
*/
|
||||||
import ElasticWrapper from '../lib/elastic-wrapper';
|
import { ElasticWrapper } from '../lib/elastic-wrapper';
|
||||||
import Base from './base-query';
|
import Base from './base-query';
|
||||||
|
|
||||||
export default class SyscheckRequest {
|
export class SyscheckRequest {
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param {*} server Hapi.js server object provided by Kibana
|
* @param {*} server Hapi.js server object provided by Kibana
|
||||||
|
@ -9,10 +9,10 @@
|
|||||||
*
|
*
|
||||||
* Find more information about this on the LICENSE file.
|
* Find more information about this on the LICENSE file.
|
||||||
*/
|
*/
|
||||||
import ElasticWrapper from '../lib/elastic-wrapper';
|
import { ElasticWrapper } from '../lib/elastic-wrapper';
|
||||||
import Base from './base-query';
|
import Base from './base-query';
|
||||||
|
|
||||||
export default class VulnerabilityRequest {
|
export class VulnerabilityRequest {
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param {*} server Hapi.js server object provided by Kibana
|
* @param {*} server Hapi.js server object provided by Kibana
|
||||||
@ -174,7 +174,7 @@ export default class VulnerabilityRequest {
|
|||||||
const response = await this.wzWrapper.searchWazuhAlertsWithPayload(base);
|
const response = await this.wzWrapper.searchWazuhAlertsWithPayload(base);
|
||||||
const { buckets } = response.aggregations['2'];
|
const { buckets } = response.aggregations['2'];
|
||||||
|
|
||||||
return buckets.map(item => {return {package: item.key, severity: severity};});
|
return buckets.map(item => ({package: item.key, severity: severity}));
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
@ -221,17 +221,13 @@ export default class VulnerabilityRequest {
|
|||||||
const response = await this.wzWrapper.searchWazuhAlertsWithPayload(base);
|
const response = await this.wzWrapper.searchWazuhAlertsWithPayload(base);
|
||||||
const { buckets } = response.aggregations['2'];
|
const { buckets } = response.aggregations['2'];
|
||||||
|
|
||||||
return buckets.map(item => {
|
return buckets.map(item => ({
|
||||||
return {
|
|
||||||
package: item.key,
|
package: item.key,
|
||||||
references: item['3'].buckets.map(ref => ref.key)
|
references: item['3'].buckets.map(ref => ref.key)
|
||||||
};
|
}));
|
||||||
});
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -9,26 +9,26 @@
|
|||||||
*
|
*
|
||||||
* Find more information about this on the LICENSE file.
|
* Find more information about this on the LICENSE file.
|
||||||
*/
|
*/
|
||||||
import { WazuhApiElastic } from '../controllers';
|
import { WazuhApiElasticCtrl } from '../controllers';
|
||||||
|
|
||||||
export default (server, options) => {
|
export function WazuhApiElasticRoutes(server) {
|
||||||
const ctrl = new WazuhApiElastic(server);
|
const ctrl = new WazuhApiElasticCtrl(server);
|
||||||
|
|
||||||
// Save the given API into elasticsearch
|
// Save the given API into elasticsearch
|
||||||
server.route({ method: 'PUT', path: '/api/wazuh-api/settings', handler: (req,reply) => ctrl.saveAPI(req,reply) });
|
server.route({ method: 'PUT', path: '/api/wazuh-api/settings', handler(req, reply) { return ctrl.saveAPI(req, reply) } });
|
||||||
|
|
||||||
// Update the given API into elasticsearch
|
// Update the given API into elasticsearch
|
||||||
server.route({ method: 'PUT', path: '/api/wazuh-api/update-settings', handler: (req,reply) => ctrl.updateFullAPI(req,reply) });
|
server.route({ method: 'PUT', path: '/api/wazuh-api/update-settings', handler(req, reply) { return ctrl.updateFullAPI(req, reply) } });
|
||||||
|
|
||||||
// Get Wazuh-API entries list (Multimanager) from elasticsearch index
|
// Get Wazuh-API entries list (Multimanager) from elasticsearch index
|
||||||
server.route({ method: 'GET', path: '/api/wazuh-api/apiEntries', handler: (req,reply) => ctrl.getAPIEntries(req,reply) });
|
server.route({ method: 'GET', path: '/api/wazuh-api/apiEntries', handler(req, reply) { return ctrl.getAPIEntries(req, reply) } });
|
||||||
|
|
||||||
// Delete Wazuh-API entry (multimanager) from elasticsearch index
|
// Delete Wazuh-API entry (multimanager) from elasticsearch index
|
||||||
server.route({ method: 'DELETE', path: '/api/wazuh-api/apiEntries/{id}', handler: (req,reply) => ctrl.deleteAPIEntries(req,reply) });
|
server.route({ method: 'DELETE', path: '/api/wazuh-api/apiEntries/{id}', handler(req, reply) { return ctrl.deleteAPIEntries(req, reply) } });
|
||||||
|
|
||||||
// Set Wazuh-API as default (multimanager) on elasticsearch index
|
// Set Wazuh-API as default (multimanager) on elasticsearch index
|
||||||
server.route({ method: 'PUT', path: '/api/wazuh-api/apiEntries/{id}', handler: (req,reply) => ctrl.setAPIEntryDefault(req,reply) });
|
server.route({ method: 'PUT', path: '/api/wazuh-api/apiEntries/{id}', handler(req, reply) { return ctrl.setAPIEntryDefault(req, reply) } });
|
||||||
|
|
||||||
// Update the API hostname
|
// Update the API hostname
|
||||||
server.route({ method: 'PUT', path: '/api/wazuh-api/updateApiHostname/{id}', handler: (req,reply) => ctrl.updateAPIHostname(req,reply) });
|
server.route({ method: 'PUT', path: '/api/wazuh-api/updateApiHostname/{id}', handler(req, reply) { return ctrl.updateAPIHostname(req, reply) } });
|
||||||
};
|
}
|
@ -9,42 +9,42 @@
|
|||||||
*
|
*
|
||||||
* Find more information about this on the LICENSE file.
|
* Find more information about this on the LICENSE file.
|
||||||
*/
|
*/
|
||||||
import { WazuhApi } from '../controllers';
|
import { WazuhApiCtrl } from '../controllers';
|
||||||
|
|
||||||
export default (server, options) => {
|
export function WazuhApiRoutes (server) {
|
||||||
const ctrl = new WazuhApi(server);
|
const ctrl = new WazuhApiCtrl(server);
|
||||||
|
|
||||||
// Returns if the wazuh-api configuration is working
|
// Returns if the wazuh-api configuration is working
|
||||||
server.route({ method: 'POST', path: '/api/wazuh-api/checkStoredAPI', handler: (req, reply) => ctrl.checkStoredAPI(req, reply) });
|
server.route({ method: 'POST', path: '/api/wazuh-api/checkStoredAPI', handler(req, reply) { return ctrl.checkStoredAPI(req, reply)} });
|
||||||
|
|
||||||
// Check if credentials on POST connect to Wazuh API. Not storing them!
|
// Check if credentials on POST connect to Wazuh API. Not storing them!
|
||||||
// Returns if the wazuh-api configuration received in the POST body will work
|
// Returns if the wazuh-api configuration received in the POST body will work
|
||||||
server.route({ method: 'POST', path: '/api/wazuh-api/checkAPI', handler: (req, reply) => ctrl.checkAPI(req, reply) });
|
server.route({ method: 'POST', path: '/api/wazuh-api/checkAPI', handler(req, reply) { return ctrl.checkAPI(req, reply) }});
|
||||||
|
|
||||||
// Returns the request result (With error control)
|
// Returns the request result (With error control)
|
||||||
server.route({ method: 'POST', path: '/api/wazuh-api/request', handler: (req, reply) => ctrl.requestApi(req, reply) });
|
server.route({ method: 'POST', path: '/api/wazuh-api/request', handler(req, reply) { return ctrl.requestApi(req, reply) }});
|
||||||
|
|
||||||
// Return a PCI requirement description
|
// Return a PCI requirement description
|
||||||
server.route({ method: 'GET', path: '/api/wazuh-api/pci/{requirement}', handler: (req, reply) => ctrl.getPciRequirement(req, reply) });
|
server.route({ method: 'GET', path: '/api/wazuh-api/pci/{requirement}', handler(req, reply) { return ctrl.getPciRequirement(req, reply) }});
|
||||||
|
|
||||||
// Return a GDPR requirement description
|
// Return a GDPR requirement description
|
||||||
server.route({ method: 'GET', path: '/api/wazuh-api/gdpr/{requirement}', handler: (req, reply) => ctrl.getGdprRequirement(req, reply) });
|
server.route({ method: 'GET', path: '/api/wazuh-api/gdpr/{requirement}', handler(req, reply) { return ctrl.getGdprRequirement(req, reply)} });
|
||||||
|
|
||||||
// Force fetch data to be inserted on wazuh-monitoring indices
|
// Force fetch data to be inserted on wazuh-monitoring indices
|
||||||
server.route({ method: 'GET', path: '/api/wazuh-api/fetchAgents', handler: (req, reply) => ctrl.fetchAgents(req, reply) });
|
server.route({ method: 'GET', path: '/api/wazuh-api/fetchAgents', handler(req, reply) { return ctrl.fetchAgents(req, reply) }});
|
||||||
|
|
||||||
// Returns the config.yml file parsed
|
// Returns the config.yml file parsed
|
||||||
server.route({ method: 'GET', path: '/api/wazuh-api/configuration', handler: (req, reply) => ctrl.getConfigurationFile(req, reply) });
|
server.route({ method: 'GET', path: '/api/wazuh-api/configuration', handler(req, reply) { return ctrl.getConfigurationFile(req, reply)} });
|
||||||
|
|
||||||
// Returns data from the Wazuh API on CSV readable format
|
// Returns data from the Wazuh API on CSV readable format
|
||||||
server.route({ method: 'POST', path: '/api/wazuh-api/csv', handler: (req,res) => ctrl.csv(req,res)})
|
server.route({ method: 'POST', path: '/api/wazuh-api/csv', handler(req,res) { return ctrl.csv(req,res)}})
|
||||||
|
|
||||||
// Returns total RAM available from the current machine where Kibana is being executed
|
// Returns total RAM available from the current machine where Kibana is being executed
|
||||||
server.route({ method: 'GET', path: '/api/wazuh-api/ram', handler: (req,res) => ctrl.totalRam(req,res)})
|
server.route({ method: 'GET', path: '/api/wazuh-api/ram', handler(req,res) { return ctrl.totalRam(req,res)}})
|
||||||
|
|
||||||
// Returns unique fields from the agents such OS, agent version ...
|
// Returns unique fields from the agents such OS, agent version ...
|
||||||
server.route({ method: 'GET', path: '/api/wazuh-api/agents-unique/{api}', handler: (req,res) => ctrl.getAgentsFieldsUniqueCount(req,res)});
|
server.route({ method: 'GET', path: '/api/wazuh-api/agents-unique/{api}', handler(req,res) { return ctrl.getAgentsFieldsUniqueCount(req,res)}});
|
||||||
|
|
||||||
// Returns Wazuh app logs ...
|
// Returns Wazuh app logs ...
|
||||||
server.route({ method: 'GET', path: '/api/wazuh-api/logs', handler: (req,res) => ctrl.getAppLogs(req,res)});
|
server.route({ method: 'GET', path: '/api/wazuh-api/logs', handler(req,res) { return ctrl.getAppLogs(req,res)}});
|
||||||
};
|
}
|
@ -9,34 +9,34 @@
|
|||||||
*
|
*
|
||||||
* Find more information about this on the LICENSE file.
|
* Find more information about this on the LICENSE file.
|
||||||
*/
|
*/
|
||||||
import { WazuhElastic } from '../controllers';
|
import { WazuhElasticCtrl } from '../controllers';
|
||||||
|
|
||||||
export default (server, options) => {
|
export function WazuhElasticRouter(server) {
|
||||||
|
|
||||||
const ctrl = new WazuhElastic(server);
|
const ctrl = new WazuhElasticCtrl(server);
|
||||||
|
|
||||||
// Get index patterns list
|
// Get index patterns list
|
||||||
server.route({ method: 'GET', path: '/get-list', handler: (req,res) => ctrl.getlist(req,res) });
|
server.route({ method: 'GET', path: '/get-list', handler(req, res) { return ctrl.getlist(req, res) } });
|
||||||
|
|
||||||
// Refresh known fields for specific index pattern
|
// Refresh known fields for specific index pattern
|
||||||
server.route({ method: 'GET', path: '/refresh-fields/{pattern}', handler: (req,res) => ctrl.refreshIndex(req,res) });
|
server.route({ method: 'GET', path: '/refresh-fields/{pattern}', handler(req, res) { return ctrl.refreshIndex(req, res) } });
|
||||||
|
|
||||||
// Create visualizations specified in 'tab' parameter and applying to 'pattern'
|
// Create visualizations specified in 'tab' parameter and applying to 'pattern'
|
||||||
server.route({ method: 'GET', path: '/api/wazuh-elastic/create-vis/{tab}/{pattern}', handler: (req,res) => ctrl.createVis(req,res) });
|
server.route({ method: 'GET', path: '/api/wazuh-elastic/create-vis/{tab}/{pattern}', handler(req, res) { return ctrl.createVis(req, res) } });
|
||||||
server.route({ method: 'POST', path: '/api/wazuh-elastic/create-vis/{tab}/{pattern}', handler: (req,res) => ctrl.createClusterVis(req,res) });
|
server.route({ method: 'POST', path: '/api/wazuh-elastic/create-vis/{tab}/{pattern}', handler(req, res) { return ctrl.createClusterVis(req, res) } });
|
||||||
|
|
||||||
// Returns whether a correct template is being applied for the index-pattern
|
// Returns whether a correct template is being applied for the index-pattern
|
||||||
server.route({ method: 'GET', path: '/api/wazuh-elastic/template/{pattern}', handler: (req,res) => ctrl.getTemplate(req,res) });
|
server.route({ method: 'GET', path: '/api/wazuh-elastic/template/{pattern}', handler(req, res) { return ctrl.getTemplate(req, res) } });
|
||||||
|
|
||||||
// Returns whether the pattern exists or not
|
// Returns whether the pattern exists or not
|
||||||
server.route({ method: 'GET', path: '/api/wazuh-elastic/pattern/{pattern}', handler: (req,res) => ctrl.checkPattern(req,res) });
|
server.route({ method: 'GET', path: '/api/wazuh-elastic/pattern/{pattern}', handler(req, res) { return ctrl.checkPattern(req, res) } });
|
||||||
|
|
||||||
// Returns the agent with most alerts
|
// Returns the agent with most alerts
|
||||||
server.route({ method: 'GET', path: '/api/wazuh-elastic/top/{mode}/{cluster}/{field}/{pattern}', handler: (req,res) => ctrl.getFieldTop(req,res) });
|
server.route({ method: 'GET', path: '/api/wazuh-elastic/top/{mode}/{cluster}/{field}/{pattern}', handler(req, res) { return ctrl.getFieldTop(req, res) } });
|
||||||
|
|
||||||
// Return Wazuh Appsetup info
|
// Return Wazuh Appsetup info
|
||||||
server.route({ method: 'GET', path: '/api/wazuh-elastic/setup', handler: (req,res) => ctrl.getSetupInfo(req,res) });
|
server.route({ method: 'GET', path: '/api/wazuh-elastic/setup', handler(req, res) { return ctrl.getSetupInfo(req, res) } });
|
||||||
|
|
||||||
// Useful to check cookie consistence
|
// Useful to check cookie consistence
|
||||||
server.route({ method: 'GET', path: '/api/wazuh-elastic/timestamp', handler: (req,res) => ctrl.getTimeStamp(req,res) });
|
server.route({ method: 'GET', path: '/api/wazuh-elastic/timestamp', handler(req, res) { return ctrl.getTimeStamp(req, res) } });
|
||||||
};
|
}
|
@ -11,18 +11,18 @@
|
|||||||
*/
|
*/
|
||||||
import { WazuhReportingCtrl } from '../controllers';
|
import { WazuhReportingCtrl } from '../controllers';
|
||||||
|
|
||||||
export default (server, options) => {
|
export function WazuhReportingRoutes(server) {
|
||||||
const ctrl = new WazuhReportingCtrl(server);
|
const ctrl = new WazuhReportingCtrl(server);
|
||||||
|
|
||||||
// Builds a PDF report from multiple PNG images
|
// Builds a PDF report from multiple PNG images
|
||||||
server.route({ method: 'POST', path: '/api/wazuh-reporting/report', handler: (req,res) => ctrl.report(req,res)});
|
server.route({ method: 'POST', path: '/api/wazuh-reporting/report', handler(req, res) { return ctrl.report(req, res) } });
|
||||||
|
|
||||||
// Fetch specific report
|
// Fetch specific report
|
||||||
server.route({ method: 'GET', path: '/api/wazuh-reporting/report/{name}', handler: (req,res) => ctrl.getReportByName(req,res)});
|
server.route({ method: 'GET', path: '/api/wazuh-reporting/report/{name}', handler(req, res) { return ctrl.getReportByName(req, res) } });
|
||||||
|
|
||||||
// Delete specific report
|
// Delete specific report
|
||||||
server.route({ method: 'DELETE', path: '/api/wazuh-reporting/report/{name}', handler: (req,res) => ctrl.deleteReportByName(req,res)});
|
server.route({ method: 'DELETE', path: '/api/wazuh-reporting/report/{name}', handler(req, res) { return ctrl.deleteReportByName(req, res) } });
|
||||||
|
|
||||||
// Fetch the reports list
|
// Fetch the reports list
|
||||||
server.route({ method: 'GET', path: '/api/wazuh-reporting/reports', handler: (req,res) => ctrl.getReports(req,res)});
|
server.route({ method: 'GET', path: '/api/wazuh-reporting/reports', handler(req, res) { return ctrl.getReports(req, res) } });
|
||||||
};
|
}
|
116
test/server/wazuh-api-elastic.js
Normal file
116
test/server/wazuh-api-elastic.js
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
const chai = require('chai');
|
||||||
|
const needle = require('needle')
|
||||||
|
|
||||||
|
chai.should();
|
||||||
|
|
||||||
|
const headers = {headers: {'kbn-xsrf': 'kibana', 'Content-Type': 'application/json'}}
|
||||||
|
|
||||||
|
let API_ID = null;
|
||||||
|
let API_PORT = null;
|
||||||
|
let API_URL = null;
|
||||||
|
let API_USER = null;
|
||||||
|
|
||||||
|
const EXAMPLE_API = {};
|
||||||
|
|
||||||
|
describe('wazuh-api-elastic', () => {
|
||||||
|
/*
|
||||||
|
|
||||||
|
// Save the given API into elasticsearch
|
||||||
|
server.route({ method: 'PUT', path: '/api/wazuh-api/settings', handler: (req,reply) => ctrl.saveAPI(req,reply) });
|
||||||
|
|
||||||
|
// Update the given API into elasticsearch
|
||||||
|
server.route({ method: 'PUT', path: '/api/wazuh-api/update-settings', handler: (req,reply) => ctrl.updateFullAPI(req,reply) });
|
||||||
|
|
||||||
|
// Get Wazuh-API entries list (Multimanager) from elasticsearch index
|
||||||
|
server.route({ method: 'GET', path: '/api/wazuh-api/apiEntries', handler: (req,reply) => ctrl.getAPIEntries(req,reply) });
|
||||||
|
|
||||||
|
// Delete Wazuh-API entry (multimanager) from elasticsearch index
|
||||||
|
server.route({ method: 'DELETE', path: '/api/wazuh-api/apiEntries/{id}', handler: (req,reply) => ctrl.deleteAPIEntries(req,reply) });
|
||||||
|
|
||||||
|
// Set Wazuh-API as default (multimanager) on elasticsearch index
|
||||||
|
server.route({ method: 'PUT', path: '/api/wazuh-api/apiEntries/{id}', handler: (req,reply) => ctrl.setAPIEntryDefault(req,reply) });
|
||||||
|
|
||||||
|
// Update the API hostname
|
||||||
|
server.route({ method: 'PUT', path: '/api/wazuh-api/updateApiHostname/{id}', handler: (req,reply) => ctrl.updateAPIHostname(req,reply) });
|
||||||
|
*/
|
||||||
|
before(async () => {
|
||||||
|
const res = await needle('get', `localhost:5601/api/wazuh-api/apiEntries`, {}, {});
|
||||||
|
if(!res.body || !res.body.length) {
|
||||||
|
console.log('There are no APIs stored in Elasticsearch, exiting...')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
API_ID = res.body[0]._id;
|
||||||
|
API_URL = res.body[0]._source.url;
|
||||||
|
API_PORT = res.body[0]._source.api_port;
|
||||||
|
API_USER = res.body[0]._source.api_user;
|
||||||
|
})
|
||||||
|
|
||||||
|
it('PUT /api/wazuh-api/settings', async () => {
|
||||||
|
const res = await needle('put', `localhost:5601/api/wazuh-api/settings`, {
|
||||||
|
user : 'foo',
|
||||||
|
password : 'bar',
|
||||||
|
url : 'http://localhost',
|
||||||
|
port : 55000,
|
||||||
|
insecure : true,
|
||||||
|
component : 'API',
|
||||||
|
active : true,
|
||||||
|
cluster_info: {},
|
||||||
|
extensions : {}
|
||||||
|
}, headers);
|
||||||
|
res.body.response.result.should.be.eql('created')
|
||||||
|
const removed = await needle('delete', `localhost:5601/api/wazuh-api/apiEntries/${res.body.response._id}`, {}, headers);
|
||||||
|
removed.body.result.should.be.eql('deleted')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('PUT /api/wazuh-api/update-settings', async () => {
|
||||||
|
const res = await needle('put', `localhost:5601/api/wazuh-api/settings`, {
|
||||||
|
user : 'foo',
|
||||||
|
password : 'bar',
|
||||||
|
url : 'http://localhost',
|
||||||
|
port : 55000,
|
||||||
|
insecure : true,
|
||||||
|
component : 'API',
|
||||||
|
active : true,
|
||||||
|
cluster_info: {},
|
||||||
|
extensions : {}
|
||||||
|
}, headers);
|
||||||
|
const updated = await needle('put', `localhost:5601/api/wazuh-api/update-settings`, {user: 'john', password: 'bar', url: 'http://0.0.0.0', port: 55000, id: res.body.response._id}, headers);
|
||||||
|
await needle('delete', `localhost:5601/api/wazuh-api/apiEntries/${res.body.response._id}`, {}, headers);
|
||||||
|
updated.body.statusCode.should.be.eql(200)
|
||||||
|
updated.body.message.should.be.eql('ok')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('GET /api/wazuh-api/apiEntries', async () => {
|
||||||
|
const res = await needle('get', `localhost:5601/api/wazuh-api/apiEntries`, {}, headers);
|
||||||
|
res.body.should.be.a('array')
|
||||||
|
res.body.length.should.be.gt(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('DELETE /api/wazuh-api/apiEntries/{id}', async () => {
|
||||||
|
const insert = await needle('put', `localhost:5601/api/wazuh-api/settings`, {
|
||||||
|
user : 'foo',
|
||||||
|
password : 'bar',
|
||||||
|
url : 'http://localhost',
|
||||||
|
port : 55000,
|
||||||
|
insecure : true,
|
||||||
|
component : 'API',
|
||||||
|
active : true,
|
||||||
|
cluster_info: {},
|
||||||
|
extensions : {}
|
||||||
|
}, headers);
|
||||||
|
const res = await needle('delete', `localhost:5601/api/wazuh-api/apiEntries/${insert.body.response._id}`, {}, headers);
|
||||||
|
res.body.result.should.be.eql('deleted')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('PUT /api/wazuh-api/apiEntries/{id}', async () => {
|
||||||
|
const res = await needle('put', `localhost:5601/api/wazuh-api/apiEntries/${API_ID}`, {}, headers);
|
||||||
|
res.body.statusCode.should.be.eql(200)
|
||||||
|
res.body.message.should.be.eql('ok')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('PUT /api/wazuh-api/updateApiHostname/{id}', async () => {
|
||||||
|
const res = await needle('put', `localhost:5601/api/wazuh-api/updateApiHostname/${API_ID}`, {}, headers);
|
||||||
|
res.body.statusCode.should.be.eql(200)
|
||||||
|
res.body.message.should.be.eql('ok')
|
||||||
|
})
|
||||||
|
})
|
108
test/server/wazuh-api.js
Normal file
108
test/server/wazuh-api.js
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
const chai = require('chai');
|
||||||
|
const needle = require('needle')
|
||||||
|
|
||||||
|
chai.should();
|
||||||
|
|
||||||
|
const headers = {headers: {'kbn-xsrf': 'kibana', 'Content-Type': 'application/json'}}
|
||||||
|
|
||||||
|
let API_ID = null;
|
||||||
|
let API_PORT = null;
|
||||||
|
let API_URL = null;
|
||||||
|
let API_USER = null;
|
||||||
|
|
||||||
|
describe('wazuh-api', () => {
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
const res = await needle('get', `localhost:5601/api/wazuh-api/apiEntries`, {}, {});
|
||||||
|
if(!res.body || !res.body.length) {
|
||||||
|
console.log('There are no APIs stored in Elasticsearch, exiting...')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
API_ID = res.body[0]._id;
|
||||||
|
API_URL = res.body[0]._source.url;
|
||||||
|
API_PORT = res.body[0]._source.api_port;
|
||||||
|
API_USER = res.body[0]._source.api_user;
|
||||||
|
})
|
||||||
|
|
||||||
|
it('POST /api/wazuh-api/csv', async () => {
|
||||||
|
const res = await needle('post', `localhost:5601/api/wazuh-api/csv`, {path:'/agents', id: API_ID}, headers);
|
||||||
|
res.body.should.be.a('string')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('POST /api/wazuh-api/checkAPI', async () => {
|
||||||
|
const res = await needle('post', `localhost:5601/api/wazuh-api/checkAPI`, {user:API_USER, url:API_URL, port:API_PORT, id:API_ID}, headers);
|
||||||
|
res.body.should.be.a('object')
|
||||||
|
res.body.manager.should.be.a('string')
|
||||||
|
res.body.cluster.should.be.a('string')
|
||||||
|
res.body.status.should.be.a('string')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('POST /api/wazuh-api/checkStoredAPI', async () => {
|
||||||
|
const res = await needle('post', `localhost:5601/api/wazuh-api/checkStoredAPI`, API_ID, headers);
|
||||||
|
res.body.should.be.a('object')
|
||||||
|
res.body.statusCode.should.be.eql(200)
|
||||||
|
res.body.data.should.be.a('object')
|
||||||
|
res.body.data.user.should.be.a('string')
|
||||||
|
res.body.data.password.should.be.a('string')
|
||||||
|
res.body.data.url.should.be.a('string')
|
||||||
|
res.body.data.port.should.be.a('string')
|
||||||
|
res.body.data.extensions.should.be.a('object')
|
||||||
|
res.body.data.cluster_info.should.be.a('object')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('POST /api/wazuh-api/request', async () => {
|
||||||
|
const res = await needle('post', `localhost:5601/api/wazuh-api/request`, {method:'GET', path:'/agents/000', body:{ }, id:API_ID }, headers);
|
||||||
|
res.body.should.be.a('object')
|
||||||
|
res.body.error.should.be.eql(0)
|
||||||
|
res.body.data.should.be.a('object')
|
||||||
|
res.body.data.status.should.be.eql('Active')
|
||||||
|
res.body.data.id.should.be.eql('000')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('GET /api/wazuh-api/pci/{requirement}', async () => {
|
||||||
|
const res = await needle('get', `localhost:5601/api/wazuh-api/pci/all`, {}, {});
|
||||||
|
res.body.should.be.a('object')
|
||||||
|
res.body['1.1.1'].should.be.eql('A formal process for approving and testing all network connections and changes to the firewall and router configurations')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('GET /api/wazuh-api/gdpr/{requirement}', async () => {
|
||||||
|
const res = await needle('get', `localhost:5601/api/wazuh-api/gdpr/all`, {}, {});
|
||||||
|
res.body.should.be.a('object')
|
||||||
|
res.body['II_5.1.f'].should.be.eql('Ensure the ongoing confidentiality, integrity, availability and resilience of processing systems and services, verifying its modifications, accesses, locations and guarantee the safety of them.<br>File sharing protection and file sharing technologies that meet the requirements of data protection.')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('GET /api/wazuh-api/configuration', async () => {
|
||||||
|
const res = await needle('get', `localhost:5601/api/wazuh-api/configuration`, {}, {});
|
||||||
|
res.body.should.be.a('object')
|
||||||
|
res.body.error.should.be.eql(0)
|
||||||
|
res.body.statusCode.should.be.eql(200)
|
||||||
|
res.body.data.should.be.a('object')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('GET /api/wazuh-api/ram', async () => {
|
||||||
|
const res = await needle('get', `localhost:5601/api/wazuh-api/ram`, {}, {});
|
||||||
|
res.body.should.be.a('object')
|
||||||
|
res.body.error.should.be.eql(0)
|
||||||
|
res.body.ram.should.be.gt(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('GET /api/wazuh-api/agents-unique/{api}', async () => {
|
||||||
|
const res = await needle('get', `localhost:5601/api/wazuh-api/agents-unique/${API_ID}`, {}, {});
|
||||||
|
res.body.should.be.a('object')
|
||||||
|
res.body.error.should.be.eql(0)
|
||||||
|
res.body.result.should.be.a('object')
|
||||||
|
res.body.result.groups.should.be.a('array')
|
||||||
|
res.body.result.nodes.should.be.a('array')
|
||||||
|
res.body.result.versions.should.be.a('array')
|
||||||
|
res.body.result.osPlatforms.should.be.a('array')
|
||||||
|
res.body.result.lastAgent.should.be.a('object')
|
||||||
|
res.body.result.summary.should.be.a('object')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('GET /api/wazuh-api/logs', async () => {
|
||||||
|
const res = await needle('get', `localhost:5601/api/wazuh-api/logs`, {}, {});
|
||||||
|
res.body.should.be.a('object')
|
||||||
|
res.body.lastLogs.should.be.a('array')
|
||||||
|
res.body.error.should.be.eql(0)
|
||||||
|
})
|
||||||
|
})
|
91
test/server/wazuh-elastic.js
Normal file
91
test/server/wazuh-elastic.js
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
const chai = require('chai');
|
||||||
|
const needle = require('needle')
|
||||||
|
|
||||||
|
chai.should();
|
||||||
|
|
||||||
|
const headers = {headers: {'kbn-xsrf': 'kibana', 'Content-Type': 'application/json'}}
|
||||||
|
|
||||||
|
describe('wazuh-elastic', () => {
|
||||||
|
|
||||||
|
describe('Checking index patterns', () => {
|
||||||
|
it('GET /get-list', async () => {
|
||||||
|
const res = await needle('get', `localhost:5601/get-list`, {}, headers);
|
||||||
|
res.body.data.should.be.a('array')
|
||||||
|
res.body.data.length.should.be.gt(0)
|
||||||
|
res.body.data[0].should.be.a('object')
|
||||||
|
res.body.data[0].id.should.be.a('string')
|
||||||
|
res.body.data[0].title.should.be.a('string')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('GET /refresh-fields/{pattern}', async () => {
|
||||||
|
const res = await needle('get', `localhost:5601/refresh-fields/wazuh-alerts-3.x-*`, {}, headers);
|
||||||
|
res.body.acknowledge.should.be.eql(true)
|
||||||
|
res.body.output.should.be.a('object')
|
||||||
|
res.body.output._index.should.be.eql('.kibana')
|
||||||
|
res.body.output._type.should.be.eql('doc')
|
||||||
|
res.body.output._id.should.be.eql('index-pattern:wazuh-alerts-3.x-*')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('Checking visualization composers', () => {
|
||||||
|
it('GET /api/wazuh-elastic/create-vis/{tab}/{pattern}', async () => {
|
||||||
|
const res = await needle('get', `localhost:5601/api/wazuh-elastic/create-vis/overview-general/wazuh-alerts-3.x-*`, {}, headers);
|
||||||
|
res.body.acknowledge.should.be.eql(true)
|
||||||
|
res.body.raw.should.be.a('array')
|
||||||
|
res.body.raw.length.should.be.eql(15)
|
||||||
|
res.body.raw[0].attributes.should.be.a('object')
|
||||||
|
res.body.raw[0].type.should.be.eql('visualization')
|
||||||
|
res.body.raw[0].id.should.be.a('string')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('POST /api/wazuh-elastic/create-vis/{tab}/{pattern}', async () => {
|
||||||
|
const res = await needle('post', `localhost:5601/api/wazuh-elastic/create-vis/cluster-monitoring/wazuh-alerts-3.x-*`, {nodes:{items:[],name:'node01'}}, headers);
|
||||||
|
res.body.acknowledge.should.be.eql(true)
|
||||||
|
res.body.raw.should.be.a('array')
|
||||||
|
res.body.raw.length.should.be.eql(4)
|
||||||
|
res.body.raw[0].attributes.should.be.a('object')
|
||||||
|
res.body.raw[0].type.should.be.eql('visualization')
|
||||||
|
res.body.raw[0].id.should.be.a('string')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('Checking template and index pattern existance', () => {
|
||||||
|
it('GET /api/wazuh-elastic/template/{pattern}', async () => {
|
||||||
|
const res = await needle('get', `localhost:5601/api/wazuh-elastic/template/wazuh-alerts-3.x-*`, {}, headers);
|
||||||
|
res.body.statusCode.should.be.eql(200)
|
||||||
|
res.body.status.should.be.eql(true)
|
||||||
|
res.body.data.should.be.eql('Template found for wazuh-alerts-3.x-*')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('GET /api/wazuh-elastic/pattern/{pattern}', async () => {
|
||||||
|
const res = await needle('get', `localhost:5601/api/wazuh-elastic/pattern/wazuh-alerts-3.x-*`, {}, headers);
|
||||||
|
res.body.statusCode.should.be.eql(200)
|
||||||
|
res.body.status.should.be.eql(true)
|
||||||
|
res.body.data.should.be.eql('Index pattern found')
|
||||||
|
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
/*it('GET /api/wazuh-elastic/top/{mode}/{cluster}/{field}/{pattern}', async () => {
|
||||||
|
throw Error('Test not implemented...')
|
||||||
|
})*/
|
||||||
|
|
||||||
|
describe('Checking .wazuh-version index', () => {
|
||||||
|
it('GET /api/wazuh-elastic/setup', async () => {
|
||||||
|
const res = await needle('get', `localhost:5601/api/wazuh-elastic/setup`, {}, headers);
|
||||||
|
res.body.statusCode.should.be.eql(200)
|
||||||
|
res.body.data.should.be.a('object')
|
||||||
|
res.body.data.name.should.be.eql('Wazuh App')
|
||||||
|
res.body.data['app-version'].should.be.eql('3.6.0')
|
||||||
|
res.body.data.revision.should.be.eql('0407')
|
||||||
|
res.body.data.installationDate.should.be.a('string')
|
||||||
|
res.body.data.lastRestart.should.be.a('string')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('GET /api/wazuh-elastic/timestamp', async () => {
|
||||||
|
const res = await needle('get', `localhost:5601/api/wazuh-elastic/timestamp`, {}, headers);
|
||||||
|
res.body.installationDate.should.be.a('string')
|
||||||
|
res.body.lastRestart.should.be.a('string')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* Find more information about this on the LICENSE file.
|
* Find more information about this on the LICENSE file.
|
||||||
*/
|
*/
|
||||||
export default config => {
|
export function getPath (config) {
|
||||||
let path = config.url;
|
let path = config.url;
|
||||||
let protocol;
|
let protocol;
|
||||||
if (config.url.startsWith("https://")) {
|
if (config.url.startsWith("https://")) {
|
||||||
@ -26,4 +26,4 @@ export default config => {
|
|||||||
path = `${config.url}:${config.port}`;
|
path = `${config.url}:${config.port}`;
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
};
|
}
|
Loading…
Reference in New Issue
Block a user