2018-04-22 20:16:38 +00:00
|
|
|
/*
|
|
|
|
* Wazuh app - Ruleset controllers
|
|
|
|
* Copyright (C) 2018 Wazuh, Inc.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* Find more information about this on the LICENSE file.
|
|
|
|
*/
|
2018-04-21 11:31:47 +00:00
|
|
|
import * as modules from 'ui/modules'
|
2018-04-30 09:18:21 +00:00
|
|
|
import CsvGenerator from './csv-generator'
|
2018-04-22 20:16:38 +00:00
|
|
|
|
2018-04-21 11:31:47 +00:00
|
|
|
const app = modules.get('app/wazuh', []);
|
2016-12-28 19:43:33 +00:00
|
|
|
|
2018-04-30 09:25:13 +00:00
|
|
|
app.controller('rulesController', function ($scope, $rootScope, Rules, RulesRelated, RulesAutoComplete, errorHandler, genericReq, appState, csvReq) {
|
2018-04-09 17:11:22 +00:00
|
|
|
|
2018-01-29 12:16:59 +00:00
|
|
|
$scope.setRulesTab = tab => $rootScope.globalsubmenuNavItem2 = tab;
|
2018-04-22 20:16:38 +00:00
|
|
|
|
2017-01-16 18:27:53 +00:00
|
|
|
//Initialization
|
2017-10-20 19:04:22 +00:00
|
|
|
$scope.loading = true;
|
2018-05-07 11:20:11 +00:00
|
|
|
$scope.viewingDetail = false;
|
2017-10-27 11:39:25 +00:00
|
|
|
$scope.rules = Rules;
|
2018-04-26 11:22:24 +00:00
|
|
|
$scope.rulesRelated = RulesRelated;
|
2018-01-29 11:37:29 +00:00
|
|
|
$scope.rulesAutoComplete = RulesAutoComplete;
|
2017-10-27 11:39:25 +00:00
|
|
|
$scope.setRulesTab('rules');
|
2018-04-24 18:00:42 +00:00
|
|
|
$scope.isArray = angular.isArray;
|
|
|
|
|
2018-05-07 11:20:11 +00:00
|
|
|
// Reloading watcher initialization
|
|
|
|
const reloadWatcher = $rootScope.$watch('rulesetIsReloaded',() => {
|
|
|
|
delete $rootScope.rulesetIsReloaded;
|
|
|
|
$scope.viewingDetail = false;
|
|
|
|
if(!$scope.$$phase) $scope.$digest();
|
|
|
|
});
|
|
|
|
|
2018-01-29 11:37:29 +00:00
|
|
|
$scope.analizeRules = async search => {
|
|
|
|
try {
|
|
|
|
$scope.rulesAutoComplete.filters = [];
|
2018-04-22 20:16:38 +00:00
|
|
|
|
2018-01-29 11:37:29 +00:00
|
|
|
if(search.startsWith('group:') && search.split('group:')[1].trim()) {
|
|
|
|
await $scope.rulesAutoComplete.addFilter('group',search.split('group:')[1].trim());
|
|
|
|
} else if(search.startsWith('level:') && search.split('level:')[1].trim()) {
|
|
|
|
await $scope.rulesAutoComplete.addFilter('level',search.split('level:')[1].trim());
|
|
|
|
} else if(search.startsWith('pci:') && search.split('pci:')[1].trim()) {
|
|
|
|
await $scope.rulesAutoComplete.addFilter('pci',search.split('pci:')[1].trim());
|
|
|
|
} else if(search.startsWith('file:') && search.split('file:')[1].trim()) {
|
|
|
|
await $scope.rulesAutoComplete.addFilter('file',search.split('file:')[1].trim());
|
|
|
|
} else {
|
|
|
|
await $scope.rulesAutoComplete.addFilter('search',search);
|
|
|
|
}
|
2018-04-22 20:16:38 +00:00
|
|
|
|
2018-01-29 11:37:29 +00:00
|
|
|
if(!$scope.$$phase) $scope.$digest();
|
|
|
|
return $scope.rulesAutoComplete.items;
|
|
|
|
} catch (error){
|
2018-01-29 14:39:21 +00:00
|
|
|
errorHandler.handle(error,'Ruleset');
|
2018-01-29 12:16:59 +00:00
|
|
|
if(!$rootScope.$$phase) $rootScope.$digest();
|
2017-10-27 11:39:25 +00:00
|
|
|
}
|
2017-12-12 16:05:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$scope.checkEnter = search => {
|
|
|
|
$scope.searchTerm = '';
|
|
|
|
angular.element(document.querySelector('#autocomplete')).blur();
|
|
|
|
if(search.startsWith('group:') && search.split('group:')[1].trim()) {
|
|
|
|
$scope.rules.addFilter('group',search.split('group:')[1].trim());
|
|
|
|
} else if(search.startsWith('level:') && search.split('level:')[1].trim()) {
|
|
|
|
$scope.rules.addFilter('level',search.split('level:')[1].trim());
|
|
|
|
} else if(search.startsWith('pci:') && search.split('pci:')[1].trim()) {
|
|
|
|
$scope.rules.addFilter('pci',search.split('pci:')[1].trim());
|
|
|
|
} else if(search.startsWith('file:') && search.split('file:')[1].trim()) {
|
|
|
|
$scope.rules.addFilter('file',search.split('file:')[1].trim());
|
2018-04-30 14:36:59 +00:00
|
|
|
} else if(search.startsWith('path:') && search.split('path:')[1].trim()) {
|
|
|
|
$scope.rules.addFilter('path',search.split('path:')[1].trim());
|
2018-01-15 15:33:12 +00:00
|
|
|
} else {
|
|
|
|
$scope.rules.addFilter('search',search.trim());
|
2017-12-12 16:05:52 +00:00
|
|
|
}
|
2016-11-03 19:52:52 +00:00
|
|
|
};
|
|
|
|
|
2018-04-30 09:18:21 +00:00
|
|
|
$scope.downloadCsv = async () => {
|
|
|
|
try {
|
|
|
|
const currentApi = JSON.parse(appState.getCurrentAPI()).id;
|
2018-04-30 11:18:54 +00:00
|
|
|
const output = await csvReq.fetch('/rules', currentApi, $scope.rules ? $scope.rules.filters : null);
|
2018-04-30 09:18:21 +00:00
|
|
|
const csvGenerator = new CsvGenerator(output.csv, 'rules.csv');
|
|
|
|
csvGenerator.download(true);
|
|
|
|
} catch (error) {
|
|
|
|
errorHandler.handle(error,'Download CSV');
|
|
|
|
if(!$rootScope.$$phase) $rootScope.$digest();
|
|
|
|
}
|
2018-04-23 17:15:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-04-30 14:36:59 +00:00
|
|
|
* This function takes back to the list but adding a filter from the detail view
|
2018-04-23 17:15:38 +00:00
|
|
|
*/
|
2018-04-30 14:36:59 +00:00
|
|
|
$scope.addDetailFilter = (name, value) => {
|
2018-04-30 13:55:02 +00:00
|
|
|
// Remove all previous filters and then add it
|
|
|
|
$scope.rules.removeAllFilters();
|
2018-04-30 14:36:59 +00:00
|
|
|
$scope.rules.addFilter(name, value);
|
2018-04-30 13:55:02 +00:00
|
|
|
|
2018-04-23 17:15:38 +00:00
|
|
|
// Clear the autocomplete component
|
|
|
|
$scope.searchTerm = '';
|
|
|
|
angular.element(document.querySelector('#autocomplete')).blur();
|
|
|
|
|
2018-04-30 13:55:02 +00:00
|
|
|
// Go back to the list
|
2018-04-23 17:15:38 +00:00
|
|
|
$scope.closeDetailView();
|
|
|
|
}
|
|
|
|
|
2018-04-23 15:01:00 +00:00
|
|
|
/**
|
2018-04-25 16:57:21 +00:00
|
|
|
* This function changes to the rule detail view
|
2018-04-23 15:01:00 +00:00
|
|
|
*/
|
|
|
|
$scope.openDetailView = (rule) => {
|
2018-04-30 13:55:02 +00:00
|
|
|
// Clear current rule variable and assign the new one
|
|
|
|
$scope.currentRule = false;
|
2018-04-23 15:01:00 +00:00
|
|
|
$scope.currentRule = rule;
|
2018-04-26 11:22:24 +00:00
|
|
|
|
2018-04-30 13:55:02 +00:00
|
|
|
// Create the related rules list, resetting it in first place
|
2018-04-26 11:22:24 +00:00
|
|
|
$scope.rulesRelated.reset();
|
|
|
|
$scope.rulesRelated.ruleID = $scope.currentRule.id;
|
|
|
|
$scope.rulesRelated.addFilter('file', $scope.currentRule.file);
|
|
|
|
|
2018-04-30 13:55:02 +00:00
|
|
|
// Enable the Detail view
|
2018-04-23 15:01:00 +00:00
|
|
|
$scope.viewingDetail = true;
|
2018-04-25 14:16:40 +00:00
|
|
|
if(!$scope.$$phase) $scope.$digest();
|
2018-04-23 15:01:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-04-25 16:57:21 +00:00
|
|
|
* This function changes to the rules list view
|
2018-04-23 15:01:00 +00:00
|
|
|
*/
|
|
|
|
$scope.closeDetailView = () => {
|
|
|
|
$scope.viewingDetail = false;
|
|
|
|
$scope.currentRule = false;
|
2018-04-26 11:22:24 +00:00
|
|
|
$scope.rulesRelated.reset();
|
2018-04-23 15:01:00 +00:00
|
|
|
if(!$scope.$$phase) $scope.$digest();
|
|
|
|
}
|
2017-12-12 16:05:52 +00:00
|
|
|
|
2018-01-29 11:37:29 +00:00
|
|
|
const load = async () => {
|
|
|
|
try {
|
|
|
|
await Promise.all([
|
|
|
|
$scope.rules.nextPage(),
|
|
|
|
$scope.rulesAutoComplete.nextPage()
|
|
|
|
]);
|
|
|
|
$scope.loading = false;
|
|
|
|
if(!$scope.$$phase) $scope.$digest();
|
|
|
|
return;
|
|
|
|
} catch (error) {
|
2018-01-29 14:39:21 +00:00
|
|
|
errorHandler.handle('Unexpected exception loading controller','Ruleset');
|
2018-01-29 12:16:59 +00:00
|
|
|
if(!$rootScope.$$phase) $rootScope.$digest();
|
2018-01-29 11:37:29 +00:00
|
|
|
}
|
2016-11-03 19:52:52 +00:00
|
|
|
}
|
2017-10-27 11:39:25 +00:00
|
|
|
|
2018-01-29 11:37:29 +00:00
|
|
|
//Load
|
|
|
|
load();
|
|
|
|
|
2016-11-03 19:52:52 +00:00
|
|
|
//Destroy
|
2018-01-08 16:12:06 +00:00
|
|
|
$scope.$on('$destroy', () => {
|
|
|
|
$scope.rules.reset();
|
2018-04-30 13:55:02 +00:00
|
|
|
$scope.rulesRelated.reset();
|
2018-04-25 16:57:21 +00:00
|
|
|
$scope.rulesAutoComplete.reset();
|
2018-05-07 11:20:11 +00:00
|
|
|
reloadWatcher();
|
2018-01-08 16:12:06 +00:00
|
|
|
});
|
2016-11-03 19:52:52 +00:00
|
|
|
});
|
|
|
|
|
2018-04-30 09:25:13 +00:00
|
|
|
app.controller('decodersController', function ($scope, $rootScope, $sce, Decoders, DecodersRelated, DecodersAutoComplete, errorHandler, genericReq, appState, csvReq) {
|
2018-01-29 11:37:29 +00:00
|
|
|
$scope.setRulesTab = tab => $rootScope.globalsubmenuNavItem2 = tab;
|
2018-04-22 20:16:38 +00:00
|
|
|
|
2017-01-16 18:27:53 +00:00
|
|
|
//Initialization
|
2017-10-27 11:39:25 +00:00
|
|
|
$scope.loading = true;
|
2018-05-07 11:20:11 +00:00
|
|
|
$scope.viewingDetail = false;
|
2017-10-20 19:04:22 +00:00
|
|
|
$scope.decoders = Decoders;
|
2018-04-25 16:57:21 +00:00
|
|
|
$scope.decodersRelated = DecodersRelated;
|
2017-12-12 16:05:52 +00:00
|
|
|
$scope.decodersAutoComplete = DecodersAutoComplete;
|
2017-11-20 11:13:37 +00:00
|
|
|
$scope.typeFilter = "all";
|
2017-10-27 11:39:25 +00:00
|
|
|
$scope.setRulesTab('decoders');
|
2018-04-24 18:00:42 +00:00
|
|
|
$scope.isArray = angular.isArray;
|
|
|
|
|
|
|
|
const colors = [
|
|
|
|
'#3F6833', '#967302', '#2F575E', '#99440A', '#58140C', '#052B51', '#511749', '#3F2B5B', //6
|
|
|
|
'#508642', '#CCA300', '#447EBC', '#C15C17', '#890F02', '#0A437C', '#6D1F62', '#584477', //2
|
|
|
|
'#629E51', '#E5AC0E', '#64B0C8', '#E0752D', '#BF1B00', '#0A50A1', '#962D82', '#614D93', //4
|
|
|
|
'#7EB26D', '#EAB839', '#6ED0E0', '#EF843C', '#E24D42', '#1F78C1', '#BA43A9', '#705DA0', // Normal
|
|
|
|
'#9AC48A', '#F2C96D', '#65C5DB', '#F9934E', '#EA6460', '#5195CE', '#D683CE', '#806EB7', //5
|
|
|
|
'#B7DBAB', '#F4D598', '#70DBED', '#F9BA8F', '#F29191', '#82B5D8', '#E5A8E2', '#AEA2E0', //3
|
|
|
|
'#E0F9D7', '#FCEACA', '#CFFAFF', '#F9E2D2', '#FCE2DE', '#BADFF4', '#F9D9F9', '#DEDAF7' //7
|
|
|
|
];
|
|
|
|
|
2018-05-07 11:20:11 +00:00
|
|
|
// Reloading watcher initialization
|
|
|
|
const reloadWatcher = $rootScope.$watch('rulesetIsReloaded',() => {
|
|
|
|
delete $rootScope.rulesetIsReloaded;
|
|
|
|
$scope.viewingDetail = false;
|
|
|
|
if(!$scope.$$phase) $scope.$digest();
|
|
|
|
});
|
|
|
|
|
2018-04-24 18:00:42 +00:00
|
|
|
$scope.colorRegex = regex => {
|
|
|
|
regex = regex.toString();
|
|
|
|
let valuesArray = regex.match(/\(((?!<\/span>).)*?\)(?!<\/span>)/gmi);
|
|
|
|
let coloredString = regex;
|
|
|
|
for (let i = 0, len = valuesArray.length; i < len; i++) {
|
|
|
|
coloredString = coloredString.replace(/\(((?!<\/span>).)*?\)(?!<\/span>)/mi, '<span style="color: ' + colors[i] + ' ">' + valuesArray[i] + '</span>');
|
|
|
|
}
|
|
|
|
return $sce.trustAsHtml(coloredString);
|
|
|
|
};
|
|
|
|
|
|
|
|
$scope.colorOrder = order => {
|
|
|
|
order = order.toString();
|
|
|
|
let valuesArray = order.split(',');
|
|
|
|
let coloredString = order;
|
|
|
|
for (let i = 0, len = valuesArray.length; i < len; i++) {
|
|
|
|
coloredString = coloredString.replace(valuesArray[i], '<span style="color: ' + colors[i] + ' ">' + valuesArray[i] + '</span>');
|
|
|
|
}
|
|
|
|
return $sce.trustAsHtml(coloredString);
|
|
|
|
};
|
2016-11-03 19:52:52 +00:00
|
|
|
|
2017-12-12 16:05:52 +00:00
|
|
|
$scope.checkEnter = search => {
|
|
|
|
$scope.searchTerm = '';
|
|
|
|
angular.element(document.querySelector('#autocomplete')).blur();
|
|
|
|
if(search.startsWith('path:') && search.split('path:')[1].trim()) {
|
|
|
|
$scope.decoders.addFilter('path',search.split('path:')[1].trim());
|
|
|
|
} else if(search.startsWith('file:') && search.split('file:')[1].trim()) {
|
|
|
|
$scope.decoders.addFilter('file',search.split('file:')[1].trim());
|
2018-01-15 15:33:12 +00:00
|
|
|
} else {
|
|
|
|
$scope.decoders.addFilter('search',search.trim());
|
2017-12-12 16:05:52 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-01-29 11:37:29 +00:00
|
|
|
$scope.analizeDecoders = async search => {
|
|
|
|
try {
|
|
|
|
$scope.decodersAutoComplete.filters = [];
|
2018-04-22 20:16:38 +00:00
|
|
|
|
2018-01-29 11:37:29 +00:00
|
|
|
if(search.startsWith('path:') && search.split('path:')[1].trim()) {
|
|
|
|
await $scope.decodersAutoComplete.addFilter('path',search.split('path:')[1].trim());
|
|
|
|
} else if(search.startsWith('file:') && search.split('file:')[1].trim()) {
|
|
|
|
await $scope.decodersAutoComplete.addFilter('file',search.split('file:')[1].trim());
|
|
|
|
} else {
|
|
|
|
await $scope.decodersAutoComplete.addFilter('search',search);
|
|
|
|
}
|
2018-04-22 20:16:38 +00:00
|
|
|
|
2018-01-29 11:37:29 +00:00
|
|
|
if(!$scope.$$phase) $scope.$digest();
|
|
|
|
return $scope.decodersAutoComplete.items;
|
|
|
|
} catch (error){
|
2018-01-29 14:39:21 +00:00
|
|
|
errorHandler.handle(error,'Ruleset');
|
2018-01-29 12:16:59 +00:00
|
|
|
if(!$rootScope.$$phase) $rootScope.$digest();
|
2017-12-12 16:05:52 +00:00
|
|
|
}
|
2018-01-29 11:37:29 +00:00
|
|
|
}
|
2017-12-12 16:05:52 +00:00
|
|
|
|
2018-04-30 09:18:21 +00:00
|
|
|
$scope.downloadCsv = async () => {
|
|
|
|
try {
|
|
|
|
const currentApi = JSON.parse(appState.getCurrentAPI()).id;
|
2018-04-30 11:18:54 +00:00
|
|
|
const output = await csvReq.fetch('/decoders', currentApi, $scope.decoders ? $scope.decoders.filters : null);
|
2018-04-30 09:18:21 +00:00
|
|
|
const csvGenerator = new CsvGenerator(output.csv, 'decoders.csv');
|
|
|
|
csvGenerator.download(true);
|
|
|
|
} catch (error) {
|
|
|
|
errorHandler.handle(error,'Download CSV');
|
|
|
|
if(!$rootScope.$$phase) $rootScope.$digest();
|
|
|
|
}
|
|
|
|
}
|
2018-04-30 11:18:54 +00:00
|
|
|
|
2018-04-30 14:36:59 +00:00
|
|
|
/**
|
|
|
|
* This function takes back to the list but adding a filter from the detail view
|
|
|
|
*/
|
|
|
|
$scope.addDetailFilter = (name, value) => {
|
|
|
|
// Remove all previous filters and then add it
|
|
|
|
$scope.decoders.removeAllFilters();
|
|
|
|
$scope.decoders.addFilter(name, value);
|
|
|
|
|
|
|
|
// Clear the autocomplete component
|
|
|
|
$scope.searchTerm = '';
|
|
|
|
angular.element(document.querySelector('#autocomplete')).blur();
|
|
|
|
|
|
|
|
// Go back to the list
|
|
|
|
$scope.closeDetailView();
|
|
|
|
}
|
|
|
|
|
2018-04-23 15:01:00 +00:00
|
|
|
/**
|
2018-04-25 16:57:21 +00:00
|
|
|
* This function changes to the decoder detail view
|
2018-04-23 15:01:00 +00:00
|
|
|
*/
|
|
|
|
$scope.openDetailView = (decoder) => {
|
2018-04-30 13:55:02 +00:00
|
|
|
// Clear current decoder variable and assign the new one
|
|
|
|
$scope.currentDecoder = false;
|
2018-04-23 15:01:00 +00:00
|
|
|
$scope.currentDecoder = decoder;
|
2018-04-26 09:13:46 +00:00
|
|
|
|
2018-04-30 13:55:02 +00:00
|
|
|
// Create the related decoders list, resetting it in first place
|
2018-04-25 16:57:21 +00:00
|
|
|
$scope.decodersRelated.reset();
|
|
|
|
$scope.decodersRelated.path = `/decoders/${$scope.currentDecoder.name}`;
|
2018-04-26 09:13:46 +00:00
|
|
|
$scope.decodersRelated.decoderPosition = $scope.currentDecoder.position;
|
2018-04-25 16:57:21 +00:00
|
|
|
$scope.decodersRelated.nextPage('');
|
2018-04-26 09:13:46 +00:00
|
|
|
|
2018-04-30 13:55:02 +00:00
|
|
|
// Enable the Detail view
|
2018-04-23 15:01:00 +00:00
|
|
|
$scope.viewingDetail = true;
|
2018-04-25 14:16:40 +00:00
|
|
|
if(!$scope.$$phase) $scope.$digest();
|
2018-04-23 15:01:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-04-25 16:57:21 +00:00
|
|
|
* This function changes to the decoders list view
|
2018-04-23 15:01:00 +00:00
|
|
|
*/
|
|
|
|
$scope.closeDetailView = () => {
|
|
|
|
$scope.viewingDetail = false;
|
|
|
|
$scope.currentDecoder = false;
|
2018-04-26 11:22:24 +00:00
|
|
|
$scope.decodersRelated.reset();
|
2018-04-23 15:01:00 +00:00
|
|
|
if(!$scope.$$phase) $scope.$digest();
|
|
|
|
}
|
|
|
|
|
2018-01-29 11:37:29 +00:00
|
|
|
const load = async () => {
|
|
|
|
try {
|
|
|
|
await Promise.all([
|
|
|
|
$scope.decoders.nextPage(),
|
|
|
|
$scope.decodersAutoComplete.nextPage()
|
|
|
|
]);
|
2018-04-09 17:11:22 +00:00
|
|
|
|
2018-01-29 11:37:29 +00:00
|
|
|
$scope.loading = false;
|
|
|
|
if(!$scope.$$phase) $scope.$digest();
|
|
|
|
return;
|
|
|
|
} catch (error) {
|
2018-04-09 17:11:22 +00:00
|
|
|
errorHandler.handle(error,'Ruleset');
|
2018-01-29 12:16:59 +00:00
|
|
|
if(!$rootScope.$$phase) $rootScope.$digest();
|
2018-01-29 11:37:29 +00:00
|
|
|
}
|
2017-12-12 16:05:52 +00:00
|
|
|
}
|
|
|
|
|
2016-11-03 19:52:52 +00:00
|
|
|
//Load
|
2018-01-29 11:37:29 +00:00
|
|
|
load();
|
2017-10-27 11:39:25 +00:00
|
|
|
|
2016-11-03 19:52:52 +00:00
|
|
|
//Destroy
|
2018-01-08 16:12:06 +00:00
|
|
|
$scope.$on("$destroy", () => {
|
|
|
|
$scope.decoders.reset();
|
2018-04-25 16:57:21 +00:00
|
|
|
$scope.decodersRelated.reset();
|
|
|
|
$scope.decodersAutoComplete.reset();
|
2018-05-07 11:20:11 +00:00
|
|
|
reloadWatcher();
|
2018-01-08 16:12:06 +00:00
|
|
|
});
|
2018-04-22 20:16:38 +00:00
|
|
|
});
|