From 8f2c371312f6ff375dc242fe340622adbd839e39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Mon, 30 Apr 2018 15:27:07 +0200 Subject: [PATCH 01/19] Removed unused route and its own function --- server/controllers/wazuh-api.js | 14 -------------- server/routes/wazuh-api.js | 3 --- 2 files changed, 17 deletions(-) diff --git a/server/controllers/wazuh-api.js b/server/controllers/wazuh-api.js index e8bac60243..c3b82bf38f 100644 --- a/server/controllers/wazuh-api.js +++ b/server/controllers/wazuh-api.js @@ -436,20 +436,6 @@ export default class WazuhApi { } } - postErrorLog (req, reply) { - - if (!req.payload.message) { - - return reply({ - 'statusCode': 500, - 'message': 'You must provide at least one error message to log' - }); - - } else { - return reply({ statusCode: 200, message: 'Error logged succesfully' }); - } - } - getConfigurationFile (req,reply) { try{ const configFile = yml.load(fs.readFileSync(path.join(__dirname,'../../config.yml'), {encoding: 'utf-8'})); diff --git a/server/routes/wazuh-api.js b/server/routes/wazuh-api.js index 731d7f7fc0..79167a7ffe 100644 --- a/server/routes/wazuh-api.js +++ b/server/routes/wazuh-api.js @@ -30,9 +30,6 @@ export default (server, options) => { // Return a PCI requirement description server.route({ method: 'GET', path: '/api/wazuh-api/pci/{requirement}', handler: (req,res) => ctrl.getPciRequirement(req,res) }); - // Write in debug log - server.route({ method: 'POST', path: '/api/wazuh/errlog', handler: (req,res) => ctrl.postErrorLog(req,res) }); - // COMMENT HERE server.route({ method: 'GET', path: '/api/wazuh-api/fetchAgents', handler: (req,res) => ctrl.fetchAgents(req,res) }); From 796572beb0825a1ff94ad5c9b56183c5eaa1f19b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Mon, 30 Apr 2018 15:27:07 +0200 Subject: [PATCH 02/19] Added new generic error response --- server/controllers/error-response.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 server/controllers/error-response.js diff --git a/server/controllers/error-response.js b/server/controllers/error-response.js new file mode 100644 index 0000000000..531de5a6c3 --- /dev/null +++ b/server/controllers/error-response.js @@ -0,0 +1,27 @@ +/* + * Wazuh app - Generic error response constructor + * 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. + */ + +/** + * Error codes: + * wazuh-api-elastic 20XX + * wazuh-api 30XX + * wazuh-elastic 40XX + * unknown 1000 + */ +export default (message = null, code = null, statusCode = null, res) => { + return res({ + message: typeof message === 'string' ? `${code ? code : 1000} - ${message}` : `${code ? code : 1000} - Unexpected error`, + code : code ? code : 1000, + statusCode: statusCode ? statusCode : 500 + }) + .code(statusCode ? statusCode : 500); +} \ No newline at end of file From 31f472028da192769552f450bfe2d046fb6ec430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Mon, 30 Apr 2018 16:23:49 +0200 Subject: [PATCH 03/19] Sanitized error responses from wazuh-api-elastic routes --- server/controllers/wazuh-api-elastic.js | 63 +++++++------------------ 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/server/controllers/wazuh-api-elastic.js b/server/controllers/wazuh-api-elastic.js index b1d188b2c0..44c4bfdfbb 100644 --- a/server/controllers/wazuh-api-elastic.js +++ b/server/controllers/wazuh-api-elastic.js @@ -11,6 +11,7 @@ */ import ElasticWrapper from '../lib/elastic-wrapper'; +import ErrorResponse from './error-response'; const userRegEx = new RegExp(/^.{3,100}$/); const passRegEx = new RegExp(/^.{3,100}$/); @@ -30,7 +31,7 @@ export default class WazuhApiElastic { return reply(data.hits.hits); } catch(error){ - return reply(error); + return ErrorResponse(error.message || error, 2001, 500, reply); } } @@ -41,7 +42,7 @@ export default class WazuhApiElastic { return reply(data); } catch(error){ - return reply(error); + return ErrorResponse(error.message || error, 2002, 500, reply); } } @@ -57,14 +58,10 @@ export default class WazuhApiElastic { await this.wzWrapper.updateWazuhIndexDocument(req.params.id, { doc: { active: 'true' } }); - return reply({ statusCode: 200, message: 'ok' }); + return reply({ statusCode: 200, message: 'ok' }); }catch(error){ - return reply({ - statusCode: 500, - error : 8, - message : `Could not save data in elasticsearch due to ${error.message || error}` - }).code(500); + return ErrorResponse(`Could not save data in elasticsearch due to ${error.message || error}`, 2003, 500, reply); } } @@ -75,7 +72,7 @@ export default class WazuhApiElastic { return reply(data.hits.hits); } catch(error){ - return reply(error); + return ErrorResponse(error.message || error, 2004, 500, reply); } } @@ -90,34 +87,30 @@ export default class WazuhApiElastic { return reply({ statusCode: 200, message: 'ok' }); } catch (error){ - return reply({ - statusCode: 500, - error : 8, - message : `Could not save data in elasticsearch due to ${error.message || error}` - }).code(500); + return ErrorResponse(`Could not save data in elasticsearch due to ${error.message || error}`, 2005, 500, reply); } } validateData (payload) { // Validate user if(!userRegEx.test(payload.user)){ - return reply({ statusCode: 400, error: 10001, message: 'Invalid user field' }).code(400); + return { code: 2006, message: 'Invalid user field' } } // Validate password if(!passRegEx.test(payload.password)){ - return reply({ statusCode: 400, error: 10002, message: 'Invalid password field' }).code(400); + return { code: 2007, message: 'Invalid password field' } } // Validate url if(!urlRegEx.test(payload.url) && !urlRegExIP.test(payload.url)){ - return reply({ statusCode: 400, error: 10003, message: 'Invalid url field' }).code(400); + return { code: 2008, message: 'Invalid url field' } } // Validate port const validatePort = parseInt(payload.port); if(!portRegEx.test(payload.port) || validatePort <= 0 || validatePort >= 99999) { - return reply({ statusCode: 400, error: 10004, message: 'Invalid port field' }).code(400); + return { code: 2009, message: 'Invalid port field' } } return false; @@ -140,15 +133,11 @@ export default class WazuhApiElastic { async saveAPI (req, reply) { try { if (!('user' in req.payload) || !('password' in req.payload) || !('url' in req.payload) || !('port' in req.payload)) { - return reply({ - statusCode: 400, - error : 7, - message : 'Missing data' - }).code(400); + return ErrorResponse('Missing data', 2010, 400, reply); } const valid = this.validateData(req.payload); - if(valid) return reply(valid).code(400); + if(valid) return ErrorResponse(valid.message, valid.code, 400, reply); const settings = this.buildSettingsObject(req.payload); @@ -157,11 +146,7 @@ export default class WazuhApiElastic { return reply({ statusCode: 200, message: 'ok', response }); } catch (error){ - return reply({ - statusCode: 500, - error : 8, - message : `Could not save data in elasticsearch due to ${error.message || error}` - }).code(500); + return ErrorResponse(`Could not save data in elasticsearch due to ${error.message || error}`, 2011, 500, reply); } } @@ -173,26 +158,18 @@ export default class WazuhApiElastic { return reply({ statusCode: 200, message: 'ok' }); } catch (error) { - return reply({ - statusCode: 500, - error : 8, - message : `Could not save data in elasticsearch due to ${error.message || error}` - }).code(500); + return ErrorResponse(`Could not save data in elasticsearch due to ${error.message || error}`, 2012, 500, reply); } } async updateFullAPI (req, reply) { try { if (!('user' in req.payload) || !('password' in req.payload) || !('url' in req.payload) || !('port' in req.payload)) { - return reply({ - statusCode: 400, - error : 7, - message : 'Missing data' - }).code(400); + return ErrorResponse('Missing data', 2013, 400, reply); } const valid = this.validateData(req.payload); - if(valid) return reply(valid).code(400); + if(valid) return ErrorResponse(valid.message, valid.code, 400, reply); const settings = this.buildSettingsObject(req.payload); @@ -201,11 +178,7 @@ export default class WazuhApiElastic { return reply({ statusCode: 200, message: 'ok' }); } catch (error) { - return reply({ - statusCode: 500, - error : 8, - message : `Could not save data in elasticsearch due to ${error.message || error}` - }).code(500); + return ErrorResponse(`Could not save data in elasticsearch due to ${error.message || error}`, 2014, 500, reply); } } } From 6c07969befe66feb4b2a608eb8d7312a7da1d901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Mon, 30 Apr 2018 16:24:19 +0200 Subject: [PATCH 04/19] Removed unused route and its own function --- server/controllers/wazuh-api.js | 69 ++++----------------------------- server/routes/wazuh-api.js | 3 -- 2 files changed, 7 insertions(+), 65 deletions(-) diff --git a/server/controllers/wazuh-api.js b/server/controllers/wazuh-api.js index c3b82bf38f..2a2778efe3 100644 --- a/server/controllers/wazuh-api.js +++ b/server/controllers/wazuh-api.js @@ -293,32 +293,6 @@ export default class WazuhApi { } - errorControl(error, response) { - if (error) { - return { - isError: true, - body: { - statusCode : 500, - error : 5, - message : 'Request error', - errorMessage: error.message || error - } - }; - } else if (!error && response.body.error) { - return { - isError: true, - body: { - statusCode: 500, - error : 6, - message : 'Wazuh api error', - errorData : response.body - } - }; - } - - return ({ isError: false }); - } - async makeRequest (method, path, data, id, reply) { try { const wapi_config = await this.wzWrapper.getWazuhConfigurationById(id); @@ -355,14 +329,15 @@ export default class WazuhApi { const fullUrl = getPath(wapi_config) + path; const response = await needle(method, fullUrl, data, options); - const errorData = this.errorControl(false, response); - if (errorData.isError) { - return reply(errorData.body).code(500); + if(response && response.body && !response.body.error && response.body.data) { + return reply(response.body) } - return reply(response.body); - + throw response && response.body && response.body.error && response.body.message ? + new Error(response.body.message) : + new Error('Unexpected error fetching data from the Wazuh API') + } catch (error) { return reply({ statusCode: 500, @@ -390,32 +365,6 @@ export default class WazuhApi { } } - async getApiSettings (req, reply) { - try{ - if(!protectedRoute(req)) return reply(this.genericErrorBuilder(401,7,'Session expired.')).code(401); - - const wapi_config = await this.wzWrapper.getWazuhConfigurationById(req.payload.id); - - if (wapi_config.error_code > 1) { - throw new Error('no_elasticsearch'); - } else if (wapi_config.error_code > 0) { - throw new Error('no_credentials'); - } - return reply({ - statusCode: 200, - data : '' - }); - - } catch(error){ - return reply({ - statusCode: 200, - error : '1', - data : error.message || error - }); - } - - }; - // Fetch agent status and insert it directly on demand async fetchAgents (req, reply) { try{ @@ -428,11 +377,7 @@ export default class WazuhApi { output }); } catch(error){ - return reply({ - statusCode: 200, - error : '1', - data : error.message || error - }); + return reply(this.genericErrorBuilder(500,6,error.message || error)).code(500) } } diff --git a/server/routes/wazuh-api.js b/server/routes/wazuh-api.js index 79167a7ffe..612bf56288 100644 --- a/server/routes/wazuh-api.js +++ b/server/routes/wazuh-api.js @@ -24,9 +24,6 @@ export default (server, options) => { // Returns the request result (With error control) server.route({ method: 'POST', path: '/api/wazuh-api/request', handler: (req,res) => ctrl.requestApi(req,res) }); - // Get Wazuh-API settings from elasticsearch index - server.route({ method: 'GET', path: '/api/wazuh-api/settings', handler: (req,res) => ctrl.getApiSettings(req,res) }); - // Return a PCI requirement description server.route({ method: 'GET', path: '/api/wazuh-api/pci/{requirement}', handler: (req,res) => ctrl.getPciRequirement(req,res) }); From c6404a00b6e5a7edfd87b5638598cda32331c573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Mon, 30 Apr 2018 17:12:55 +0200 Subject: [PATCH 05/19] Sanitized wazuh-api error responses --- server/controllers/wazuh-api.js | 131 ++++++++++++-------------------- 1 file changed, 47 insertions(+), 84 deletions(-) diff --git a/server/controllers/wazuh-api.js b/server/controllers/wazuh-api.js index 2a2778efe3..365ab78223 100644 --- a/server/controllers/wazuh-api.js +++ b/server/controllers/wazuh-api.js @@ -21,6 +21,7 @@ import ElasticWrapper from '../lib/elastic-wrapper' import getPath from '../../util/get-path' import packageInfo from '../../package.json' import monitoring from '../monitoring' +import ErrorResponse from './error-response' const blueWazuh = colors.blue('wazuh'); @@ -32,17 +33,16 @@ export default class WazuhApi { async checkStoredAPI (req, reply) { try{ - if(!protectedRoute(req)) return reply(this.genericErrorBuilder(401,7,'Session expired.')).code(401); + if(!protectedRoute(req)) return ErrorResponse('Session expired', 3001, 401, reply); // Get config from elasticsearch const wapi_config = await this.wzWrapper.getWazuhConfigurationById(req.payload) if (wapi_config.error_code > 1) { // Can not connect to elasticsearch - return reply({ statusCode: 200, error: '1', data: 'no_elasticsearch' }); - + throw new Error(`Could not connect with elasticsearch, maybe it's down.`) } else if (wapi_config.error_code > 0) { // Credentials not found - return reply({ statusCode: 400, error: '2', data: 'no_credentials' }); + throw new Error('Valid credentials not found in elasticsearch. It seems the credentials were not saved.') } let response = await needle('get', `${wapi_config.url}:${wapi_config.port}/version`, {}, { @@ -80,11 +80,11 @@ export default class WazuhApi { return reply({ statusCode: 200, data: wapi_config }); } else if (response.body.error){ - return reply({ - statusCode: 500, - error : 7, - message : response.body.message - }).code(500); + const tmpMsg = response && response.body && response.body.message ? + response.body.message : + 'Unexpected error from /cluster/node'; + + throw new Error(tmpMsg) } } else { // Cluster mode is not active @@ -95,73 +95,58 @@ export default class WazuhApi { wapi_config.cluster_info.cluster = 'Disabled'; wapi_config.cluster_info.manager = managerName; wapi_config.password = '****' - return reply({ statusCode: 200, data: wapi_config }); + return reply({ statusCode: 200, data: wapi_config }); } + } else { - return reply({ - statusCode: 500, - error : 5, - message : 'Error occurred' - }).code(500); + const tmpMsg = response && response.body && response.body.message ? + response.body.message : + 'Unexpected error from /cluster/status'; + + throw new Error(tmpMsg) } } else { - return reply({ - statusCode: 500, - error : 7, - message : response.body - }); + throw new Error(`${wapi_config.url}:${wapi_config.port}/version is unreachable`) } } catch(error){ if(error.code === 'ECONNREFUSED'){ return reply({ statusCode: 200, data: {password: '****', apiIsDown: true } }); } else { - return reply({ - statusCode: 500, - error : 8, - message : error.message || error - }); + return ErrorResponse(error.message || error, 3002, 500, reply); } } } validateCheckApiParams (payload) { if (!('user' in payload)) { - return this.genericErrorBuilder(400,3,'Missing param: API USER'); + return 'Missing param: API USER'; } if (!('password' in payload)) { - return this.genericErrorBuilder(400,4,'Missing param: API PASSWORD'); + return 'Missing param: API PASSWORD'; } if (!('url' in payload)) { - return this.genericErrorBuilder(400,5,'Missing param: API URL'); + return 'Missing param: API URL'; } if (!('port' in payload)) { - return this.genericErrorBuilder(400,6,'Missing param: API PORT'); + return 'Missing param: API PORT'; } if (!(payload.url.includes('https://')) && !(payload.url.includes('http://'))) { - return this.genericErrorBuilder(200,1,'protocol_error'); + return 'protocol_error'; } return false; } - genericErrorBuilder (status,code,message) { - return { - statusCode: status, - error : code, - message : message || 'Error ocurred' - }; - } - async checkAPI (req, reply) { try { const notValid = this.validateCheckApiParams(req.payload); - if(notValid) return this.genericErrorBuilder(valid); + if(notValid) return ErrorResponse(notValid, 3003, 500, reply); // UPDATE CODE req.payload.password = Buffer.from(req.payload.password, 'base64').toString('ascii'); @@ -174,7 +159,7 @@ export default class WazuhApi { // Check wrong credentials if(parseInt(response.statusCode) === 401){ - return reply(this.genericErrorBuilder(500,10401,'wrong_credentials')).code(500); + return ErrorResponse('Wrong credentials', 3004, 500, reply); } if (parseInt(response.body.error) === 0 && response.body.data) { @@ -225,18 +210,21 @@ export default class WazuhApi { } } } + const tmpMsg = response.body && response.body.message ? + response.body.message : + 'Unexpected error checking the Wazuh API'; - throw new Error(response.body.message) + throw new Error(tmpMsg) } catch(error) { - return reply(this.genericErrorBuilder(500,5,error.message || error)).code(500); + return ErrorResponse(error.message || error, 3005, 500, reply); } } async getPciRequirement (req, reply) { try { - if(!protectedRoute(req)) return reply(this.genericErrorBuilder(401,7,'Session expired.')).code(401); + if(!protectedRoute(req)) return ErrorResponse('Session expired', 3006, 401, reply); let pci_description = ''; @@ -248,10 +236,10 @@ export default class WazuhApi { if (wapi_config.error_code > 1) { // Can not connect to elasticsearch - return reply({ statusCode: 200, error: '1', data: 'no_elasticsearch' }); + return ErrorResponse('Elasticsearch unexpected error or cannot connect', 3007, 400, reply); // UPDATE CODE } else if (wapi_config.error_code > 0) { // Credentials not found - return reply({ statusCode: 400, error: '2', data: 'no_credentials' }); + return ErrorResponse('Credentials does not exists', 3008, 400, reply); // UPDATE CODE } const response = await needle('get', `${wapi_config.url}:${wapi_config.port}/rules/pci`, {}, { @@ -267,7 +255,7 @@ export default class WazuhApi { } return reply(PCIobject); } else { - return reply({ statusCode: 400, error: '9998', data: 'An error occurred trying to parse PCI DSS requirements' }); + return ErrorResponse('An error occurred trying to parse PCI DSS requirements', 3009, 400, reply); // UPDATE CODE } } else { @@ -283,12 +271,7 @@ export default class WazuhApi { }); } } catch (error) { - - return reply({ - statusCode: 400, - error : '9999', - data : `An error occurred trying to obtain PCI DSS requirements due to ${error.message || error}` - }); + return ErrorResponse(error.message || error, 3010, 400, reply); // UPDATE CODE } } @@ -299,19 +282,10 @@ export default class WazuhApi { if (wapi_config.error_code > 1) { //Can not connect to elasticsearch - return reply({ - statusCode: 404, - error : 2, - message : 'Could not connect with elasticsearch' - }).code(404); - + return ErrorResponse('Could not connect with elasticsearch', 3011, 404, reply); // UPDATE CODE } else if (wapi_config.error_code > 0) { //Credentials not found - return reply({ - statusCode: 404, - error : 1, - message : 'Credentials does not exists' - }).code(404); + return ErrorResponse('Credentials does not exists', 3012, 404, reply); // UPDATE CODE } if (!data) { @@ -339,27 +313,16 @@ export default class WazuhApi { new Error('Unexpected error fetching data from the Wazuh API') } catch (error) { - return reply({ - statusCode: 500, - data : error.message || error - }).code(500); + return ErrorResponse(error.message || error, 3013, 500, reply); // UPDATE CODE } } requestApi (req, reply) { - if(!protectedRoute(req)) return reply(this.genericErrorBuilder(401,7,'Session expired.')).code(401); + if(!protectedRoute(req)) return ErrorResponse('Session expired', 3014, 401, reply); if (!req.payload.method) { - return reply({ - statusCode: 400, - error : 3, - message : 'Missing param: Method' - }).code(400); + return ErrorResponse('Missing param: method', 3015, 400, reply); // UPDATE CODE } else if (!req.payload.path) { - return reply({ - statusCode: 400, - error : 4, - message : 'Missing param: Path' - }).code(400); + return ErrorResponse('Missing param: path', 3016, 400, reply); // UPDATE CODE } else { return this.makeRequest(req.payload.method, req.payload.path, req.payload.body, req.payload.id, reply); } @@ -368,7 +331,7 @@ export default class WazuhApi { // Fetch agent status and insert it directly on demand async fetchAgents (req, reply) { try{ - if(!protectedRoute(req)) return reply(this.genericErrorBuilder(401,7,'Session expired.')).code(401); + if(!protectedRoute(req)) return ErrorResponse('Session expired', 3017, 401, reply); const output = await this.fetchAgentsExternal(); return reply({ 'statusCode': 200, @@ -377,7 +340,7 @@ export default class WazuhApi { output }); } catch(error){ - return reply(this.genericErrorBuilder(500,6,error.message || error)).code(500) + return ErrorResponse(error.message || error, 3018, 500, reply); // UPDATE CODE } } @@ -396,7 +359,7 @@ export default class WazuhApi { }); } catch (error) { - return reply(this.genericErrorBuilder(500,6,error.message || error)).code(500) + return ErrorResponse(error.message || error, 3019, 500, reply); // UPDATE CODE } } @@ -410,9 +373,9 @@ export default class WazuhApi { } if(!req.payload.password) { - return reply(this.genericErrorBuilder(401,7,'Please give me a password.')).code(401) + return ErrorResponse('Please give me a password.', 3020, 401, reply); // UPDATE CODE } else if(req.payload.password !== configFile['login.password']){ - return reply(this.genericErrorBuilder(401,7,'Wrong password, please try again.')).code(401) + return ErrorResponse('Wrong password, please try again.', 3021, 401, reply); // UPDATE CODE } const code = (new Date()-1) + 'wazuhapp'; @@ -425,7 +388,7 @@ export default class WazuhApi { return reply({ statusCode: 200, error: 0, code }); } catch (error) { - return reply(this.genericErrorBuilder(500,6,error.message || error)).code(500) + return ErrorResponse(error.message || error, 3022, 500, reply); // UPDATE CODE } } } From 925e5550f276b81afaf7d150b84054ed4eec1c84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Mon, 30 Apr 2018 17:32:33 +0200 Subject: [PATCH 06/19] Deleted deprecated methods --- server/lib/elastic-wrapper.js | 85 ----------------------------------- 1 file changed, 85 deletions(-) diff --git a/server/lib/elastic-wrapper.js b/server/lib/elastic-wrapper.js index b3a2f62a05..7322f65cd0 100644 --- a/server/lib/elastic-wrapper.js +++ b/server/lib/elastic-wrapper.js @@ -247,23 +247,6 @@ export default class ElasticWrapper { } } - /** - * Force refreshing an index - * @param {*} name - */ - async refreshIndexByName(name){ - try { - if(!name) return Promise.reject(new Error('No valid name given')); - - const data = await this.elasticRequest.callWithInternalUser('indices.refresh', { index: name }); - - return data; - - } catch (error) { - return Promise.reject(error); - } - } - /** * Get the .wazuh-version index */ @@ -535,74 +518,6 @@ export default class ElasticWrapper { } } - /** - * Used to delete all visualizations with the given description - * @param {*} description - */ - async deleteVisualizationByDescription(description,retroactive) { - try { - if(!description) return Promise.reject(new Error('No description given')) - - const data = await this.elasticRequest.callWithInternalUser('deleteByQuery', { - index: this.WZ_KIBANA_INDEX, - body: - retroactive ? - { - query: { range: { 'visualization.description': { lte: description } } }, - size : 9999 - } : - { - query: { bool: { must: { match: { 'visualization.description': description } } } }, - size : 9999 - } - }); - - return data; - - } catch (error) { - return Promise.reject(error); - } - } - - /** - * Used to get all visualizations with the given description - * @param {*} description - */ - async getVisualizationByDescription(description) { - try { - if(!description) return Promise.reject(new Error('No description given')) - - const data = await this.elasticRequest.callWithInternalUser('search', { - index: this.WZ_KIBANA_INDEX, - body: { - query: { bool: { must: { match: { 'visualization.description': description } } } }, - size : 9999 - } - }); - - return data; - - } catch (error) { - return Promise.reject(error); - } - } - - /** - * Make a bulk request to update the Kibana index - * @param {*} bulk - */ - async pushBulkToKibanaIndex(bulk) { - try { - if(!bulk) return Promise.reject(new Error('No bulk given')) - - const data = await this.elasticRequest.callWithInternalUser('bulk', { index: this.WZ_KIBANA_INDEX, body: bulk }); - - return data; - } catch (error) { - return Promise.reject(error); - } - } - /** * Make a bulk request to update any index * @param {*} bulk From f3fb763e7c6622b8baea19e93f231d84c2f772a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Mon, 30 Apr 2018 17:32:55 +0200 Subject: [PATCH 07/19] Sanitized error responses --- server/controllers/wazuh-elastic.js | 51 +++++------------------------ 1 file changed, 9 insertions(+), 42 deletions(-) diff --git a/server/controllers/wazuh-elastic.js b/server/controllers/wazuh-elastic.js index 45de2f4f9b..cfb3d878cd 100644 --- a/server/controllers/wazuh-elastic.js +++ b/server/controllers/wazuh-elastic.js @@ -13,6 +13,7 @@ import ElasticWrapper from '../lib/elastic-wrapper'; import fs from 'fs'; import yml from 'js-yaml'; import path from 'path'; +import ErrorResponse from './error-response' import { AgentsVisualizations, OverviewVisualizations, RulesetVisualizations } from '../integration-files/visualizations/index' @@ -42,11 +43,7 @@ export default class WazuhElastic { } } catch (err) { - return reply({ - statusCode: 500, - error : 99, - message : err.message || 'Could not fetch .wazuh-version index' - }).code(500); + return ErrorResponse(error.message || 'Could not fetch .wazuh-version index', 4001, 500, reply); } } @@ -88,11 +85,7 @@ export default class WazuhElastic { } } catch (error){ - return reply({ - statusCode: 500, - error : 10000, - message : `Could not retrieve templates from Elasticsearch due to ${error.message || error}` - }).code(500); + return ErrorResponse(`Could not retrieve templates from Elasticsearch due to ${error.message || error}`, 4002, 500, reply); } } @@ -107,11 +100,7 @@ export default class WazuhElastic { reply({ statusCode: 500, status: false, error:10020, message: 'Index pattern not found' }); } catch (error) { - return reply({ - statusCode: 500, - error : 10000, - message : `Something went wrong retrieving index-patterns from Elasticsearch due to ${error.message || error}` - }).code(500); + return ErrorResponse(`Something went wrong retrieving index-patterns from Elasticsearch due to ${error.message || error}`, 4003, 500, reply); } } @@ -160,11 +149,7 @@ export default class WazuhElastic { reply({ statusCode: 200, data: data.aggregations['2'].buckets[0].key }); } catch (error) { - return reply({ - statusCode: 500, - error : 9, - message : error.message || error - }).code(500); + return ErrorResponse(error.message || error, 4004, 500, reply); } } @@ -176,13 +161,8 @@ export default class WazuhElastic { reply({ statusCode: 200, data: '' }) : reply({ statusCode: 200, data: data.hits.hits[0]._source }); - } catch (error) { - return reply({ - statusCode: 500, - error : 9, - message : `Could not get data from elasticsearch due to ${error.message || error}` - }).code(500); + return ErrorResponse(`Could not get data from elasticsearch due to ${error.message || error}`, 4005, 500, reply); } } @@ -257,20 +237,7 @@ export default class WazuhElastic { throw new Error('The Elasticsearch request didn\'t fetch the expected data'); } catch(error){ - return res({error: error.message || error}).code(500) - } - } - - async deleteVis (req, res) { - try { - await this.wzWrapper.refreshIndexByName(this.wzWrapper.WZ_KIBANA_INDEX); - - const tmp = await this.wzWrapper.deleteVisualizationByDescription(req.params.timestamp); - - return res({acknowledge: true , output: tmp}); - - } catch(error){ - return res({error:error.message || error}).code(500); + return ErrorResponse(error.message || error, 4006, 500, reply); } } @@ -335,7 +302,7 @@ export default class WazuhElastic { return res({acknowledge: true, raw: raw }); } catch(error){ - return res({error:error.message || error}).code(500); + return ErrorResponse(error.message || error, 4007, 500, reply); } } @@ -348,7 +315,7 @@ export default class WazuhElastic { return res({acknowledge: true, output: output }); } catch(error){ - return res({error:error.message || error}).code(500); + return ErrorResponse(error.message || error, 4008, 500, reply); } } From 2335cb80ccd7d26f68b03ee584258917bce70a11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Mon, 30 Apr 2018 17:40:42 +0200 Subject: [PATCH 08/19] Removed useless visualizations initialization --- public/controllers/ruleset.js | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/public/controllers/ruleset.js b/public/controllers/ruleset.js index ec539cc230..3c721f4150 100644 --- a/public/controllers/ruleset.js +++ b/public/controllers/ruleset.js @@ -23,7 +23,6 @@ app.controller('rulesController', function ($scope, $rootScope, Rules, RulesRela $scope.rulesRelated = RulesRelated; $scope.rulesAutoComplete = RulesAutoComplete; $scope.setRulesTab('rules'); - $rootScope.tabVisualizations = { ruleset: 4 }; $scope.isArray = angular.isArray; $scope.analizeRules = async search => { @@ -118,13 +117,6 @@ app.controller('rulesController', function ($scope, $rootScope, Rules, RulesRela const load = async () => { try { - $rootScope.rawVisualizations = null; - const data = await genericReq.request('GET',`/api/wazuh-elastic/create-vis/manager-ruleset-rules/${appState.getCurrentPattern()}`) - $rootScope.rawVisualizations = data.data.raw; - // Render visualizations - $rootScope.$broadcast('updateVis'); - if(!$rootScope.$$phase) $rootScope.$digest(); - await Promise.all([ $scope.rules.nextPage(), $scope.rulesAutoComplete.nextPage() @@ -159,13 +151,6 @@ app.controller('rulesController', function ($scope, $rootScope, Rules, RulesRela $scope.$on('$destroy', () => { $scope.rules.reset(); $scope.rulesAutoComplete.reset(); - $rootScope.rawVisualizations = null; - if($rootScope.ownHandlers){ - for(let h of $rootScope.ownHandlers){ - h._scope.$destroy(); - } - } - $rootScope.ownHandlers = []; }); }); @@ -179,7 +164,6 @@ app.controller('decodersController', function ($scope, $rootScope, $sce, Decoder $scope.decodersAutoComplete = DecodersAutoComplete; $scope.typeFilter = "all"; $scope.setRulesTab('decoders'); - $rootScope.tabVisualizations = { ruleset: 1 }; $scope.isArray = angular.isArray; const colors = [ @@ -284,13 +268,6 @@ app.controller('decodersController', function ($scope, $rootScope, $sce, Decoder const load = async () => { try { - $rootScope.rawVisualizations = null; - const data = await genericReq.request('GET',`/api/wazuh-elastic/create-vis/manager-ruleset-decoders/${appState.getCurrentPattern()}`) - $rootScope.rawVisualizations = data.data.raw; - // Render visualizations - $rootScope.$broadcast('updateVis'); - if(!$rootScope.$$phase) $rootScope.$digest(); - await Promise.all([ $scope.decoders.nextPage(), $scope.decodersAutoComplete.nextPage() @@ -313,12 +290,5 @@ app.controller('decodersController', function ($scope, $rootScope, $sce, Decoder $scope.decoders.reset(); $scope.decodersRelated.reset(); $scope.decodersAutoComplete.reset(); - $rootScope.rawVisualizations = null; - if($rootScope.ownHandlers){ - for(let h of $rootScope.ownHandlers){ - h._scope.$destroy(); - } - } - $rootScope.ownHandlers = []; }); }); From 42ffa7e7115fb3b612b496e60c9325342e5bcf3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Mon, 30 Apr 2018 17:43:02 +0200 Subject: [PATCH 09/19] Deleted ruleset visualizations --- .../visualizations/ruleset/index.js | 15 ---- .../ruleset/ruleset-decoders.js | 27 ------- .../visualizations/ruleset/ruleset-rules.js | 71 ------------------- 3 files changed, 113 deletions(-) delete mode 100644 server/integration-files/visualizations/ruleset/index.js delete mode 100644 server/integration-files/visualizations/ruleset/ruleset-decoders.js delete mode 100644 server/integration-files/visualizations/ruleset/ruleset-rules.js diff --git a/server/integration-files/visualizations/ruleset/index.js b/server/integration-files/visualizations/ruleset/index.js deleted file mode 100644 index e33bede83d..0000000000 --- a/server/integration-files/visualizations/ruleset/index.js +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Wazuh app - Module to export ruleset visualizations raw content - * 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. - */ -import decoders from './ruleset-decoders' -import rules from './ruleset-rules' - -export { decoders, rules} \ No newline at end of file diff --git a/server/integration-files/visualizations/ruleset/ruleset-decoders.js b/server/integration-files/visualizations/ruleset/ruleset-decoders.js deleted file mode 100644 index 43aeb8b7e0..0000000000 --- a/server/integration-files/visualizations/ruleset/ruleset-decoders.js +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Wazuh app - Module for Ruleset/Decoders visualizations - * 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. - */ -export default [ - { - "_id": "Wazuh-App-Manager-Ruleset-Decoders-Top-24h-Decoder-name", - "_source": { - "title": "Wazuh App Manager Ruleset Decoders Top 24h Decoder name", - "visState": "{\"title\":\"Wazuh App Manager Ruleset Decoders Top 24h Decoder name\",\"type\":\"area\",\"params\":{\"type\":\"area\",\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"truncate\":100},\"title\":{}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":100},\"title\":{\"text\":\"Count\"}}],\"seriesParams\":[{\"show\":\"true\",\"type\":\"area\",\"mode\":\"stacked\",\"data\":{\"label\":\"Count\",\"id\":\"1\"},\"drawLinesBetweenPoints\":true,\"showCircles\":true,\"interpolate\":\"linear\",\"valueAxis\":\"ValueAxis-1\"}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"times\":[],\"addTimeMarker\":false},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"decoder.name\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"h\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}}]}", - "uiStateJSON": "{}", - "description": "", - "version": 1, - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"index\":\"wazuh-alerts\",\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"}}" - } - }, - "_type": "visualization" - } -] diff --git a/server/integration-files/visualizations/ruleset/ruleset-rules.js b/server/integration-files/visualizations/ruleset/ruleset-rules.js deleted file mode 100644 index c8d9c0c42d..0000000000 --- a/server/integration-files/visualizations/ruleset/ruleset-rules.js +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Wazuh app - Module for Ruleset/Rules visualizations - * 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. - */ -export default [ - { - "_id": "Wazuh-App-Manager-Ruleset-Rules-Top-24h-Groups", - "_source": { - "title": "Wazuh App Manager Ruleset Rules Top 24h Groups", - "visState": - "{\"title\":\"Wazuh App Manager Ruleset Rules Top 24h Groups\",\"type\":\"pie\",\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":true},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"rule.groups\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}]}", - "uiStateJSON": "{}", - "description": "", - "version": 1, - "kibanaSavedObjectMeta": { - "searchSourceJSON": - "{\"index\":\"wazuh-alerts\",\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"}}" - } - }, - "_type": "visualization" - }, - { - "_id": "Wazuh-App-Manager-Ruleset-Rules-Top-24h-Level", - "_source": { - "title": "Wazuh App Manager Ruleset Rules Top 24h Level", - "visState": "{\"title\":\"Wazuh App Manager Ruleset Rules Top 24h Level\",\"type\":\"pie\",\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":true},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"rule.level\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}]}", - "uiStateJSON": "{}", - "description": "", - "version": 1, - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"index\":\"wazuh-alerts\",\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"}}" - } - }, - "_type": "visualization" - }, - { - "_id": "Wazuh-App-Manager-Ruleset-Rules-Top-24h-Rule-ID", - "_source": { - "title": "Wazuh App Manager Ruleset Rules Top 24h Rule ID", - "visState": "{\"title\":\"Wazuh App Manager Ruleset Rules Top 24h Rule ID\",\"type\":\"pie\",\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":true},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"rule.id\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}]}", - "uiStateJSON": "{}", - "description": "", - "version": 1, - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"index\":\"wazuh-alerts\",\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"}}" - } - }, - "_type": "visualization" - }, - { - "_id": "Wazuh-App-Manager-Ruleset-Rules-Top-24h-PCI-DSS-requirements", - "_source": { - "title": "Wazuh App Manager Ruleset Rules Top 24h PCI DSS requirements", - "visState": "{\"title\":\"Wazuh App Manager Ruleset Rules Top 24h PCI DSS requirements\",\"type\":\"pie\",\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":true},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"rule.pci_dss\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}]}", - "uiStateJSON": "{}", - "description": "", - "version": 1, - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"index\":\"wazuh-alerts\",\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"}}" - } - }, - "_type": "visualization" - } -] From ebe0342770b3e5f76101c57d8a71f84d7dc1ebcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Mon, 30 Apr 2018 17:43:30 +0200 Subject: [PATCH 10/19] Not exporting ruleset visualizations any more --- server/integration-files/visualizations/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/integration-files/visualizations/index.js b/server/integration-files/visualizations/index.js index e2dee27073..ebf68f17eb 100644 --- a/server/integration-files/visualizations/index.js +++ b/server/integration-files/visualizations/index.js @@ -11,6 +11,5 @@ */ import * as AgentsVisualizations from './agents/index' import * as OverviewVisualizations from './overview/index' -import * as RulesetVisualizations from './ruleset/index' -export { AgentsVisualizations, OverviewVisualizations, RulesetVisualizations } \ No newline at end of file +export { AgentsVisualizations, OverviewVisualizations } \ No newline at end of file From 7c1e2092bb6f98994fde7b47e7b10db3ae843242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Mon, 30 Apr 2018 17:44:22 +0200 Subject: [PATCH 11/19] Removed useless logic for rules vis since they are no longer avalaible --- server/controllers/wazuh-elastic.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/server/controllers/wazuh-elastic.js b/server/controllers/wazuh-elastic.js index cfb3d878cd..d491843ce9 100644 --- a/server/controllers/wazuh-elastic.js +++ b/server/controllers/wazuh-elastic.js @@ -15,7 +15,7 @@ import yml from 'js-yaml'; import path from 'path'; import ErrorResponse from './error-response' -import { AgentsVisualizations, OverviewVisualizations, RulesetVisualizations } from '../integration-files/visualizations/index' +import { AgentsVisualizations, OverviewVisualizations } from '../integration-files/visualizations/index' export default class WazuhElastic { constructor(server){ @@ -277,7 +277,7 @@ export default class WazuhElastic { try { if(!req.params.pattern || !req.params.tab || - (req.params.tab && !req.params.tab.includes('manager-') && !req.params.tab.includes('overview-') && !req.params.tab.includes('agents-')) + (req.params.tab && !req.params.tab.includes('overview-') && !req.params.tab.includes('agents-')) ) { throw new Error('Missing parameters'); } @@ -285,16 +285,13 @@ export default class WazuhElastic { const apiConfig = (req.headers && req.headers.id) ? await this.wzWrapper.getWazuhConfigurationById(req.headers.id) : false; const clusterName = apiConfig && apiConfig.cluster_info ? apiConfig.cluster_info.cluster : false; const tabPrefix = req.params.tab.includes('overview') ? - 'overview' : req.params.tab.includes('manager') ? - 'manager' : + 'overview' : 'agents'; const tabSplit = req.params.tab.split('-'); - const tabSufix = tabPrefix === 'manager' ? tabSplit[2] : tabSplit[1]; + const tabSufix = tabSplit[1]; - const file = tabPrefix === 'manager' ? - RulesetVisualizations[tabSufix] : - tabPrefix === 'overview' ? + const file = tabPrefix === 'overview' ? OverviewVisualizations[tabSufix] : AgentsVisualizations[tabSufix]; From 282a8513b2c00d954fab9187b6e73ddb4e73adf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Mon, 30 Apr 2018 17:51:29 +0200 Subject: [PATCH 12/19] Removed prep-error module since it's no longer needed --- public/services/generic-request.js | 19 ++---------- public/services/prep-error.js | 48 ------------------------------ 2 files changed, 3 insertions(+), 64 deletions(-) delete mode 100644 public/services/prep-error.js diff --git a/public/services/generic-request.js b/public/services/generic-request.js index 1187286528..660ba0e371 100644 --- a/public/services/generic-request.js +++ b/public/services/generic-request.js @@ -9,7 +9,6 @@ * * Find more information about this on the LICENSE file. */ -import prepError from 'plugins/wazuh/services/prep-error'; import chrome from 'ui/chrome'; import * as modules from 'ui/modules' @@ -53,13 +52,7 @@ modules.get('app/wazuh', []) defered.resolve(data); } }) - .catch(error => { - if(error.status && error.status === -1){ - defered.reject({data: 'request_timeout_genericreq', url }); - }else { - defered.reject(error); - } - }); + .catch(defered.reject); return defered.promise; }; @@ -77,14 +70,8 @@ modules.get('app/wazuh', []) } _request(method, path, payload) - .then((data) => defered.resolve(data)) - .catch(error => { - if(error.status && error.status === 401){ - defered.reject(error); - } else { - defered.reject(prepError(error)); - } - }); + .then(defered.resolve) + .catch(defered.reject); return defered.promise; } diff --git a/public/services/prep-error.js b/public/services/prep-error.js deleted file mode 100644 index b3333a19b6..0000000000 --- a/public/services/prep-error.js +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Wazuh app - Module for error messages - * 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. - */ -export default err => { - - if (err.data && err.data === 'request_timeout_genericreq' && err.url) { - err['html'] = `The request to ${err.url} took too long and was aborted.`; - err.message = `The request to ${err.url} took too long and was aborted.`; - } else if (parseInt(err.error) < 0) { - err['html'] = `Unexpected error located on controller. Error: ${err.message} (code ${err.error}).`; - err.message = `Unexpected error located on controller. Error: ${err.message} (code ${err.error}).`; - } else if (parseInt(err.error) === 1) { - err['html'] = "Error getting credentials for Wazuh API. Please, check credentials at settings tab."; - err.message = "Error getting credentials for Wazuh API. Please, check credentials at settings tab."; - } else if (parseInt(err.error) === 2) { - err['html'] = "Error getting credentials for Wazuh API. Could not connect with Elasticsearch."; - err.message = "Error getting credentials for Wazuh API. Could not connect with Elasticsearch."; - } else if (parseInt(err.error) < 5) { - err['html'] = `Unexpected error located on Kibana server. Error: ${err.message} (code ${err.error}).`; - err.message = `Unexpected error located on Kibana server. Error: ${err.message} (code ${err.error}).`; - } else if (parseInt(err.error) === 5) { - err['html'] = `Could not connect with Wazuh API. Error: ${err.errorMessage}.
Please, check the URL at settings tab.`; - err.message = `Could not connect with Wazuh API. Error: ${err.errorMessage}. Please, check the URL at settings tab.`; - } else if (parseInt(err.error) === 6) { - if (err.errorData.statusCode && err.errorData.statusCode === '404') { - err['html'] = "Wazuh API URL could not be found on elasticsearch. Please, configure the application properly."; - err.message = "Wazuh API URL could not be found on elasticsearch. Please, configure the application properly."; - } else { - err['html'] = `Wazuh API returned an error message. Error: ${err.errorData.message}`; - err.message = `Wazuh API returned an error message. Error: ${err.errorData.message}`; - } - } else if (parseInt(err.error) === 7) { - err['html'] = `Unexpected error filtering the data. Error ${err.message}.`; - err.message = `Unexpected error filtering the data. Error ${err.message}.`; - } else if (err.message) { - err['html'] = err.message; - } - - return err; -}; From ed25eb7d9b4f47c4c4a54e176f7461c141b880b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Mon, 30 Apr 2018 18:02:52 +0200 Subject: [PATCH 13/19] Optimizing error management --- public/services/api-tester.js | 22 +++-------- public/services/error-handler.js | 64 +------------------------------- 2 files changed, 6 insertions(+), 80 deletions(-) diff --git a/public/services/api-tester.js b/public/services/api-tester.js index 36b11fe20b..280ba940f7 100644 --- a/public/services/api-tester.js +++ b/public/services/api-tester.js @@ -56,10 +56,10 @@ app.service('testAPI', function ($http, $location, $rootScope, appState, generic } catch (error) { if(error.status && error.status === -1){ $rootScope.apiIsDown = true; - return Promise.reject({data: 'request_timeout_checkstored'}); - } else { - return Promise.reject(error); - } + } + + return Promise.reject(error); + } }, check: async data => { @@ -77,19 +77,7 @@ app.service('testAPI', function ($http, $location, $rootScope, appState, generic return response; } catch(error) { - if(error.data && error.data.message && error.data.message.includes('ENOTFOUND')) { - return Promise.reject({data: 'invalid_url'}); - } else if(error.data && error.data.message && error.data.message.includes('ECONNREFUSED')) { - return Promise.reject({data: 'invalid_port'}); - } else if(error.status && error.status === -1){ - return Promise.reject({data: 'request_timeout_checkapi'}); - } else if (error.data && error.data.message && error.data.message === 'wrong_credentials') { - return Promise.reject({data: 'wrong_credentials'}); - } else if(error.data && ((error.data.message && error.data.message === 'socket hang up') || (parseInt(error.data.error) === 5))) { - return Promise.reject({data:'socket_hang_up',extraMessage: `Wazuh API throws ${error.data.message}`, https: (data.url && data.url.includes('https'))}); - } else { - return Promise.reject(error); - } + return Promise.reject(error); } } }; diff --git a/public/services/error-handler.js b/public/services/error-handler.js index da809bd181..27502bf6d0 100644 --- a/public/services/error-handler.js +++ b/public/services/error-handler.js @@ -31,9 +31,6 @@ app.service('errorHandler', function ( Notifier, appState, $location) { } const isUnauthorized = error => (error.status && error.status === 401); - const isNotFound = error => (error.status && error.status === 404); - const isHttps = error => (typeof error.https !== 'undefined' && error.https); - const isBadRequest = error => (error.status && error.status === 400); const isAPIUnauthorized = error => (error && error.data && parseInt(error.data.statusCode) === 500 && parseInt(error.data.error) === 7 && error.data.message === '401 Unauthorized'); const info = (message,location) => { @@ -50,7 +47,6 @@ app.service('errorHandler', function ( Notifier, appState, $location) { return; } const message = extractMessage(error); - let goSettings = false; if(isUnauthorized(error)){ appState.removeUserCode(); $location.path('/wlogin'); @@ -58,71 +54,13 @@ app.service('errorHandler', function ( Notifier, appState, $location) { } let text; - switch (message) { - case 'kibana_index_pattern_error': - text = `There seem to be a problem with Wazuh app visualizations in Kibana, please reinstall the Wazuh app.`; - break; - case 'elasticsearch_down': - text = `Could not find Kibana index on Elasticsearch or maybe Elasticsearch is down.
Please check it and try again.`; - break; - case 'no_elasticsearch': - text = `Could not connect with elasticsearch, maybe it's down.`; - break; - case 'no_credentials': - text = 'Valid credentials not found in elasticsearch. It seems the credentials ' + - 'were not saved.'; - break; - case 'protocol_error': - text = 'Invalid protocol in the API url. Please, specify http:// or ' + - 'https://.'; - break; - case 'unauthorized': - text = 'Credentials were found, but they are not valid.'; - break; - case 'bad_url': - text = 'The given URL does not contain a valid Wazuh RESTful API installation.'; - break; - case 'self_signed': - text = 'The request to Wazuh RESTful API was blocked, because it is using a ' + - 'selfsigned SSL certificate. Please, enable "Accept selfsigned SSL" ' + - 'option if you want to connect anyway.'; - break; - case 'not_running': - text = 'There are not services running in the given URL.'; - break; - case 'request_timeout_checkstored': - text = 'The request to /api/wazuh-api/checkStoredAPI took too long and was aborted.'; - goSettings = true; - break; - case 'request_timeout_checkapi': - text = 'The request to /api/wazuh-api/checkAPI took too long and was aborted.'; - break; - case 'wrong_credentials': - text = 'Wrong Wazuh API credentials, please check them and try again'; - break; - case 'invalid_url': - text = 'Wrong Wazuh API url, please check it and try again'; - break; - case 'invalid_port': - text = 'Wrong Wazuh API port, please check it and try again'; - break; - case 'socket_hang_up': - if(isHttps(error)){ - text = 'Wrong Wazuh API protocol, please check it and try again with http instead https'; - } else { - text = 'Could not connect with Wazuh API, please check url and port and try again.' - } - break; - default: - text = isWarning ? `Warning. ${message}` : `Error. ${message}`; - } + text = isWarning ? `Warning. ${message}` : `Error. ${message}`; if(error.extraMessage) text = error.extraMessage; text = location ? location + '. ' + text : text; if(!silent){ if(isWarning) notify.warning(text); else notify.error(text); } - if(goSettings) $location.path('/settings'); return text; } From a9e765d853f6bd43ccd1d57d9a7516451173a922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Mon, 30 Apr 2018 18:17:44 +0200 Subject: [PATCH 14/19] Improve new generic error response constructor (in progress) --- server/controllers/error-response.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/server/controllers/error-response.js b/server/controllers/error-response.js index 531de5a6c3..ecbb9ec856 100644 --- a/server/controllers/error-response.js +++ b/server/controllers/error-response.js @@ -18,8 +18,23 @@ * unknown 1000 */ export default (message = null, code = null, statusCode = null, res) => { + let filteredMessage = ''; + if(code) { + if(typeof message === 'string' && message === 'socket hang up' && code === 3005) { + filteredMessage = 'Wrong protocol being used to connect to the Wazuh API' + } else if(typeof message === 'string' && message.includes('ENOTFOUND') && code === 3005) { + filteredMessage = 'Wrong URL being used to connect to the Wazuh API' + } else if(typeof message === 'string' && message.includes('ECONNREFUSED') && code === 3005) { + filteredMessage = 'Wrong port being used to connect to the Wazuh API' + } + + } + return res({ - message: typeof message === 'string' ? `${code ? code : 1000} - ${message}` : `${code ? code : 1000} - Unexpected error`, + message: filteredMessage ? filteredMessage : + typeof message === 'string' ? + `${code ? code : 1000} - ${message}` : + `${code ? code : 1000} - Unexpected error`, code : code ? code : 1000, statusCode: statusCode ? statusCode : 500 }) From 1aa5b609d5d009db8ea248ac7ace4ceec16a2f1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Thu, 3 May 2018 13:29:21 +0200 Subject: [PATCH 15/19] Fix typo --- public/services/api-request.js | 10 ++++++---- public/services/routes.js | 4 ++-- server/controllers/error-response.js | 4 ++-- server/controllers/wazuh-api.js | 30 ++++++++++++++-------------- server/controllers/wazuh-elastic.js | 16 +++++++-------- server/routes/wazuh-api-elastic.js | 16 +++++++-------- server/routes/wazuh-api.js | 14 ++++++------- 7 files changed, 48 insertions(+), 46 deletions(-) diff --git a/public/services/api-request.js b/public/services/api-request.js index 114905ca5b..408a8aa8bf 100644 --- a/public/services/api-request.js +++ b/public/services/api-request.js @@ -17,7 +17,7 @@ const app = modules.get('app/wazuh', []); app.service('apiReq', function ($q, $http, genericReq, appState, $location, $rootScope) { return { request: (method, path, body) => { - let defered = $q.defer(); + const defered = $q.defer(); if (!method || !path || !body) { defered.reject({ @@ -27,14 +27,16 @@ app.service('apiReq', function ($q, $http, genericReq, appState, $location, $roo return defered.promise; } - if (appState.getCurrentAPI() === undefined || appState.getCurrentAPI() === null) + if (!appState.getCurrentAPI()){ defered.reject({ error: -3, message: 'No API selected.' }); + return defered.promise; + } - let id = JSON.parse(appState.getCurrentAPI()).id; - let requestData = { method, path, body, id }; + const id = JSON.parse(appState.getCurrentAPI()).id; + const requestData = { method, path, body, id }; genericReq.request('POST', '/api/wazuh-api/request', requestData) .then(data => { diff --git a/public/services/routes.js b/public/services/routes.js index 81784380ae..02ef388938 100644 --- a/public/services/routes.js +++ b/public/services/routes.js @@ -40,8 +40,8 @@ const checkTimestamp = async (appState,genericReq,errorHandler,$rootScope,$locat $location.path('/blank-screen'); } return; - } catch (err){ - $rootScope.blankScreenError = err.message || err; + } catch (error){ + $rootScope.blankScreenError = error.message || error; $location.search('tab',null); $location.path('/blank-screen'); } diff --git a/server/controllers/error-response.js b/server/controllers/error-response.js index ecbb9ec856..55f4bd3ac3 100644 --- a/server/controllers/error-response.js +++ b/server/controllers/error-response.js @@ -17,7 +17,7 @@ * wazuh-elastic 40XX * unknown 1000 */ -export default (message = null, code = null, statusCode = null, res) => { +export default (message = null, code = null, statusCode = null, reply) => { let filteredMessage = ''; if(code) { if(typeof message === 'string' && message === 'socket hang up' && code === 3005) { @@ -30,7 +30,7 @@ export default (message = null, code = null, statusCode = null, res) => { } - return res({ + return reply({ message: filteredMessage ? filteredMessage : typeof message === 'string' ? `${code ? code : 1000} - ${message}` : diff --git a/server/controllers/wazuh-api.js b/server/controllers/wazuh-api.js index 365ab78223..7d80ff61a4 100644 --- a/server/controllers/wazuh-api.js +++ b/server/controllers/wazuh-api.js @@ -146,7 +146,7 @@ export default class WazuhApi { async checkAPI (req, reply) { try { const notValid = this.validateCheckApiParams(req.payload); - if(notValid) return ErrorResponse(notValid, 3003, 500, reply); // UPDATE CODE + if(notValid) return ErrorResponse(notValid, 3003, 500, reply); req.payload.password = Buffer.from(req.payload.password, 'base64').toString('ascii'); @@ -236,10 +236,10 @@ export default class WazuhApi { if (wapi_config.error_code > 1) { // Can not connect to elasticsearch - return ErrorResponse('Elasticsearch unexpected error or cannot connect', 3007, 400, reply); // UPDATE CODE + return ErrorResponse('Elasticsearch unexpected error or cannot connect', 3007, 400, reply); } else if (wapi_config.error_code > 0) { // Credentials not found - return ErrorResponse('Credentials does not exists', 3008, 400, reply); // UPDATE CODE + return ErrorResponse('Credentials does not exists', 3008, 400, reply); } const response = await needle('get', `${wapi_config.url}:${wapi_config.port}/rules/pci`, {}, { @@ -255,7 +255,7 @@ export default class WazuhApi { } return reply(PCIobject); } else { - return ErrorResponse('An error occurred trying to parse PCI DSS requirements', 3009, 400, reply); // UPDATE CODE + return ErrorResponse('An error occurred trying to parse PCI DSS requirements', 3009, 400, reply); } } else { @@ -271,7 +271,7 @@ export default class WazuhApi { }); } } catch (error) { - return ErrorResponse(error.message || error, 3010, 400, reply); // UPDATE CODE + return ErrorResponse(error.message || error, 3010, 400, reply); } } @@ -282,10 +282,10 @@ export default class WazuhApi { if (wapi_config.error_code > 1) { //Can not connect to elasticsearch - return ErrorResponse('Could not connect with elasticsearch', 3011, 404, reply); // UPDATE CODE + return ErrorResponse('Could not connect with elasticsearch', 3011, 404, reply); } else if (wapi_config.error_code > 0) { //Credentials not found - return ErrorResponse('Credentials does not exists', 3012, 404, reply); // UPDATE CODE + return ErrorResponse('Credentials does not exists', 3012, 404, reply); } if (!data) { @@ -313,16 +313,16 @@ export default class WazuhApi { new Error('Unexpected error fetching data from the Wazuh API') } catch (error) { - return ErrorResponse(error.message || error, 3013, 500, reply); // UPDATE CODE + return ErrorResponse(error.message || error, 3013, 500, reply); } } requestApi (req, reply) { if(!protectedRoute(req)) return ErrorResponse('Session expired', 3014, 401, reply); if (!req.payload.method) { - return ErrorResponse('Missing param: method', 3015, 400, reply); // UPDATE CODE + return ErrorResponse('Missing param: method', 3015, 400, reply); } else if (!req.payload.path) { - return ErrorResponse('Missing param: path', 3016, 400, reply); // UPDATE CODE + return ErrorResponse('Missing param: path', 3016, 400, reply); } else { return this.makeRequest(req.payload.method, req.payload.path, req.payload.body, req.payload.id, reply); } @@ -340,7 +340,7 @@ export default class WazuhApi { output }); } catch(error){ - return ErrorResponse(error.message || error, 3018, 500, reply); // UPDATE CODE + return ErrorResponse(error.message || error, 3018, 500, reply); } } @@ -359,7 +359,7 @@ export default class WazuhApi { }); } catch (error) { - return ErrorResponse(error.message || error, 3019, 500, reply); // UPDATE CODE + return ErrorResponse(error.message || error, 3019, 500, reply); } } @@ -373,9 +373,9 @@ export default class WazuhApi { } if(!req.payload.password) { - return ErrorResponse('Please give me a password.', 3020, 401, reply); // UPDATE CODE + return ErrorResponse('Please give me a password.', 3020, 401, reply); } else if(req.payload.password !== configFile['login.password']){ - return ErrorResponse('Wrong password, please try again.', 3021, 401, reply); // UPDATE CODE + return ErrorResponse('Wrong password, please try again.', 3021, 401, reply); } const code = (new Date()-1) + 'wazuhapp'; @@ -388,7 +388,7 @@ export default class WazuhApi { return reply({ statusCode: 200, error: 0, code }); } catch (error) { - return ErrorResponse(error.message || error, 3022, 500, reply); // UPDATE CODE + return ErrorResponse(error.message || error, 3022, 500, reply); } } } diff --git a/server/controllers/wazuh-elastic.js b/server/controllers/wazuh-elastic.js index d491843ce9..c85e797f05 100644 --- a/server/controllers/wazuh-elastic.js +++ b/server/controllers/wazuh-elastic.js @@ -42,7 +42,7 @@ export default class WazuhElastic { throw new Error('Could not fetch .wazuh-version index'); } - } catch (err) { + } catch (error) { return ErrorResponse(error.message || 'Could not fetch .wazuh-version index', 4001, 500, reply); } } @@ -209,7 +209,7 @@ export default class WazuhElastic { return list; } - async getlist (req,res) { + async getlist (req,reply) { try { const xpack = await this.wzWrapper.getPlugins(); @@ -231,7 +231,7 @@ export default class WazuhElastic { if(data && data.hits && data.hits.hits){ const list = this.validateIndexPattern(data.hits.hits); - return res({data: isXpackEnabled && !isSuperUser ? await this.filterAllowedIndexPatternList(list,req) : list}); + return reply({data: isXpackEnabled && !isSuperUser ? await this.filterAllowedIndexPatternList(list,req) : list}); } throw new Error('The Elasticsearch request didn\'t fetch the expected data'); @@ -273,13 +273,13 @@ export default class WazuhElastic { } } - async createVis (req, res) { + async createVis (req, reply) { try { if(!req.params.pattern || !req.params.tab || (req.params.tab && !req.params.tab.includes('overview-') && !req.params.tab.includes('agents-')) ) { - throw new Error('Missing parameters'); + throw new Error('Missing parameters creating visualizations'); } const apiConfig = (req.headers && req.headers.id) ? await this.wzWrapper.getWazuhConfigurationById(req.headers.id) : false; @@ -296,20 +296,20 @@ export default class WazuhElastic { AgentsVisualizations[tabSufix]; const raw = await this.buildVisualizationsRaw(file, req.params.pattern); - return res({acknowledge: true, raw: raw }); + return reply({acknowledge: true, raw: raw }); } catch(error){ return ErrorResponse(error.message || error, 4007, 500, reply); } } - async refreshIndex (req,res) { + async refreshIndex (req,reply) { try { if(!req.params.pattern) throw new Error('Missing parameters'); const output = await this.wzWrapper.updateIndexPatternKnownFields(req.params.pattern); - return res({acknowledge: true, output: output }); + return reply({acknowledge: true, output: output }); } catch(error){ return ErrorResponse(error.message || error, 4008, 500, reply); diff --git a/server/routes/wazuh-api-elastic.js b/server/routes/wazuh-api-elastic.js index 593a7d3c2d..614159b956 100644 --- a/server/routes/wazuh-api-elastic.js +++ b/server/routes/wazuh-api-elastic.js @@ -15,26 +15,26 @@ export default (server, options) => { const ctrl = new WazuhApiElastic(server); // Save the given API into elasticsearch - server.route({ method: 'PUT', path: '/api/wazuh-api/settings', handler: (req,res) => ctrl.saveAPI(req,res) }); + 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,res) => ctrl.updateFullAPI(req,res) }); + 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,res) => ctrl.getAPIEntries(req,res) }); + 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,res) => ctrl.deleteAPIEntries(req,res) }); + 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,res) => ctrl.setAPIEntryDefault(req,res) }); + server.route({ method: 'PUT', path: '/api/wazuh-api/apiEntries/{id}', handler: (req,reply) => ctrl.setAPIEntryDefault(req,reply) }); // Toggle extension state: Enable / Disable - server.route({ method: 'PUT', path: '/api/wazuh-api/extension/toggle/{id}/{extensionName}/{extensionValue}', handler: (req,res) => ctrl.toggleExtension(req,res) }); + server.route({ method: 'PUT', path: '/api/wazuh-api/extension/toggle/{id}/{extensionName}/{extensionValue}', handler: (req,reply) => ctrl.toggleExtension(req,reply) }); // Return extension state list - server.route({ method: 'GET', path: '/api/wazuh-api/extension', handler: (req,res) => ctrl.getExtensions(req,res) }); + server.route({ method: 'GET', path: '/api/wazuh-api/extension', handler: (req,reply) => ctrl.getExtensions(req,reply) }); // Update the API hostname - server.route({ method: 'PUT', path: '/api/wazuh-api/updateApiHostname/{id}', handler: (req,res) => ctrl.updateAPIHostname(req,res) }); + server.route({ method: 'PUT', path: '/api/wazuh-api/updateApiHostname/{id}', handler: (req,reply) => ctrl.updateAPIHostname(req,reply) }); }; diff --git a/server/routes/wazuh-api.js b/server/routes/wazuh-api.js index 612bf56288..7855d84fcf 100644 --- a/server/routes/wazuh-api.js +++ b/server/routes/wazuh-api.js @@ -15,24 +15,24 @@ export default (server, options) => { const ctrl = new WazuhApi(server); // Returns if the wazuh-api configuration is working - server.route({ method: 'POST', path: '/api/wazuh-api/checkStoredAPI', handler: (req,res) => ctrl.checkStoredAPI(req,res) }); + server.route({ method: 'POST', path: '/api/wazuh-api/checkStoredAPI', handler: (req, reply) => ctrl.checkStoredAPI(req, reply) }); // 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 - server.route({ method: 'POST', path: '/api/wazuh-api/checkAPI', handler: (req,res) => ctrl.checkAPI(req,res) }); + server.route({ method: 'POST', path: '/api/wazuh-api/checkAPI', handler: (req, reply) => ctrl.checkAPI(req, reply) }); // Returns the request result (With error control) - server.route({ method: 'POST', path: '/api/wazuh-api/request', handler: (req,res) => ctrl.requestApi(req,res) }); + server.route({ method: 'POST', path: '/api/wazuh-api/request', handler: (req, reply) => ctrl.requestApi(req, reply) }); // Return a PCI requirement description - server.route({ method: 'GET', path: '/api/wazuh-api/pci/{requirement}', handler: (req,res) => ctrl.getPciRequirement(req,res) }); + server.route({ method: 'GET', path: '/api/wazuh-api/pci/{requirement}', handler: (req, reply) => ctrl.getPciRequirement(req, reply) }); // COMMENT HERE - server.route({ method: 'GET', path: '/api/wazuh-api/fetchAgents', handler: (req,res) => ctrl.fetchAgents(req,res) }); + server.route({ method: 'GET', path: '/api/wazuh-api/fetchAgents', handler: (req, reply) => ctrl.fetchAgents(req, reply) }); // COMMENT HERE - server.route({ method: 'GET', path: '/api/wazuh-api/configuration', handler: (req,res) => ctrl.getConfigurationFile(req,res) }); + server.route({ method: 'GET', path: '/api/wazuh-api/configuration', handler: (req, reply) => ctrl.getConfigurationFile(req, reply) }); // COMMENT HERE - server.route({ method: 'POST',path: '/api/wazuh-api/wlogin', handler: (req,res) => ctrl.login(req,res) }); + server.route({ method: 'POST',path: '/api/wazuh-api/wlogin', handler: (req, reply) => ctrl.login(req, reply) }); }; From 7c2bb41d1b428f176926d76a5a9d0e6e9842418b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Fri, 4 May 2018 11:07:57 +0200 Subject: [PATCH 16/19] Continue managing errors in a better way (in progress) --- public/services/api-tester.js | 3 +-- public/services/routes.js | 9 ++++++++- server/controllers/error-response.js | 4 +++- server/controllers/wazuh-api.js | 8 +++----- server/lib/elastic-wrapper.js | 2 +- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/public/services/api-tester.js b/public/services/api-tester.js index 280ba940f7..cfa010d5ca 100644 --- a/public/services/api-tester.js +++ b/public/services/api-tester.js @@ -35,7 +35,7 @@ app.service('testAPI', function ($http, $location, $rootScope, appState, generic appState.setPatternSelector(typeof configuration.data.data['ip.selector'] !== 'undefined' ? configuration.data.data['ip.selector'] : true) - return 'cookies_outdated'; + return 'cookies_outdated' /** End of checks for outdated cookies */ } else { @@ -57,7 +57,6 @@ app.service('testAPI', function ($http, $location, $rootScope, appState, generic if(error.status && error.status === -1){ $rootScope.apiIsDown = true; } - return Promise.reject(error); } diff --git a/public/services/routes.js b/public/services/routes.js index 02ef388938..dc98d31c00 100644 --- a/public/services/routes.js +++ b/public/services/routes.js @@ -127,7 +127,14 @@ const settingsWizard = ($rootScope, $location, $q, $window, testAPI, appState, g } } }) - .catch(error => errorHandler.handle(error,'Routes')); + .catch(error => { + appState.removeCurrentAPI(); + errorHandler.handle(error,'Routes'); + errorHandler.handle('Wazuh App: please add a new API.','Routes',true); + $location.search('_a', null); + $location.search('tab', 'api'); + $location.path('/settings'); + }); } if (!$location.path().includes("/health-check") && healthCheck($window, $rootScope)) { diff --git a/server/controllers/error-response.js b/server/controllers/error-response.js index 55f4bd3ac3..c36e4388a9 100644 --- a/server/controllers/error-response.js +++ b/server/controllers/error-response.js @@ -26,12 +26,14 @@ export default (message = null, code = null, statusCode = null, reply) => { filteredMessage = 'Wrong URL being used to connect to the Wazuh API' } else if(typeof message === 'string' && message.includes('ECONNREFUSED') && code === 3005) { filteredMessage = 'Wrong port being used to connect to the Wazuh API' + } else if(typeof message === 'string' && message.toLowerCase().includes('not found') && code === 3002) { + filteredMessage = 'Wazuh API entry not found' } } return reply({ - message: filteredMessage ? filteredMessage : + message: filteredMessage ? `${code ? code : 1000} - ${filteredMessage}` : typeof message === 'string' ? `${code ? code : 1000} - ${message}` : `${code ? code : 1000} - Unexpected error`, diff --git a/server/controllers/wazuh-api.js b/server/controllers/wazuh-api.js index 7d80ff61a4..6322710ca3 100644 --- a/server/controllers/wazuh-api.js +++ b/server/controllers/wazuh-api.js @@ -36,13 +36,11 @@ export default class WazuhApi { if(!protectedRoute(req)) return ErrorResponse('Session expired', 3001, 401, reply); // Get config from elasticsearch const wapi_config = await this.wzWrapper.getWazuhConfigurationById(req.payload) - + console.log(wapi_config) if (wapi_config.error_code > 1) { - // Can not connect to elasticsearch - throw new Error(`Could not connect with elasticsearch, maybe it's down.`) + throw new Error(`Could not find Wazuh API entry on Elasticsearch.`) } else if (wapi_config.error_code > 0) { - // Credentials not found - throw new Error('Valid credentials not found in elasticsearch. It seems the credentials were not saved.') + throw new Error('Valid credentials not found in Elasticsearch. It seems the credentials were not saved.') } let response = await needle('get', `${wapi_config.url}:${wapi_config.port}/version`, {}, { diff --git a/server/lib/elastic-wrapper.js b/server/lib/elastic-wrapper.js index 7322f65cd0..00c8df62a2 100644 --- a/server/lib/elastic-wrapper.js +++ b/server/lib/elastic-wrapper.js @@ -360,7 +360,7 @@ export default class ElasticWrapper { }; } catch (error){ - return { error: 'no elasticsearch', error_code: 2 }; + return Promise.reject(error) } } From f0469556d84bd30cddd8f142e6b8c1ff87b142d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Fri, 4 May 2018 12:29:07 +0200 Subject: [PATCH 17/19] Applying facade pattern --- public/app.js | 65 ++----------------- public/controllers/index.js | 22 +++++++ public/directives/index.js | 20 ++++++ public/factories/index.js | 12 ++++ public/kibana-integrations/index.js | 15 +++++ public/services/index.js | 20 ++++++ server/controllers/index.js | 16 +++++ server/controllers/wazuh-api.js | 1 - server/controllers/wazuh-elastic.js | 2 +- .../integration-files/visualizations/index.js | 4 +- server/routes/wazuh-api-elastic.js | 2 +- server/routes/wazuh-api.js | 2 +- server/routes/wazuh-elastic.js | 2 +- 13 files changed, 117 insertions(+), 66 deletions(-) create mode 100644 public/controllers/index.js create mode 100644 public/directives/index.js create mode 100644 public/factories/index.js create mode 100644 public/kibana-integrations/index.js create mode 100644 public/services/index.js create mode 100644 server/controllers/index.js diff --git a/public/app.js b/public/app.js index 7bf02e61dd..46bdac00b9 100644 --- a/public/app.js +++ b/public/app.js @@ -38,65 +38,12 @@ import 'plugins/wazuh/../node_modules/angular-material/angular-material.js'; // Cookies import 'plugins/wazuh/../node_modules/angular-cookies/angular-cookies.min.js'; -//////////////////////////////////////////////////////////////////// -// Require Kibana integrations import 'ui/autoload/all'; import 'ui/chrome'; -import 'plugins/wazuh/kibana-integrations/kibana-visualization.js'; -import 'plugins/wazuh/kibana-integrations/kibana-filter-bar.js'; -import 'plugins/wazuh/kibana-integrations/kibana-discover.js'; -import 'plugins/wazuh/kibana-integrations/saved-visualizations.js'; -// Require services -import 'plugins/wazuh/services/error-handler.js'; -import 'plugins/wazuh/services/theming.js'; -import 'plugins/wazuh/services/api-request.js'; -import 'plugins/wazuh/services/generic-request.js'; -import 'plugins/wazuh/services/data-handler.js'; -import 'plugins/wazuh/services/app-state.js'; -import 'plugins/wazuh/services/api-tester.js'; -import 'plugins/wazuh/services/pattern-handler.js'; - -// Set up routes and views -import 'plugins/wazuh/services/routes.js'; - -// Require controllers - -// Factories -import 'plugins/wazuh/factories/data-handler-composer.js'; - -// Wazuh Directives -import 'plugins/wazuh/directives/wz-dynamic/wz-dynamic.js'; -import 'plugins/wazuh/directives/wz-enter/wz-enter.js'; -import 'plugins/wazuh/directives/wz-menu/wz-menu.js'; -import 'plugins/wazuh/directives/wz-menu/wz-menu.less'; -import 'plugins/wazuh/directives/wz-search-bar/wz-search-bar.js'; -import 'plugins/wazuh/directives/wz-table-header/wz-table-header.js'; -import 'plugins/wazuh/directives/wz-table-header/wz-table-header.less'; -import 'plugins/wazuh/directives/wz-table/wz-table.js'; -import 'plugins/wazuh/directives/wz-table/wz-table.less'; - -// Blank Screen -import 'plugins/wazuh/controllers/blank-screen-controller.js'; - -// Login -import 'plugins/wazuh/controllers/login.js'; - -// Overview -import 'plugins/wazuh/controllers/overview.js'; - -// Manager -import 'plugins/wazuh/controllers/manager.js'; -import 'plugins/wazuh/controllers/ruleset.js'; -import 'plugins/wazuh/controllers/osseclog.js'; -import 'plugins/wazuh/controllers/groups.js'; - -// Agents -import 'plugins/wazuh/controllers/agents.js'; -import 'plugins/wazuh/controllers/agents-preview.js'; - -// Settings -import 'plugins/wazuh/controllers/settings.js'; - -// Health check -import 'plugins/wazuh/controllers/health-check.js'; +// Wazuh +import 'plugins/wazuh/kibana-integrations' +import 'plugins/wazuh/services' +import 'plugins/wazuh/controllers' +import 'plugins/wazuh/factories' +import 'plugins/wazuh/directives' \ No newline at end of file diff --git a/public/controllers/index.js b/public/controllers/index.js new file mode 100644 index 0000000000..7aeb315925 --- /dev/null +++ b/public/controllers/index.js @@ -0,0 +1,22 @@ +/* + * Wazuh app - File for app requirements and set up + * 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. + */ +import 'plugins/wazuh/controllers/blank-screen-controller' +import 'plugins/wazuh/controllers/login' +import 'plugins/wazuh/controllers/overview' +import 'plugins/wazuh/controllers/manager' +import 'plugins/wazuh/controllers/ruleset' +import 'plugins/wazuh/controllers/osseclog' +import 'plugins/wazuh/controllers/groups' +import 'plugins/wazuh/controllers/agents' +import 'plugins/wazuh/controllers/agents-preview' +import 'plugins/wazuh/controllers/settings' +import 'plugins/wazuh/controllers/health-check' \ No newline at end of file diff --git a/public/directives/index.js b/public/directives/index.js new file mode 100644 index 0000000000..63dd290b6c --- /dev/null +++ b/public/directives/index.js @@ -0,0 +1,20 @@ +/* + * Wazuh app - File for app requirements and set up + * 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. + */ +import 'plugins/wazuh/directives/wz-dynamic/wz-dynamic'; +import 'plugins/wazuh/directives/wz-enter/wz-enter'; +import 'plugins/wazuh/directives/wz-menu/wz-menu'; +import 'plugins/wazuh/directives/wz-menu/wz-menu.less'; +import 'plugins/wazuh/directives/wz-search-bar/wz-search-bar'; +import 'plugins/wazuh/directives/wz-table-header/wz-table-header'; +import 'plugins/wazuh/directives/wz-table-header/wz-table-header.less'; +import 'plugins/wazuh/directives/wz-table/wz-table'; +import 'plugins/wazuh/directives/wz-table/wz-table.less'; \ No newline at end of file diff --git a/public/factories/index.js b/public/factories/index.js new file mode 100644 index 0000000000..e93c8f07c8 --- /dev/null +++ b/public/factories/index.js @@ -0,0 +1,12 @@ +/* + * Wazuh app - File for app requirements and set up + * 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. + */ +import 'plugins/wazuh/factories/data-handler-composer'; \ No newline at end of file diff --git a/public/kibana-integrations/index.js b/public/kibana-integrations/index.js new file mode 100644 index 0000000000..b29942a6c5 --- /dev/null +++ b/public/kibana-integrations/index.js @@ -0,0 +1,15 @@ +/* + * Wazuh app - File for app requirements and set up + * 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. + */ +import 'plugins/wazuh/kibana-integrations/kibana-visualization.js'; +import 'plugins/wazuh/kibana-integrations/kibana-filter-bar.js'; +import 'plugins/wazuh/kibana-integrations/kibana-discover.js'; +import 'plugins/wazuh/kibana-integrations/saved-visualizations.js'; \ No newline at end of file diff --git a/public/services/index.js b/public/services/index.js new file mode 100644 index 0000000000..5f8f0b8444 --- /dev/null +++ b/public/services/index.js @@ -0,0 +1,20 @@ +/* + * Wazuh app - File for app requirements and set up + * 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. + */ +import 'plugins/wazuh/services/error-handler.js'; +import 'plugins/wazuh/services/theming.js'; +import 'plugins/wazuh/services/api-request.js'; +import 'plugins/wazuh/services/generic-request'; +import 'plugins/wazuh/services/data-handler'; +import 'plugins/wazuh/services/app-state'; +import 'plugins/wazuh/services/api-tester'; +import 'plugins/wazuh/services/pattern-handler'; +import 'plugins/wazuh/services/routes'; \ No newline at end of file diff --git a/server/controllers/index.js b/server/controllers/index.js new file mode 100644 index 0000000000..629ebdd9bd --- /dev/null +++ b/server/controllers/index.js @@ -0,0 +1,16 @@ +/* + * Wazuh app - Module to export all the 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. + */ +import WazuhElastic from './wazuh-elastic' +import WazuhApiElastic from './wazuh-api-elastic' +import WazuhApi from './wazuh-api' + +export { WazuhElastic, WazuhApiElastic, WazuhApi } \ No newline at end of file diff --git a/server/controllers/wazuh-api.js b/server/controllers/wazuh-api.js index 6322710ca3..eefacc61a2 100644 --- a/server/controllers/wazuh-api.js +++ b/server/controllers/wazuh-api.js @@ -36,7 +36,6 @@ export default class WazuhApi { if(!protectedRoute(req)) return ErrorResponse('Session expired', 3001, 401, reply); // Get config from elasticsearch const wapi_config = await this.wzWrapper.getWazuhConfigurationById(req.payload) - console.log(wapi_config) if (wapi_config.error_code > 1) { throw new Error(`Could not find Wazuh API entry on Elasticsearch.`) } else if (wapi_config.error_code > 0) { diff --git a/server/controllers/wazuh-elastic.js b/server/controllers/wazuh-elastic.js index c85e797f05..6b8ef25dc1 100644 --- a/server/controllers/wazuh-elastic.js +++ b/server/controllers/wazuh-elastic.js @@ -15,7 +15,7 @@ import yml from 'js-yaml'; import path from 'path'; import ErrorResponse from './error-response' -import { AgentsVisualizations, OverviewVisualizations } from '../integration-files/visualizations/index' +import { AgentsVisualizations, OverviewVisualizations } from '../integration-files/visualizations' export default class WazuhElastic { constructor(server){ diff --git a/server/integration-files/visualizations/index.js b/server/integration-files/visualizations/index.js index ebf68f17eb..b51ad0566e 100644 --- a/server/integration-files/visualizations/index.js +++ b/server/integration-files/visualizations/index.js @@ -9,7 +9,7 @@ * * Find more information about this on the LICENSE file. */ -import * as AgentsVisualizations from './agents/index' -import * as OverviewVisualizations from './overview/index' +import * as AgentsVisualizations from './agents' +import * as OverviewVisualizations from './overview' export { AgentsVisualizations, OverviewVisualizations } \ No newline at end of file diff --git a/server/routes/wazuh-api-elastic.js b/server/routes/wazuh-api-elastic.js index 614159b956..3bebc8c715 100644 --- a/server/routes/wazuh-api-elastic.js +++ b/server/routes/wazuh-api-elastic.js @@ -9,7 +9,7 @@ * * Find more information about this on the LICENSE file. */ -import WazuhApiElastic from '../controllers/wazuh-api-elastic'; +import { WazuhApiElastic } from '../controllers'; export default (server, options) => { const ctrl = new WazuhApiElastic(server); diff --git a/server/routes/wazuh-api.js b/server/routes/wazuh-api.js index 7855d84fcf..38c8440f3f 100644 --- a/server/routes/wazuh-api.js +++ b/server/routes/wazuh-api.js @@ -9,7 +9,7 @@ * * Find more information about this on the LICENSE file. */ -import WazuhApi from '../controllers/wazuh-api'; +import { WazuhApi } from '../controllers'; export default (server, options) => { const ctrl = new WazuhApi(server); diff --git a/server/routes/wazuh-elastic.js b/server/routes/wazuh-elastic.js index da019b8f39..d0ab1f0310 100644 --- a/server/routes/wazuh-elastic.js +++ b/server/routes/wazuh-elastic.js @@ -9,7 +9,7 @@ * * Find more information about this on the LICENSE file. */ -import WazuhElastic from '../controllers/wazuh-elastic'; +import { WazuhElastic } from '../controllers'; export default (server, options) => { From 93ddb304b99da2bbfbd5bb52c99c57b1a0673a18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Fri, 4 May 2018 13:39:37 +0200 Subject: [PATCH 18/19] Modularized functions being called on resolves from each route --- public/services/index.js | 18 +- public/services/resolves/check-timestamp.js | 31 +++ public/services/resolves/get-ip.js | 79 ++++++ public/services/resolves/get-saved-search.js | 25 ++ public/services/resolves/go-to-kibana.js | 26 ++ public/services/resolves/health-check.js | 19 ++ public/services/resolves/index.js | 19 ++ public/services/resolves/settings-wizard.js | 147 ++++++++++ public/services/routes.js | 267 +------------------ 9 files changed, 357 insertions(+), 274 deletions(-) create mode 100644 public/services/resolves/check-timestamp.js create mode 100644 public/services/resolves/get-ip.js create mode 100644 public/services/resolves/get-saved-search.js create mode 100644 public/services/resolves/go-to-kibana.js create mode 100644 public/services/resolves/health-check.js create mode 100644 public/services/resolves/index.js create mode 100644 public/services/resolves/settings-wizard.js diff --git a/public/services/index.js b/public/services/index.js index 5f8f0b8444..9d310e5ba5 100644 --- a/public/services/index.js +++ b/public/services/index.js @@ -9,12 +9,12 @@ * * Find more information about this on the LICENSE file. */ -import 'plugins/wazuh/services/error-handler.js'; -import 'plugins/wazuh/services/theming.js'; -import 'plugins/wazuh/services/api-request.js'; -import 'plugins/wazuh/services/generic-request'; -import 'plugins/wazuh/services/data-handler'; -import 'plugins/wazuh/services/app-state'; -import 'plugins/wazuh/services/api-tester'; -import 'plugins/wazuh/services/pattern-handler'; -import 'plugins/wazuh/services/routes'; \ No newline at end of file +import 'plugins/wazuh/services/error-handler' +import 'plugins/wazuh/services/theming'; +import 'plugins/wazuh/services/api-request' +import 'plugins/wazuh/services/generic-request' +import 'plugins/wazuh/services/data-handler' +import 'plugins/wazuh/services/app-state' +import 'plugins/wazuh/services/api-tester' +import 'plugins/wazuh/services/pattern-handler' +import 'plugins/wazuh/services/routes' \ No newline at end of file diff --git a/public/services/resolves/check-timestamp.js b/public/services/resolves/check-timestamp.js new file mode 100644 index 0000000000..dae0ddcc0f --- /dev/null +++ b/public/services/resolves/check-timestamp.js @@ -0,0 +1,31 @@ +/* + * Wazuh app - File for routes definition + * 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. + */ +export default async (appState,genericReq,errorHandler,$rootScope,$location) => { + try { + const data = await genericReq.request('GET', '/api/wazuh-elastic/timestamp'); + const current = appState.getCreatedAt(); + if(data && data.data){ + if(!current) appState.setCreatedAt(data.data.lastRestart); + $rootScope.lastRestart = data.data.lastRestart; + if(!$rootScope.$$phase) $rootScope.$digest(); + } else { + $rootScope.blankScreenError = 'Your .wazuh-version index is empty or corrupt.' + $location.search('tab',null); + $location.path('/blank-screen'); + } + return; + } catch (error){ + $rootScope.blankScreenError = error.message || error; + $location.search('tab',null); + $location.path('/blank-screen'); + } +} \ No newline at end of file diff --git a/public/services/resolves/get-ip.js b/public/services/resolves/get-ip.js new file mode 100644 index 0000000000..0841fa4876 --- /dev/null +++ b/public/services/resolves/get-ip.js @@ -0,0 +1,79 @@ +/* + * Wazuh app - File for routes definition + * 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. + */ +import { StateProvider } from 'ui/state_management/state'; +import { SavedObjectsClientProvider } from 'ui/saved_objects'; + +import healthCheck from './health-check' + +export default (Promise, courier, config, $q, $rootScope, $window, $location, Private, appState, genericReq,errorHandler) => { + const deferred = $q.defer(); + + const catchFunction = error => { + deferred.reject(error); + $rootScope.blankScreenError = errorHandler.handle(error,'Elasticsearch',false,true); + $location.path('/blank-screen'); + } + + if (healthCheck($window, $rootScope)) { + deferred.reject(); + $location.path('/health-check'); + } else { + const State = Private(StateProvider); + const savedObjectsClient = Private(SavedObjectsClientProvider); + savedObjectsClient.find({ + type : 'index-pattern', + fields : ['title'], + perPage: 10000 + }) + .then(({ savedObjects }) => { + genericReq.request('GET', '/get-list') + .then(data => { + let currentPattern = ''; + if (appState.getCurrentPattern()) { // There's cookie for the pattern + currentPattern = appState.getCurrentPattern(); + } else { + if(!data.data.data.length){ + $rootScope.blankScreenError = 'Sorry but no valid index patterns were found' + $location.search('tab',null); + $location.path('/blank-screen'); + return; + } + currentPattern = data.data.data[0].id; + appState.setCurrentPattern(currentPattern); + } + + const onlyWazuhAlerts = savedObjects.filter(element => element.id === currentPattern); + + if (onlyWazuhAlerts.length === 0) { // There's now selected ip + deferred.resolve('No ip'); + return; + } + + courier.indexPatterns.get(currentPattern) + .then(data => { + deferred.resolve({ + list : onlyWazuhAlerts, + loaded : data, + stateVal : null, + stateValFound: false + }); + }) + .catch(catchFunction); + + }) + .catch(catchFunction); + }) + .catch(catchFunction); + + } + return deferred.promise; +} \ No newline at end of file diff --git a/public/services/resolves/get-saved-search.js b/public/services/resolves/get-saved-search.js new file mode 100644 index 0000000000..d8154b4b7f --- /dev/null +++ b/public/services/resolves/get-saved-search.js @@ -0,0 +1,25 @@ +/* + * Wazuh app - File for routes definition + * 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. + */ +import healthCheck from './health-check' + +export default (courier, $q, $window, $rootScope, savedSearches, $route) => { + if (healthCheck($window, $rootScope)) { + $location.path('/health-check'); + return Promise.reject(); + } else { + return savedSearches.get($route.current.params.id) + .catch(courier.redirectWhenMissing({ + 'search': '/discover', + 'index-pattern': '/management/kibana/objects/savedSearches/' + $route.current.params.id + })); + } +}; \ No newline at end of file diff --git a/public/services/resolves/go-to-kibana.js b/public/services/resolves/go-to-kibana.js new file mode 100644 index 0000000000..012e01afc5 --- /dev/null +++ b/public/services/resolves/go-to-kibana.js @@ -0,0 +1,26 @@ +/* + * Wazuh app - File for routes definition + * 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. + */ +// Manage leaving the app to another Kibana tab +export default ($location, $window) => { + + let url = $location.$$absUrl.substring(0, $location.$$absUrl.indexOf('#')); + + if ($window.sessionStorage.getItem(`lastSubUrl:${url}`).includes('/wazuh#/visualize') || + $window.sessionStorage.getItem(`lastSubUrl:${url}`).includes('/wazuh#/doc') || + $window.sessionStorage.getItem(`lastSubUrl:${url}`).includes('/wazuh#/context')){ + + $window.sessionStorage.setItem(`lastSubUrl:${url}`, url); + + } + + $window.location.href = $location.absUrl().replace('/wazuh#', '/kibana#'); +} \ No newline at end of file diff --git a/public/services/resolves/health-check.js b/public/services/resolves/health-check.js new file mode 100644 index 0000000000..f238839b01 --- /dev/null +++ b/public/services/resolves/health-check.js @@ -0,0 +1,19 @@ +/* + * Wazuh app - File for routes definition + * 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. + */ +export default ($window, $rootScope) => { + if (!$window.sessionStorage.getItem('healthCheck')) { // New session, execute health check + $window.sessionStorage.setItem('healthCheck', 'executed'); + return true; + } else { + return false; + } +} \ No newline at end of file diff --git a/public/services/resolves/index.js b/public/services/resolves/index.js new file mode 100644 index 0000000000..78eb6c21ae --- /dev/null +++ b/public/services/resolves/index.js @@ -0,0 +1,19 @@ +/* + * Wazuh app - File for routes definition + * 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. + */ +import checkTimestamp from './check-timestamp' +import healthCheck from './health-check' +import settingsWizard from './settings-wizard' +import getSavedSearch from './get-saved-search' +import goToKibana from './go-to-kibana' +import getIp from './get-ip' + +export { checkTimestamp, healthCheck, settingsWizard, getSavedSearch, goToKibana, getIp } \ No newline at end of file diff --git a/public/services/resolves/settings-wizard.js b/public/services/resolves/settings-wizard.js new file mode 100644 index 0000000000..af458f02ac --- /dev/null +++ b/public/services/resolves/settings-wizard.js @@ -0,0 +1,147 @@ +/* + * Wazuh app - File for routes definition + * 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. + */ +import checkTimestamp from './check-timestamp' +import healthCheck from './health-check' + +export default ($rootScope, $location, $q, $window, testAPI, appState, genericReq, errorHandler) => { + try { + const deferred = $q.defer(); + + // Save current location if we aren't performing a health-check, to later be able to come back to the same tab + if (!$location.path().includes("/health-check")) { + $rootScope.previousLocation = $location.path(); + } + + const checkResponse = data => { + let fromElastic = false; + if (parseInt(data.data.error) === 2){ + errorHandler.handle('Wazuh App: Please set up Wazuh API credentials.','Routes',true); + } else if((data.data && (data.data.apiIsDown || data.data.message === 'socket hang up')) || + (data.data.data && (data.data.data.apiIsDown || data.data.data.message === 'socket hang up'))){ + $rootScope.apiIsDown = "down"; + errorHandler.handle('Wazuh RESTful API seems to be down.','Routes'); + } else { + fromElastic = true; + $rootScope.blankScreenError = errorHandler.handle(data,'Routes'); + appState.removeCurrentAPI(); + } + + if(!fromElastic){ + $rootScope.comeFromWizard = true; + if(!$rootScope.$$phase) $rootScope.$digest(); + if(!$location.path().includes("/settings")) { + $location.search('_a', null); + $location.search('tab', 'api'); + $location.path('/settings'); + } + } else { + if(data && data.data && parseInt(data.data.statusCode) === 500 && parseInt(data.data.error) === 7 && data.data.message === '401 Unauthorized'){ + errorHandler.handle('Wrong Wazuh API credentials, please add a new API and/or modify the existing one.','Routes'); + $location.search('_a', null); + $location.search('tab', 'api'); + $location.path('/settings'); + } else { + $location.path('/blank-screen'); + } + } + + deferred.reject(); + } + + const changeCurrentApi = data => { + // Should change the currentAPI configuration depending on cluster + if (data.data.data.cluster_info.status === 'disabled'){ + appState.setCurrentAPI(JSON.stringify({ + name: data.data.data.cluster_info.manager, + id: JSON.parse(appState.getCurrentAPI()).id + })); + } else { + appState.setCurrentAPI(JSON.stringify({ + name: data.data.data.cluster_info.cluster, + id: JSON.parse(appState.getCurrentAPI()).id + })); + } + + appState.setClusterInfo(data.data.data.cluster_info); + appState.setExtensions(data.data.data.extensions); + deferred.resolve(); + } + + const callCheckStored = () => { + checkTimestamp(appState,genericReq,errorHandler,$rootScope,$location) + .then(() => testAPI.check_stored(JSON.parse(appState.getCurrentAPI()).id)) + .then(data => { + if(data && data === 'cookies_outdated'){ + $location.search('tab','general'); + $location.path('/overview') + } else { + if (data.data.error || data.data.data.apiIsDown) { + checkResponse(data); + } else { + $rootScope.apiIsDown = null; + changeCurrentApi(data); + } + } + }) + .catch(error => { + appState.removeCurrentAPI(); + errorHandler.handle(error,'Routes'); + errorHandler.handle('Wazuh App: please add a new API.','Routes',true); + $location.search('_a', null); + $location.search('tab', 'api'); + $location.path('/settings'); + }); + } + + if (!$location.path().includes("/health-check") && healthCheck($window, $rootScope)) { + $location.path('/health-check'); + deferred.reject(); + } else { + // There's no cookie for current API + if (!appState.getCurrentAPI()) { + genericReq.request('GET', '/api/wazuh-api/apiEntries') + .then(data => { + if (data.data.length > 0) { + const apiEntries = data.data; + appState.setCurrentAPI(JSON.stringify({name: apiEntries[0]._source.cluster_info.manager, id: apiEntries[0]._id })); + callCheckStored(); + } else { + errorHandler.handle('Wazuh App: Please set up Wazuh API credentials.','Routes',true); + $rootScope.comeFromWizard = true; + if(!$location.path().includes("/settings")) { + $location.search('_a', null); + $location.search('tab', 'api'); + $location.path('/settings'); + } + deferred.reject(); + } + }) + .catch(error => { + errorHandler.handle(error,'Routes'); + $rootScope.comeFromWizard = true; + if(!$location.path().includes("/settings")) { + $location.search('_a', null); + $location.search('tab', 'api'); + $location.path('/settings'); + } + deferred.reject(); + }); + } else { + callCheckStored(); + } + } + + return deferred.promise; + } catch (error) { + console.log(error.message || error) + } +}; \ No newline at end of file diff --git a/public/services/routes.js b/public/services/routes.js index dc98d31c00..84de6eaaf6 100644 --- a/public/services/routes.js +++ b/public/services/routes.js @@ -13,271 +13,8 @@ // Require routes import routes from 'ui/routes'; -// Kibana dependencies to load index-patterns and saved searches -import { StateProvider } from 'ui/state_management/state'; -import { SavedObjectsClientProvider } from 'ui/saved_objects'; - -const healthCheck = ($window, $rootScope) => { - if (!$window.sessionStorage.getItem('healthCheck')) { // New session, execute health check - $window.sessionStorage.setItem('healthCheck', 'executed'); - return true; - } else { - return false; - } -}; - -const checkTimestamp = async (appState,genericReq,errorHandler,$rootScope,$location) => { - try { - const data = await genericReq.request('GET', '/api/wazuh-elastic/timestamp'); - const current = appState.getCreatedAt(); - if(data && data.data){ - if(!current) appState.setCreatedAt(data.data.lastRestart); - $rootScope.lastRestart = data.data.lastRestart; - if(!$rootScope.$$phase) $rootScope.$digest(); - } else { - $rootScope.blankScreenError = 'Your .wazuh-version index is empty or corrupt.' - $location.search('tab',null); - $location.path('/blank-screen'); - } - return; - } catch (error){ - $rootScope.blankScreenError = error.message || error; - $location.search('tab',null); - $location.path('/blank-screen'); - } -} - -//Installation wizard -const settingsWizard = ($rootScope, $location, $q, $window, testAPI, appState, genericReq, errorHandler) => { - let deferred = $q.defer(); - - // Save current location if we aren't performing a health-check, to later be able to come back to the same tab - if (!$location.path().includes("/health-check")) { - $rootScope.previousLocation = $location.path(); - } - - const checkResponse = data => { - let fromElastic = false; - if (parseInt(data.data.error) === 2){ - errorHandler.handle('Wazuh App: Please set up Wazuh API credentials.','Routes',true); - } else if((data.data && (data.data.apiIsDown || data.data.message === 'socket hang up')) || - (data.data.data && (data.data.data.apiIsDown || data.data.data.message === 'socket hang up'))){ - $rootScope.apiIsDown = "down"; - errorHandler.handle('Wazuh RESTful API seems to be down.','Routes'); - } else { - fromElastic = true; - $rootScope.blankScreenError = errorHandler.handle(data,'Routes'); - appState.removeCurrentAPI(); - } - - if(!fromElastic){ - $rootScope.comeFromWizard = true; - if(!$rootScope.$$phase) $rootScope.$digest(); - if(!$location.path().includes("/settings")) { - $location.search('_a', null); - $location.search('tab', 'api'); - $location.path('/settings'); - } - } else { - if(data && data.data && parseInt(data.data.statusCode) === 500 && parseInt(data.data.error) === 7 && data.data.message === '401 Unauthorized'){ - errorHandler.handle('Wrong Wazuh API credentials, please add a new API and/or modify the existing one.','Routes'); - $location.search('_a', null); - $location.search('tab', 'api'); - $location.path('/settings'); - } else { - $location.path('/blank-screen'); - } - } - - deferred.reject(); - } - - const changeCurrentApi = data => { - // Should change the currentAPI configuration depending on cluster - if (data.data.data.cluster_info.status === 'disabled'){ - appState.setCurrentAPI(JSON.stringify({ - name: data.data.data.cluster_info.manager, - id: JSON.parse(appState.getCurrentAPI()).id - })); - } else { - appState.setCurrentAPI(JSON.stringify({ - name: data.data.data.cluster_info.cluster, - id: JSON.parse(appState.getCurrentAPI()).id - })); - } - - appState.setClusterInfo(data.data.data.cluster_info); - appState.setExtensions(data.data.data.extensions); - deferred.resolve(); - } - - const callCheckStored = () => { - checkTimestamp(appState,genericReq,errorHandler,$rootScope,$location) - .then(() => testAPI.check_stored(JSON.parse(appState.getCurrentAPI()).id)) - .then(data => { - if(data && data === 'cookies_outdated'){ - $location.search('tab','general'); - $location.path('/overview') - } else { - if (data.data.error || data.data.data.apiIsDown) { - checkResponse(data); - } else { - $rootScope.apiIsDown = null; - changeCurrentApi(data); - } - } - }) - .catch(error => { - appState.removeCurrentAPI(); - errorHandler.handle(error,'Routes'); - errorHandler.handle('Wazuh App: please add a new API.','Routes',true); - $location.search('_a', null); - $location.search('tab', 'api'); - $location.path('/settings'); - }); - } - - if (!$location.path().includes("/health-check") && healthCheck($window, $rootScope)) { - $location.path('/health-check'); - deferred.reject(); - } else { - // There's no cookie for current API - if (!appState.getCurrentAPI()) { - genericReq.request('GET', '/api/wazuh-api/apiEntries') - .then(data => { - if (data.data.length > 0) { - const apiEntries = data.data; - appState.setCurrentAPI(JSON.stringify({name: apiEntries[0]._source.cluster_info.manager, id: apiEntries[0]._id })); - callCheckStored(); - } else { - errorHandler.handle('Wazuh App: Please set up Wazuh API credentials.','Routes',true); - $rootScope.comeFromWizard = true; - if(!$location.path().includes("/settings")) { - $location.search('_a', null); - $location.search('tab', 'api'); - $location.path('/settings'); - } - deferred.reject(); - } - }) - .catch(error => { - errorHandler.handle(error,'Routes'); - $rootScope.comeFromWizard = true; - if(!$location.path().includes("/settings")) { - $location.search('_a', null); - $location.search('tab', 'api'); - $location.path('/settings'); - } - deferred.reject(); - }); - } else { - callCheckStored(); - } - } - - return deferred.promise; -}; - -// Manage leaving the app to another Kibana tab -const goToKibana = ($location, $window) => { - let url = $location.$$absUrl.substring(0, $location.$$absUrl.indexOf('#')); - - if (sessionStorage.getItem(`lastSubUrl:${url}`).includes('/wazuh#/visualize') || - sessionStorage.getItem(`lastSubUrl:${url}`).includes('/wazuh#/doc') || - sessionStorage.getItem(`lastSubUrl:${url}`).includes('/wazuh#/context')){ - - sessionStorage.setItem(`lastSubUrl:${url}`, url); - - } - - $window.location.href = $location.absUrl().replace('/wazuh#', '/kibana#'); -}; - -const getIp = (Promise, courier, config, $q, $rootScope, $window, $location, Private, appState, genericReq,errorHandler) => { - let deferred = $q.defer(); - if (healthCheck($window, $rootScope)) { - deferred.reject(); - $location.path('/health-check'); - } else { - const State = Private(StateProvider); - const savedObjectsClient = Private(SavedObjectsClientProvider); - - savedObjectsClient.find({ - type : 'index-pattern', - fields : ['title'], - perPage: 10000 - }) - .then(({ savedObjects }) => { - - genericReq.request('GET', '/get-list') - .then(data => { - let currentPattern = ''; - if (appState.getCurrentPattern()) { // There's cookie for the pattern - currentPattern = appState.getCurrentPattern(); - } else { - if(!data.data.data.length){ - $rootScope.blankScreenError = 'Sorry but no valid index patterns were found' - $location.search('tab',null); - $location.path('/blank-screen'); - return; - } - currentPattern = data.data.data[0].id; - appState.setCurrentPattern(currentPattern); - } - - const onlyWazuhAlerts = savedObjects.filter(element => element.id === currentPattern); - - if (onlyWazuhAlerts.length === 0) { // There's now selected ip - deferred.resolve('No ip'); - return; - } - - courier.indexPatterns.get(currentPattern) - .then(data => { - deferred.resolve({ - list : onlyWazuhAlerts, - loaded : data, - stateVal : null, - stateValFound: false - }); - }) - .catch(error => { - deferred.reject(error); - $rootScope.blankScreenError = errorHandler.handle(error,'Elasticsearch',false,true); - $location.path('/blank-screen'); - }); - - }) - .catch(error => { - deferred.reject(error); - $rootScope.blankScreenError = errorHandler.handle(error,'Elasticsearch',false,true); - $location.path('/blank-screen'); - }); - }) - .catch(error => { - deferred.reject(error); - $rootScope.blankScreenError = errorHandler.handle(error,'Elasticsearch',false,true); - $location.path('/blank-screen'); - }); - } - return deferred.promise; - -}; - -const getSavedSearch = (courier, $q, $window, $rootScope, savedSearches, $route) => { - if (healthCheck($window, $rootScope)) { - let deferred = $q.defer(); - $location.path('/health-check'); - deferred.reject(); - return deferred.promise; - } else { - return savedSearches.get($route.current.params.id) - .catch(courier.redirectWhenMissing({ - 'search': '/discover', - 'index-pattern': '/management/kibana/objects/savedSearches/' + $route.current.params.id - })); - } -}; +// Functions to be executed before loading certain routes +import { healthCheck, settingsWizard, getSavedSearch, goToKibana, getIp } from './resolves' // HTML templates import healthCheckTemplate from 'plugins/wazuh/templates/health-check/health-check.html' From d3b7c8995faafa0677497b810a22e3d68a7943a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel=20Gonz=C3=A1lez?= Date: Fri, 4 May 2018 13:43:36 +0200 Subject: [PATCH 19/19] Replaced debug console by proper errorHandler call --- public/services/resolves/check-timestamp.js | 2 +- public/services/resolves/get-ip.js | 2 +- public/services/resolves/get-saved-search.js | 2 +- public/services/resolves/go-to-kibana.js | 2 +- public/services/resolves/health-check.js | 2 +- public/services/resolves/index.js | 2 +- public/services/resolves/settings-wizard.js | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/public/services/resolves/check-timestamp.js b/public/services/resolves/check-timestamp.js index dae0ddcc0f..38566dd066 100644 --- a/public/services/resolves/check-timestamp.js +++ b/public/services/resolves/check-timestamp.js @@ -1,5 +1,5 @@ /* - * Wazuh app - File for routes definition + * Wazuh app - Module to check cookie consistence * Copyright (C) 2018 Wazuh, Inc. * * This program is free software; you can redistribute it and/or modify diff --git a/public/services/resolves/get-ip.js b/public/services/resolves/get-ip.js index 0841fa4876..1bb119ceeb 100644 --- a/public/services/resolves/get-ip.js +++ b/public/services/resolves/get-ip.js @@ -1,5 +1,5 @@ /* - * Wazuh app - File for routes definition + * Wazuh app - Module to fetch index patterns * Copyright (C) 2018 Wazuh, Inc. * * This program is free software; you can redistribute it and/or modify diff --git a/public/services/resolves/get-saved-search.js b/public/services/resolves/get-saved-search.js index d8154b4b7f..1fd0fdd196 100644 --- a/public/services/resolves/get-saved-search.js +++ b/public/services/resolves/get-saved-search.js @@ -1,5 +1,5 @@ /* - * Wazuh app - File for routes definition + * Wazuh app - Module to check discover * Copyright (C) 2018 Wazuh, Inc. * * This program is free software; you can redistribute it and/or modify diff --git a/public/services/resolves/go-to-kibana.js b/public/services/resolves/go-to-kibana.js index 012e01afc5..e6480e4fe6 100644 --- a/public/services/resolves/go-to-kibana.js +++ b/public/services/resolves/go-to-kibana.js @@ -1,5 +1,5 @@ /* - * Wazuh app - File for routes definition + * Wazuh app - Module to catch last url * Copyright (C) 2018 Wazuh, Inc. * * This program is free software; you can redistribute it and/or modify diff --git a/public/services/resolves/health-check.js b/public/services/resolves/health-check.js index f238839b01..c220fb9d75 100644 --- a/public/services/resolves/health-check.js +++ b/public/services/resolves/health-check.js @@ -1,5 +1,5 @@ /* - * Wazuh app - File for routes definition + * Wazuh app - Module to check health check executed status * Copyright (C) 2018 Wazuh, Inc. * * This program is free software; you can redistribute it and/or modify diff --git a/public/services/resolves/index.js b/public/services/resolves/index.js index 78eb6c21ae..8f38ce094c 100644 --- a/public/services/resolves/index.js +++ b/public/services/resolves/index.js @@ -1,5 +1,5 @@ /* - * Wazuh app - File for routes definition + * Wazuh app - File for app requirements and set up * Copyright (C) 2018 Wazuh, Inc. * * This program is free software; you can redistribute it and/or modify diff --git a/public/services/resolves/settings-wizard.js b/public/services/resolves/settings-wizard.js index af458f02ac..eb862f3720 100644 --- a/public/services/resolves/settings-wizard.js +++ b/public/services/resolves/settings-wizard.js @@ -1,5 +1,5 @@ /* - * Wazuh app - File for routes definition + * Wazuh app - Module to execute some checks on most app routes * Copyright (C) 2018 Wazuh, Inc. * * This program is free software; you can redistribute it and/or modify @@ -142,6 +142,6 @@ export default ($rootScope, $location, $q, $window, testAPI, appState, genericRe return deferred.promise; } catch (error) { - console.log(error.message || error) + errorHandler.handle(error,'Routes'); } }; \ No newline at end of file