From 87827631174e1253fd06500b69fd2728aad25298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Tue, 12 Dec 2017 17:05:52 +0100 Subject: [PATCH 1/6] Fix search on autocomplete, added multiple filters --- public/controllers/ruleset.js | 134 +++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 57 deletions(-) diff --git a/public/controllers/ruleset.js b/public/controllers/ruleset.js index 12a9d9478..333835547 100644 --- a/public/controllers/ruleset.js +++ b/public/controllers/ruleset.js @@ -1,51 +1,59 @@ let app = require('ui/modules').get('app/wazuh', []); -app.controller('rulesController', function ($scope,$rootScope, Notifier, Rules) { +app.controller('rulesController', function ($scope,$q,$rootScope, Notifier, Rules,RulesAutoComplete) { $scope.setRulesTab = (tab) => $rootScope.globalsubmenuNavItem2 = tab; //Initialization const notify = new Notifier({ location: 'Manager - Rules' }); $scope.loading = true; $scope.rules = Rules; + $scope.rulesAutoComplete = RulesAutoComplete; $scope.setRulesTab('rules'); + + $scope.analizeRules = search => { + let deferred = $q.defer(); + + let promise; + $scope.rulesAutoComplete.filters = []; - $scope.analizeRules = (search) => { - $scope.autoComplete = []; - - if (search !== '') $scope.autoComplete.push({ - name: search, - type: 'search' - }); - - for(let element of $scope.rules.items){ - for(let pci of element.pci){ - $scope.autoComplete.push({ - name: pci, - type: 'pci' - }); - } - for(let group of element.groups){ - $scope.autoComplete.push({ - name: group, - type: 'group' - }); - } - $scope.autoComplete.push({ - name: element.file, - type: 'file' - }); + if(search.startsWith('group:') && search.split('group:')[1].trim()) { + promise = $scope.rulesAutoComplete.addFilter('group',search.split('group:')[1].trim()); + } else if(search.startsWith('level:') && search.split('level:')[1].trim()) { + promise = $scope.rulesAutoComplete.addFilter('level',search.split('level:')[1].trim()); + } else if(search.startsWith('pci:') && search.split('pci:')[1].trim()) { + promise = $scope.rulesAutoComplete.addFilter('pci',search.split('pci:')[1].trim()); + } else if(search.startsWith('file:') && search.split('file:')[1].trim()) { + promise = $scope.rulesAutoComplete.addFilter('file',search.split('file:')[1].trim()); + } else { + promise = $scope.rulesAutoComplete.addFilter('search',search); } - $scope.autoComplete = new Set($scope.autoComplete.map(e => JSON.stringify(e))); - $scope.autoComplete = Array.from($scope.autoComplete).map(e => JSON.parse(e)); + promise + .then(() => deferred.resolve($scope.rulesAutoComplete.items)) + .catch(error => notify.error(error)); + + return deferred.promise; + } + + $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()); + } }; + //Load try { $scope.rules.nextPage('') - .then(() => { - $scope.loading = false; - $scope.analizeRules(''); - }) + .then(() => $scope.rulesAutoComplete.nextPage('')) + .then(() => $scope.loading = false) .catch(error => notify.error(error.message)); } catch (e) { notify.error('Unexpected exception loading controller'); @@ -68,15 +76,16 @@ app.controller('rulesController', function ($scope,$rootScope, Notifier, Rules) $scope.$on('$destroy', () => $scope.rules.reset()); }); -app.controller('decodersController', function ($scope,$rootScope, $sce, Notifier, Decoders) { +app.controller('decodersController', function ($scope,$q, $rootScope, $sce, Notifier, Decoders,DecodersAutoComplete) { $scope.setRulesTab = (tab) => $rootScope.globalsubmenuNavItem2 = tab; //Initialization const notify = new Notifier({ location: 'Manager - Decoders' }); $scope.loading = true; $scope.decoders = Decoders; + $scope.decodersAutoComplete = DecodersAutoComplete; $scope.typeFilter = "all"; $scope.setRulesTab('decoders'); - + const colors = [ '#3F6833', '#967302', '#2F575E', '#99440A', '#58140C', '#052B51', '#511749', '#3F2B5B', //6 '#508642', '#CCA300', '#447EBC', '#C15C17', '#890F02', '#0A437C', '#6D1F62', '#584477', //2 @@ -87,25 +96,6 @@ app.controller('decodersController', function ($scope,$rootScope, $sce, Notifier '#E0F9D7', '#FCEACA', '#CFFAFF', '#F9E2D2', '#FCE2DE', '#BADFF4', '#F9D9F9', '#DEDAF7' //7 ]; - $scope.analizeDecoders = (search) => { - $scope.autoComplete = []; - if (search !== '') { - $scope.autoComplete.push({ - name: search, - type: 'search' - }); - } - - for(let element of $scope.decoders.items){ - $scope.autoComplete.push({ - name: element.file, - type: 'file' - }); - } - - $scope.autoComplete = new Set($scope.autoComplete.map(e => JSON.stringify(e))); - $scope.autoComplete = Array.from($scope.autoComplete).map(e => JSON.parse(e)); - }; let timesOpened = 0; let lastName = false; @@ -140,13 +130,43 @@ app.controller('decodersController', function ($scope,$rootScope, $sce, Notifier return $sce.trustAsHtml(coloredString); }; + + $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()); + } + }; + + $scope.analizeDecoders = search => { + let deferred = $q.defer(); + + let promise; + $scope.decodersAutoComplete.filters = []; + + if(search.startsWith('path:') && search.split('path:')[1].trim()) { + promise = $scope.decodersAutoComplete.addFilter('path',search.split('path:')[1].trim()); + } else if(search.startsWith('file:') && search.split('file:')[1].trim()) { + promise = $scope.decodersAutoComplete.addFilter('file',search.split('file:')[1].trim()); + } else { + promise = $scope.decodersAutoComplete.addFilter('search',search); + } + + promise + .then(() => deferred.resolve($scope.decodersAutoComplete.items)) + .catch(error => notify.error(error)); + + return deferred.promise; + } + //Load try { $scope.decoders.nextPage('') - .then(() => { - $scope.loading = false; - $scope.analizeDecoders(''); - }) + .then(() => $scope.decodersAutoComplete.nextPage()) + .then(() => $scope.loading = false) .catch(error => notify.error(error.message)); } catch (e) { notify.error('Unexpected exception loading controller'); From f1895ad49337ceedb3f1ff2c2e56807330562777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Tue, 12 Dec 2017 17:06:08 +0100 Subject: [PATCH 2/6] Added new directive to handle enter key event --- public/controllers/common/directives.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/public/controllers/common/directives.js b/public/controllers/common/directives.js index 3cf9bfdc9..6e67f00a0 100644 --- a/public/controllers/common/directives.js +++ b/public/controllers/common/directives.js @@ -12,6 +12,19 @@ app }, }; }) + .directive('myEnter', function () { + return function (scope, element, attrs) { + element.bind("keydown keypress", function (event) { + if(event.which === 13) { + scope.$apply(function (){ + scope.$eval(attrs.myEnter); + }); + + event.preventDefault(); + } + }); + }; + }) .directive('menuTop',function(){ return{ template: From 5588b1cc7e541162e96c3855bcc12f13f28c243f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Tue, 12 Dec 2017 17:06:38 +0100 Subject: [PATCH 3/6] Added two new factories, and a new directive to lazy loading on datahandler autocomplete situations --- public/controllers/common/factories.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/public/controllers/common/factories.js b/public/controllers/common/factories.js index c7c545a16..026909cc4 100644 --- a/public/controllers/common/factories.js +++ b/public/controllers/common/factories.js @@ -26,4 +26,21 @@ app .factory('Agents', agents) .factory('Logs', logs) .factory('Rules', rules) - .factory('Decoders', decoders); + .factory('RulesAutoComplete', rules) + .factory('Decoders', decoders) + .factory('DecodersAutoComplete', decoders) + .directive('lazyLoadData', function($compile) { + return { + link: (scope, el, attrs) => { + let now = new Date().getTime(); + let rep = angular.element(document.getElementsByClassName('md-virtual-repeat-scroller')); + rep.on('scroll', evt => { + if (rep[0].scrollTop + rep[0].offsetHeight >= rep[0].scrollHeight) + if (new Date().getTime() - now > 100) { + now = new Date().getTime(); + scope.$apply(() => scope.$eval(attrs.lazyLoadData)); + } + }); + } + }; + }); From 16ea3ee90823bb86110e296eaae039fecad61bff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Tue, 12 Dec 2017 17:07:02 +0100 Subject: [PATCH 4/6] More specific on removing filters --- public/services/dataHandler.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/public/services/dataHandler.js b/public/services/dataHandler.js index 9a3e297a3..3bf83f08d 100644 --- a/public/services/dataHandler.js +++ b/public/services/dataHandler.js @@ -84,17 +84,20 @@ app.factory('DataHandler', function ($q, apiReq) { addFilter (filterName, value) { this.removeFilter(filterName, false); + this.filters.push({ name: filterName, value: value }); - - this.search(); + return this.search(); } removeFilter (filterName, search) { - this.filters = this.filters.filter(filter => filterName !== filter.name); + if(search) this.filters = this.filters.filter(filter => filterName !== filter.name && filter.value !== search); + else this.filters = this.filters.filter(filter => filterName !== filter.name); + if (search) this.search(); + } delete (name, index) { @@ -106,6 +109,7 @@ app.factory('DataHandler', function ($q, apiReq) { } search () { + let deferred = $q.defer(); let requestData; this.end = false; this.busy = false; @@ -116,11 +120,13 @@ app.factory('DataHandler', function ($q, apiReq) { limit: this.initialBatch }; let isUnknown = false; + for(let filter of this.filters){ - if (filter.value !== '' && filter.value !== 'Unknown') requestData[filter.name] = filter.value; + if (filter.value !== '' && filter.value !== 'Unknown') requestData[filter.name] = filter.value; if (filter.value === 'Unknown') isUnknown = true; } + apiReq.request('GET', this.path, requestData) .then(data => { this.items = []; @@ -134,8 +140,11 @@ app.factory('DataHandler', function ($q, apiReq) { this.items = this.items.filter(item => typeof item.os === 'undefined'); } this.offset = items.length; + deferred.resolve(true); }) .catch(console.error); + + return deferred.promise; } sort(by) { From f0bd9380e69964a2d16adb8550d9d4b4b1db70e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Tue, 12 Dec 2017 17:07:14 +0100 Subject: [PATCH 5/6] Fix autocomplete --- public/templates/agents.head | 3 ++- public/templates/ruleset-decoders.html | 32 +++++++++++++++++++++----- public/templates/ruleset-rules.html | 26 ++++++++++++++++----- 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/public/templates/agents.head b/public/templates/agents.head index 8d253a1a3..8404a9d4c 100644 --- a/public/templates/agents.head +++ b/public/templates/agents.head @@ -19,7 +19,8 @@ - + {{agentAutoComplete.name}} ({{agentAutoComplete.id}}) diff --git a/public/templates/ruleset-decoders.html b/public/templates/ruleset-decoders.html index a2fc3c59f..93944f302 100644 --- a/public/templates/ruleset-decoders.html +++ b/public/templates/ruleset-decoders.html @@ -14,10 +14,27 @@
- + - {{decoder.name}} + {{decoder.name}} {{decoder.file}}
- - - Search: {{filter.name}} + + + Search: {{decoders.getFilter('search')}} - File: {{filter.name}} + File: {{decoders.getFilter('file')}} + + + Path: {{decoders.getFilter('path')}} diff --git a/public/templates/ruleset-rules.html b/public/templates/ruleset-rules.html index b34a7ff68..bc99295de 100644 --- a/public/templates/ruleset-rules.html +++ b/public/templates/ruleset-rules.html @@ -35,13 +35,27 @@
- + - {{rule.name}} + {{rule.file}} - {{rule.description}}
- + Search: {{rules.getFilter('search')}} From 1a5e20f5266ab3fc9af5603ac2b42c8f56e3f209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Tue, 12 Dec 2017 17:27:29 +0100 Subject: [PATCH 6/6] Fix autocomplete --- public/controllers/agents.js | 18 +++++++++++++++++- public/templates/agents.head | 14 +++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/public/controllers/agents.js b/public/controllers/agents.js index dfaee2f6a..083274b16 100644 --- a/public/controllers/agents.js +++ b/public/controllers/agents.js @@ -1,7 +1,7 @@ let app = require('ui/modules').get('app/wazuh', []); app.controller('agentsController', -function ($scope, $location, $rootScope, Notifier, appState, genericReq, apiReq, AgentsAutoComplete) { +function ($scope, $location, $q, $rootScope, Notifier, appState, genericReq, apiReq, AgentsAutoComplete) { $rootScope.page = 'agents'; $scope.extensions = appState.getExtensions().extensions; $scope.agentsAutoComplete = AgentsAutoComplete; @@ -165,6 +165,22 @@ function ($scope, $location, $rootScope, Notifier, appState, genericReq, apiReq, $location.path('/manager'); }; + + $scope.analizeAgents = search => { + let deferred = $q.defer(); + + let promise; + $scope.agentsAutoComplete.filters = []; + + promise = $scope.agentsAutoComplete.addFilter('search',search); + + promise + .then(() => deferred.resolve($scope.agentsAutoComplete.items)) + .catch(error => notify.error(error)); + + return deferred.promise; + } + //Load try { $scope.getAgent(); diff --git a/public/templates/agents.head b/public/templates/agents.head index 8404a9d4c..b3ec7cbf2 100644 --- a/public/templates/agents.head +++ b/public/templates/agents.head @@ -19,7 +19,19 @@
-