diff --git a/docs/installation_ubuntu_14.04.md b/docs/installation_ubuntu_14.04.md index c2484e1..5a056ec 100644 --- a/docs/installation_ubuntu_14.04.md +++ b/docs/installation_ubuntu_14.04.md @@ -67,7 +67,7 @@ during the installation the procedure asks the following information: * ##### Install dependencies using npm ``` -npm install -g --unsafe log4js@1.1.1 requestify mysql nconf ip express node-uuid autobahn q body-parser ps-node nodemailer nodemailer-smtp-transport swagger-jsdoc cors bcrypt optimist jsonwebtoken md5 +npm install -g --unsafe log4js@1.1.1 requestify mysql nconf ip express node-uuid autobahn q body-parser ps-node nodemailer nodemailer-smtp-transport swagger-jsdoc cors bcrypt optimist jsonwebtoken md5 crypto npm install -g --unsafe @mdslab/wstun ``` diff --git a/docs/installation_ubuntu_16.04.md b/docs/installation_ubuntu_16.04.md index 4057131..2ebf061 100644 --- a/docs/installation_ubuntu_16.04.md +++ b/docs/installation_ubuntu_16.04.md @@ -63,7 +63,7 @@ during the installation the procedure asks the following information: * ##### Install dependencies using npm ``` -npm install -g --unsafe log4js@1.1.1 requestify mysql nconf ip express node-uuid autobahn q body-parser ps-node nodemailer nodemailer-smtp-transport swagger-jsdoc cors bcrypt optimist jsonwebtoken md5 +npm install -g --unsafe log4js@1.1.1 requestify mysql nconf ip express node-uuid autobahn q body-parser ps-node nodemailer nodemailer-smtp-transport swagger-jsdoc cors bcrypt optimist jsonwebtoken md5 crypto npm install -g --unsafe @mdslab/wstun ``` diff --git a/docs/iotronic-docs-gen.js b/docs/iotronic-docs-gen.js index 43b7d36..b253833 100644 --- a/docs/iotronic-docs-gen.js +++ b/docs/iotronic-docs-gen.js @@ -49,6 +49,12 @@ var genApiDocumentation = function (){ console.log("[API-DOCS] - Starting doc generation..."); + + if(port == undefined) + var swg_host = IoTronic_IP; + else + var swg_host = IoTronic_IP+':'+port; + // swagger definition var swaggerDefinition = { info: { @@ -56,7 +62,7 @@ var genApiDocumentation = function (){ version: '2.1.0', description: 'IoTronic-standalone API by Stack4Things.' }, - host: IoTronic_IP+':'+port, + //host: swg_host, basePath: '/', licence:{ name: 'Apache v2', @@ -227,7 +233,22 @@ if (argv.i != undefined && argv.e != undefined){ IOTRONIC_CFG = process.env.IOTRONIC_HOME + "/settings.json"; nconf.file({file: IOTRONIC_CFG}); - IoTronic_IP = nconf.get('config:server:public_ip'); + + // Set fronted IP address + public_ip = nconf.get('config:server:public_ip'); + + if (public_ip == "") + IoTronic_IP = utility.getIP(intr, 'IPv4'); + else if(public_ip == "env"){ + IoTronic_IP = process.env.IOTRONIC_PUB_IP; + } + else if(public_ip == undefined){ + logger.error("[SYSTEM] - Iotronic public IP not defined: " + public_ip); + process.exit(); + } + else + IoTronic_IP = public_ip; + https_enable = nconf.get('config:server:https:enable'); https_key = nconf.get('config:server:https:key'); https_cert = nconf.get('config:server:https:cert'); diff --git a/lib/init_iotronic.js b/lib/init_iotronic.js index 424c997..5b942eb 100644 --- a/lib/init_iotronic.js +++ b/lib/init_iotronic.js @@ -28,6 +28,7 @@ server_rest_port = null; iotronic_session = null; reconnection = false; + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // LOGGING CONFIGURATION //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -119,6 +120,9 @@ var initIoTronicModules = function() { // Load settings intr = nconf.get('config:server:interface'); public_ip = nconf.get('config:server:public_ip'); + api_ip = nconf.get('config:server:api_ip'); + crossbar_pub_ip = nconf.get('config:wamp:crossbar_pub_ip'); + topic_connection = nconf.get('config:wamp:topic_connection'); wamp_ssl = nconf.get('config:wamp:ssl'); @@ -141,36 +145,49 @@ var initIoTronicModules = function() { docs_url_spec = nconf.get('config:server:docs:expose:url_spec'); - if(nconf.get('config:wstun:ip') == "env"){ - wstun_ip = process.env.WSTUN_IP; - logger.debug("[SYSTEM] - WSTUN public IP (env):",wstun_ip); - }else - wstun_ip = nconf.get('config:wstun:ip'); + // Modules loading flags + vnet_enabled = nconf.get('config:modules:vnets_manager:enabled'); console.log("VNETs Manager: " + vnet_enabled); + service_enabled = nconf.get('config:modules:services_manager:enabled'); console.log("Services Manager: " + service_enabled); + nodered_enabled = nconf.get('config:modules:nodered_manager:enabled'); console.log("Node-RED Manager: " + nodered_enabled); + plugin_enabled = nconf.get('config:modules:plugins_manager:enabled'); console.log("Plugins Manager: " + plugin_enabled); + gpio_enabled = nconf.get('config:modules:gpio_manager:enabled'); console.log("GPIO Manager: " + gpio_enabled); + vfs_enabled = nconf.get('config:modules:vfs_manager:enabled'); console.log("VFS Manager: " + vfs_enabled); + driver_enabled = nconf.get('config:modules:drivers_manager:enabled'); console.log("Drivers Manager: " + driver_enabled); - if(nconf.get('config:wstun:port_range:high') == "env" && nconf.get('config:wstun:port_range:low') == "env"){ - wstun_h_port = parseInt(process.env.WSTUN_H_PORT); - wstun_l_port = parseInt(process.env.WSTUN_L_PORT); - logger.debug("[SYSTEM] - WSTUN port range (env):",wstun_l_port, wstun_h_port); - } - else { - wstun_h_port = parseInt(nconf.get('config:wstun:port_range:high')); - wstun_l_port = parseInt(nconf.get('config:wstun:port_range:low')); - logger.debug("[SYSTEM] - WSTUN port range (conf):",wstun_l_port, wstun_h_port); + + if(service_enabled){ + if(nconf.get('config:modules:services_manager:wstun:public_ip') == "env"){ + wstun_ip = process.env.WSTUN_IP; + logger.debug("[SYSTEM] - WSTUN public IP (env):", wstun_ip); + }else + wstun_ip = nconf.get('config:modules:services_manager:wstun:public_ip'); + + if(nconf.get('config:modules:services_manager:wstun:port_range:high') == "env" && nconf.get('config:modules:services_manager:wstun:port_range:low') == "env"){ + wstun_h_port = parseInt(process.env.WSTUN_H_PORT); + wstun_l_port = parseInt(process.env.WSTUN_L_PORT); + logger.debug("[SYSTEM] - WSTUN port range (env):",wstun_l_port, wstun_h_port); + } + else { + wstun_h_port = parseInt(nconf.get('config:modules:services_manager:wstun:port_range:high')); + wstun_l_port = parseInt(nconf.get('config:modules:services_manager:wstun:port_range:low')); + logger.debug("[SYSTEM] - WSTUN port range (conf):",wstun_l_port, wstun_h_port); + } } + // INIT IoTronic modules - db_utils = require('./management/mng_db'); - plugin_utility = require('./modules/plugin_manager'); - driver_utility = require('./modules/driver_manager'); - vfs_utility = require('./modules/vfs_manager'); - gpio_utility = require('./modules/gpio_manager'); - nr_utility = require('./modules/nodered_manager'); - + if(plugin_enabled) plugin_utility = require('./modules/plugin_manager'); + if(driver_enabled) driver_utility = require('./modules/driver_manager'); + if(vfs_enabled) vfs_utility = require('./modules/vfs_manager'); + if(gpio_enabled) gpio_utility = require('./modules/gpio_manager'); + if(nodered_enabled) nr_utility = require('./modules/nodered_manager'); + if(service_enabled) service_utility = require('./modules/service_manager'); + + db_utils = require('./management/mng_db'); board_utility = require('./management/mng_board'); utility = require('./management/utility'); - service_utility = require('./modules/service_manager'); layout_utility = require('./management/mng_layout'); project_utility = require('./management/mng_project'); user_utility = require('./management/mng_user'); @@ -197,23 +214,50 @@ var initIoTronicModules = function() { else if(public_ip == "env"){ IoTronic_IP = process.env.IOTRONIC_PUB_IP; } + else if(public_ip == undefined){ + logger.error("[SYSTEM] - Iotronic public IP not defined: " + public_ip); + process.exit(); + } else IoTronic_IP = public_ip; - - - // Init IoTronic Manager - if (net_backend == 'iotronic') { - net_utility = require('./modules/vnet_iotronic_manager'); - net_utility.initVNET(); - } - /* - else if(net_backend == 'neutron'){ - net_utility = require('./modules/vnet_neutron_manager'); + + if(api_ip == "env") + API_IP = process.env.API_PUB_IP; + else if(api_ip == undefined || api_ip == ""){ + logger.error("[SYSTEM] - API IP not defined: " + api_ip); + process.exit(); } - */ - else { - logger.warn("[SYSTEM] - IoTronic does not support this network backend: " + net_backend) + else + API_IP = api_ip; + + + if(crossbar_pub_ip == "env") + CROSSBAR_IP = process.env.CROSSBAR_PUB_IP; + else if(crossbar_pub_ip == undefined || crossbar_pub_ip == ""){ + logger.error("[SYSTEM] - Crossbar IP not defined: " + crossbar_pub_ip); + process.exit(); } + else + CROSSBAR_IP = crossbar_ip; + + + logger.info("[SYSTEM] - Iotronic public endpoints:\n - WEB_IP: "+IoTronic_IP + "\n - CROSSBAR_IP: "+ CROSSBAR_IP + "\n - API_IP: " + API_IP) + + + if(vnet_enabled) + // Init IoTronic Manager + if (net_backend == 'iotronic') { + net_utility = require('./modules/vnet_iotronic_manager'); + net_utility.initVNET(); + } + /* + else if(net_backend == 'neutron'){ + net_utility = require('./modules/vnet_neutron_manager'); + } + */ + else { + logger.warn("[SYSTEM] - IoTronic does not support this network backend: " + net_backend) + } // CHECK WSTUN PROCESS STATUS @@ -242,6 +286,7 @@ var initIoTronicModules = function() { var loadIoTronicModules = function(session, rest) { + logger.info("[SYSTEM] -------------------------------------------------------"); logger.info("[SYSTEM] - IoTronic modules loading..."); var d = Q.defer(); @@ -252,22 +297,30 @@ var loadIoTronicModules = function(session, rest) { }; try { - - // Loading IoTronic modules + + logger.info("[SYSTEM] -------------------------------------------------------"); + logger.info("[SYSTEM] --> Loading Iotronic libraries:"); board_utils = new board_utility(session, rest); - plugin_utils = new plugin_utility(session, rest); - driver_utils = new driver_utility(session, rest); - net_utils = new net_utility(session, rest); - vfs_utils = new vfs_utility(session, rest); - gpio_utils = new gpio_utility(session, rest); - services_utils = new service_utility(session, rest); layouts_utils = new layout_utility(session, rest); projects_utils = new project_utility(session, rest); users_utils = new user_utility(session, rest); - nr_utils = new nr_utility(session, rest); requests_utils = new request_utility(session, rest); + logger.info("[SYSTEM] -------------------------------------------------------"); + - response.message = "IoTronic modules successfully loaded."; + + logger.info("[SYSTEM] --> Loading Iotronic modules:"); + if(plugin_enabled) plugin_utils = new plugin_utility(session, rest); + if(driver_enabled) driver_utils = new driver_utility(session, rest); + if(vnet_enabled) net_utils = new net_utility(session, rest); + if(vfs_enabled) vfs_utils = new vfs_utility(session, rest); + if(gpio_enabled) gpio_utils = new gpio_utility(session, rest); + if(service_enabled) services_utils = new service_utility(session, rest); + if(nodered_enabled) nr_utils = new nr_utility(session, rest); + logger.info("[SYSTEM] -------------------------------------------------------"); + + + response.message = "IoTronic components successfully loaded."; response.result = "SUCCESS"; d.resolve(response); @@ -291,35 +344,6 @@ var subscribeTopics = function(session, topic_connection, onBoardConnected) { session.publish(topic_connection, ['Iotronic-connected', session._id]); }; -// NO USED ANYMORE -/* -var mngRpcRegister = function(session){ - - logger.debug("[SYSTEM] - " + "Registering IoTronic RPCs:"); - - // CHECK IF IOTRONIC IS ALIVE------------------------------------------------------------------------------------------------------------------- - session.register('s4t.iotronic.isAlive', board_utils.isAlive); - logger.debug('[SYSTEM] --> s4t.iotronic.isAlive'); - // --------------------------------------------------------------------------------------------------------------------------------------------- - - // PROVISIONING OF A NEW BOARD------------------------------------------------------------------------------------------------------------------ - session.register('s4t.board.provisioning', board_utils.Provisioning); - logger.debug('[SYSTEM] --> s4t.board.provisioning'); - // --------------------------------------------------------------------------------------------------------------------------------------------- - - - // BOARD SERVICES RESTORE ON CONNECTION--------------------------------------------------------------------------------------------------------- - session.register('s4t.iotronic.service.restore', services_utils.restoreServices); - logger.debug('[SYSTEM] --> s4t.iotronic.service.restore'); - // --------------------------------------------------------------------------------------------------------------------------------------------- - - // VNET CONFIGURATION INJECTION AFTER BOARD RECONNECTION---------------------------------------------------------------------------------------- - session.register('s4t.iotronic.vnet.result_network_board', net_utils.result_network_board); - logger.debug('[SYSTEM] --> s4t.iotronic.vnet.result_network_board'); - // --------------------------------------------------------------------------------------------------------------------------------------------- - -}; -*/ module.exports.initIoTronicModules = initIoTronicModules; module.exports.loadIoTronicModules = loadIoTronicModules; diff --git a/lib/iotronic_standalone.js b/lib/iotronic_standalone.js index b206fa4..9bcfb3f 100644 --- a/lib/iotronic_standalone.js +++ b/lib/iotronic_standalone.js @@ -17,6 +17,7 @@ //## //############################################################################################ + nconf = require('nconf'); log4js = require('log4js'); @@ -58,9 +59,16 @@ iotronic_standalone.prototype.start = function (wamp_router_url, wamp_realm) { logger.info("[SYSTEM] - Connected to WAMP router!"); + if (https_enable == "true"){ + logger.info("[SYSTEM] - Admin dashboard available at https://" + IoTronic_IP + "/iotronic/login"); + + }else{ + logger.info("[SYSTEM] - Admin dashboard available at http://" + IoTronic_IP + "/iotronic/login"); + } + iotronic_session = session; - if (IoTronic_IP != undefined) { + if (API_IP != undefined) { var rest = express(); @@ -83,9 +91,9 @@ iotronic_standalone.prototype.start = function (wamp_router_url, wamp_realm) { if ( (docs_embedded == "true" || docs_embedded == true) && (docs_exp == "false" || docs_exp == false) ){ if (https_enable == "true"){ - link_docs = "https://" + IoTronic_IP + ":" + https_port + "/v1/iotronic-api-docs/"; + link_docs = "https://" + API_IP + ":" + https_port + "/v1/iotronic-api-docs/"; }else{ - link_docs = "http://" + IoTronic_IP + ":" + http_port + "/v1/iotronic-api-docs/"; + link_docs = "http://" + API_IP + ":" + http_port + "/v1/iotronic-api-docs/"; } res.status(200).send("
Welcome in Iotronic-standalone!


Please visit API documentation
"); @@ -116,7 +124,7 @@ iotronic_standalone.prototype.start = function (wamp_router_url, wamp_realm) { rest.use(function(req, res, next) { - console.log("URL: " + req.url); console.log("Header:\n" + JSON.stringify(req.headers, null, "\t")); console.log("Body:\n" + JSON.stringify(req.body, null, "\t")); + //console.log("URL: " + req.url); console.log("Header:\n" + JSON.stringify(req.headers, null, "\t")); console.log("Body:\n" + JSON.stringify(req.body, null, "\t")); var ip_requester = req.headers['x-forwarded-for'] || req.connection.remoteAddress; @@ -198,6 +206,7 @@ iotronic_standalone.prototype.start = function (wamp_router_url, wamp_realm) { if (load_result.result == "SUCCESS"){ logger.info("[SYSTEM] - " + load_result.message); + logger.info("[SYSTEM] -------------------------------------------------------"); // REST server starting if there are not errors caught if (iotronic_status === "OK") { @@ -233,7 +242,7 @@ iotronic_standalone.prototype.start = function (wamp_router_url, wamp_realm) { //logger.debug("CREDENTIALS: " + JSON.stringify(credentials)); https.createServer(credentials, rest).listen(https_port, function(){ - logger.info("[SYSTEM] - Server REST started on: https://" + IoTronic_IP + ":" + https_port + " - IoTronic CERT: \n" + s4t_cert); + logger.info("[SYSTEM] - Server REST started on: https://" + API_IP + ":" + https_port + " - IoTronic CERT: \n" + s4t_cert); }); }else{ @@ -242,7 +251,7 @@ iotronic_standalone.prototype.start = function (wamp_router_url, wamp_realm) { server_rest_port = http_port; var http = require('http'); http.createServer(rest).listen(http_port, function(){ - logger.info("[SYSTEM] - Server REST started on: http://" + IoTronic_IP + ":" + http_port); + logger.info("[SYSTEM] - Server REST started on: http://" + API_IP + ":" + http_port); }); } diff --git a/lib/management/mng_auth.js b/lib/management/mng_auth.js index 00b4a87..7e3be9a 100644 --- a/lib/management/mng_auth.js +++ b/lib/management/mng_auth.js @@ -29,6 +29,9 @@ var wamp = require('./mng_wamp'); var uuid = require('node-uuid'); var bcrypt = require('bcrypt'); var jwt = require('jsonwebtoken'); +var fs = require('fs'); +var crypto = require('crypto'); + auth = function (session, rest) { @@ -95,6 +98,8 @@ auth = function (session, rest) { */ rest.post('/v1/auth/',function(req, res){ + //console.log("URL: " + req.url); console.log("Header:\n" + JSON.stringify(req.headers, null, "\t")); console.log("Body:\n" + JSON.stringify(req.body, null, "\t")); + var message; var response = { @@ -131,7 +136,7 @@ auth = function (session, rest) { logger.info("[USER] - Token request from user: " + selected_user.username); - checkPassword(req.body.password, selected_user.password).then( function (pw_result) { + verifyPassword(req.body.password, selected_user.password).then( function (pw_result) { if (pw_result.result == "SUCCESS"){ @@ -183,7 +188,7 @@ auth = function (session, rest) { -var checkAuthorization = function (board_id, callback) { +var checkAuthorization = function (board_id, auth_credentials, callback) { var response = { message: '', @@ -191,53 +196,48 @@ var checkAuthorization = function (board_id, callback) { }; - if( auth_lr_mode == "basic" ){ + db.checkBoard(board_id, function (data) { - db.checkBoard(board_id, function (data) { - - if (data.result == "ERROR") { + if (data.result == "ERROR") { - logger.error("[SYSTEM] --> " + data.message); + logger.error("[SYSTEM] --> " + data.message); - response.message = data.message; - response.result = 'ERROR'; + response.message = data.message; + response.result = 'ERROR'; - callback(response); + callback(response); - } else { + } else { - //console.log(data.message[0].status); + if (data.message.length == 0) { - if (data.message.length == 0) { + // Board not registered in Iotronic - // Board not registered in Iotronic + logger.warn("[SYSTEM] - A not registered board has tried connecting to Iotronic!"); - logger.warn("[SYSTEM] - A not registered board has tried connecting to Iotronic!"); + response.message = "Board with UUID '"+board_id+"' not authorized!"; + response.result = 'REJECTED'; - response.message = "Board with UUID '"+board_id+"' not authorized!"; - response.result = 'REJECTED'; + callback(response); + } + else if (data.message[0].status == "C"){ - callback(response); - - } - else if (data.message[0].status == "C"){ + logger.warn("[SYSTEM] - This board '"+board_id+"' is already connected to Iotronic!"); - logger.warn("[SYSTEM] - This board '"+board_id+"' is already connected to Iotronic!"); + response.message = "Board with UUID '"+board_id+"' is already connected!"; + response.result = 'REJECTED'; - response.message = "Board with UUID '"+board_id+"' is already connected!"; - response.result = 'REJECTED'; + callback(response); - callback(response); + } + else { - } - else { + if( auth_lr_mode == "basic" ){ // Board registered in Iotronic logger.info("[SYSTEM] --> Board with UUID '"+board_id+"' is authorized!"); - //logger.info("[SYSTEM] - Access granted for board " + board_id); - wamp.computeStatus(board_id, data.message[0].state, function (confStatus) { if(confStatus.result == "SUCCESS"){ @@ -262,19 +262,130 @@ var checkAuthorization = function (board_id, callback) { }); + } + else if( auth_lr_mode == "password" ){ + + var b_pw = auth_credentials; + + verifyPassword(b_pw, data.message[0].password).then( + + function (pw_result) { + + if (pw_result.result == "SUCCESS"){ + + // Board registered in Iotronic + logger.info("[SYSTEM] --> Board with UUID '"+board_id+"' is authorized!"); + + wamp.computeStatus(board_id, data.message[0].state, function (confStatus) { + + if(confStatus.result == "SUCCESS"){ + + response.message = confStatus.message; + response.result = 'SUCCESS'; + + callback(response); + + + }else{ + + logger.error("[SYSTEM] --> " + confStatus.message); + + response.message = confStatus.message; + response.result = 'ERROR'; + + callback(response); + + + } + + }); + + }else{ + logger.warn("[SYSTEM] --> " + pw_result.message); + + response.message = pw_result.message; + response.result = 'REJECTED'; + + callback(response); + } + + } + + ); + + + } + else if( auth_lr_mode == "certs" ) { + + //get board public key from DB + var board_publicKey = data.message[0].pubkey; //fs.readFileSync('/opt/stack4things/new-iotronic-standalone/ssl/client.pem', 'utf-8'); + + //console.log(board_publicKey) + logger.debug("[AUTH] - Public Key:\n"+board_publicKey); + + verifySignature(board_id, auth_credentials, board_publicKey).then( + + function (signV) { + + if(signV.result == "SUCCESS"){ + + // Board registered in Iotronic + logger.info("[SYSTEM] --> Board with UUID '"+board_id+"' is authorized!"); + + wamp.computeStatus(board_id, data.message[0].state, function (confStatus) { + + if(confStatus.result == "SUCCESS"){ + + response.message = confStatus.message; + response.result = 'SUCCESS'; + + callback(response); + + + }else{ + + logger.error("[SYSTEM] --> " + confStatus.message); + + response.message = confStatus.message; + response.result = 'ERROR'; + + callback(response); + + + } + + }); + + }else{ + + logger.warn("[SYSTEM] --> " + signV.message); + + response.message = signV.message; + response.result = 'REJECTED'; + + callback(response); + + } + + } + + ); } + + + } - }); + } - } + }); -}; +}; Array.prototype.findByValueOfObject = function(key, value) { return this.filter(function(item) { @@ -282,7 +393,6 @@ Array.prototype.findByValueOfObject = function(key, value) { }); }; - var encryptPassword = function (user_pw, callback) { var response = { @@ -308,8 +418,7 @@ var encryptPassword = function (user_pw, callback) { }; - -var checkPassword = function(user_pw, crypted_pw) { +var verifyPassword = function(user_pw, crypted_pw) { var response = { message: '', @@ -336,7 +445,279 @@ var checkPassword = function(user_pw, crypted_pw) { }; +var verifySignature = function(board_id, board_signature, board_publicKey) { + + var response = { + message: '', + result: '' + }; + + var d = Q.defer(); + + board_signature = Buffer.from(board_signature, 'base64'); + + var verify = crypto.createVerify('RSA-SHA256'); + verify.update(board_id); verify.end(); + var verification = verify.verify(board_publicKey, board_signature); + + if (verification){ + //authorized + response.message = "board certificate is valid!"; + response.result = "SUCCESS"; + logger.info("[AUTH] - Board '"+board_id+"' signature verified!"); + logger.debug("[AUTH] --> Board signature:\n"+board_signature.toString('hex')); + d.resolve(response); + }else{ + //no authorized + response.message = "board certificate is not valid!"; + response.result = "ERROR"; + d.resolve(response); + } + + return d.promise; + +}; + +var computePassword = function (b_pw, callback) { + + var response = { + message: '', + result: '' + }; + + + //b_pw.trim(); //avoid password composed from "spaces" + + if( auth_lr_mode == "password"){ + + if(b_pw == "" || b_pw == undefined){ + + crypto.randomBytes(18, function(err, buffer) { //36 char + + if (err) { + response.message = "Error generating board password: " + err.message; + response.result = "ERROR"; + callback(response); + + } else { + response.message = buffer.toString('hex'); + response.result = "SUCCESS"; + callback(response); + } + + + }); + + + } + else{ + + if(b_pw.length > 60 || b_pw.length < 4){ + response.message = "Board password must be between 4 and 60 characters long! ("+b_pw.length+" long)"; + response.result = "ERROR"; + callback(response); + } + else{ + + response.message = b_pw; + response.result = "SUCCESS"; + callback(response); + + } + + } + + } + + + + +}; + +var computeCredentials = function (b_pw, b_pub_key, callback) { + + var response = { + hash_pw: '', + pub_key: '', + message: '', + result: '' + }; + + if( auth_lr_mode == "password"){ + + if(b_pw != undefined && b_pw != "") { + + if(b_pw.length > 60 || b_pw.length < 4){ + response.message = "Board password must be between 4 and 60 characters long! ("+b_pw.length+" long)"; + response.result = "ERROR"; + callback(response); + } + else{ + + encryptPassword(b_pw, function (pw_result) { + + if (pw_result.result == "ERROR") { + response.message = pw_result.message; + response.result = pw_result.result; + callback(response); + + } else { + + response.message = "credentials"; + response.result = "SUCCESS"; + response.hash_pw = pw_result.message; + callback(response); + + } + + }); + + } + + } + else if(b_pw == "" || b_pw == undefined){ + + crypto.randomBytes(18, function(err, buffer) { //36 char + + if (err) { + response.message = "Error generating board password: " + err.message; + response.result = "ERROR"; + callback(response); + + } else { + + var gen_pw = buffer.toString('hex'); + + encryptPassword(gen_pw, function (pw_result) { + + if (pw_result.result == "ERROR") { + response.message = pw_result.message; + response.result = pw_result.result; + callback(response); + + } else { + + response.message = "credentials"; + response.result = "SUCCESS"; + response.hash_pw = pw_result.message; + callback(response); + + } + + }); + + } + + + }); + + + } + + + } + else if( auth_lr_mode == "certs" ){ + + if(b_pub_key == "" || b_pub_key == undefined){ + + response.message = "Public Key not specified!"; + response.result = "ERROR"; + callback(response); + + }else{ + response.message = "credentials"; + response.result = "SUCCESS"; + response.pub_key = b_pub_key; + callback(response); + } + + + } + else if ( auth_lr_mode == "basic" ){ + + response.message = "credentials"; + response.result = "SUCCESS"; + callback(response); + + } + + +}; + +var updateCredentials = function (b_pw, b_pub_key, callback) { + + var response = { + hash_pw: '', + pub_key: '', + message: '', + result: '' + }; + + if( auth_lr_mode == "password"){ + + if(b_pw != undefined && b_pw != "") { + + if(b_pw.length > 60 || b_pw.length < 4){ + response.message = "Board password must be between 4 and 60 characters long! ("+b_pw.length+" long)"; + response.result = "ERROR"; + callback(response); + } + else{ + + encryptPassword(b_pw, function (pw_result) { + + if (pw_result.result == "ERROR") { + response.message = pw_result.message; + response.result = pw_result.result; + callback(response); + + } else { + + response.message = "credentials"; + response.result = "SUCCESS"; + response.hash_pw = pw_result.message; + callback(response); + + } + + }); + + } + + } + else if(b_pw == "" || b_pw == undefined){ + + response.message = "credentials"; + response.result = "SUCCESS"; + callback(response); + + } + + + } + else if( auth_lr_mode == "certs" ){ + + response.message = "credentials"; + response.result = "SUCCESS"; + response.pub_key = b_pub_key; + callback(response); + + } + else if ( auth_lr_mode == "basic" ){ + + response.message = "credentials"; + response.result = "SUCCESS"; + callback(response); + + } + + +}; + module.exports = auth; -module.exports.checkPassword = checkPassword; +module.exports.verifyPassword = verifyPassword; module.exports.encryptPassword = encryptPassword; +module.exports.computePassword = computePassword; +module.exports.computeCredentials = computeCredentials; +module.exports.updateCredentials = updateCredentials; module.exports.checkAuthorization = checkAuthorization; \ No newline at end of file diff --git a/lib/management/mng_board.js b/lib/management/mng_board.js index facf725..0b48389 100644 --- a/lib/management/mng_board.js +++ b/lib/management/mng_board.js @@ -27,6 +27,8 @@ var Q = require("q"); var project_utils = require('./mng_project'); var request_utils = require('./mng_request'); +var auth = require('./mng_auth'); + var session_wamp; @@ -367,7 +369,6 @@ board_utils = function (session, rest) { * - notify * - notify_rate * - notify_retry - * - state * properties: * board_id: * type: string @@ -375,6 +376,12 @@ board_utils = function (session, rest) { * board_label: * type: string * description: "Board label" + * password: + * type: string + * description: "Board password: used only in 'password' authentication mode and if it is not specified Iotronic will generate a random password (alphanumeric 36 chars long)." + * pubkey: + * type: string + * description: "Board password: used only in 'certs' authentication mode and if it is not specified Iotronic return an error." * latitude: * type: number * description: "Board latitude" @@ -420,9 +427,6 @@ board_utils = function (session, rest) { * notify_retry: * type: integer * description: "number of notifications retry" - * state: - * type: string - * description: "Board registration state: 'new' or 'registered'." * responses: * 200: * description: A Json IoTronic response @@ -435,6 +439,11 @@ board_utils = function (session, rest) { */ rest.post('/v1/boards/', function (req, res) { + var response = { + result: '', + message: '' + }; + var board_id = req.body.board_id; var board_label = req.body.board_label; var description = req.body.description; @@ -458,13 +467,14 @@ board_utils = function (session, rest) { var extra = req.body.extra; - var response = { - result: '', - message: '' - }; + var b_pub_key = req.body.pubkey; + if(b_pub_key == undefined) b_pub_key = ""; + var b_pw = req.body.password; + if(b_pw == undefined) b_pw = ""; var ApiRequired= { "board_id":board_id, "board_label":board_label, "latitude":latitude, "longitude":longitude, "altitude":altitude, - "net_enabled":net_enabled, "layout_id":layout_id, "user_id":user_id, "project_id":project_id, "mobile":mobile, "position_refr_time":position_refr_time, "notify":notify, "notify_rate":notify_rate, "notify_retry":notify_retry}; + "net_enabled":net_enabled, "layout_id":layout_id, "user_id":user_id, "project_id":project_id, "mobile":mobile, "position_refr_time":position_refr_time, + "notify":notify, "notify_rate":notify_rate, "notify_retry":notify_retry}; checkRequired(ApiRequired, function (check){ @@ -491,25 +501,55 @@ board_utils = function (session, rest) { try { - logger.info("[SYSTEM] - New board " + board_label + " (" + board_id + ") - registration parameters:\n" + JSON.stringify(req.body, null, "\t")); + logger.debug("[SYSTEM] - New board '" + board_label + "' (ID: " + board_id + ")"); + //logger.debug("[SYSTEM] - New board '" + board_label + "' (ID: " + board_id + ") - registration parameters:\n" + JSON.stringify(req.body, null, "\t")); + if(extra == undefined) extra = '{}'; - db.regBoard(board_id, board_label, latitude, longitude, altitude, net_enabled, sensorslist, layout_id, description, extra, project_id, user_id, mobile, position_refr_time, notify, notify_rate, notify_retry, function (db_result) { + auth.computeCredentials(b_pw, b_pub_key, function(credentials) { - if (db_result.result === "SUCCESS") { - - logger.info("[SYSTEM] --> Registration of board '" + board_id + "' successfully completed!"); - res.status(200).send(db_result); + if (credentials.result == "ERROR") { + + response.message = credentials.message; + response.result = credentials.result; + logger.error("[SYSTEM] --> " + response.message); + res.status(500).send(response); } else { - res.status(500).send(db_result); - } + + var hash_b_pw = credentials.hash_pw; + var b_pub_key = credentials.pub_key; + + db.regBoard(board_id, board_label, latitude, longitude, altitude, net_enabled, sensorslist, layout_id, description, + extra, project_id, user_id, mobile, position_refr_time, notify, notify_rate, notify_retry, b_pub_key, hash_b_pw, + + function (db_result) { + + if (db_result.result === "SUCCESS") { + + logger.info("[SYSTEM] --> Registration of board '" + board_id + "' successfully completed!"); + db_result.password = b_pw; + + res.status(200).send(db_result); + + } else { + res.status(500).send(db_result); + } + } + + ); + + } + }); + + + } catch (err) { @@ -520,6 +560,7 @@ board_utils = function (session, rest) { } + } @@ -570,6 +611,12 @@ board_utils = function (session, rest) { * board_label: * type: string * description: "Board label" + * password: + * type: string + * description: "Board password: used only in 'password' authentication mode and if it is specified Iotronic will update the existing password." + * pubkey: + * type: string + * description: "Board password: used only in 'certs' authentication mode." * latitude: * type: number * description: "Board latitude" @@ -656,14 +703,17 @@ board_utils = function (session, rest) { var notify_rate = req.body.notify_rate; var notify_retry = req.body.notify_retry; + var b_pub_key = req.body.pubkey; + var b_pw = req.body.password; + var response = { result: "", message: "" }; logger.info("[SYSTEM] - BOARD " + board_label + " (" + board + ") UPDATING..."); - logger.debug("[SYSTEM] --> New configuration\n" + JSON.stringify(req.body, null, "\t")); - logger.debug(extra); + //logger.debug("[SYSTEM] --> New configuration\n" + JSON.stringify(req.body, null, "\t")); + //logger.debug(extra); var ApiRequired = { "board_label":board_label, "latitude":latitude, "longitude":longitude, "altitude":altitude, @@ -692,76 +742,104 @@ board_utils = function (session, rest) { } else{ - db.updateBoard(board, board_label, latitude, longitude, altitude, net_enabled, sensorslist, layout_id, description, extra, project_id, user_id, mobile, position_refr_time, - notify, notify_rate, notify_retry, state, function (db_result) { + auth.updateCredentials(b_pw, b_pub_key, function(credentials) { - if (db_result.result == "ERROR") { - logger.error("[SYSTEM] --> " + db_result.message); - res.status(500).send(db_result); - - } else { + if (credentials.result == "ERROR") { + response.message = credentials.message; + response.result = credentials.result; + logger.error("[USER] --> " + response.message); + res.status(500).send(response); - var position = { - "altitude": altitude, - "longitude": longitude, - "latitude": latitude - }; + } else { - db.checkBoardConnected(board, function (check_result) { + var hash_b_pw = credentials.hash_pw; + var b_pub_key = credentials.pub_key; - if (check_result.result == "ERROR") { + db.updateBoard(board, board_label, latitude, longitude, altitude, net_enabled, sensorslist, layout_id, description, + extra, project_id, user_id, mobile, position_refr_time, notify, notify_rate, notify_retry, state, b_pub_key, hash_b_pw, + function (db_result) { - response.result = check_result.result; - response.message = "DB checkBoardConnected error for board " + board + ": " + check_result.message; - logger.error("[SYSTEM] --> " + response.message); - res.status(500).send(response); + if (db_result.result == "ERROR") { + logger.error("[SYSTEM] --> " + db_result.message); + res.status(500).send(db_result); } else { - var status = check_result.message[0].status; + var position = { + "altitude": altitude, + "longitude": longitude, + "latitude": latitude + }; - if (status === "C") { + db.checkBoardConnected(board, function (check_result) { - logger.debug("[SYSTEM] - RPC call towards: 's4t." + board + "'.board.setBoardPosition \n with parameters: " + JSON.stringify(position)); + if (check_result.result == "ERROR") { - session.call('s4t.' + board + '.board.setBoardPosition', [position]).then( - - function (conf_result) { - response.message = db_result.message + " - " + conf_result; - response.result = "SUCCESS"; - res.status(200).send(response); - }, - function (rpc_error) { + response.result = check_result.result; + response.message = "DB checkBoardConnected error for board " + board + ": " + check_result.message; + logger.error("[SYSTEM] --> " + response.message); + res.status(500).send(response); + + } else { + + var status = check_result.message[0].status; + + if (status === "C") { + + logger.debug("[SYSTEM] - RPC call towards: 's4t." + board + "'.board.setBoardPosition \n with parameters: " + JSON.stringify(position)); + + var tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds + var localISOTime = (new Date(Date.now() - tzoffset)).toISOString(); + position.timestamp=localISOTime; + + session.call('s4t.' + board + '.board.setBoardPosition', [position]).then( + + function (conf_result) { + response.message = db_result.message + " - " + conf_result; + response.result = "SUCCESS"; + res.status(200).send(response); + }, + function (rpc_error) { - response.message = "RPC UNAVAILABLE: " + rpc_error.error; + response.message = "RPC UNAVAILABLE: " + rpc_error.error; + response.result = "WARNING"; + logger.warn("[SYSTEM] - RPC UNAVAILABLE: " + rpc_error.error); + res.status(200).send(response); + + } + + ); + + } else { + + response.message = db_result.message + " - !!! WARNING: REMOTE BOARD CONFIGURATION NOT UPDATED !!!"; response.result = "WARNING"; - logger.warn("[SYSTEM] - RPC UNAVAILABLE: " + rpc_error.error); + res.status(200).send(response); - } - - ); - } else { - - response.message = db_result.message + " - !!! WARNING: REMOTE BOARD CONFIGURATION NOT UPDATED !!!"; - response.result = "WARNING"; + } - res.status(200).send(response); - } - } + }); - }); + } - } + } + ); + } - ); + }); + + + + + } @@ -1046,6 +1124,12 @@ board_utils = function (session, rest) { * action: * type: string * description: "supported actions: hostname, reboot, restart_lr" + * parameters: + * type: object + * description: "JSON object where specify action arguments" + * long_running: + * type: boolean + * description: "If 'false' the api will wait for action response; if 'true' Iotronic release a 'request-id' to be used to retrieve the response." * produces: * - application/json * responses: @@ -1063,7 +1147,13 @@ board_utils = function (session, rest) { logger.info("[API] - Board Operation - " + Object.keys( req.route.methods ) + " - " + req.route.path + " - " + req.IotronicUser); var action = req.body.action; // reboot | etc.. + var long_running = req.body.long_running; var parameters = req.body.parameters; // OPTIONAL + + if(long_running == "true") + long_running = true; + else if (long_running == undefined || long_running == "" || long_running == "false") + long_running = false; var ApiRequired = {"action":action}; @@ -1075,8 +1165,18 @@ board_utils = function (session, rest) { } else { - var request_id = null; - execActionOnBoard(board, request_id, [action, parameters, res]); + if(long_running){ + + var subject = "board action: " + action; + request_utils.singleRequest(board, subject, res, execActionOnBoard, [action, parameters, false]); + + } + else{ + var request_id = null; + execActionOnBoard(board, request_id, [action, parameters, res]); + } + + } @@ -1114,6 +1214,12 @@ board_utils = function (session, rest) { * action: * type: string * description: "supported actions: hostname, reboot, restart_lr" + * parameters: + * type: object + * description: "JSON object where specify action arguments" + * long_running: + * type: boolean + * description: "If 'false' the api will wait for action response; if 'true' Iotronic release a 'request-id' to be used to retrieve the response." * produces: * - application/json * responses: @@ -1134,11 +1240,6 @@ board_utils = function (session, rest) { var ApiRequired = {"action":action}; - var response = { - message: '', - result: '' - }; - checkRequired(ApiRequired, function (check) { if (check.result == "ERROR") { @@ -1147,7 +1248,7 @@ board_utils = function (session, rest) { } else { - var subject = "/projects/"+project+"/boards/action"; + var subject = "board action: " + action; request_utils.batchRequest(project, subject, res, execActionOnBoard, [action, parameters, false]); @@ -1158,7 +1259,7 @@ board_utils = function (session, rest) { }); - + //Add board position /** * @swagger @@ -1535,6 +1636,7 @@ board_utils = function (session, rest) { result: '' }; + checkBoardExists(board, res, function (available) { if (available.result == "SUCCESS") { @@ -1590,7 +1692,7 @@ board_utils = function (session, rest) { result: '' }; - var subject = "/projects/"+project+"/boards/conf"; + var subject = "inject configuration"; request_utils.batchRequest(project, subject, res, board_utils.injectConf, [false]); @@ -1598,6 +1700,418 @@ board_utils = function (session, rest) { }); + + //Manage package on board + /** + * @swagger + * /v1/boards/{board}/package: + * post: + * tags: + * - Boards + * description: Manage packages on IoTronic board + * summary: manage packages on a board + * parameters: + * - in: path + * name: board + * required: true + * schema: + * type: string + * description: The IoTronic board ID + * - name: body + * in: body + * required: true + * schema: + * type: object + * required: + * - pkg_mng + * - pkg_mng_cmd + * - pkg_name + * properties: + * pkg_mng: + * type: string + * description: "package manager: 'apt', 'apt-get', 'pip', 'pip3', 'opkg'" + * pkg_mng_cmf: + * type: string + * description: "package manager sub-command: 'install', 'update', 'remove', etc..." + * pkg_name: + * type: string + * description: "package name" + * pkg_opts: + * type: string + * description: "options supported by package managers, e.g. '-y', '--force', etc..." + * produces: + * - application/json + * responses: + * 200: + * $ref: "#/definitions/IoTronicResponse" + * 403: + * description: "Wrong, expired or not specified token in request header." + * 500: + * description: "API specific error message." + */ + rest.post('/v1/boards/:board/package', function (req, res) { + + var board = req.params.board; + + logger.info("[API] - Manage package on board - " + Object.keys( req.route.methods ) + " - " + req.route.path + " - " + req.IotronicUser); + + var action = "pkg_manager"; + var long_running = req.body.long_running; + + var pkg_mng = req.body.pkg_mng; + var pkg_mng_cmd = req.body.pkg_mng_cmd; + var pkg_opts = req.body.pkg_opts; + var pkg_name = req.body.pkg_name; + + var parameters = {}; + parameters.pkg_mng = pkg_mng; + parameters.pkg_mng_cmd = pkg_mng_cmd; + parameters.pkg_opts = pkg_opts; + parameters.pkg_name = pkg_name; + + if(long_running == "true") + long_running = true; + else if (long_running == undefined || long_running == "" || long_running == "false") + long_running = false; + + var ApiRequired = {"pkg_mng":pkg_mng, "pkg_mng_cmd":pkg_mng_cmd, "pkg_name":pkg_name}; + + checkRequired(ApiRequired, function (check) { + + if (check.result == "ERROR") { + + res.status(500).send(check); + + } else { + + if(long_running){ + + var subject = pkg_mng_cmd + " package " + pkg_name; + request_utils.singleRequest(board, subject, res, execActionOnBoard, [action, parameters, false]); + + } + else{ + var request_id = null; + execActionOnBoard(board, request_id, [action, parameters, res]); + } + + + + } + + }); + + }); + + //BATCH: Manage package on board + /** + * @swagger + * /v1/projects/{project}/package: + * post: + * tags: + * - Boards + * description: Manage packages on IoTronic boards in a project + * summary: "manage packages on project's boards" + * parameters: + * - in: path + * name: project + * required: true + * schema: + * type: string + * description: The IoTronic project ID + * - name: body + * in: body + * required: true + * schema: + * type: object + * required: + * - pkg_mng + * - pkg_mng_cmd + * - pkg_name + * properties: + * pkg_mng: + * type: string + * description: "package manager: 'apt', 'apt-get', 'pip', 'pip3', 'opkg'" + * pkg_mng_cmf: + * type: string + * description: "package manager sub-command: 'install', 'update', 'remove', etc..." + * pkg_name: + * type: string + * description: "package name" + * pkg_opts: + * type: string + * description: "options supported by package managers, e.g. '-y', '--force', etc..." + * produces: + * - application/json + * responses: + * 200: + * $ref: "#/definitions/IoTronicResponse" + * 403: + * description: "Wrong, expired or not specified token in request header." + * 500: + * description: "API specific error message." + */ + rest.post('/v1/projects/:project/boards/package', function (req, res) { + + logger.info("[API] - Batch - Board operation - " + Object.keys( req.route.methods ) + " - " + req.route.path + " - " + req.IotronicUser); + + var project = req.params.project; + var action = "pkg_manager"; + + var pkg_mng = req.body.pkg_mng; + var pkg_mng_cmd = req.body.pkg_mng_cmd; + var pkg_opts = req.body.pkg_opts; + var pkg_name = req.body.pkg_name; + + var parameters = {}; + parameters.pkg_mng = pkg_mng; + parameters.pkg_mng_cmd = pkg_mng_cmd; + parameters.pkg_opts = pkg_opts; + parameters.pkg_name = pkg_name; + + var ApiRequired = {"pkg_mng":pkg_mng, "pkg_mng_cmd":pkg_mng_cmd, "pkg_name":pkg_name}; + + checkRequired(ApiRequired, function (check) { + + if (check.result == "ERROR") { + + res.status(500).send(check); + + } else { + + var subject = pkg_mng_cmd + " package " + pkg_name; + + request_utils.batchRequest(project, subject, res, execActionOnBoard, [action, parameters, false]); + + + } + + }); + + + }); + + //Manage LR update + /** + * @swagger + * /v1/boards/{board}/lr: + * post: + * tags: + * - Boards + * description: Manage Lightning-rod package on a board + * summary: manage Lightning-rod package + * parameters: + * - in: path + * name: board + * required: true + * schema: + * type: string + * description: The IoTronic board ID + * - name: body + * in: body + * required: true + * schema: + * type: object + * required: + * - operation + * properties: + * operation: + * type: string + * description: "You have to specify one of these two options: 'update' or 'revert' (to downgrade to the previous version)." + * lr_version: + * type: string + * description: "ONLY for debian boards: Lightning-rod package version." + * produces: + * - application/json + * responses: + * 200: + * $ref: "#/definitions/IoTronicResponse" + * 403: + * description: "Wrong, expired or not specified token in request header." + * 500: + * description: "API specific error message." + */ + rest.post('/v1/boards/:board/lr', function (req, res) { + + logger.info("[API] - Manage package on board - " + Object.keys( req.route.methods ) + " - " + req.route.path + " - " + req.IotronicUser); + + var board = req.params.board; + var lr_new_version = req.body.lr_version; + var operation = req.body.operation; + + + var response = { + message: '', + result: '' + }; + + + switch (operation) { + + case 'update': + + db.BoardInfo(board, function (data) { + + if (data.result == "ERROR") { + + response.message = "Error getting board info: " + data.message; + response.result = "ERROR"; + logger.error("[SYSTEM] --> " + response.message); + res.status(500).send(response); + + } else { + + var lr_version = data.message.info.lr_version; + + if (lr_version == lr_new_version) { + + response.message = "Warning: LR is already updated at this version: " + lr_version; + response.result = "WARNING"; + logger.warn("[SYSTEM] --> " + response.message); + res.status(500).send(response); + + } + else { + + var distro = data.message.info.distro; + + if (distro == "openwrt") + var pkg_mng = "opkg"; + else if (distro == "debian") + var pkg_mng = "apt-get"; + else { + response.message = "Error: wrong image distribution!"; + response.result = "ERROR"; + logger.error("[SYSTEM] --> " + response.message); + res.status(500).send(response); + } + + var action = "update_lr"; + var subject = "LR update"; + + request_utils.singleRequest(board, subject, res, updateLR, [action, lr_new_version, pkg_mng, operation, false]); + + } + + + } + + }); + + break; + + default: + response.message = "LR operation '" + operation + "' not supported!"; + response.result = 'ERROR'; + logger.error("[SYSTEM] - " + response.message); + res.status(500).send(response); + break; + + } + + }); + + //BATCH: Manage LR update + /** + * @swagger + * /v1/projects/{project}/lr: + * post: + * tags: + * - Boards + * summary: Manage Lightning-rod package on the board of a project + * description: Manage Lightning-rod package on the board of a project + * produces: + * - application/json + * parameters: + * - in: path + * name: project + * required: true + * schema: + * type: string + * description: The IoTronic project ID or NAME + * - name: body + * in: body + * required: true + * schema: + * type: object + * required: + * - operation + * - distro + * properties: + * operation: + * type: string + * description: "You have to specify one of these two options: 'update' or 'revert' (to downgrade to the previous version)." + * lr_version: + * type: string + * description: "ONLY for debian boards: Lightning-rod package version." + * distro: + * type: string + * description: "You have to specify one of these two options: 'openwrt' or 'debian'." + * responses: + * 200: + * $ref: "#/definitions/IoTronicResponse" + * 403: + * description: "Wrong, expired or not specified token in request header." + * 500: + * description: "API specific error message." + */ + rest.post('/v1/projects/:project/lr', function (req, res) { + + logger.info("[API] - Batch - Update LR called - " + Object.keys( req.route.methods ) + " - " + req.route.path + " - " + req.IotronicUser); + + var project = req.params.project; + var lr_new_version = req.body.lr_version; + var operation = req.body.operation; + var distro = req.body.distro; + + var response = { + message: '', + result: '' + }; + + switch (operation) { + + case 'update': + + var subject = "LR update"; + var action = "update_lr"; + + if (distro != "openwrt" && distro != "debian") { + response.message = "Error: wrong image distribution!"; + response.result = "ERROR"; + logger.error("[SYSTEM] --> " + response.message); + res.status(500).send(response); + } + else { + + if (distro == "openwrt") + var pkg_mng = "opkg"; + else if (distro == "debian") + var pkg_mng = "apt-get"; + + request_utils.batchRequest(project, subject, res, updateLR, [action, lr_new_version, pkg_mng, operation, false]); + + } + + break; + + default: + + response.message = "LR operation '" + operation + "' not supported!"; + response.result = 'ERROR'; + logger.error("[SYSTEM] - " + response.message); + res.status(500).send(response); + + break; + + } + + + }); + + + + logger.debug("[REST-EXPORT] - Board's APIs exposed!"); //--------------------------------------------------------------------------------------------------- @@ -1611,6 +2125,186 @@ board_utils = function (session, rest) { +var updateLR = function (board_id, request_id, args) { + + var response = { + message: {}, + logs: "", + result: "" + }; + + var lr_version = args[1]; + var pkg_mng = args[2]; + var operation = args[3]; + var res = args[4]; + + + checkBoardAvailable(board_id, res, function (available) { + + if (available.result == "SUCCESS") { + + session_wamp.call('s4t.' + board_id + '.board.updateLR', [lr_version, pkg_mng, operation]).then( + + function (rpc_response) { + + logger.info("[SYSTEM] --> On board '" + board_id + "' there is now this LR version: " + rpc_response.lr_version); + + if (rpc_response.result == "ERROR") { + + if(rpc_response.logs != undefined){ + response.message = rpc_response.logs; + + }else + response.message = rpc_response.message; + + response.result = "ERROR"; + + if(res != false){ + logger.error("[SYSTEM] --> Restart LR error on board '" + board_id + "': " + JSON.stringify(response.message)); + res.status(500).send(response); + } + else{ + + request_utils.updateResult(request_id, board_id, response.result, response.message); + + } + + } + else { + + + db.changeBoardState(board_id, "updated", lr_version, function (response) { + + if(response.result == "ERROR") + logger.error("[SYSTEM] - Error updating board state: " +response.message); + else { + logger.debug("[SYSTEM] - Board state '" + board_id + " set to 'updated'"); + + + session_wamp.call('s4t.' + board_id + '.board.execAction', ["restart_lr", null]).then( + + function (restart_response) { + + if (restart_response.result == "ERROR") { + + if(restart_response.logs != undefined){ + response.message = rpc_response.logs + "\n\n" + restart_response.logs; + + }else + response.message = rpc_response.message + "\n\n" + restart_response.message; + + response.result = "ERROR"; + + if(res != false){ + logger.error("[SYSTEM] --> Restart LR error on board '" + board_id + "': " + JSON.stringify(response.message)); + res.status(500).send(response); + } + else{ + + request_utils.updateResult(request_id, board_id, response.result, response.message); + + } + + + }else { + + if(restart_response.logs != undefined){ + response.message = rpc_response.logs + "\n\n" + restart_response.logs; + + }else + response.message = rpc_response.message + "\n\n" + restart_response.message; + + response.result = restart_response.result; + + if(res != false){ + logger.debug("[SYSTEM] --> Update LR result on board '" + board_id + "': " + response.message); + res.status(200).send(response); + } + else{ + + request_utils.updateResult(request_id, board_id, response.result, response.message); + + } + + } + + + }, + function (rpc_error) { + + response.message = "RPC UNAVAILABLE: " + rpc_error.error; + response.result = "WARNING"; + if(res != false){ + logger.warn("[SYSTEM] - RPC UNAVAILABLE: " + rpc_error.error); + res.status(200).send(response); + } + else{ + + request_utils.updateResult(request_id, board_id, response.result, response.message); + + } + + } + + ); + + + } + + }); + + + + } + + + }, + function (rpc_error) { + + response.message = "RPC UNAVAILABLE: " + rpc_error.error; + response.result = "WARNING"; + if(res != false){ + logger.warn("[SYSTEM] - RPC UNAVAILABLE: " + rpc_error.error); + res.status(200).send(response); + } + else{ + + request_utils.updateResult(request_id, board_id, response.result, response.message); + + } + + } + + ); + + } + else if (available.result == "WARNING") { + + if(res != false){ + logger.warn("[API] --> " + available.message); + } + else{ + + var result_msg = "board disconnected"; + + request_utils.updateResult(request_id, board_id, available.result, result_msg); + + } + + } + + + }); + + + + + + + +}; + + var addBoardPosition = function (board, latitude, longitude, altitude, res){ @@ -1675,6 +2369,7 @@ var execActionOnBoard = function (board_id, request_id, args) { var response = { message: {}, + logs: "", result: "" }; @@ -1692,10 +2387,18 @@ var execActionOnBoard = function (board_id, request_id, args) { if (rpc_response.result == "ERROR") { - response.message = rpc_response.message; + if(rpc_response.logs != undefined){ + response.message = rpc_response.message; + response.logs = rpc_response.logs; + + }else + response.message = rpc_response.message; + + response.result = "ERROR"; + if(res != false){ - logger.error("[SYSTEM] --> Action error on board '" + board_id + "': " + response.message); + logger.error("[SYSTEM] --> Action error on board '" + board_id + "': " + JSON.stringify(response.message)); res.status(500).send(response); } else{ @@ -1707,10 +2410,16 @@ var execActionOnBoard = function (board_id, request_id, args) { }else { - response.message = rpc_response.message; + if(rpc_response.logs != undefined){ + response.message = rpc_response.logs; + + }else + response.message = rpc_response.message; + response.result = rpc_response.result; + if(res != false){ - logger.info("[SYSTEM] --> Action result on board '" + board_id + "': " + response.message); + logger.debug("[SYSTEM] --> Action result on board '" + board_id + "': " + response.message); res.status(200).send(response); } else{ @@ -1746,6 +2455,8 @@ var execActionOnBoard = function (board_id, request_id, args) { if(res != false){ logger.warn("[API] --> " + available.message); + res.status(500).send(available); + } else{ @@ -1793,14 +2504,14 @@ var checkBoardAvailable = function (board, res, callback) { if (data.message[0].status == 'D') { response.result = "WARNING"; - response.message = "Board " + board + " is disconnected!"; + response.message = "Board '" + data.message[0].label + "' (" + board + ") is disconnected!"; callback(response); } else { response.result = "SUCCESS"; - response.message = "Board " + board + " is connected!"; + response.message = "Board '" + data.message[0].label + "' (" + board + ") is connected!"; callback(response); } @@ -1809,7 +2520,7 @@ var checkBoardAvailable = function (board, res, callback) { else { response.result = "ERROR"; - response.message = "Board " + board + " doesn't exist!"; + response.message = "Board '" + board + "' doesn't exist!"; if(res != false){ logger.error("[API] - " + response.message); res.status(500).send(response); @@ -1845,17 +2556,17 @@ var checkBoardExists = function (board, res, callback) { } else { if (data.message.length == 1) { + response.result = "SUCCESS"; - response.message = data.message[0]; //"Board "+data.message[0].label+" (" + board + ") exists!"; + response.message = data.message[0]; callback(response); } else { - logger.error("[API] - Board " + board + " does not exist!"); - response.result = "ERROR"; - response.message = "Board " + board + " doesn't exist!"; + response.message = "Board '" + board + "' does not exist!"; + logger.error("[API] - " + response.message); res.status(500).send(response); callback(response); @@ -1864,9 +2575,8 @@ var checkBoardExists = function (board, res, callback) { } - - }); + }; var checkBodyParams = function (req, callback){ @@ -1965,17 +2675,16 @@ var checkRequired = function (APIparams, callback){ }; var createBoardConf = function (board_id, callback) { - + var response = { message: '', result: '' }; - db.BoardInfo(board_id, function (data) { if (data.result == "ERROR") { - + response.message = "Error getting board info: " + data.message; response.result = "ERROR"; logger.error("[SYSTEM] --> " + response.message); @@ -1983,42 +2692,19 @@ var createBoardConf = function (board_id, callback) { } else { - var settings = JSON.parse(fs.readFileSync(__dirname+"/../../utils/board_settings_template.json", 'utf8')); + var settings = JSON.parse(fs.readFileSync(IotronicHome+"/board_settings_template.json", 'utf8')); - settings.config.device = data.message.info.layout; - settings.config.board.code = data.message.info.board_id; settings.config.board.label = data.message.info.label; - settings.config.board.status = "registered"; settings.config.board.position = data.message.info.coordinates; - if( settings.config.wamp.url_wamp == "") - if (wamp_ssl == "true") - settings.config.wamp.url_wamp = "wss://" + IoTronic_IP; - else - settings.config.wamp.url_wamp = "ws://" + IoTronic_IP; - - - if( settings.config.reverse.server.url_reverse == "") - //if (https_enable == "true") - if (wamp_ssl == "true") - settings.config.reverse.server.url_reverse = "wss://" + IoTronic_IP; - else - settings.config.reverse.server.url_reverse = "ws://" + IoTronic_IP; - - response.message = settings; response.result = "SUCCESS"; callback(response); - - } }); - - - - + }; @@ -2082,11 +2768,10 @@ board_utils.prototype.injectConf = function (board_id, request_id, args){ else request_utils.updateResult(request_id, board_id, response.result, response.message); - } else{ - response.message = "Configuration successfully injected into the board" + board_id; + response.message = "Configuration injected into the board '" + board_id + "': LR restarting..."; response.result = "SUCCESS"; if(res != false){ logger.info("[SYSTEM] --> " + response.message); @@ -2095,7 +2780,6 @@ board_utils.prototype.injectConf = function (board_id, request_id, args){ else request_utils.updateResult(request_id, board_id, response.result, response.message); - } }, @@ -2126,6 +2810,7 @@ board_utils.prototype.injectConf = function (board_id, request_id, args){ if(res != false){ logger.warn("[API] --> " + available.message); + res.status(500).send(available); } else{ diff --git a/lib/management/mng_db.js b/lib/management/mng_db.js index d74f9a0..a2fe852 100644 --- a/lib/management/mng_db.js +++ b/lib/management/mng_db.js @@ -30,20 +30,45 @@ var IotronicHome = process.env.IOTRONIC_HOME; var nconf = require('nconf'); nconf.file({file: IotronicHome + '/settings.json'}); -var db_host = nconf.get('config:server:db:host'); -var db_port = nconf.get('config:server:db:port'); -var db_user = nconf.get('config:server:db:user'); -var db_pass = nconf.get('config:server:db:password'); -var db_name = nconf.get('config:server:db:db_name'); +db_host = nconf.get('config:server:db:host'); +db_port = nconf.get('config:server:db:port'); +db_user = nconf.get('config:server:db:user'); +db_pass = nconf.get('config:server:db:password'); +db_name = nconf.get('config:server:db:db_name'); + +if(db_host == "env" && db_port == "env" && db_user == "env" && db_pass == "env" && db_name == "env"){ + + logger.debug("[SYSTEM] - DB (env) configurations."); + + db_host = process.env.DB_HOST; + db_port = process.env.DB_PORT; + db_user = process.env.DB_USER; + db_pass = process.env.DB_PW; + db_name = process.env.DB_NAME; + + //logger.debug(process.env.DB_HOST, process.env.DB_PORT, process.env.DB_USER, process.env.DB_PW, process.env.DB_NAME); + +}else{ + + logger.debug("[SYSTEM] - DB (file) configurations."); + +} + + + var connection; db_utils = function () { - var db_host = nconf.get('config:server:db:host'); - var db_port = nconf.get('config:server:db:port'); - var db_user = nconf.get('config:server:db:user'); - var db_pass = nconf.get('config:server:db:password'); - var db_name = nconf.get('config:server:db:db_name'); + + /* + var db_host = nconf.get('config:server:db:host'); + var db_port = nconf.get('config:server:db:port'); + var db_user = nconf.get('config:server:db:user'); + var db_pass = nconf.get('config:server:db:password'); + var db_name = nconf.get('config:server:db:db_name'); + */ + }; function conn() { @@ -86,10 +111,10 @@ db_utils.prototype.getBoardsList = function (project, callback) { if(project == "all" || project == undefined){ - var query_list = "SELECT * FROM boards b LEFT JOIN coordinates c ON c.board_id = b.board_id WHERE timestamp = (SELECT MAX(timestamp) FROM coordinates c2 WHERE c2.board_id = b.board_id)"; + var query_list = "SELECT * FROM layouts, boards b LEFT JOIN coordinates c ON c.board_id = b.board_id WHERE b.layout_id=layouts.id_layout AND timestamp = (SELECT MAX(timestamp) FROM coordinates c2 WHERE c2.board_id = b.board_id)"; } else - var query_list = "SELECT * FROM boards b LEFT JOIN coordinates c ON c.board_id = b.board_id WHERE b.projects_id = '" + project + "' && timestamp = (SELECT MAX(timestamp) FROM coordinates c2 WHERE c2.board_id = b.board_id)"; + var query_list = "SELECT * FROM layouts, boards b LEFT JOIN coordinates c ON c.board_id = b.board_id WHERE b.layout_id=layouts.id_layout AND b.projects_id = " + mysql.escape(project) + " && timestamp = (SELECT MAX(timestamp) FROM coordinates c2 WHERE c2.board_id = b.board_id)"; connection.query(query_list, function (err, result) { @@ -178,7 +203,7 @@ db_utils.prototype.BoardInfo = function (board, callback) { message: '', result: '' }; - + connection.query("SELECT " + "boards.board_id, " + "boards.label, " + @@ -192,6 +217,8 @@ db_utils.prototype.BoardInfo = function (board, callback) { "boards.notify_rate, " + "boards.notify_retry, " + "boards.extra, " + + "boards.pubkey, " + + "boards.lr_version, " + "boards.position_refresh_time, " + "users.username as user, " + "projects.name as project, " + @@ -199,9 +226,10 @@ db_utils.prototype.BoardInfo = function (board, callback) { "layouts.model, " + "layouts.manufacturer, " + "layouts.image, " + + "layouts.distro, " + "layouts.layout " + "FROM boards, coordinates, layouts, users, projects " + - "WHERE boards.board_id = '" + board + "' AND coordinates.board_id = boards.board_id AND boards.layout_id = layouts.id_layout AND boards.projects_id = projects.uuid AND boards.users_id = users.uuid", function (err_info, result_info) { + "WHERE boards.board_id = " + mysql.escape(board) + " AND coordinates.board_id = boards.board_id AND boards.layout_id = layouts.id_layout AND boards.projects_id = projects.uuid AND boards.users_id = users.uuid", function (err_info, result_info) { if (err_info != null) { @@ -214,7 +242,7 @@ db_utils.prototype.BoardInfo = function (board, callback) { } else { - connection.query("SELECT altitude, longitude, latitude, timestamp FROM coordinates WHERE coordinates.board_id = '" + board + "' ORDER BY timestamp DESC LIMIT 1", function (err_coord, coord) { + connection.query("SELECT altitude, longitude, latitude, timestamp FROM coordinates WHERE coordinates.board_id = " + mysql.escape(board) + " ORDER BY timestamp DESC LIMIT 1", function (err_coord, coord) { if (err_coord != null) { response.result = "ERROR"; @@ -228,7 +256,7 @@ db_utils.prototype.BoardInfo = function (board, callback) { result_info[0]["coordinates"] = coord[0]; result_info[0]["extra"] = JSON.parse(result_info[0]["extra"]); - connection.query("SELECT plugins.name, plugins.id, plugins.category, plugins_injected.state FROM plugins_injected, plugins WHERE plugins_injected.board_id = '" + board + "' AND plugins_injected.plugin_id = plugins.id", function (err_plugin, result_plugin) { + connection.query("SELECT plugins.name, plugins.version, plugins.id, plugins.category, plugins_injected.state FROM plugins_injected, plugins WHERE plugins_injected.board_id = " + mysql.escape(board) + " AND plugins_injected.plugin_id = plugins.id", function (err_plugin, result_plugin) { if (err_plugin != null) { response.result = "ERROR"; @@ -239,7 +267,7 @@ db_utils.prototype.BoardInfo = function (board, callback) { } else { - connection.query("SELECT sensors.type, sensors.model, sensors.id FROM sensors, sensors_on_board WHERE sensors_on_board.id_board = '" + board + "' AND sensors_on_board.id_sensor = sensors.id", function (err_sensor, result_sensor) { + connection.query("SELECT sensors.type, sensors.model, sensors.id FROM sensors, sensors_on_board WHERE sensors_on_board.id_board = " + mysql.escape(board) + " AND sensors_on_board.id_sensor = sensors.id", function (err_sensor, result_sensor) { if (err_sensor != null) { response.result = "ERROR"; @@ -250,7 +278,7 @@ db_utils.prototype.BoardInfo = function (board, callback) { } else { - connection.query("SELECT drivers.name, drivers_injected.state, drivers_injected.latest_change FROM drivers_injected, drivers WHERE drivers.id = drivers_injected.driver_id AND drivers_injected.board_id = '" + board + "'", function (err_driver, result_driver) { + connection.query("SELECT drivers.name, drivers_injected.state, drivers_injected.latest_change FROM drivers_injected, drivers WHERE drivers.id = drivers_injected.driver_id AND drivers_injected.board_id = " + mysql.escape(board), function (err_driver, result_driver) { if (err_driver != null) { response.result = "ERROR"; @@ -262,7 +290,7 @@ db_utils.prototype.BoardInfo = function (board, callback) { } else { - connection.query("SELECT vlan_name, ip_vlan, net_uuid FROM vlans, vlans_connection, socat_connections WHERE id_socat_connection = (select id from socat_connections where id_board='" + board + "') AND vlans_connection.id_socat_connection = socat_connections.id AND vlans_connection.id_vlan = vlans.id", function (err_vnet, result_vnet) { + connection.query("SELECT vlan_name, ip_vlan, net_uuid FROM vlans, vlans_connection, socat_connections WHERE id_socat_connection = (select id from socat_connections where id_board=" + mysql.escape(board) + ") AND vlans_connection.id_socat_connection = socat_connections.id AND vlans_connection.id_vlan = vlans.id", function (err_vnet, result_vnet) { if (err_vnet != null) { response.result = "ERROR"; response.message = err_vnet; @@ -272,8 +300,7 @@ db_utils.prototype.BoardInfo = function (board, callback) { } else { - - connection.query("SELECT services.name, active_services.public_port FROM services, active_services WHERE services.id = active_services.service_id AND active_services.board_id = '" + board + "'", function (err_service, result_service) { + connection.query("SELECT services.name, active_services.public_port, services.port as local_port, services.protocol FROM services, active_services WHERE services.id = active_services.service_id AND active_services.board_id = " + mysql.escape(board), function (err_service, result_service) { if (err_service != null) { response.result = "ERROR"; @@ -331,7 +358,8 @@ db_utils.prototype.BoardInfo = function (board, callback) { }; //Function to register a new board -db_utils.prototype.regBoard = function (board, board_label, latitude, longitude, altitude, net_enabled, sensorsList, layout_id, description, extra, project_id, user_id, mobile, position_refr_time, notify, notify_rate, notify_retry, callback) { +db_utils.prototype.regBoard = function (board, board_label, latitude, longitude, altitude, net_enabled, sensorsList, layout_id, description, extra, project_id, user_id, mobile, + position_refr_time, notify, notify_rate, notify_retry, b_pub_key, b_pw, callback) { var connection = conn(); @@ -340,7 +368,7 @@ db_utils.prototype.regBoard = function (board, board_label, latitude, longitude, result: '' }; - logger.debug("[SYSTEM] --> Sensors list: " + sensorsList); + //logger.debug("[SYSTEM] --> Sensors list: " + sensorsList); if (sensorsList != "empty" && sensorsList != "" && sensorsList != undefined) var sensorsList2 = sensorsList.split(","); @@ -350,13 +378,10 @@ db_utils.prototype.regBoard = function (board, board_label, latitude, longitude, //check if the board already exists //logger.debug("[SYSTEM] --> Board ID check..."); - connection.query("SELECT board_id FROM boards WHERE board_id = '" + board + "'", function (err, result) { + connection.query("SELECT board_id FROM boards WHERE board_id = " + mysql.escape(board) , function (err, result) { if (result.length == 0) { - - //logger.debug("[SYSTEM] ----> Board " + board_label + " ("+board+") is not registered." ); - - + /* Begin transaction */ connection.beginTransaction(function(err) { @@ -385,23 +410,25 @@ db_utils.prototype.regBoard = function (board, board_label, latitude, longitude, notify = 0; connection.query("INSERT INTO boards (board_id, label, session_id, status, net_enabled, layout_id, description, extra, projects_id, users_id, mobile, position_refresh_time, " + - "notify, notify_rate, notify_retry, state) " + - "VALUES ('" + board + "', " + - "'" + board_label + "'," + + "notify, notify_rate, notify_retry, state, pubkey, password) " + + "VALUES (" + mysql.escape(board) + ", " + + mysql.escape(board_label) + "," + "'null'," + "'D', " + - "'" + net_enabled + "', " + - "'" + layout_id + "', " + - "'" + description + "', " + - "'" + extra + "', " + - "'" + project_id + "', " + - "'" + user_id + "', " + - "'" + mobile + "', " + - "'" + position_refr_time + "'," + - "'" + notify +"'," + - "'" + notify_rate +"'," + - "'" + notify_retry +"'," + - "'new')" + mysql.escape(net_enabled) + "," + + mysql.escape(layout_id) + "," + + mysql.escape(description) + "," + + mysql.escape(extra) + "," + + mysql.escape(project_id) + "," + + mysql.escape(user_id) + "," + + mysql.escape(mobile) + "," + + mysql.escape(position_refr_time) + "," + + mysql.escape(notify) + "," + + mysql.escape(notify_rate) + "," + + mysql.escape(notify_retry) + "," + + "'new'," + + mysql.escape(b_pub_key) + "," + + mysql.escape(b_pw) + ")" , function (err, latest_result) { @@ -419,7 +446,7 @@ db_utils.prototype.regBoard = function (board, board_label, latitude, longitude, else { - connection.query("INSERT INTO coordinates (board_id, altitude, longitude, latitude) VALUES ('" + board + "', '" + altitude + "', '" + longitude + "', '" + latitude + "')" , function (err, latest_result) { + connection.query("INSERT INTO coordinates (board_id, altitude, longitude, latitude) VALUES (" + mysql.escape(board) + ", " + mysql.escape(altitude) + ", " + mysql.escape(longitude) + ", " + mysql.escape(latitude) + ")" , function (err, latest_result) { if (err != null) { @@ -557,7 +584,7 @@ db_utils.prototype.regBoard = function (board, board_label, latitude, longitude, //Function to update a new board db_utils.prototype.updateBoard = function (board, board_label, latitude, longitude, altitude, net_enabled, sensorsList, layout_id, description, extra, project_id, user_id, mobile, - position_refr_time, notify, notify_rate, notify_retry, state, callback) { + position_refr_time, notify, notify_rate, notify_retry, state, b_pub_key, hash_b_pw, callback) { var connection = conn(); @@ -573,7 +600,7 @@ db_utils.prototype.updateBoard = function (board, board_label, latitude, longitu if (result.length != 0) { - logger.debug("[SYSTEM] --> Updating Iotronic DB for board " + board + "..."); + //logger.debug("[SYSTEM] --> Updating Iotronic DB for board " + board + "..."); if (net_enabled == "true") net_enabled = 1; @@ -603,24 +630,135 @@ db_utils.prototype.updateBoard = function (board, board_label, latitude, longitu } else { - connection.query("UPDATE boards, coordinates SET " + - "boards.label='" + board_label + "', " + - "boards.layout_id='" + layout_id + "', " + - "boards.description='" + description + "', " + - "boards.extra='" + extra + "', " + - "boards.state='" + state + "', " + - "boards.projects_id='" + project_id + "', " + - "coordinates.altitude='" + altitude + "', " + - "coordinates.longitude='" + longitude + "', " + - "coordinates.latitude='" + latitude + "', " + - "boards.users_id='" + user_id + "', " + - "boards.mobile='" + mobile + "', " + - "boards.net_enabled='" + net_enabled + "', " + - "boards.position_refresh_time='" + position_refr_time + "', " + - "notify='"+notify+"', " + - "notify_rate='"+notify_rate+"', " + - "notify_retry='"+notify_retry+"' " + - "WHERE boards.board_id='" + board + "' AND coordinates.board_id='" + board + "'", function (err, latest_result) { + if( auth_lr_mode == "password" ){ + + if(hash_b_pw != "" && hash_b_pw != undefined){ + + logger.debug("[SYSTEM] --> updating password..."); + + var up_query = "UPDATE boards, coordinates SET " + + "boards.label=" + mysql.escape(board_label) + ", " + + "boards.layout_id=" + mysql.escape(layout_id) + ", " + + "boards.description=" + mysql.escape(description) + ", " + + "boards.extra=" + mysql.escape(extra) + ", " + + "boards.state=" + mysql.escape(state) + ", " + + "boards.projects_id=" + mysql.escape(project_id) + ", " + + "coordinates.altitude=" + mysql.escape(altitude) + ", " + + "coordinates.longitude=" + mysql.escape(longitude) + ", " + + "coordinates.latitude=" + mysql.escape(latitude) + ", " + + "boards.users_id=" + mysql.escape(user_id) + ", " + + "boards.mobile=" + mysql.escape(mobile) + ", " + + "boards.net_enabled=" + mysql.escape(net_enabled) + ", " + + "boards.position_refresh_time=" + mysql.escape(position_refr_time) + ", " + + "notify=" + mysql.escape(notify) + ", " + + "notify_rate=" + mysql.escape(notify_rate) + ", " + + "notify_retry=" + mysql.escape(notify_retry) + ", " + + "pubkey=" + mysql.escape(b_pub_key) + ", " + + "password=" + mysql.escape(hash_b_pw) + " " + + "WHERE boards.board_id=" + mysql.escape(board) + " AND coordinates.board_id=" + mysql.escape(board); + } + else { + + var up_query = "UPDATE boards, coordinates SET " + + "boards.label=" + mysql.escape(board_label) + ", " + + "boards.layout_id=" + mysql.escape(layout_id) + ", " + + "boards.description=" + mysql.escape(description) + ", " + + "boards.extra=" + mysql.escape(extra) + ", " + + "boards.state=" + mysql.escape(state) + ", " + + "boards.projects_id=" + mysql.escape(project_id) + ", " + + "coordinates.altitude=" + mysql.escape(altitude) + ", " + + "coordinates.longitude=" + mysql.escape(longitude) + ", " + + "coordinates.latitude=" + mysql.escape(latitude) + ", " + + "boards.users_id=" + mysql.escape(user_id) + ", " + + "boards.mobile=" + mysql.escape(mobile) + ", " + + "boards.net_enabled=" + mysql.escape(net_enabled) + ", " + + "boards.position_refresh_time=" + mysql.escape(position_refr_time) + ", " + + "notify=" + mysql.escape(notify) + ", " + + "notify_rate=" + mysql.escape(notify_rate) + ", " + + "notify_retry=" + mysql.escape(notify_retry) + ", " + + "pubkey=" + mysql.escape(b_pub_key) + + "WHERE boards.board_id=" + mysql.escape(board) + " AND coordinates.board_id=" + mysql.escape(board); + } + + } + else if( auth_lr_mode == "certs" ){ + + if(b_pub_key != "" && b_pub_key != undefined){ + + logger.debug("[SYSTEM] --> updating public key..."); + + var up_query = "UPDATE boards, coordinates SET " + + "boards.label=" + mysql.escape(board_label) + ", " + + "boards.layout_id=" + mysql.escape(layout_id) + ", " + + "boards.description=" + mysql.escape(description) + ", " + + "boards.extra=" + mysql.escape(extra) + ", " + + "boards.state=" + mysql.escape(state) + ", " + + "boards.projects_id=" + mysql.escape(project_id) + ", " + + "coordinates.altitude=" + mysql.escape(altitude) + ", " + + "coordinates.longitude=" + mysql.escape(longitude) + ", " + + "coordinates.latitude=" + mysql.escape(latitude) + ", " + + "boards.users_id=" + mysql.escape(user_id) + ", " + + "boards.mobile=" + mysql.escape(mobile) + ", " + + "boards.net_enabled=" + mysql.escape(net_enabled) + ", " + + "boards.position_refresh_time=" + mysql.escape(position_refr_time) + ", " + + "notify=" + mysql.escape(notify) + ", " + + "notify_rate=" + mysql.escape(notify_rate) + ", " + + "notify_retry=" + mysql.escape(notify_retry) + ", " + + "pubkey=" + mysql.escape(b_pub_key) + ", " + + "password=" + mysql.escape(hash_b_pw) + " " + + "WHERE boards.board_id=" + mysql.escape(board) + " AND coordinates.board_id=" + mysql.escape(board); + } + else { + + var up_query = "UPDATE boards, coordinates SET " + + "boards.label=" + mysql.escape(board_label) + ", " + + "boards.layout_id=" + mysql.escape(layout_id) + ", " + + "boards.description=" + mysql.escape(description) + ", " + + "boards.extra=" + mysql.escape(extra) + ", " + + "boards.state=" + mysql.escape(state) + ", " + + "boards.projects_id=" + mysql.escape(project_id) + ", " + + "coordinates.altitude=" + mysql.escape(altitude) + ", " + + "coordinates.longitude=" + mysql.escape(longitude) + ", " + + "coordinates.latitude=" + mysql.escape(latitude) + ", " + + "boards.users_id=" + mysql.escape(user_id) + ", " + + "boards.mobile=" + mysql.escape(mobile) + ", " + + "boards.net_enabled=" + mysql.escape(net_enabled) + ", " + + "boards.position_refresh_time=" + mysql.escape(position_refr_time) + ", " + + "notify=" + mysql.escape(notify) + ", " + + "notify_rate=" + mysql.escape(notify_rate) + ", " + + "notify_retry=" + mysql.escape(notify_retry) + ", " + + "password=" + mysql.escape(hash_b_pw) + " " + + "WHERE boards.board_id=" + mysql.escape(board) + " AND coordinates.board_id=" + mysql.escape(board); + } + + } + else if( auth_lr_mode == "basic" ){ + + var up_query = "UPDATE boards, coordinates SET " + + "boards.label=" + mysql.escape(board_label) + ", " + + "boards.layout_id=" + mysql.escape(layout_id) + ", " + + "boards.description=" + mysql.escape(description) + ", " + + "boards.extra=" + mysql.escape(extra) + ", " + + "boards.state=" + mysql.escape(state) + ", " + + "boards.projects_id=" + mysql.escape(project_id) + ", " + + "coordinates.altitude=" + mysql.escape(altitude) + ", " + + "coordinates.longitude=" + mysql.escape(longitude) + ", " + + "coordinates.latitude=" + mysql.escape(latitude) + ", " + + "boards.users_id=" + mysql.escape(user_id) + ", " + + "boards.mobile=" + mysql.escape(mobile) + ", " + + "boards.net_enabled=" + mysql.escape(net_enabled) + ", " + + "boards.position_refresh_time=" + mysql.escape(position_refr_time) + ", " + + "notify=" + mysql.escape(notify) + ", " + + "notify_rate=" + mysql.escape(notify_rate) + ", " + + "notify_retry=" + mysql.escape(notify_retry) + ", " + + "pubkey=" + mysql.escape(b_pub_key) + ", " + + "password=" + mysql.escape(hash_b_pw) + " " + + "WHERE boards.board_id=" + mysql.escape(board) + " AND coordinates.board_id=" + mysql.escape(board); + + } + + + connection.query(up_query, function (err, latest_result) { if (err != null) { @@ -636,14 +774,14 @@ db_utils.prototype.updateBoard = function (board, board_label, latitude, longitu } else { - logger.debug("[SYSTEM] --> Updating sensor list for board " + board + "..."); + //logger.debug("[SYSTEM] --> Updating sensor list for board " + board + "..."); if (sensorsList != "empty" && sensorsList != "" && sensorsList != undefined) var sensorsList2 = sensorsList.split(","); else var sensorsList2 = []; - connection.query("DELETE FROM sensors_on_board WHERE id_board='" + board + "';", function (err, result3) { + connection.query("DELETE FROM sensors_on_board WHERE id_board=" + mysql.escape(board) , function (err, result3) { if (err != null) { @@ -657,7 +795,7 @@ db_utils.prototype.updateBoard = function (board, board_label, latitude, longitu } else { - logger.debug("[SYSTEM] --> Cleaning sensor list successfully completed!"); + //logger.debug("[SYSTEM] --> Cleaning sensor list successfully completed!"); var values = []; var val = []; @@ -679,9 +817,9 @@ db_utils.prototype.updateBoard = function (board, board_label, latitude, longitu if (err != null) { connection.rollback(function () { - logger.error("[SYSTEM] --> Updating sensor list error in sensors_on_board: " + err); response.result = "ERROR"; response.message = "Updating sensor list error in sensors_on_board table!"; + logger.error("[SYSTEM] --> " + response.message + ": " + err); callback(response); }); @@ -701,9 +839,9 @@ db_utils.prototype.updateBoard = function (board, board_label, latitude, longitu } else { disconn(connection); - logger.info("[SYSTEM] --> Updating board successfully completed!"); response.result = "SUCCESS"; response.message = "Board successfully updated in Iotronic!"; + logger.info("[SYSTEM] --> " + response.message); callback(response); } @@ -734,10 +872,11 @@ db_utils.prototype.updateBoard = function (board, board_label, latitude, longitu } else { disconn(connection); - logger.info("[SYSTEM] --> Updating board successfully completed!"); response.result = "SUCCESS"; response.message = "Board successfully updated in Iotronic!"; + logger.info("[SYSTEM] --> " + response.message); callback(response); + } }); @@ -765,10 +904,11 @@ db_utils.prototype.updateBoard = function (board, board_label, latitude, longitu } else { - logger.warn("--> The board " + board + " does not exist!"); disconn(connection); response.result = "ERROR"; - response.message = "The board " + board + " does not exist!"; + response.message = "The board '" + board + "' does not exist!"; + logger.warn("--> " + response.message); + callback(response); } @@ -790,11 +930,11 @@ db_utils.prototype.unRegBoard = function (board, callback) { //check if the board already exists //logger.debug("[SYSTEM] --> Board ID check..."); - connection.query("SELECT board_id FROM boards WHERE board_id = '" + board + "'", function (err, result) { + connection.query("SELECT board_id FROM boards WHERE board_id = " + mysql.escape(board), function (err, result) { if (result.length != 0) { - connection.query("DELETE FROM boards WHERE board_id='" + board + "';", function (err, result3) { + connection.query("DELETE FROM boards WHERE board_id=" + mysql.escape(board), function (err, result3) { if (err != null) { //logger.error("[SYSTEM] --> Unregistration error in board_ids: " + err); @@ -840,7 +980,7 @@ db_utils.prototype.unRegProjectBoards = function (project_id, callback) { result: '' }; - connection.query("DELETE FROM boards WHERE projects_id='" + project_id + "';", function (err, result3) { + connection.query("DELETE FROM boards WHERE projects_id=" + mysql.escape(project_id) , function (err, result3) { if (err != null) { response.message = "Unregistration error in boards table: " + err; @@ -868,7 +1008,7 @@ db_utils.prototype.checkBoard = function (board_id, callback) { message: '', result: '' }; - connection.query("SELECT * FROM boards WHERE boards.board_id ='" + board_id + "'", function (err, result) { + connection.query("SELECT * FROM boards WHERE boards.board_id=" + mysql.escape(board_id), function (err, result) { if (err != null) { response.result = "ERROR"; response.message = err; @@ -893,7 +1033,7 @@ db_utils.prototype.checkBoardConnected = function (board_id, callback) { message: '', result: '' }; - connection.query("SELECT status FROM boards WHERE boards.board_id ='" + board_id + "'", function (err, result) { + connection.query("SELECT status, session_id, state, label FROM boards WHERE boards.board_id =" + mysql.escape(board_id), function (err, result) { if (err != null) { response.result = "ERROR"; response.message = err; @@ -920,7 +1060,7 @@ db_utils.prototype.getBoard = function (board_id, callback) { result: '' }; - connection.query("SELECT * FROM boards WHERE boards.board_id ='" + board_id + "'", function (err, result) { + connection.query("SELECT * FROM boards WHERE boards.board_id=" + mysql.escape(board_id), function (err, result) { if (err != null) { response.result = "ERROR"; @@ -948,7 +1088,7 @@ db_utils.prototype.changeBoardWampStatus = function (board_id, session, status, message: '', result: '' }; - connection.query("UPDATE boards SET board_id='" + board_id + "', session_id='" + session + "', status='" + status + "' WHERE board_id='" + board_id + "'", function (err, result) { + connection.query("UPDATE boards SET board_id=" + mysql.escape(board_id) + ", session_id=" + mysql.escape(session) + ", status=" + mysql.escape(status) + " WHERE board_id=" + mysql.escape(board_id), function (err, result) { if (err != null) { response.result = "ERROR"; response.message = err; @@ -966,14 +1106,15 @@ db_utils.prototype.changeBoardWampStatus = function (board_id, session, status, }; -db_utils.prototype.changeBoardStatus = function (board_id, session, status, state, callback) { +//Function to update the connection status, LR version and registration state of the board in DB +db_utils.prototype.changeBoardStatus = function (board_id, session, status, state, lr_version, callback) { var connection = conn(); var response = { message: '', result: '' }; - connection.query("UPDATE boards SET board_id='" + board_id + "', session_id='" + session + "', status='" + status + "', state='" + state + "' WHERE board_id='" + board_id + "'", function (err, result) { + connection.query("UPDATE boards SET board_id=" + mysql.escape(board_id) + ", session_id=" + mysql.escape(session) + ", status=" + mysql.escape(status) + ", state=" + mysql.escape(state) + ", lr_version=" + mysql.escape(lr_version) + " WHERE board_id=" + mysql.escape(board_id), function (err, result) { if (err != null) { response.result = "ERROR"; response.message = err; @@ -991,6 +1132,31 @@ db_utils.prototype.changeBoardStatus = function (board_id, session, status, stat }; +//Function to update the LR version and registration state of the board in DB +db_utils.prototype.changeBoardState = function (board_id, state, lr_version, callback) { + + var connection = conn(); + var response = { + message: '', + result: '' + }; + connection.query("UPDATE boards SET state=" + mysql.escape(state) + ", lr_version=" + mysql.escape(lr_version) + " WHERE board_id=" + mysql.escape(board_id), function (err, result) { + if (err != null) { + response.result = "ERROR"; + response.message = err; + disconn(connection); + callback(response); + } + else { + response.message = result; + response.result = "SUCCESS"; + disconn(connection); + callback(response); + } + }); + +}; + //Function to get the name and code of a generic driver db_utils.prototype.getBoardPosition = function (board_id, samples, callback) { var connection = conn(); @@ -998,7 +1164,7 @@ db_utils.prototype.getBoardPosition = function (board_id, samples, callback) { message: '', result: '' }; - connection.query("SELECT altitude, longitude, latitude, timestamp FROM coordinates WHERE coordinates.board_id = '" + board_id + "' ORDER BY timestamp DESC LIMIT " + samples, function (err, result) { + connection.query("SELECT altitude, longitude, latitude, timestamp FROM coordinates WHERE coordinates.board_id =" + mysql.escape(board_id) + " ORDER BY timestamp DESC LIMIT " + samples, function (err, result) { if (err != null) { response.result = "ERROR"; response.message = err; @@ -1022,7 +1188,7 @@ db_utils.prototype.findBySessionId = function (session_id, callback) { message: '', result: '' }; - connection.query("SELECT * FROM boards WHERE boards.session_id = '" + session_id + "'", function (err, result) { + connection.query("SELECT * FROM boards WHERE boards.session_id = " + mysql.escape(session_id), function (err, result) { if (err != null) { response.result = "ERROR"; response.message = err; @@ -1068,7 +1234,7 @@ db_utils.prototype.getBoardPositionHistory = function (board_id, interval, callb message: '', result: '' }; - connection.query("SELECT altitude, longitude, latitude, timestamp FROM coordinates WHERE coordinates.board_id = '" + board_id + "' AND timestamp between (CURDATE() - INTERVAL "+interval+" ) and CURDATE()", function (err, result) { + connection.query("SELECT altitude, longitude, latitude, timestamp FROM coordinates WHERE coordinates.board_id = " + mysql.escape(board_id) + " AND timestamp between (CURDATE() - INTERVAL "+interval+" ) and CURDATE()", function (err, result) { if (err != null) { response.result = "ERROR"; response.message = err; @@ -1132,7 +1298,7 @@ db_utils.prototype.getLayoutById = function (layout_id, callback) { message: '', result: '' }; - connection.query("SELECT * FROM layouts WHERE id_layout = '" + layout_id + "'", function (err, result) { + connection.query("SELECT * FROM layouts WHERE id_layout = " + mysql.escape(layout_id), function (err, result) { if (err != null) { response.message = err; @@ -1153,13 +1319,13 @@ db_utils.prototype.getLayoutById = function (layout_id, callback) { }; //Function to create a new board layout -db_utils.prototype.createLayout = function (model, manufacturer, image, layout, callback) { +db_utils.prototype.createLayout = function (model, manufacturer, image, layout, distro, callback) { var connection = conn(); var response = { message: '', result: '' }; - connection.query("INSERT INTO layouts (model, manufacturer, image, layout) VALUES (" + mysql.escape(model) + " , " + mysql.escape(manufacturer) + " , " + mysql.escape(image) + " , " + mysql.escape(layout) + ")", function (err, result) { + connection.query("INSERT INTO layouts (model, manufacturer, image, layout, distro) VALUES (" + mysql.escape(model) + " , " + mysql.escape(manufacturer) + " , " + mysql.escape(image) + " , " + mysql.escape(layout) + " , " + mysql.escape(distro) + " )", function (err, result) { if (err != null) { response.message = err; response.result = "ERROR"; @@ -1181,7 +1347,7 @@ db_utils.prototype.deleteLayoutById = function (layout_id, callback) { message: '', result: '' }; - connection.query("DELETE FROM layouts WHERE id_layout=" + layout_id, function (err, result) { + connection.query("DELETE FROM layouts WHERE id_layout=" + mysql.escape(layout_id), function (err, result) { if (err != null) { response.message = err; response.result = "ERROR"; @@ -1197,13 +1363,13 @@ db_utils.prototype.deleteLayoutById = function (layout_id, callback) { }; //Function to update a board layout -db_utils.prototype.updateLayoutById = function (layout_id, model, manufacturer, image, layout, callback) { +db_utils.prototype.updateLayoutById = function (layout_id, model, manufacturer, image, layout, distro, callback) { var connection = conn(); var response = { message: '', result: '' }; - connection.query("UPDATE layouts SET model = '" + model + "', manufacturer = '" + manufacturer + "', image = '" + image + "', layout = '"+layout+"' WHERE id_layout=" + layout_id, function (err, result) { + connection.query("UPDATE layouts SET model = " + mysql.escape(model) + ", manufacturer = " + mysql.escape(manufacturer) + ", image = " + mysql.escape(image) + ", layout = "+mysql.escape(layout)+", distro ="+ mysql.escape(distro)+" WHERE id_layout=" + mysql.escape(layout_id), function (err, result) { if (err != null) { response.result = "ERROR"; response.message = "UPDATE error in layout table: " + err; @@ -1226,7 +1392,8 @@ db_utils.prototype.getLayoutByBoardId = function (board_id, callback) { message: '', result: '' }; - connection.query("SELECT layouts.id_layout, layouts.model, layouts.manufacturer, layouts.image FROM layouts, boards WHERE boards.layout_id = layouts.id_layout AND boards.board_id = '" + board_id + "'", function (err, result) { + connection.query("SELECT layouts.id_layout, layouts.model, layouts.manufacturer, layouts.image FROM layouts, boards " + + "WHERE boards.layout_id = layouts.id_layout AND boards.board_id =" + mysql.escape(board_id) , function (err, result) { if (err != null) { response.message = err; @@ -1311,7 +1478,7 @@ db_utils.prototype.getProject = function (project, callback) { result: '' }; - connection.query("SELECT * FROM projects WHERE uuid = '" + project + "' OR name = '"+project+"'", function (err, result) { + connection.query("SELECT * FROM projects WHERE uuid = " + mysql.escape(project) + " OR name = " + mysql.escape(project), function (err, result) { if (err != null) { response.message = err; @@ -1338,7 +1505,7 @@ db_utils.prototype.deleteProject = function (project_id, callback) { message: '', result: '' }; - connection.query("DELETE FROM projects WHERE uuid='" + project_id +"'", function (err, result) { + connection.query("DELETE FROM projects WHERE uuid=" + mysql.escape(project_id), function (err, result) { if (err != null) { response.message = err; response.result = "ERROR"; @@ -1360,7 +1527,7 @@ db_utils.prototype.updateProject = function (project_id, name, description, cal message: '', result: '' }; - connection.query("UPDATE projects SET name = '" + name + "', description = '" + description + "' WHERE uuid='" + project_id +"'", function (err, result) { + connection.query("UPDATE projects SET name = " + mysql.escape(name) + ", description = " + mysql.escape(description) + " WHERE uuid=" + mysql.escape(project_id), function (err, result) { if (err != null) { response.result = "ERROR"; response.message = "UPDATE error in projects table: " + err; @@ -1375,7 +1542,6 @@ db_utils.prototype.updateProject = function (project_id, name, description, cal }) }; - //Function to get the IoTronic project's boards db_utils.prototype.getProjectBoards = function (project, callback) { var connection = conn(); @@ -1384,7 +1550,7 @@ db_utils.prototype.getProjectBoards = function (project, callback) { result: '' }; - connection.query("SELECT boards.* FROM projects, boards WHERE (projects.uuid = '" + project + "' OR projects.name = '"+project+"') AND projects.uuid = boards.projects_id", function (err, result) { + connection.query("SELECT boards.* FROM projects, boards WHERE (projects.uuid = " + mysql.escape(project) + " OR projects.name = " + mysql.escape(project) +") AND projects.uuid = boards.projects_id", function (err, result) { if (err != null) { response.message = err; @@ -1404,7 +1570,6 @@ db_utils.prototype.getProjectBoards = function (project, callback) { }; - //Function to get the IoTronic project's boards db_utils.prototype.getProjectUsers = function (project, callback) { var connection = conn(); @@ -1413,7 +1578,7 @@ db_utils.prototype.getProjectUsers = function (project, callback) { result: '' }; - connection.query("SELECT users.* FROM projects, users, boards WHERE (projects.uuid = '" + project + "' OR projects.name = '"+project+"') AND projects.uuid = boards.projects_id AND boards.users_id = users.uuid GROUP BY users.username", function (err, result) { + connection.query("SELECT users.* FROM projects, users, boards WHERE (projects.uuid = " + mysql.escape(project) + " OR projects.name = " + mysql.escape(project) +") AND projects.uuid = boards.projects_id AND boards.users_id = users.uuid GROUP BY users.username", function (err, result) { if (err != null) { response.message = err; @@ -1431,9 +1596,7 @@ db_utils.prototype.getProjectUsers = function (project, callback) { }; - - - +//Function to get all request for all Iotronic projects db_utils.prototype.getGlobalRequestsList = function (callback) { var connection = conn(); var response = { @@ -1460,14 +1623,14 @@ db_utils.prototype.getGlobalRequestsList = function (callback) { }; - +//Function to get the request's info db_utils.prototype.getRequest = function (request_id, callback) { var connection = conn(); var response = { message: '', result: '' }; - connection.query("SELECT * FROM requests WHERE id_request='"+request_id+"'", function (err, result) { + connection.query("SELECT * FROM requests WHERE id_request=" + mysql.escape(request_id) , function (err, result) { if (err != null) { response.message = err; @@ -1487,14 +1650,14 @@ db_utils.prototype.getRequest = function (request_id, callback) { }; - +//Funcion to get the results of a request db_utils.prototype.getRequestResults = function (request_id, callback) { var connection = conn(); var response = { message: '', result: '' }; - connection.query("SELECT board_id, result, message, timestamp FROM results WHERE request_id='"+request_id+"'", function (err, result) { + connection.query("SELECT board_id, result, message, timestamp FROM results WHERE request_id=" + mysql.escape(request_id) , function (err, result) { if (err != null) { response.message = err; @@ -1514,14 +1677,14 @@ db_utils.prototype.getRequestResults = function (request_id, callback) { }; - +//Function to get all request's info of a Iotronic project db_utils.prototype.getProjectRequestsList = function (project_id, callback) { var connection = conn(); var response = { message: '', result: '' }; - connection.query("SELECT id_request, subject, result, timestamp FROM requests WHERE project_id='"+project_id+"'", function (err, result) { + connection.query("SELECT id_request, subject, result, timestamp FROM requests WHERE project_id=" + mysql.escape(project_id), function (err, result) { if (err != null) { response.message = err; @@ -1541,7 +1704,6 @@ db_utils.prototype.getProjectRequestsList = function (project_id, callback) { }; - //Function to create a new IoTronic request db_utils.prototype.insertRequest = function (request_id, project, subject, req_result, callback) { var connection = conn(); @@ -1564,7 +1726,6 @@ db_utils.prototype.insertRequest = function (request_id, project, subject, req_r }); }; - //Function to insert a new IoTronic request result db_utils.prototype.insertRequestResult = function (request_id, board_id, result, message, callback) { var connection = conn(); @@ -1587,7 +1748,6 @@ db_utils.prototype.insertRequestResult = function (request_id, board_id, result, }); }; - //Function to update an IoTronic request db_utils.prototype.updateRequestStatus = function (request_id, result, callback) { var connection = conn(); @@ -1595,7 +1755,7 @@ db_utils.prototype.updateRequestStatus = function (request_id, result, callback message: '', result: '' }; - connection.query("UPDATE requests SET result = '" + result + "' WHERE id_request ='" + request_id +"'", function (err, result) { + connection.query("UPDATE requests SET result = " + mysql.escape(result) + " WHERE id_request = " + mysql.escape(request_id) , function (err, result) { if (err != null) { response.result = "ERROR"; response.message = "Error updating request: " + err; @@ -1610,7 +1770,6 @@ db_utils.prototype.updateRequestStatus = function (request_id, result, callback }) }; - //Function to update an IoTronic request result db_utils.prototype.updateResultStatus = function (request_id, board_id, result, message, callback) { var connection = conn(); @@ -1618,7 +1777,8 @@ db_utils.prototype.updateResultStatus = function (request_id, board_id, result, message: '', result: '' }; - connection.query("UPDATE results SET result = '" + result + "', message = "+mysql.escape(message)+" WHERE request_id ='" + request_id +"' AND board_id ='" + board_id +"'", function (err, result) { + + connection.query("UPDATE results SET result = " + mysql.escape(result) + ", message = \""+mysql.escape(message)+"\" WHERE request_id =" + mysql.escape(request_id) +" AND board_id =" + mysql.escape(board_id), function (err, result) { if (err != null) { response.result = "ERROR"; response.message = "Error updating request result: " + err; @@ -1640,7 +1800,51 @@ db_utils.prototype.deleteRequest = function (request_id, callback) { message: '', result: '' }; - connection.query("DELETE FROM requests WHERE id_request='" + request_id +"'", function (err, result) { + connection.query("DELETE FROM requests WHERE id_request=" + mysql.escape(request_id), function (err, result) { + if (err != null) { + response.message = err; + response.result = "ERROR"; + disconn(connection); + callback(response); + } else { + response.message = result; + response.result = "SUCCESS"; + disconn(connection); + callback(response); + } + }); +}; + +//Function to delete all IoTronic requests +db_utils.prototype.deleteAllRequests = function (callback) { + var connection = conn(); + var response = { + message: '', + result: '' + }; + connection.query("DELETE FROM requests", function (err, result) { + if (err != null) { + response.message = err; + response.result = "ERROR"; + disconn(connection); + callback(response); + } else { + response.message = result; + response.result = "SUCCESS"; + disconn(connection); + callback(response); + } + }); +}; + +//Function to delete requests of a project +db_utils.prototype.deleteProjectRequests = function (project_id, callback) { + var connection = conn(); + var response = { + message: '', + result: '' + }; + connection.query("DELETE FROM requests WHERE project_id=" + mysql.escape(project_id) , function (err, result) { if (err != null) { response.message = err; response.result = "ERROR"; @@ -1657,6 +1861,7 @@ db_utils.prototype.deleteRequest = function (request_id, callback) { + /////////////////////////////////////////// // USERS MANAGEMENT // /////////////////////////////////////////// @@ -1721,7 +1926,7 @@ db_utils.prototype.getUser = function (user, callback) { result: '' }; - connection.query("SELECT * FROM users WHERE uuid = '" + user + "' OR username = '"+user+"'", function (err, result) { + connection.query("SELECT * FROM users WHERE uuid = " + mysql.escape(user) + " OR username = " + mysql.escape(user) , function (err, result) { if (err != null) { response.message = err; @@ -1748,7 +1953,7 @@ db_utils.prototype.deleteUser = function (user_id, callback) { message: '', result: '' }; - connection.query("DELETE FROM users WHERE uuid='" + user_id +"'", function (err, result) { + connection.query("DELETE FROM users WHERE uuid=" + mysql.escape(user_id), function (err, result) { if (err != null) { response.message = err; response.result = "ERROR"; @@ -1770,7 +1975,7 @@ db_utils.prototype.updateUser = function (user_id, username, password, email, f message: '', result: '' }; - connection.query("UPDATE users SET username = '" + username + "', password = '" + password + "', email = '" + email + "', first_name = '" + f_name + "', last_name = '" + l_name + "' WHERE uuid='" + user_id +"'", function (err, result) { + connection.query("UPDATE users SET username = " + mysql.escape(username) + ", password = " + mysql.escape(password) + ", email = " + mysql.escape(email) + ", first_name = " + mysql.escape(f_name) + ", last_name = " + mysql.escape(l_name) + " WHERE uuid=" + mysql.escape(user_id) , function (err, result) { if (err != null) { response.result = "ERROR"; response.message = "UPDATE error in users table: " + err; @@ -1795,7 +2000,7 @@ db_utils.prototype.getUserByBoard = function (board_id, callback) { result: '' }; - connection.query("SELECT * FROM users, boards WHERE boards.users_id = users.uuid AND boards.board_id = '"+board_id+"'", function (err, result) { + connection.query("SELECT * FROM users, boards WHERE boards.users_id = users.uuid AND boards.board_id = " + mysql.escape(board_id) , function (err, result) { if (err != null) { response.message = err; @@ -1815,7 +2020,6 @@ db_utils.prototype.getUserByBoard = function (board_id, callback) { }; - //Function to get the IoTronic user details db_utils.prototype.getUserBoards = function (user, callback) { var connection = conn(); @@ -1824,7 +2028,7 @@ db_utils.prototype.getUserBoards = function (user, callback) { result: '' }; - connection.query("SELECT boards.* FROM users, boards WHERE (users.uuid = '" + user + "' OR users.username = '"+user+"') AND users.uuid = boards.users_id", function (err, result) { + connection.query("SELECT boards.* FROM users, boards WHERE (users.uuid = " + mysql.escape(user) + " OR users.username = " + mysql.escape(user) +") AND users.uuid = boards.users_id", function (err, result) { if (err != null) { response.message = err; @@ -1942,9 +2146,9 @@ db_utils.prototype.updateService = function (service, serviceName, port, protoc result: '' }; if (isNaN(service)) - var query = "UPDATE services SET name = '" + serviceName + "', port = '" + port + "', protocol = '" + protocol + "' WHERE name='" + service + "'"; + var query = "UPDATE services SET name = " + mysql.escape(serviceName) + ", port = " + mysql.escape(port) + ", protocol = " + mysql.escape(protocol) + " WHERE name=" + mysql.escape(service); else - var query = "UPDATE services SET name = '" + serviceName + "', port = '" + port + "', protocol = '" + protocol + "' WHERE id='" + service + "'"; + var query = "UPDATE services SET name = " + mysql.escape(serviceName) + ", port = " + mysql.escape(port) + ", protocol = " + mysql.escape(protocol) + " WHERE id=" + mysql.escape(service); connection.query(query, function (err, result) { if (err != null) { @@ -2001,7 +2205,7 @@ db_utils.prototype.getActiveService = function (service_id, board_id, callback) result: '' }; - connection.query("SELECT * FROM active_services WHERE board_id = '" + board_id + "' AND service_id = '" + service_id + "'", function (err, result) { + connection.query("SELECT * FROM active_services WHERE board_id = " + mysql.escape(board_id) + " AND service_id = " + mysql.escape(service_id), function (err, result) { if (err != null) { response.message = err; @@ -2029,7 +2233,8 @@ db_utils.prototype.getBoardServices = function (board_id, callback) { result: '' }; - connection.query("SELECT services.name as service_name, active_services.service_id, active_services.public_port, services.port as local_port, services.protocol, active_services.last_update, active_services.pid FROM active_services, services WHERE active_services.service_id = services.id AND active_services.board_id = '" + board_id + "'", function (err, result) { + connection.query("SELECT services.name as service_name, active_services.service_id, active_services.public_port, services.port as local_port, services.protocol, active_services.last_update, active_services.pid FROM active_services, services " + + "WHERE active_services.service_id = services.id AND active_services.board_id = " + mysql.escape(board_id), function (err, result) { if (err != null) { response.message = err; @@ -2059,7 +2264,7 @@ db_utils.prototype.registerTunnel = function (service_name, board_id, public_por message: '', result: '' }; - connection.query("SELECT id FROM services WHERE name = '" + service_name + "'", function (err, result) { + connection.query("SELECT id FROM services WHERE name = " + mysql.escape(service_name), function (err, result) { if (err) { logger.error("registerTunnel: " + err); @@ -2072,7 +2277,7 @@ db_utils.prototype.registerTunnel = function (service_name, board_id, public_por service_id = result[0].id; - connection.query("INSERT INTO active_services (service_id, board_id, public_port, pid) VALUES ('" + service_id + "','" + board_id + "','" + public_port + "','" + pid + "')", function (err, result) { + connection.query("INSERT INTO active_services (service_id, board_id, public_port, pid) VALUES (" + mysql.escape(service_id) + "," + mysql.escape(board_id) + "," + mysql.escape(public_port) + "," + mysql.escape(pid) + ")", function (err, result) { if (err) { logger.error("registerTunnel: " + err); response.message = err; @@ -2081,7 +2286,7 @@ db_utils.prototype.registerTunnel = function (service_name, board_id, public_por callback(response); } else { - response.message = "Tunnel for service " + service_name + " registered!" + response.message = "Tunnel for service " + service_name + " registered!"; response.result = "SUCCESS"; disconn(connection); callback(response); @@ -2103,7 +2308,7 @@ db_utils.prototype.removeTunnel = function (service_id, board_id, callback) { result: '' }; - connection.query("DELETE FROM active_services WHERE service_id ='" + service_id + "' AND board_id ='" + board_id + "'" , function (err, result) { + connection.query("DELETE FROM active_services WHERE service_id =" + mysql.escape(service_id) + " AND board_id =" + mysql.escape(board_id), function (err, result) { if (err != null) { logger.error("removeTunnel: " + err); @@ -2124,7 +2329,6 @@ db_utils.prototype.removeTunnel = function (service_id, board_id, callback) { }; - //Function to update the plugin status of a specific board db_utils.prototype.updateTunnelPid = function (service_id, board_id, pid, callback) { @@ -2134,7 +2338,7 @@ db_utils.prototype.updateTunnelPid = function (service_id, board_id, pid, callba result: '' }; - connection.query("UPDATE active_services SET pid = '" + pid + "', last_update=NOW() WHERE service_id ='" + service_id + "' AND board_id ='" + board_id + "'", function (err, result) { + connection.query("UPDATE active_services SET pid = '" + pid + "', last_update=NOW() WHERE service_id =" + mysql.escape(service_id) + " AND board_id =" + mysql.escape(board_id), function (err, result) { if (err) { response.message = "updateTunnelPid (update): " + err; response.result = "ERROR"; @@ -2152,7 +2356,6 @@ db_utils.prototype.updateTunnelPid = function (service_id, board_id, pid, callba }; - //Function to check if a specific port is already used db_utils.prototype.checkPort = function (s_port, callback) { var connection = conn(); @@ -2161,7 +2364,7 @@ db_utils.prototype.checkPort = function (s_port, callback) { result: '' }; - connection.query("SELECT * FROM active_services WHERE active_services.public_port='" + s_port + "'", function (err, result) { + connection.query("SELECT * FROM active_services WHERE active_services.public_port=" + mysql.escape(s_port), function (err, result) { if (err != null) { logger.error("checkPort: " + err); @@ -2182,7 +2385,7 @@ db_utils.prototype.checkPort = function (s_port, callback) { }; - +//Function to get the number of the active tunnels db_utils.prototype.getTunnels = function (callback) { var connection = conn(); @@ -2213,6 +2416,7 @@ db_utils.prototype.getTunnels = function (callback) { }; + /////////////////////////////////////////// // PLUGINS MANAGEMENT // /////////////////////////////////////////// @@ -2249,7 +2453,7 @@ db_utils.prototype.getPluginsChecksums = function (board_id, callback) { message: '', result: '' }; - connection.query("SELECT plugins.name, plugins.checksum FROM plugins, plugins_injected WHERE plugins.id = plugins_injected.plugin_id AND plugins_injected.board_id = '" + board_id + "' ", + connection.query("SELECT plugins.name, plugins.checksum FROM plugins, plugins_injected WHERE plugins.id = plugins_injected.plugin_id AND plugins_injected.board_id = " + mysql.escape(board_id), function (err, result) { if (err != null) { @@ -2357,7 +2561,7 @@ db_utils.prototype.getPlugin = function (plugin, callback) { var query = "SELECT plugins.id, plugins.name, plugins.category, plugins.version, plugins.checksum, plugins.code, plugins.defaults, plugins.checksum, plugin_tags.tag, plugin_tags.id as tag_id, plugin_types.type, plugins.type_id, " + "plugins.created_at, plugins.updated_at, plugins.description " + "FROM plugins, plugin_tags, plugin_types " + - "WHERE plugin_types.id = plugins.type_id AND plugins.tag_id = plugin_tags.id AND plugins.id=" + plugin; + "WHERE plugin_types.id = plugins.type_id AND plugins.tag_id = plugin_tags.id AND plugins.id=" + mysql.escape(plugin); connection.query(query, function (err, result) { @@ -2389,7 +2593,7 @@ db_utils.prototype.checkPluginExists = function (name, version, category, type, result: '' }; - var query = "SELECT * FROM plugins WHERE category=" + mysql.escape(category) + " AND type_id=" + type + " AND version=" + mysql.escape(version) + " AND name=" + mysql.escape(name); + var query = "SELECT * FROM plugins WHERE category=" + mysql.escape(category) + " AND type_id=" + mysql.escape(type) + " AND version=" + mysql.escape(version) + " AND name=" + mysql.escape(name); connection.query(query, function (err, result) { @@ -2417,7 +2621,7 @@ db_utils.prototype.getInjectedPlugin = function (plugin_id, board, callback) { message: '', result: '' }; - connection.query("SELECT * FROM plugins_injected WHERE board_id = '" + board + "' AND plugin_id = '" + plugin_id + "'", function (err, result) { + connection.query("SELECT * FROM plugins_injected WHERE board_id = " + mysql.escape(board) + " AND plugin_id = " + mysql.escape(plugin_id) , function (err, result) { if (err != null) { response.message = err; @@ -2443,7 +2647,7 @@ db_utils.prototype.getUsedPlugin = function (plugin_id, callback) { message: '', result: '' }; - connection.query("SELECT * FROM plugins_injected WHERE plugin_id = '" + plugin_id + "'", function (err, result) { + connection.query("SELECT * FROM plugins_injected WHERE plugin_id = " + mysql.escape(plugin_id) , function (err, result) { if (err != null) { response.message = err; @@ -2462,14 +2666,14 @@ db_utils.prototype.getUsedPlugin = function (plugin_id, callback) { }; - +//Function to get the version of a plugin by name db_utils.prototype.getPluginVersions = function (plugin_name, callback) { var connection = conn(); var response = { message: '', result: '' }; - connection.query("SELECT id, version FROM plugins WHERE name = '" + plugin_name + "'", function (err, result) { + connection.query("SELECT id, version FROM plugins WHERE name = " + mysql.escape(plugin_name) , function (err, result) { if (err != null) { response.message = err; @@ -2497,7 +2701,7 @@ db_utils.prototype.updatePluginStatus = function (board, plugin_id, status, call result: '' }; - connection.query("UPDATE plugins_injected SET state = '" + status + "', latest_change=NOW() WHERE board_id='" + board + "' AND plugin_id='" + plugin_id + "'", function (err, result) { + connection.query("UPDATE plugins_injected SET state = " + mysql.escape(status) + ", latest_change=NOW() WHERE board_id=" + mysql.escape(board) + " AND plugin_id=" + mysql.escape(plugin_id) , function (err, result) { if (err) { response.message = "updatePluginStatus (update): " + err; response.result = "ERROR"; @@ -2557,7 +2761,7 @@ db_utils.prototype.tagPlugin = function (plugin_id, tag_id, callback) { result: '' }; - connection.query("UPDATE plugins SET tag_id = '" + tag_id + "', updated_at=NOW() WHERE id='" + plugin_id + "'", function (err, result) { + connection.query("UPDATE plugins SET tag_id = " + mysql.escape(tag_id) + ", updated_at=NOW() WHERE id=" + mysql.escape(plugin_id), function (err, result) { if (err) { response.message = "tagPlugin: " + err; @@ -2597,8 +2801,9 @@ db_utils.prototype.BoardPlugins = function (board, callback) { message: '', result: '' }; - connection.query("SELECT plugins.name, plugins.id, plugins.description, plugins.category, plugins_injected.state, plugin_tags.tag, plugin_types.type FROM plugins_injected, plugins, plugin_tags, plugin_types WHERE " + - "plugins_injected.board_id = '" + board + "' AND plugins_injected.plugin_id = plugins.id AND plugins.tag_id = plugin_tags.id AND plugins.type_id = plugin_types.id ", function (err_plugin, result_plugin) { + + connection.query("SELECT plugins.name, plugins.version, plugins.id, plugins.description, plugins.category, plugins_injected.state, plugin_tags.tag, plugin_types.type FROM plugins_injected, plugins, plugin_tags, plugin_types WHERE " + + "plugins_injected.board_id = " + mysql.escape(board) + " AND plugins_injected.plugin_id = plugins.id AND plugins.tag_id = plugin_tags.id AND plugins.type_id = plugin_types.id ", function (err_plugin, result_plugin) { if (err_plugin != null) { response.result = "ERROR"; @@ -2625,7 +2830,7 @@ db_utils.prototype.getPluginCategory = function (pluginName, callback) { message: '', result: '' }; - connection.query("SELECT category FROM plugins WHERE name = '" + pluginName + "' ORDER BY id desc limit 1", function (err, result) { + connection.query("SELECT category FROM plugins WHERE name = " + mysql.escape(pluginName) + " ORDER BY id desc limit 1", function (err, result) { if (err != null) { response.message = err; @@ -2652,7 +2857,7 @@ db_utils.prototype.deleteInjectedPlugin = function (board, plugin_name, callback result: '' }; - connection.query("DELETE FROM plugins_injected WHERE board_id='" + board + "' AND plugin_name='" + plugin_name + "'", function (err, result) { + connection.query("DELETE FROM plugins_injected WHERE board_id=" + mysql.escape(board) + " AND plugin_name=" + mysql.escape(plugin_name) , function (err, result) { if (err != null) { response.message = err; @@ -2699,7 +2904,7 @@ db_utils.prototype.insertInjectedPlugin = function (board, plugin_id, plugin_nam result: '' }; - connection.query("INSERT INTO plugins_injected (board_id, plugin_id, plugin_name, state) VALUES ('" + board + "','" + plugin_id + "','" + plugin_name + "', 'injected')", function (err, result) { + connection.query("INSERT INTO plugins_injected (board_id, plugin_id, plugin_name, state) VALUES (" + mysql.escape(board) + "," + mysql.escape(plugin_id) + "," + mysql.escape(plugin_name) + ", 'injected')", function (err, result) { if (err) { logger.error("insertInjectedPlugin: " + err); response.message = err; @@ -2769,7 +2974,7 @@ db_utils.prototype.getTypeId = function (type, callback) { if (isNaN(type)) { - connection.query("SELECT id, type FROM plugin_types WHERE type = '" + type + "'", function (err, result) { + connection.query("SELECT id, type FROM plugin_types WHERE type =" + mysql.escape(type) , function (err, result) { if (err != null) { response.result = "ERROR"; @@ -2790,7 +2995,7 @@ db_utils.prototype.getTypeId = function (type, callback) { } else{ - connection.query("SELECT id, type FROM plugin_types WHERE id=" + type, function (err, result) { + connection.query("SELECT id, type FROM plugin_types WHERE id=" + mysql.escape(type) , function (err, result) { if (err != null) { response.result = "ERROR"; @@ -2866,7 +3071,7 @@ db_utils.prototype.getPluginFromVersion = function (plugin_name, plugin_version, message: '', result: '' }; - connection.query("SELECT * FROM plugins WHERE version = '" + plugin_version + "' AND name = '" + plugin_name + "'", function (err, result) { + connection.query("SELECT * FROM plugins WHERE version = " + mysql.escape(plugin_version) + " AND name = " + mysql.escape(plugin_name) , function (err, result) { if (err != null) { response.message = err; @@ -2892,7 +3097,6 @@ db_utils.prototype.getPluginFromVersion = function (plugin_name, plugin_version, - ////////////////////////////////////// // VNET MANAGEMENT // ////////////////////////////////////// @@ -2935,7 +3139,8 @@ db_utils.prototype.insertVNET = function (vlan_ip, vlan_mask, net_uuid, vlan_nam }; //socat ID creation related to the new board FOREVER - connection.query("INSERT INTO vlans (vlan_ip, vlan_mask, net_uuid, vlan_name) VALUES ('" + vlan_ip + "', '" + vlan_mask + "', '" + net_uuid + "', '" + vlan_name + "' )", function (err, result) { + connection.query("INSERT INTO vlans (vlan_ip, vlan_mask, net_uuid, vlan_name) VALUES (" + mysql.escape(vlan_ip) + ", " + mysql.escape(vlan_mask) + ", " + mysql.escape(net_uuid) + ", " + + "" + mysql.escape(vlan_name) + " )", function (err, result) { if (err != null) { @@ -2973,7 +3178,7 @@ db_utils.prototype.insertAddresses = function (list_ip, net_uuid, callback) { logger.debug("[VNET] --> Creating the addresses poll for the new VLAN " + net_uuid); var query = "INSERT INTO free_addresses (vlans_id, ip, insert_date) VALUES "; - var getVID = "SELECT id FROM vlans WHERE net_uuid='" + net_uuid + "' "; + var getVID = "SELECT id FROM vlans WHERE net_uuid=" + mysql.escape(net_uuid); connection.query(getVID, function (err, result) { @@ -3049,7 +3254,8 @@ db_utils.prototype.getVnetBoardsInfo = function (net_uuid, callback) { result: '' }; - connection.query("select boards.label AS board_name, id_board AS board_id, vlans.vlan_name AS vlan_name, vlans_connection.id_vlan AS vlan_id, vlans_connection.ip_vlan AS vlan_ip, socat_connections.id AS socat_id, socat_connections.ip_board AS socat_ip, socat_connections.port AS socat_port from socat_connections,vlans_connection, vlans, boards where socat_connections.id = vlans_connection.id_socat_connection AND boards.board_id = socat_connections.id_board AND id_vlan = vlans.id AND vlans.net_uuid='" + net_uuid + "'", function (err, result) { + connection.query("select boards.label AS board_name, id_board AS board_id, vlans.vlan_name AS vlan_name, vlans_connection.id_vlan AS vlan_id, vlans_connection.ip_vlan AS vlan_ip, socat_connections.id AS socat_id, socat_connections.ip_board AS socat_ip, socat_connections.port AS socat_port from socat_connections,vlans_connection, vlans, boards " + + "WHERE socat_connections.id = vlans_connection.id_socat_connection AND boards.board_id = socat_connections.id_board AND id_vlan = vlans.id AND vlans.net_uuid=" + mysql.escape(net_uuid), function (err, result) { if (err != null) { response.result = "ERROR"; @@ -3079,7 +3285,7 @@ db_utils.prototype.destroyVNET = function (net_uuid, callback) { result: '' }; - connection.query("DELETE FROM vlans WHERE vlans.net_uuid='" + net_uuid + "'", function (err, result) { + connection.query("DELETE FROM vlans WHERE vlans.net_uuid=" + mysql.escape(net_uuid), function (err, result) { if (err != null) { response.result = "ERROR"; @@ -3110,7 +3316,7 @@ db_utils.prototype.getNetEnabledId = function (board, callback) { }; //select net_enabled from user_boards where board_id=30303030 - connection.query("SELECT net_enabled FROM boards WHERE board_id = '" + board + "'", function (err, result) { + connection.query("SELECT net_enabled FROM boards WHERE board_id =" + mysql.escape(board), function (err, result) { if (err != null) { response.result = "ERROR"; @@ -3140,7 +3346,7 @@ db_utils.prototype.checkAddressPool = function (net_uuid, callback) { result: '' }; - query = "select ip from free_addresses where vlans_id = (SELECT id FROM vlans WHERE net_uuid='" + net_uuid + "' ) ORDER BY insert_date, ip ASC limit 1"; + query = "select ip from free_addresses where vlans_id = (SELECT id FROM vlans WHERE net_uuid=" + mysql.escape(net_uuid) + " ) ORDER BY insert_date, ip ASC limit 1"; connection.query(query, function (err, result) { @@ -3186,7 +3392,7 @@ db_utils.prototype.getVnet = function (net_uuid, callback) { }; //get the socat ID just created before - connection.query("SELECT * FROM vlans WHERE net_uuid='" + net_uuid + "'", function (err, result) { + connection.query("SELECT * FROM vlans WHERE net_uuid=" + mysql.escape(net_uuid), function (err, result) { if (err != null) { response.result = "ERROR"; @@ -3217,7 +3423,8 @@ db_utils.prototype.checkBoardIntoVLAN = function (board, net_uuid, callback) { result: '' }; - connection.query("SELECT EXISTS( SELECT id_vlan, id_socat_connection FROM vlans_connection WHERE id_vlan = (SELECT id FROM vlans WHERE net_uuid='" + net_uuid + "' ) AND id_socat_connection=(SELECT id FROM socat_connections WHERE id_board='" + board + "' ) ) AS found", function (err, result) { + connection.query("SELECT EXISTS( SELECT id_vlan, id_socat_connection FROM vlans_connection " + + "WHERE id_vlan = (SELECT id FROM vlans WHERE net_uuid=" + mysql.escape(net_uuid) + " ) AND id_socat_connection=(SELECT id FROM socat_connections WHERE id_board=" + mysql.escape(board) + " ) ) AS found", function (err, result) { if (err != null) { response.result = "ERROR"; @@ -3246,7 +3453,7 @@ db_utils.prototype.getSocatConn = function (board, callback) { result: '' }; - connection.query("SELECT id, port FROM socat_connections WHERE id_board='" + board + "'", function (err, result) { + connection.query("SELECT id, port FROM socat_connections WHERE id_board=" + mysql.escape(board), function (err, result) { if (err != null) { response.result = "ERROR"; @@ -3275,7 +3482,7 @@ db_utils.prototype.checkAssignedVlanIP = function (user_ip, vlan_id, callback) { result: '' }; - connection.query("SELECT EXISTS( SELECT vlans_id, ip FROM free_addresses WHERE vlans_id ='" + vlan_id + "' AND ip ='" + user_ip + "' ) AS found", function (err, result) { + connection.query("SELECT EXISTS( SELECT vlans_id, ip FROM free_addresses WHERE vlans_id =" + mysql.escape(vlan_id) + " AND ip =" + mysql.escape(user_ip) + " ) AS found", function (err, result) { if (err != null) { response.result = "ERROR"; @@ -3338,8 +3545,7 @@ db_utils.prototype.getFreeAddress = function (net_uuid, callback) { result: '' }; - //SELECT id, ip FROM vlans, free_addresses WHERE net_uuid='85268bf8-55d6-42b2-8ce5-fb89cc2101ae' AND vlans.id=free_addresses.vlans_id; - query = "select ip from free_addresses where vlans_id = (SELECT id FROM vlans WHERE net_uuid='" + net_uuid + "' ) ORDER BY insert_date, ip ASC limit 1"; + query = "select ip from free_addresses where vlans_id = (SELECT id FROM vlans WHERE net_uuid=" + mysql.escape(net_uuid) + " ) ORDER BY insert_date, ip ASC limit 1"; connection.query(query, function (err, ip_result) { @@ -3401,7 +3607,7 @@ db_utils.prototype.insertVnetConnection = function (vlan_ip, net_uuid, id_board, result: '' }; - connection.query("SELECT EXISTS(SELECT 1 FROM vlans_connection WHERE ip_vlan ='" + vlan_ip + "' LIMIT 1) AS found", function (err, result) { + connection.query("SELECT EXISTS(SELECT 1 FROM vlans_connection WHERE ip_vlan =" + mysql.escape(vlan_ip) + " LIMIT 1) AS found", function (err, result) { if (err != null) { logger.warn("[VNET] ----> insertVnetConnection - Select error in checking ip_vlans table: " + err); response.message = err; @@ -3421,7 +3627,7 @@ db_utils.prototype.insertVnetConnection = function (vlan_ip, net_uuid, id_board, else { //Socat ID related to the new board assigned "forever" - connection.query("INSERT INTO vlans_connection (id_vlan, id_socat_connection,ip_vlan) VALUES ((select id from vlans where net_uuid='" + net_uuid + "'), (select id from socat_connections where id_board='" + id_board + "'), '" + vlan_ip + "')", function (err, result) { + connection.query("INSERT INTO vlans_connection (id_vlan, id_socat_connection,ip_vlan) VALUES ((select id from vlans where net_uuid=" + mysql.escape(net_uuid) + "), (select id from socat_connections where id_board=" + mysql.escape(id_board) + "), " + mysql.escape(vlan_ip) + ")", function (err, result) { if (err != null) { @@ -3462,7 +3668,7 @@ db_utils.prototype.getSocatStatus = function (board, callback) { result: '' }; - connection.query("SELECT status FROM socat_connections WHERE id_board='" + board + "'", function (err, result) { + connection.query("SELECT status FROM socat_connections WHERE id_board=" + mysql.escape(board), function (err, result) { if (err != null) { response.result = "ERROR"; @@ -3491,7 +3697,7 @@ db_utils.prototype.getSocatConf = function (board, basePort, socatNetwork, callb result: '' }; - connection.query("SELECT id FROM socat_connections WHERE id_board='" + board + "'", function (err, result) { + connection.query("SELECT id FROM socat_connections WHERE id_board=" + mysql.escape(board), function (err, result) { if (err != null) { @@ -3524,7 +3730,7 @@ db_utils.prototype.getSocatConf = function (board, basePort, socatNetwork, callb }else{ //socat ID creation related to the new board FOREVER - connection.query("INSERT INTO socat_connections (id_board, status, port, ip_board, ip_server) VALUES ('" + board + "', 'noactive', 0, 'None', 'None' )", function (err, result) { + connection.query("INSERT INTO socat_connections (id_board, status, port, ip_board, ip_server) VALUES (" + mysql.escape(board) + ", 'noactive', 0, 'None', 'None' )", function (err, result) { if (err != null) { @@ -3611,7 +3817,7 @@ db_utils.prototype.getSocatConf = function (board, basePort, socatNetwork, callb // If the board is already registered //get the socat ID created before - connection.query("SELECT id, ip_board, ip_server, port FROM socat_connections WHERE id_board='" + board + "'", function (err, result) { + connection.query("SELECT id, ip_board, ip_server, port FROM socat_connections WHERE id_board=" + mysql.escape(board), function (err, result) { if (err != null) { response.result = "ERROR"; @@ -3658,7 +3864,7 @@ db_utils.prototype.updateSocatStatus = function (board, status, callback) { message: '', result: '' }; - connection.query("UPDATE socat_connections SET status = '" + status + "' WHERE id_board='" + board + "'", function (err, result) { + connection.query("UPDATE socat_connections SET status =" + mysql.escape(status) + " WHERE id_board=" + mysql.escape(board), function (err, result) { if (err != null) { response.result = "ERROR"; response.message = "UPDATE error in socat_connection tables: " + err; @@ -3683,7 +3889,7 @@ db_utils.prototype.restoreIpAddress = function (board_ip, net_uuid, callback) { message: '', result: '' }; - connection.query("INSERT INTO free_addresses (vlans_id, ip, insert_date) VALUES ( (SELECT id FROM vlans WHERE net_uuid='" + net_uuid + "' ), '" + board_ip + "', NOW())", function (err, result) { + connection.query("INSERT INTO free_addresses (vlans_id, ip, insert_date) VALUES ( (SELECT id FROM vlans WHERE net_uuid=" + mysql.escape(net_uuid) + " ), " + mysql.escape(board_ip) + ", NOW())", function (err, result) { if (err != null) { @@ -3716,7 +3922,7 @@ db_utils.prototype.removeBoardFromVlan = function (board_id, net_uuid, callback) result: '' }; - query = "select ip_vlan from vlans_connection where id_vlan = (SELECT id FROM vlans WHERE net_uuid='" + net_uuid + "' ) and id_socat_connection = (SELECT id FROM socat_connections WHERE id_board='" + board_id + "' )"; + query = "select ip_vlan from vlans_connection where id_vlan = (SELECT id FROM vlans WHERE net_uuid=" + mysql.escape(net_uuid) + " ) and id_socat_connection = (SELECT id FROM socat_connections WHERE id_board=" + mysql.escape(board_id) + " )"; connection.query(query, function (err, result) { @@ -3758,7 +3964,7 @@ db_utils.prototype.removeBoardFromVlan = function (board_id, net_uuid, callback) } else { - connection.query("INSERT INTO free_addresses (vlans_id, ip, insert_date) VALUES ( (SELECT id FROM vlans WHERE net_uuid='" + net_uuid + "' ), '" + board_ip + "', NOW())", function (err, result) { + connection.query("INSERT INTO free_addresses (vlans_id, ip, insert_date) VALUES ( (SELECT id FROM vlans WHERE net_uuid=" + mysql.escape(net_uuid) + " ), '" + board_ip + "', NOW())", function (err, result) { if (err != null) { @@ -3834,7 +4040,7 @@ db_utils.prototype.getBoardVLAN = function (board, callback) { message: '', result: '' }; - connection.query("SELECT vlan_name, ip_vlan, net_uuid FROM vlans, vlans_connection, socat_connections WHERE id_socat_connection = (select id from socat_connections where id_board='" + board + "') AND vlans_connection.id_socat_connection = socat_connections.id AND vlans_connection.id_vlan = vlans.id", function (err, result) { + connection.query("SELECT vlan_name, ip_vlan, net_uuid FROM vlans, vlans_connection, socat_connections WHERE id_socat_connection = (select id from socat_connections where id_board=" + mysql.escape(board) + ") AND vlans_connection.id_socat_connection = socat_connections.id AND vlans_connection.id_vlan = vlans.id", function (err, result) { if (err != null) { response.result = "ERROR"; response.message = err; diff --git a/lib/management/mng_docs.js b/lib/management/mng_docs.js index c9565f3..d1cca72 100644 --- a/lib/management/mng_docs.js +++ b/lib/management/mng_docs.js @@ -113,9 +113,9 @@ var exposeApiDocumentation = function (rest, swaggerSpec){ if ( (docs_embedded == "true" || docs_embedded == true) && (docs_exp == "false" || docs_exp == false) ) if (https_enable == "true"){ - link_docs = "https://" + IoTronic_IP + ":" + https_port + "/v1/iotronic-api-docs/"; + link_docs = "https://" + API_IP + ":" + https_port + "/v1/iotronic-api-docs/"; }else{ - link_docs = "http://" + IoTronic_IP + ":" + http_port + "/v1/iotronic-api-docs/"; + link_docs = "http://" + API_IP + ":" + http_port + "/v1/iotronic-api-docs/"; } diff --git a/lib/management/mng_layout.js b/lib/management/mng_layout.js index 770581b..fe80b0f 100644 --- a/lib/management/mng_layout.js +++ b/lib/management/mng_layout.js @@ -66,10 +66,13 @@ layout_utils = function (session, rest) { * description: "device manufacturer name" * image: * type: string - * description: "OS distribution image used by device" + * description: "OS image version used by device: 'Raspbian', 'LEDE'" * layout: * type: string - * description: "Iotronic device layout" + * description: "Iotronic device layout" + * distro: + * type: string + * description: "OS distribution: 'debian', 'openwrt'" * 403: * description: "Wrong, expired or not specified token in request header." * 500: @@ -129,10 +132,13 @@ layout_utils = function (session, rest) { * description: "evice manufacturer name" * image: * type: string - * description: "OS distribution image used by device" + * description: "OS image version used by device: 'Raspbian', 'LEDE'" * layout: * type: string * description: "Iotronic device layout" + * distro: + * type: string + * description: "OS distribution: 'debian', 'openwrt'" * responses: * 200: * description: A Json IoTronic response @@ -151,8 +157,9 @@ layout_utils = function (session, rest) { var manufacturer = req.body.manufacturer; var image = req.body.image; var layout = req.body.layout; + var distro = req.body.distro; - var ApiRequired= {"model":model, "manufacturer":manufacturer, "layout":layout}; + var ApiRequired= {"model":model, "manufacturer":manufacturer, "layout":layout, "distro":distro}; board_utility.checkRequired(ApiRequired, function (check){ @@ -162,7 +169,7 @@ layout_utils = function (session, rest) { }else { - layout_utils.prototype.createLayout(model, manufacturer, image, layout, res); + layout_utils.prototype.createLayout(model, manufacturer, image, layout, distro, res); } @@ -240,10 +247,13 @@ layout_utils = function (session, rest) { * description: "device manufacturer name" * image: * type: string - * description: "OS distribution image used by device" + * description: "OS image version used by device: 'Raspbian', 'LEDE'" * layout: * type: string * description: "Iotronic device layout" + * distro: + * type: string + * description: "OS distribution: 'debian', 'openwrt'" * produces: * - application/json * responses: @@ -263,8 +273,9 @@ layout_utils = function (session, rest) { var manufacturer = req.body.manufacturer; var image = req.body.image; var layout = req.body.layout; + var distro = req.body.distro; - var ApiRequired= {"model":model, "manufacturer":manufacturer, "layout":layout}; + var ApiRequired= {"model":model, "manufacturer":manufacturer, "layout":layout, "distro":distro}; board_utility.checkRequired(ApiRequired, function (check){ @@ -274,7 +285,7 @@ layout_utils = function (session, rest) { }else { - layout_utils.prototype.updateLayout(layout_id, model, manufacturer, image, layout, res); + layout_utils.prototype.updateLayout(layout_id, model, manufacturer, image, layout, distro, res); } @@ -324,10 +335,13 @@ layout_utils = function (session, rest) { * description: "device manufacturer name" * image: * type: string - * description: "OS distribution image used by device" + * description: "OS image version used by device: 'Raspbian', 'LEDE'" * layout: * type: string - * description: "Iotronic device layout" + * description: "Iotronic device layout" + * distro: + * type: string + * description: "OS distribution: 'debian', 'openwrt'" * 403: * description: "Wrong, expired or not specified token in request header." * 500: @@ -374,22 +388,23 @@ layout_utils = function (session, rest) { }); }); - - logger.debug("[REST-EXPORT] - Layout management APIs exposed!"); + logger.debug("[REST-EXPORT] - Layout management APIs exposed!"); + }; -layout_utils.prototype.createLayout = function (model, manufacturer, image, layout, res) { +layout_utils.prototype.createLayout = function (model, manufacturer, image, layout, distro, res) { logger.info("[LAYOUT] - Creating board layout:"); logger.info("[LAYOUT] --> model " + model); logger.info("[LAYOUT] --> manufacturer " + manufacturer); logger.info("[LAYOUT] --> image " + image); logger.info("[LAYOUT] --> layout " + layout); + logger.info("[LAYOUT] --> distro " + distro); var response = { @@ -397,7 +412,7 @@ layout_utils.prototype.createLayout = function (model, manufacturer, image, layo result: '' }; - db.createLayout(model, manufacturer, image, layout, function (result_db) { + db.createLayout(model, manufacturer, image, layout, distro, function (result_db) { if (result_db.result == "ERROR") { logger.error("[LAYOUT] --> createLayout - DB write error: " + result_db.message); @@ -407,7 +422,7 @@ layout_utils.prototype.createLayout = function (model, manufacturer, image, layo } else { - response.message = "Board layout " + model + " successfully created in IoTronic!"; + response.message = "Board layout '" + model + "' successfully created in IoTronic!"; response.result = "SUCCESS"; logger.info("[LAYOUT] --> " +response.message); res.status(200).send(response); @@ -482,9 +497,9 @@ layout_utils.prototype.deleteLayout = function (layout_id, res) { }; -layout_utils.prototype.updateLayout = function (layout_id, model, manufacturer, image, layout, res) { +layout_utils.prototype.updateLayout = function (layout_id, model, manufacturer, image, layout, distro, res) { - logger.info("[LAYOUT] - UPDATING LAYOUT with ID " + layout_id + "..."); + logger.info("[LAYOUT] - UPDATING LAYOUT with ID '" + layout_id + "'..."); var response = { message: '', @@ -512,7 +527,7 @@ layout_utils.prototype.updateLayout = function (layout_id, model, manufacturer, logger.debug("[LAYOUT] --> updating board model with ID = " + layout_id); - db.updateLayoutById(layout_id, model, manufacturer, image, layout, function (result_db) { + db.updateLayoutById(layout_id, model, manufacturer, image, layout, distro, function (result_db) { if (result_db.result == "ERROR") { logger.error("[LAYOUT] --> updateLayoutById - DB write error: " + result_db.message); @@ -522,7 +537,7 @@ layout_utils.prototype.updateLayout = function (layout_id, model, manufacturer, } else { - response.message = "Board layout with ID " + layout_id + " successfully updated!"; + response.message = "Board layout with ID '" + layout_id + "' successfully updated!"; response.result = "SUCCESS"; logger.info("[LAYOUT] --> " +response.message); res.status(200).send(response); diff --git a/lib/management/mng_request.js b/lib/management/mng_request.js index 454e3d8..8b71a9f 100644 --- a/lib/management/mng_request.js +++ b/lib/management/mng_request.js @@ -182,6 +182,8 @@ request_utils = function (session, rest) { res.status(500).send(response); } else { + + //data.message[0].message = data.message[0].message.slice(1,-1); response.message = data.message; response.result = "SUCCESS"; logger.debug("[REQUEST] --> Results of the request '"+request+"': " + JSON.stringify(response.message)); @@ -351,6 +353,106 @@ request_utils = function (session, rest) { }); + //DELETE all IoTronic requests + /** + * @swagger + * /v1/requests/: + * delete: + * tags: + * - Requests + * description: Delete all IoTronic requests + * summary: delete all IoTronic requests + * produces: + * - application/json + * responses: + * 200: + * $ref: "#/definitions/IoTronicResponse" + * 403: + * description: "Wrong, expired or not specified token in request header." + * 500: + * description: "API specific error message." + */ + rest.delete('/v1/requests/', function (req, res) { + + logger.info("[API] - Delete all IoTronic request - " + Object.keys( req.route.methods ) + " - " + req.route.path + " - " + req.IotronicUser); + + var response = { + message: '', + result: '' + }; + + db.deleteAllRequests(function (data) { + + if (data.result == "ERROR") { + response.message = "Error deleting Iotronic requests: " + data.message; + response.result = "ERROR"; + logger.error("[REQUEST] --> " + response.message); + res.status(500).send(response); + + } else { + response.message = "Requests successfully deleted!"; + response.result = "SUCCESS"; + logger.info("[REQUEST] --> " + response.message); + res.status(200).send(response); + + } + + }); + + + }); + + + //DELETE all project requests + /** + * @swagger + * /v1/projects/{project}/requests: + * delete: + * tags: + * - Requests + * description: It deletes all requests of a project + * summary: delete project's requests + * produces: + * - application/json + * responses: + * 200: + * $ref: "#/definitions/IoTronicResponse" + * 403: + * description: "Wrong, expired or not specified token in request header." + * 500: + * description: "API specific error message." + */ + rest.delete('/v1/projects/:project/requests', function (req, res) { + + logger.info("[API] - Delete project's requests called - " + Object.keys( req.route.methods ) + " - " + req.route.path + " - " + req.IotronicUser); + + var project = req.params.project; + + var response = { + message: '', + result: '' + }; + + db.deleteProjectRequests(project, function (data) { + + if (data.result == "ERROR") { + response.message = "Error deleting project requests: " + data.message; + response.result = "ERROR"; + logger.error("[REQUEST] --> " + response.message); + res.status(500).send(response); + + } else { + response.message = "Requests of the project '"+project+"' successfully deleted!"; + response.result = "SUCCESS"; + logger.info("[REQUEST] --> " + response.message); + res.status(200).send(response); + } + + }); + + }); + + logger.debug("[REST-EXPORT] - IoTronic requests management APIs exposed!"); @@ -358,6 +460,86 @@ request_utils = function (session, rest) { }; +var singleRequest = function (board_id, subject, res, funcAction, funcArgs) { + + var response = { + message: {}, + result: "" + }; + + + //get project ID of the board + + db.checkBoard(board_id, function (data) { + + if (data.result == "ERROR") { + + response.message = "Error getting board info: " + data.message; + response.result = "ERROR"; + logger.error("[SYSTEM] --> " + response.message); + res.status(500).send(response); + + } else { + + var project = data.message[0].projects_id; + var board_label = data.message[0].label; + + insertRequest(project, subject).then( + + function (request) { + + if (request.result == "ERROR") { + + res.status(500).send(request); + + } else { + + var request_id = request.message; + + REQUESTS[request_id]=1; + + db.insertRequestResult(request_id, board_id, "pending", "-", function (data) { + + if (data.result == "ERROR") { + + logger.error("[SYSTEM] --> " + data.message); + + }else{ + + funcAction(board_id, request_id, funcArgs); + + response.result = "SUCCESS"; + response.message = "Performing action '"+funcArgs[0]+"' on board '" + board_label + "' ("+board_id+")."; + response.board_id = board_id; + response.req_id = request_id; + response.subject = subject; + logger.info("[SYSTEM] --> " + response.message); + res.status(200).send(response); + + } + + }); + + } + + + } + + ); + + + } + + }); + + + + + + + +}; + var batchRequest = function (project, subject, res, funcAction, funcArgs) { @@ -394,7 +576,7 @@ var batchRequest = function (project, subject, res, funcAction, funcArgs) { var board_id = boards_list[i]["board_id"]; - db.insertRequestResult(request_id, board_id, "-", "-", function (data) { + db.insertRequestResult(request_id, board_id, "pending", "-", function (data) { if (data.result == "ERROR") { @@ -412,12 +594,16 @@ var batchRequest = function (project, subject, res, funcAction, funcArgs) { response.result = "SUCCESS"; response.message = "Action on boards of the project '" + project + "' - Request ID: " + request_id; + response.project_id = project; + response.req_id = request_id; + response.subject = subject; logger.info("[PROJECT] --> " + response.message); res.status(200).send(response); } })(i); + } } else{ @@ -433,8 +619,7 @@ var batchRequest = function (project, subject, res, funcAction, funcArgs) { } ); - - + } @@ -486,7 +671,7 @@ var insertRequest = function (project, subject) { var updateResult = function (request_id, board_id, result, message) { REQUESTS[request_id] = REQUESTS[request_id] - 1; - + db.updateResultStatus(request_id, board_id, result, message, function (data) { if (data.result == "ERROR") { @@ -495,10 +680,13 @@ var updateResult = function (request_id, board_id, result, message) { } else { - logger.debug("[SYSTEM] --> Action result on board '" + board_id + "': " + message); + if(result == "ERROR") + logger.error("[SYSTEM] --> Action result on board '" + board_id + "' for request '"+request_id+"':\n" + message); + else + logger.debug("[SYSTEM] --> Action result on board '" + board_id + "' for request '"+request_id+"':\n" + message); if (REQUESTS[request_id] == 0) { - + db.updateRequestStatus(request_id, "completed", function (data) { if (data.result == "ERROR") { @@ -508,8 +696,7 @@ var updateResult = function (request_id, board_id, result, message) { } delete REQUESTS[request_id]; - - + }); } @@ -527,4 +714,5 @@ var updateResult = function (request_id, board_id, result, message) { module.exports = request_utils; module.exports.insertRequest = insertRequest; module.exports.updateResult = updateResult; +module.exports.singleRequest = singleRequest; module.exports.batchRequest = batchRequest; \ No newline at end of file diff --git a/lib/management/mng_user.js b/lib/management/mng_user.js index 552ecbb..46cdcb0 100644 --- a/lib/management/mng_user.js +++ b/lib/management/mng_user.js @@ -27,7 +27,7 @@ var board_utility = require('./mng_board'); var auth = require('./mng_auth'); var uuid = require('node-uuid'); -var bcrypt = require('bcrypt'); +//var bcrypt = require('bcrypt'); user_utils = function (session, rest) { diff --git a/lib/management/mng_wamp.js b/lib/management/mng_wamp.js index 832c36a..ea76d9d 100644 --- a/lib/management/mng_wamp.js +++ b/lib/management/mng_wamp.js @@ -21,7 +21,7 @@ logger.setLevel(loglevel); var db_utils = require('./mng_db'); var db = new db_utils; -var board_utility = require('./mng_board'); +//var board_utility = require('./mng_board'); //var auth = require('./mng_auth'); @@ -113,7 +113,7 @@ var boardSync = function(){ logger.warn("[WAMP] --> "+wrong_conn_boards[w]); //Input parameters: board_id - res = false - restore = false - net_utils.activateBoardNetwork(wrong_conn_boards[w], false, true); + if(vnet_enabled) net_utils.activateBoardNetwork(wrong_conn_boards[w], false, true); })(w); @@ -266,13 +266,13 @@ var onBoardConnected = function (args) { var board_id = args[0]; var wamp_conn_status = args[1]; var wamp_session = args[2]; - + var auth_credentials = args[3]; + if (wamp_conn_status == 'connection') { //CHECK IF THE BOARD IS AUTHORIZED: IF IT EXISTS IN boards TABLE OR BY MEANS OF KEYSTONE SERVICE + auth.checkAuthorization(board_id, auth_credentials, function (auth_data) { - auth.checkAuthorization(board_id, function (auth_data) { - if(auth_data.result == "SUCCESS"){ iotronic_session.call('s4t.' + wamp_session + '.board.checkRegistrationStatus', [auth_data]).then( @@ -281,16 +281,18 @@ var onBoardConnected = function (args) { if(msg.result == "SUCCESS"){ - logger.debug("SYSTEM] --> " + msg.message); + //logger.debug("[SYSTEM] --> " + msg.message); var confStatus = auth_data; + + var lr_version = msg.lr_version; - if(confStatus.message.state == "new") + if(confStatus.message.state == "new" || confStatus.message.state == "updated") var state = "registered"; else var state = confStatus.message.state; - db.changeBoardStatus(board_id, wamp_session, 'C', state, function (data) { + db.changeBoardStatus(board_id, wamp_session, 'C', state, lr_version, function (data) { if (data.result == "ERROR") { @@ -314,7 +316,7 @@ var onBoardConnected = function (args) { // ENABLE NETWORK MANAGER ---------------------------------------------------------- //Input parameters: board_id - res = false - restore = false - net_utils.activateBoardNetwork(board_id, false, "false"); + if(vnet_enabled) net_utils.activateBoardNetwork(board_id, false, "false"); //---------------------------------------------------------------------------------- @@ -606,6 +608,7 @@ var IoTronicSubscribe = function () { }; +//This function decides to inject the configuration to the board related to registration-status var computeStatus = function (board_id, state, callback) { var response = { @@ -613,8 +616,7 @@ var computeStatus = function (board_id, state, callback) { result: 'SUCCESS' }; - if (state == "new"){ - + if (state == "new" || state == "updated"){ board_utility.createBoardConf(board_id, function (conf) { @@ -648,7 +650,7 @@ var computeStatus = function (board_id, state, callback) { response.message = {}; response.message['state'] = state; response.message['log'] = 'Board with UUID '+board_id+' is authorized!'; - logger.debug(JSON.stringify(response,null,"\t")); + //logger.debug(JSON.stringify(response,null,"\t")); callback(response) } diff --git a/lib/management/utility.js b/lib/management/utility.js index 6dde7c4..ff1e073 100644 --- a/lib/management/utility.js +++ b/lib/management/utility.js @@ -22,13 +22,9 @@ logger.setLevel(loglevel); var networkInterfaces = require('os').networkInterfaces(); - var spawn = require('child_process').spawn; - var ps = require('ps-node'); -//var Q = require("q"); - // Function to execute a command var execute = function (command, label) { @@ -189,6 +185,7 @@ var sendEmail = function (smtpConfig, email, subject, message) { }; + var getLocalTime = function (){ var tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds diff --git a/lib/modules/nodered_manager.js b/lib/modules/nodered_manager.js index e037724..43742ac 100644 --- a/lib/modules/nodered_manager.js +++ b/lib/modules/nodered_manager.js @@ -117,7 +117,42 @@ nodered_utils = function (session, rest) { }); - + //Get flows list of the board + /** + * @swagger + * /v1/boards/{board}/nodered/flows: + * post: + * tags: + * - Node-Red + * description: Get flows list of the board + * summary: get flows list + * parameters: + * - in: path + * name: board + * required: true + * schema: + * type: string + * description: The IoTronic board ID + * produces: + * - application/json + * responses: + * 200: + * description: List of Node-RED flows of a board + * properties: + * result: + * type: string + * description: "SUCCESS" + * message: + * type: array + * description: "List of Node-RED flows" + * items: + * title: flow info from Node-RED + * type: object + * 403: + * description: "Wrong, expired or not specified token in request header." + * 500: + * description: "API specific error message." + */ rest.get('/v1/boards/:board/nodered/flows', function (req, res) { var board = req.params.board; @@ -179,7 +214,32 @@ nodered_utils = function (session, rest) { }); - + //BATCH: Get flows list of the board + /** + * @swagger + * /v1/projects/{project}/nodered/flows: + * post: + * tags: + * - Node-Red + * description: Get flows list from the boards of a project + * summary: get flows list + * parameters: + * - in: path + * name: project + * required: true + * schema: + * type: string + * description: "The IoTronic projects ID or NAME" + * produces: + * - application/json + * responses: + * 200: + * $ref: "#/definitions/IoTronicResponse" + * 403: + * description: "Wrong, expired or not specified token in request header." + * 500: + * description: "API specific error message." + */ rest.get('/v1/projects/:project/nodered/flows', function (req, res) { logger.info("[API] - BATCH Get Node-RED flows - " + Object.keys( req.route.methods ) + " - " + req.route.path + " - " + req.IotronicUser); @@ -278,6 +338,186 @@ nodered_utils = function (session, rest) { + }); + + + //Get flows list of the board + /** + * @swagger + * /v1/boards/{board}/nodered/flows: + * post: + * tags: + * - Node-Red + * description: Get flows list of the board + * summary: get flows list + * parameters: + * - in: path + * name: board + * required: true + * schema: + * type: string + * description: The IoTronic board ID + * produces: + * - application/json + * responses: + * 200: + * description: List of Node-RED flows of a board + * properties: + * result: + * type: string + * description: "SUCCESS" + * message: + * type: array + * description: "List of Node-RED flows" + * items: + * title: flow info from Node-RED + * type: object + * 403: + * description: "Wrong, expired or not specified token in request header." + * 500: + * description: "API specific error message." + */ + rest.get('/v1/boards/:board/nodered/flow/:flow', function (req, res) { + + var board = req.params.board; + var flow_id = req.params.flow; + + logger.info("[API] - Node-RED board flow info - " + Object.keys( req.route.methods ) + " - " + req.route.path + " - " + req.IotronicUser); + + board_utility.checkBoardAvailable(board, res, function (available) { + + if (available.result == "SUCCESS") { + + var response = { + message: {}, + result: "" + }; + + session_wamp.call('s4t.' + board + '.nodered.getFlowInfo', [flow_id]).then( + + function (rpc_response) { + + if (rpc_response.result == "ERROR") { + + response.message = rpc_response.message; + response.result = "ERROR"; + res.status(500).send(response); + logger.warn("[SYSTEM] --> Got error retrieving flow info from board '" + board + "': " + JSON.stringify(response.message)); + + } else { + + response.message = rpc_response.message; + response.result = rpc_response.result; + res.status(200).send(response); + logger.info("[SYSTEM] --> Retrieved flow ("+flow_id+") details from board '" + board + "'!"); + + } + + }, + function (rpc_error) { + + response.message = "RPC UNAVAILABLE: " + rpc_error.error; + response.result = "WARNING"; + + logger.warn("[SYSTEM] - RPC UNAVAILABLE: " + rpc_error.error); + res.status(200).send(response); + + } + + ); + + + }else if(available.result == "WARNING") { + logger.error("[API] --> " + available.message); + res.status(200).send(available); + } + + + }); + + + + + }); + + + //INJECT flow + /** + * @swagger + * /v1/boards/{board}/nodered/flow: + * post: + * tags: + * - Node-Red + * description: Inject a flow in the Node-RED instance of the board + * summary: Inject a flow in Node-RED + * parameters: + * - in: path + * name: board + * required: true + * schema: + * type: string + * description: The IoTronic board ID + * - name: body + * in: body + * required: true + * schema: + * type: object + * required: + * - flow + * properties: + * flow: + * type: array + * description: "flow represented by an array of nodes (Complete Flow configuration)" + * produces: + * - application/json + * responses: + * 200: + * $ref: "#/definitions/IoTronicResponse" + * 403: + * description: "Wrong, expired or not specified token in request header." + * 500: + * description: "API specific error message." + */ + rest.post('/v1/boards/:board/nodered/flow', function (req, res){ + + var board = req.params.board; + + logger.info("[API] - Node-RED flow injection - " + Object.keys( req.route.methods ) + " - " + req.route.path + " - " + req.IotronicUser); + + board_utility.checkBoardAvailable(board, res, function (available) { + + if (available.result == "SUCCESS") { + + var exported_flow = req.body.exported_flow; //Complete Flow configuration + + var ApiRequired = {"exported_flow":exported_flow}; + + board_utility.checkRequired(ApiRequired, function (check) { + + if (check.result == "ERROR") { + + res.status(500).send(check); + + } else { + + injectFlow(board, null, [exported_flow, res]); + + + } + + }); + + + }else if(available.result == "WARNING") { + logger.error("[API] --> " + available.message); + res.status(200).send(available); + } + + + }); + + + }); @@ -292,6 +532,7 @@ nodered_utils = function (session, rest) { }; + var execEngineAction = function (board, action, parameters, res) { var response = { @@ -389,6 +630,115 @@ var execEngineAction = function (board, action, parameters, res) { }; +var injectFlow = function (board, request_id, args) { + + + var response = { + message: '', + result: '' + }; + + var exported_flow = args[0]; + var res = args[1]; + + flowFormatConverter(exported_flow, function (single_flow) { + + /* + response.message = single_flow; + response.result = "SUCCESS"; + res.status(200).send(response); + */ + + session_wamp.call('s4t.'+ board + '.nodered.injectFlow', [single_flow]).then( + + function (rpc_response) { + + if (rpc_response.result == "ERROR") { + + response.message = rpc_response.message; + response.result = "ERROR"; + + if(res != false){ + logger.warn("[PLUGIN] --> Flow injection error for board '" + board + "': " + JSON.stringify(response.message, null, "\t")); + res.status(500).send(response); + }else{ + request_utils.updateResult(request_id, board, response.result, response.message); + } + + }else{ + + response.message = rpc_response.message; + response.result = rpc_response.result; + + if(res != false){ + logger.info("[PLUGIN] --> Flow injection result for board '" + board + "': " + JSON.stringify(response.message, null, "\t")); + res.status(200).send(response); + }else{ + request_utils.updateResult(request_id, board, response.result, response.message); + } + + } + + }, + function (rpc_error) { + + response.message = "RPC UNAVAILABLE: " + rpc_error.error; + response.result = "WARNING"; + if(res != false){ + logger.warn("[SYSTEM] - RPC UNAVAILABLE: " + rpc_error.error); + res.status(200).send(response); + } + else{ + + request_utils.updateResult(request_id, board, response.result, response.message); + + } + + } + + ); + + + }) + +}; + + +var flowFormatConverter = function (exported, callback) { + + var single_format_template = { + "label": "", //A label for the the flow + "nodes": [], //An array of the Nodes in the flow + "configs": [], //An array of the Configs in the flow + "subflows": [] //An array of the Subflows in the flow - only used when representing the global flow configuration + }; + + var single_flow = single_format_template; //import template + + var exported = JSON.parse(exported); //from string to JSON + + for (var item in exported) { + + var node_type = exported[item].type; + + if(node_type != "tab"){ + + single_flow.nodes.push(exported[item]) + } + else{ + single_flow.label = exported[item].label; + } + + if (item == exported.length - 1 ){ + callback(single_flow); + + } + + } + + +}; + nodered_utils.prototype.exportCommands = function (session){ diff --git a/lib/modules/plugin_manager.js b/lib/modules/plugin_manager.js index c8b8cea..aafd3e9 100644 --- a/lib/modules/plugin_manager.js +++ b/lib/modules/plugin_manager.js @@ -742,7 +742,7 @@ plugin_utils = function (session, rest) { if (pluginTag == "released") { - var subject = "/projects/"+project+"/plugins/"+plugin; + var subject = "plugin inject: "+plugin; request_utils.batchRequest(project, subject, res, plugin_utils.injectPlugin, [plugin, onboot, force, false]); @@ -989,7 +989,7 @@ plugin_utils = function (session, rest) { logger.info("[PLUGIN] - BATCH plugin operation on boards of the project "+ project +": " + operation + " plugin '" + plugin +"'"); - var subject = "/projects/"+project+"/plugins/"+plugin; + var subject = "plugin action: " + operation + " "+ plugin; request_utils.batchRequest(project, subject, res, plugin_utils.managePlugins, [plugin, parameters, operation, false]); @@ -1102,7 +1102,7 @@ plugin_utils = function (session, rest) { }; - var subject = "/projects/"+project+"/plugins/"+plugin; + var subject = "remove plugin: "+plugin; request_utils.batchRequest(project, subject, res, plugin_utils.removePlugin, [plugin, false]); @@ -1270,7 +1270,6 @@ plugin_utils = function (session, rest) { }); - //GET plugin logs of a board /** * @swagger @@ -1323,27 +1322,16 @@ plugin_utils = function (session, rest) { var plugin = req.params.plugin; var rows = req.query.rows; - board_utility.checkBoardAvailable(board, res, function (available){ - - if(available.result == "SUCCESS"){ - - if(rows == undefined){ - rows = 10; //default value - } - - plugin_utils.getPluginLogs(board, null, [plugin, rows, res]); - }else if(available.result == "WARNING") { - logger.error("[API] --> " + available.message); - res.status(200).send(available); - } + if(rows == undefined){ + rows = 10; //default value + } - }); + plugin_utils.getPluginLogs(board, null, [plugin, rows, res]); }); - //BATCH: GET plugin logs of a board /** * @swagger @@ -1397,7 +1385,7 @@ plugin_utils = function (session, rest) { var rows = req.query.rows; - var subject = "/projects/"+project+"/plugins/"+plugin; + var subject = "get plugin logs: "+plugin; request_utils.batchRequest(project, subject, res, plugin_utils.getPluginLogs, [plugin, rows, false]); @@ -2616,6 +2604,7 @@ plugin_utils.prototype.managePlugins = function (board, request_id, args) { }); }else{ + response.message = rpc_response; response.result = "SUCCESS"; diff --git a/lib/modules/service_manager.js b/lib/modules/service_manager.js index 6b188fa..4a8ddcf 100644 --- a/lib/modules/service_manager.js +++ b/lib/modules/service_manager.js @@ -331,15 +331,15 @@ services_utils = function (session, rest) { logger.info("[API] - Service Operation - " + Object.keys( req.route.methods ) + " - " + req.route.path + " - " + req.IotronicUser); - var board = req.params.board; - var service = req.params.service; // ssh | tty | ideino | osjs + var board_id = req.params.board; + var service = req.params.service; //e.g.: ssh | osjs var response = { message: '', result: {} }; - board_utility.checkBoardAvailable(board, res, function (available){ + board_utility.checkBoardAvailable(board_id, res, function (available){ if(available.result == "SUCCESS"){ @@ -349,12 +349,14 @@ services_utils = function (session, rest) { var ApiRequired = {"service_action": service_action}; + var board_label = available.b_label; + board_utility.checkRequired(ApiRequired, function (check) { if (check.result == "ERROR") { res.status(500).send(check); } else { - services_utils.manageService(board, service, service_action, res, null); + services_utils.manageService(board_id, service, service_action, res, null); } }); @@ -362,7 +364,7 @@ services_utils = function (session, rest) { } else { response.result = "ERROR"; - response.message = "Service action " + service_action + " is not supported! [ 'enable' | 'disable' | 'restore' ]"; + response.message = "Service action '" + service_action + "' is not supported! [ 'enable' | 'disable' | 'restore' ]"; logger.error("[API] --> " + response.message); res.status(500).send(response.message); @@ -446,7 +448,7 @@ services_utils = function (session, rest) { res.status(500).send(check); } else { - var subject = "/projects/"+project+"/services/"+service+"/action"; + var subject = "service action: "+ service_action + " " +service; request_utils.insertRequest(project, subject).then( @@ -534,6 +536,8 @@ services_utils = function (session, rest) { if (i === (boards_list.length - 1)) { + response.req_id = request_id; + response.subject = subject; response.result = "SUCCESS"; response.message = "Performing "+ service_action +" action for service "+service+" on boards of the project '" + project + "' - Request ID: " + request_id; logger.info("[PROJECT] --> " + response.message); @@ -602,6 +606,8 @@ services_utils = function (session, rest) { if (i === (boards_list.length - 1)) { + response.req_id = request_id; + response.subject = subject; response.result = "SUCCESS"; response.message = "Performing "+ service_action +" action for service "+service+" on boards of the project '" + project + "' - Request ID: "+ request_id; logger.info("[PROJECT] --> " + response.message); @@ -655,7 +661,7 @@ services_utils = function (session, rest) { } else { response.result = "ERROR"; - response.message = "Service action " + service_action + " is not supported! [ 'enable' | 'disable' | 'restore' ]"; + response.message = "Service action '" + service_action + "' is not supported! [ 'enable' | 'disable' | 'restore' ]"; logger.error("[API] --> " + response.message); res.status(500).send(response.message); @@ -748,7 +754,6 @@ services_utils = function (session, rest) { } }); - }); @@ -822,9 +827,6 @@ services_utils = function (session, rest) { - - - logger.debug("[REST-EXPORT] - Services's APIs exposed!"); //--------------------------------------------------------------------------------------------------- @@ -840,7 +842,7 @@ services_utils = function (session, rest) { services_utils.prototype.createService = function (service_name, port, protocol, res) { - logger.info("[SERVICE] - CREATING service " + service_name + "..."); + logger.info("[SERVICE] - Creating service '" + service_name + "'..."); var response = { message: '', @@ -871,7 +873,7 @@ services_utils.prototype.createService = function (service_name, port, protocol, } else { - response.message = "Service " + service_name + " successfully created in IoTronic!"; + response.message = "Service '" + service_name + "' successfully created in IoTronic!"; response.result = "SUCCESS"; logger.info("[SERVICE] --> " +response.message); res.status(200).send(response); @@ -885,7 +887,7 @@ services_utils.prototype.createService = function (service_name, port, protocol, } else { - response.message = "Service " + service_name + " already exists!"; + response.message = "Service '" + service_name + "' already exists!"; response.result = "ERROR"; logger.warn("[SERVICE] --> " + response.message); res.status(500).send(response); @@ -941,7 +943,7 @@ services_utils.prototype.updateService = function (service, service_name, port, } else { - response.message = "Service " + service_name + " successfully updated!"; + response.message = "Service '" + service_name + "' successfully updated!"; response.result = "SUCCESS"; logger.info("[SERVICE] --> " +response.message); res.status(200).send(response); @@ -963,7 +965,7 @@ services_utils.prototype.updateService = function (service, service_name, port, services_utils.prototype.deleteService = function (service_name, res) { - logger.info("[SERVICE] - Deleting service " + service_name + " from Iotronic..."); + logger.info("[SERVICE] - Deleting service '" + service_name + "' from Iotronic..."); var response = { message: '', @@ -982,7 +984,7 @@ services_utils.prototype.deleteService = function (service_name, res) { } else { if (data.message[0] === undefined) { - response.message = "Service " + service_name + " does not exist!"; + response.message = "Service '" + service_name + "' does not exist!"; response.result = "ERROR"; logger.warn("[SERVICE] --> " + response.message); res.status(500).send(response); @@ -1000,7 +1002,7 @@ services_utils.prototype.deleteService = function (service_name, res) { } else { - response.message = "Service " + service_name + " successfully deleted from IoTronic!"; + response.message = "Service '" + service_name + "' successfully deleted from IoTronic!"; response.result = "SUCCESS"; logger.info("[SERVICE] --> " +response.message); res.status(200).send(response); @@ -1043,7 +1045,10 @@ services_utils.prototype.manageService = function (board_id, service, service_ac res.status(500).send(service_info.message); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + response.message); } } else { @@ -1064,13 +1069,17 @@ services_utils.prototype.manageService = function (board_id, service, service_ac if (data_p.result == "ERROR") { response.result = data_p.result; - response.message = "DB getActiveService error for " + service_name + ": " + data_p.message; + response.message = "DB getActiveService error for '" + service_name + "': " + data_p.message; if(res != false){ logger.error("[SERVICE] --> " + response.message); res.status(200).send(response); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + response.message); } } else { @@ -1100,7 +1109,10 @@ services_utils.prototype.manageService = function (board_id, service, service_ac res.status(500).send(response); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } } else { @@ -1108,9 +1120,10 @@ services_utils.prototype.manageService = function (board_id, service, service_ac service_msg.public_port = publicPort; service_msg.service = service_name; service_msg.pid = service_result.pid; - service_msg.log = "Service '"+service_name+"' of board '" + board_id + "' updated: " + check_result.message; + //service_msg.log = "Service '"+service_name+"' of board '" + board_id + "' updated: " + check_result.message; - response.message = service_msg; + response.message = service_result.message; + response.logs = service_msg; response.result = "SUCCESS"; if(res != false){ @@ -1118,7 +1131,10 @@ services_utils.prototype.manageService = function (board_id, service, service_ac res.status(200).send(response); } else{ - request_utils.updateResult(request_id, board_id, response.result, JSON.stringify(response.message)); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, JSON.stringify(response.message)); + else + logger.info("[SYSTEM] --> " + service_result.message); } @@ -1134,7 +1150,10 @@ services_utils.prototype.manageService = function (board_id, service, service_ac res.status(500).send(service_result); } else{ - request_utils.updateResult(request_id, board_id, service_result.result, service_result.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, service_result.result, service_result.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } } @@ -1148,7 +1167,10 @@ services_utils.prototype.manageService = function (board_id, service, service_ac res.status(500).send(response); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } } @@ -1163,26 +1185,31 @@ services_utils.prototype.manageService = function (board_id, service, service_ac res.status(200).send(response); } else{ - - request_utils.updateResult(request_id, board_id, response.result, response.message); - + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } } ); - }else{ + } + else{ response.result = "WARNING"; - response.message = "The '" + service_name + "' service is not enabled!"; + response.message = "Service '" + service_name + "' is not enabled!"; if(res != false){ logger.warn("[SERVICE] --> " + response.message); res.status(200).send(response); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + response.message); } } @@ -1198,21 +1225,24 @@ services_utils.prototype.manageService = function (board_id, service, service_ac case 'enable': if(res != false) - logger.info("[SERVICE] - Exposing '" + service_name + "' service of the board " + board_id + "..."); + logger.info("[SERVICE] - Exposing service '" + service_name + "' on the board " + board_id + "..."); db.getActiveService(service_id, board_id, function (data_p) { if (data_p.result == "ERROR") { response.result = data_p.result; - response.message = "DB getActiveService error for " + service_name + ": " + data_p.message; + response.message = "DB getActiveService error for '" + service_name + "': " + data_p.message; if(res != false){ logger.error("[SERVICE] --> " + response.message); res.status(500).send(response); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } @@ -1230,7 +1260,7 @@ services_utils.prototype.manageService = function (board_id, service, service_ac if (service_result.message.status === "ACTIVE") { - response.message = "Service " + service_name + " already exposed!"; + response.message = "Service '" + service_name + "' already exposed!"; response.result = "WARNING"; if(res != false){ @@ -1238,7 +1268,11 @@ services_utils.prototype.manageService = function (board_id, service, service_ac res.status(200).send(response); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); + } @@ -1251,7 +1285,7 @@ services_utils.prototype.manageService = function (board_id, service, service_ac if (service_result.message.status === "INACTIVE") { - logger.warn("[SERVICE] --> " + service_name + " service of board " + board_id + " is in wrong state.. Updating..."); + logger.warn("[SERVICE] --> Service '" + service_name + "' of board '" + board_id + "' is in wrong state.. Updating..."); //UPDATE DB db.removeTunnel(service_id, board_id, function (check_result) { @@ -1264,7 +1298,10 @@ services_utils.prototype.manageService = function (board_id, service, service_ac res.status(500).send(response); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } @@ -1277,7 +1314,10 @@ services_utils.prototype.manageService = function (board_id, service, service_ac res.status(200).send(response); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } @@ -1303,7 +1343,10 @@ services_utils.prototype.manageService = function (board_id, service, service_ac } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } @@ -1324,7 +1367,10 @@ services_utils.prototype.manageService = function (board_id, service, service_ac res.status(500).send(publicPort); } else{ - request_utils.updateResult(request_id, board_id, publicPort.result, publicPort.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } @@ -1353,7 +1399,10 @@ services_utils.prototype.manageService = function (board_id, service, service_ac res.status(500).send(response); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } } else { @@ -1375,7 +1424,10 @@ services_utils.prototype.manageService = function (board_id, service, service_ac res.status(200).send(response); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } @@ -1394,7 +1446,10 @@ services_utils.prototype.manageService = function (board_id, service, service_ac res.status(500).send(response); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } } @@ -1410,7 +1465,10 @@ services_utils.prototype.manageService = function (board_id, service, service_ac } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } @@ -1438,35 +1496,43 @@ services_utils.prototype.manageService = function (board_id, service, service_ac case 'disable': if(res != false) - logger.info("[SERVICE] - Disabling tunnel for service " + service_name + " in the board " + board_id +" ( local port = "+localport+" )"); + logger.info("[SERVICE] - Disabling tunnel for service '" + service_name + "' in the board '" + board_id +"' ( local port = "+localport+" )"); db.getActiveService(service_id, board_id, function (data_p) { if (data_p.result == "ERROR") { response.result = data_p.result; - response.message = "DB getActiveService error for " + service_name + ": " + data_p.message; + response.message = "DB getActiveService error for '" + service_name + "': " + data_p.message; if(res != false){ logger.error("[SERVICE] --> " + response.message); res.status(500).send(response); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } } else { if (data_p.message[0] == undefined) { - response.message = "Service " + service_name + " not exposed for the board " + board_id; + //response.message = "Service '" + service_name + "' not exposed for the board " + board_id; + response.message = "Service '" + service_name + "' not exposed!"; + response.result = "WARNING"; if(res != false){ logger.warn("[SERVICE] --> " + response.message); res.status(200).send(response); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } } else { @@ -1490,19 +1556,27 @@ services_utils.prototype.manageService = function (board_id, service, service_ac res.status(500).send(response); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } } else { - response.message = "Tunnel for service " + service_name + " disabled on board " + board_id + " (public port = "+publicPort+")"; + //response.message = "Service " + service_name + " disabled on board " + board_id + " (public port = "+publicPort+")"; + response.message = "Service '" + service_name + "' disabled on port "+publicPort; + response.result = "SUCCESS"; if(res != false){ logger.info("[SERVICE] --> " + response.message); res.status(200).send(response); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } } @@ -1523,12 +1597,15 @@ services_utils.prototype.manageService = function (board_id, service, service_ac res.status(500).send(response); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } }else if (service_result.result === "WARNING"){ - logger.warn("[SERVICE] --> " + service_name + " service of board " + board_id + " is in wrong state.. Updating..."); + logger.warn("[SERVICE] --> service '" + service_name + "' of board " + board_id + " is in wrong state.. Updating..."); if (service_result.message.status === "INACTIVE"){ @@ -1543,7 +1620,10 @@ services_utils.prototype.manageService = function (board_id, service, service_ac res.status(500).send(response); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } } else { @@ -1555,7 +1635,10 @@ services_utils.prototype.manageService = function (board_id, service, service_ac res.status(200).send(response); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } } @@ -1580,7 +1663,10 @@ services_utils.prototype.manageService = function (board_id, service, service_ac } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } @@ -1599,14 +1685,17 @@ services_utils.prototype.manageService = function (board_id, service, service_ac default: response.result = "ERROR"; - response.message = "Service action " + service_action + " is not supported! [ 'enable' | 'disable' | 'restore' ]"; + response.message = "Service action '" + service_action + "' is not supported! [ 'enable' | 'disable' | 'restore' ]"; if(res != false){ logger.warn("[SERVICE] --> " + response.message); res.status(500).send(response.message); } else{ - request_utils.updateResult(request_id, board_id, response.result, response.message); + if(request_id != null) + request_utils.updateResult(request_id, board_id, response.result, response.message); + else + logger.info("[SYSTEM] --> " + service_result.message); } break; @@ -1659,7 +1748,7 @@ services_utils.prototype.restoreServices = function (result) { } else{ - logger.info("[SERVICE] - RELOAD BOARD SERVICE TUNNELS:\n"+ JSON.stringify(data.message, null, "\t")); + logger.info("[SERVICE] - Reload board services tunnels:\n"+ JSON.stringify(data.message, null, "\t")); for(var key=0; key < data.message.length; key++) { diff --git a/lib/modules/vnet_iotronic_manager.js b/lib/modules/vnet_iotronic_manager.js index 9c82db2..79510d5 100644 --- a/lib/modules/vnet_iotronic_manager.js +++ b/lib/modules/vnet_iotronic_manager.js @@ -1723,8 +1723,8 @@ net_utils.prototype.activateBoardNetwork = function (board, res, restore) { //NETWORK INIT logger.info("[VNET] - Socat initialization..."); - var socatNetwork = nconf.get('config:socat:ip'); - var basePort = nconf.get('config:socat:server:port'); + var socatNetwork = nconf.get('config:modules:vnets_manager:socat:ip'); + var basePort = nconf.get('config:modules:vnets_manager:socat:server:port'); if (data.message[0] == undefined) { logger.debug("[VNET] --> New board " + db_board_id); diff --git a/lib/modules/vnet_neutron_manager.js b/lib/modules/vnet_neutron_manager.js index d8a0f31..2659bb8 100644 --- a/lib/modules/vnet_neutron_manager.js +++ b/lib/modules/vnet_neutron_manager.js @@ -27,8 +27,8 @@ var IotronicHome = "/var/lib/iotronic"; var nconf = require('nconf'); nconf.file({file: IotronicHome + '/settings.json'}); -var socatNetwork = nconf.get('config:socat:ip'); -var basePort = nconf.get('config:socat:server:port'); +var socatNetwork = nconf.get('config:modules:vnets_manager:socat:ip'); +var basePort = nconf.get('config:modules:vnets_manager:socat:server:port'); var spawn = require('child_process').spawn; @@ -210,8 +210,8 @@ net_utils.prototype.activateBoardNetwork = function (board, res, restore) { //NETWORK INIT logger.info("[VNET] - SOCAT INITIALIZATION: getting Socat parameters..."); - var socatNetwork = nconf.get('config:socat:ip'); - var basePort = nconf.get('config:socat:server:port'); + var socatNetwork = nconf.get('config:modules:vnets_manager:socat:ip'); + var basePort = nconf.get('config:modules:vnets_manager:socat:server:port'); if (data[0] == undefined) { diff --git a/package.json b/package.json index 005d4d3..e3300df 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mdslab/iotronic-standalone", - "version": "2.1.2", + "version": "2.2.0", "description": "IoTronic-standalone is the implementation of a personal Cloud to remote manage embedded devices (Arduino YUN/Linino One, Raspberry Pi 2/3, etc)", "main": "lib/iotronic_standalone.js", "scripts": { @@ -29,7 +29,8 @@ "nodemailer-smtp-transport":"<=2.7.4", "jsonwebtoken": "<=8.1.0", "swagger-jsdoc":"<=1.9.7", - "md5":"<=2.2.1" + "md5":"<=2.2.1", + "crypto":">=1.0.1" }, "repository": { "type": "git", diff --git a/utils/createAdminToken.js b/utils/createAdminToken.js deleted file mode 100644 index 448e84c..0000000 --- a/utils/createAdminToken.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - Copyright (c) 2017 Nicola Peditto - -*/ - -var bcrypt = require('bcrypt'); - -var encryptPassword = function (user_pw, callback) { - - var response = { - message: '', - result: '' - }; - - bcrypt.hash(user_pw, 5, function(err, bcryptedPassword) { - - if (err) { - response.message = "Error encrypting user password: " + err.message; - response.result = "ERROR"; - callback(response); - - } else { - response.message = bcryptedPassword; - response.result = "SUCCESS"; - callback(response); - } - - }); - - -}; - - -args = process.argv; -console.log("Password:" + args[2]); -admin_pw = args[2]; - -encryptPassword(admin_pw, function (response) { - - console.log("Encrypted Admin Token: " + response.message) - -}); diff --git a/utils/s4t-db.sql b/utils/s4t-db.sql index a7e4672..a5433eb 100644 --- a/utils/s4t-db.sql +++ b/utils/s4t-db.sql @@ -1,5 +1,5 @@ -- MySQL Script generated by MySQL Workbench --- gio 24 mag 2018 18:11:57 CEST +-- lun 16 lug 2018 10:41:12 CEST -- Model: New Model Version: 1.0 -- MySQL Workbench Forward Engineering @@ -29,6 +29,7 @@ CREATE TABLE IF NOT EXISTS `s4t-iotronic`.`layouts` ( `manufacturer` VARCHAR(45) NULL, `image` VARCHAR(45) NULL, `layout` VARCHAR(45) NOT NULL, + `distro` VARCHAR(45) NOT NULL, PRIMARY KEY (`id_layout`)) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8; @@ -92,6 +93,9 @@ CREATE TABLE IF NOT EXISTS `s4t-iotronic`.`boards` ( `notify_retry` INT NULL, `extra` VARCHAR(600) NULL, `state` VARCHAR(45) NOT NULL, + `pubkey` LONGTEXT NULL, + `password` VARCHAR(60) NULL, + `lr_version` VARCHAR(10) NULL, PRIMARY KEY (`board_id`), INDEX `fk_boards_layout1_idx` (`layout_id` ASC), INDEX `fk_boards_projects1_idx` (`projects_id` ASC), @@ -190,7 +194,7 @@ CREATE TABLE IF NOT EXISTS `s4t-iotronic`.`plugins_injected` ( `plugin_id` INT(11) NOT NULL, `plugin_name` VARCHAR(100) NULL, `state` VARCHAR(20) NOT NULL, - `plugin_name` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `latest_change` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `fk_plugins_injected_plugins1_idx` (`plugin_id` ASC), PRIMARY KEY (`board_id`, `plugin_id`), INDEX `fk_plugins_injected_boards1_idx` (`board_id` ASC), @@ -596,7 +600,7 @@ CREATE TABLE IF NOT EXISTS `s4t-iotronic`.`requests` ( CONSTRAINT `fk_requests_projects1` FOREIGN KEY (`project_id`) REFERENCES `s4t-iotronic`.`projects` (`uuid`) - ON DELETE NO ACTION + ON DELETE CASCADE ON UPDATE CASCADE) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8; @@ -625,7 +629,7 @@ CREATE TABLE IF NOT EXISTS `s4t-iotronic`.`results` ( CONSTRAINT `fk_results_boards1` FOREIGN KEY (`board_id`) REFERENCES `s4t-iotronic`.`boards` (`board_id`) - ON DELETE NO ACTION + ON DELETE CASCADE ON UPDATE CASCADE) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8; @@ -640,10 +644,11 @@ SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; -- ----------------------------------------------------- START TRANSACTION; USE `s4t-iotronic`; -INSERT INTO `s4t-iotronic`.`layouts` (`id_layout`, `model`, `manufacturer`, `image`, `layout`) VALUES (1, 'YUN', 'Arduino', 'linino', 'arduino_yun'); -INSERT INTO `s4t-iotronic`.`layouts` (`id_layout`, `model`, `manufacturer`, `image`, `layout`) VALUES (2, 'server', 'generic', 'debian-like', 'server'); -INSERT INTO `s4t-iotronic`.`layouts` (`id_layout`, `model`, `manufacturer`, `image`, `layout`) VALUES (3, 'Raspberry Pi 3', 'Raspberry', 'LEDE', 'raspberry_pi'); -INSERT INTO `s4t-iotronic`.`layouts` (`id_layout`, `model`, `manufacturer`, `image`, `layout`) VALUES (4, 'Raspberry Pi 3', 'Raspberry', 'Raspbian', 'raspberry_pi'); +INSERT INTO `s4t-iotronic`.`layouts` (`id_layout`, `model`, `manufacturer`, `image`, `layout`, `distro`) VALUES (1, 'YUN', 'Arduino', 'linino', 'arduino_yun', 'openwrt'); +INSERT INTO `s4t-iotronic`.`layouts` (`id_layout`, `model`, `manufacturer`, `image`, `layout`, `distro`) VALUES (2, 'server', 'generic', 'ubuntu', 'server', 'debian'); +INSERT INTO `s4t-iotronic`.`layouts` (`id_layout`, `model`, `manufacturer`, `image`, `layout`, `distro`) VALUES (3, 'Raspberry Pi 3', 'Raspberry', 'LEDE', 'raspberry_pi', 'openwrt'); +INSERT INTO `s4t-iotronic`.`layouts` (`id_layout`, `model`, `manufacturer`, `image`, `layout`, `distro`) VALUES (4, 'Raspberry Pi 3', 'Raspberry', 'Raspbian', 'raspberry_pi', 'debian'); +INSERT INTO `s4t-iotronic`.`layouts` (`id_layout`, `model`, `manufacturer`, `image`, `layout`, `distro`) VALUES (5, 'Artik 710c', 'Samsung', 'Ubuntu-16.04', 'artik', 'debian'); COMMIT; @@ -692,7 +697,11 @@ COMMIT; -- ----------------------------------------------------- START TRANSACTION; USE `s4t-iotronic`; -INSERT INTO `s4t-iotronic`.`services` (`id`, `name`, `port`, `protocol`) VALUES (1, 'SSH', 22, 'TCP'); +INSERT INTO `s4t-iotronic`.`services` (`id`, `name`, `port`, `protocol`) VALUES (1, 'SSH', 22, 'SSH'); +INSERT INTO `s4t-iotronic`.`services` (`id`, `name`, `port`, `protocol`) VALUES (2, 'WEB', 80, 'HTTP'); +INSERT INTO `s4t-iotronic`.`services` (`id`, `name`, `port`, `protocol`) VALUES (3, 'WEB SSL', 443, 'HTTPS'); +INSERT INTO `s4t-iotronic`.`services` (`id`, `name`, `port`, `protocol`) VALUES (4, 'Node-RED', 1880, 'HTTP'); +INSERT INTO `s4t-iotronic`.`services` (`id`, `name`, `port`, `protocol`) VALUES (5, 'Mosquitto', 1883, 'HTTP'); COMMIT; diff --git a/utils/board_settings_template.json b/utils/templates/board_settings_template.json similarity index 60% rename from utils/board_settings_template.json rename to utils/templates/board_settings_template.json index ac09354..cb66681 100644 --- a/utils/board_settings_template.json +++ b/utils/templates/board_settings_template.json @@ -1,36 +1,12 @@ { + "config": { - "device": "", "log": { "logfile": "/var/log/iotronic/lightning-rod.log", - "loglevel": "debug" - }, - "wamp": { - "url_wamp": "", - "port_wamp": "8181", - "realm": "s4t", - "wifi_force_reconnect": "true" - }, - "reverse": { - "server": { - "url_reverse": "", - "port_reverse": "8080" - }, - "lib": { - "bin": "wstun" - }, - "pid": "" - }, - "socat": { - "client": { - "port": "20000" - }, - "pid": "" + "loglevel": "info" }, "board": { - "code": "", "label":"", - "status": "", "position": { "altitude": "", "longitude": "", @@ -41,7 +17,7 @@ "plugins_manager": { "enabled": true, "boot": true, - "alive_timer": 10000 + "alive_timer": 60 }, "services_manager": { "enabled": true, @@ -53,7 +29,16 @@ }, "vnets_manager": { "enabled": false, - "boot": false + "boot": false, + "socat": { + "client": { + "port": "20000" + }, + "pid": "" + }, + "wstun":{ + "pid":"" + } }, "gpio_manager": { "enabled": false, @@ -71,4 +56,4 @@ } } -} \ No newline at end of file +} diff --git a/settings.example.json b/utils/templates/settings.example.json similarity index 61% rename from settings.example.json rename to utils/templates/settings.example.json index 60c3f93..9a8b190 100644 --- a/settings.example.json +++ b/utils/templates/settings.example.json @@ -4,6 +4,7 @@ { "interface": "", "public_ip": "", + "api_ip": "", "http_port":"8888", "https":{ "enable":"false", @@ -61,24 +62,50 @@ "port": "8181", "ssl": "false", "realm": "s4t", - "topic_connection": "board.connection" + "topic_connection": "board.connection", + "crossbar_pub_ip":"" }, - "socat": - { - "ip":"20.0.0.0", - "server": - { - "port":"10000" - } - }, - "wstun": - { - "port_range":{ - "high":7000, - "low": 6000 + "modules": { + "plugins_manager": { + "enabled": true }, - "ip":"" + "services_manager": { + "enabled": true, + "wstun": + { + "port_range":{ + "high":7000, + "low": 6000 + }, + "public_ip":"" + } + }, + "nodered_manager": { + "enabled": true + }, + "vnets_manager": { + "enabled": false, + "socat": + { + "ip":"20.0.0.0", + "server": + { + "port":"10000" + } + } + }, + "gpio_manager": { + "enabled": false + }, + "drivers_manager": { + "enabled": false + }, + "vfs_manager": { + "enabled": false + } } } + + }