mirror of
https://github.com/Hopiu/webapi-eca.git
synced 2026-04-02 14:20:32 +00:00
- unit testing seems a bit more complex because of the dependencies, this has to be started before solving above point because it will give hints to better loose coupling
266 lines
8.5 KiB
JavaScript
266 lines
8.5 KiB
JavaScript
// # DB Interface
|
|
// Handles the connection to the database and provides functionalities for
|
|
// event/action modules, rules and the encrypted storing of authentication tokens.
|
|
|
|
// ## General
|
|
// General functionality as a wrapper for the module holds initialization,
|
|
// encryption/decryption, the retrieval of modules and shut down.
|
|
// Modules of the same group, e.g. action modules are registered in an unordered
|
|
// set in the database, from where they can be retrieved again. For example a new
|
|
// action module has its ID (e.g 'probinder') first registered in the set
|
|
// 'action_modules' and then stored in the db with the key 'action\_module\_' + ID
|
|
// (e.g. action\_module\_probinder).
|
|
'use strict';
|
|
var redis = require('redis'),
|
|
crypto = require('crypto'),
|
|
log = require('./logging'),
|
|
crypto_key, db;
|
|
|
|
|
|
/*
|
|
* Initializes the DB connection. Requires a port where the DB listens to requests
|
|
* and a key that is used for encryptions.
|
|
* @param {int} db_port
|
|
*/
|
|
exports.init = function(cb){
|
|
require('./config').getConfig(null, function(err, data) {
|
|
if(!err) {
|
|
crypto_key = data.crypto_key;
|
|
db = redis.createClient(data.db_port);
|
|
db.on("error", function (err) {
|
|
err.addInfo = 'message from DB';
|
|
log.error('DB', err);
|
|
});
|
|
if(typeof cb === 'function') cb();
|
|
} else {
|
|
err.addInfo = 'fetching db_port and crypto_key';
|
|
if(typeof cb === 'function') cb(err);
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
* ### encrypt
|
|
*/
|
|
function encrypt(plainText) {
|
|
if(!plainText) return null;
|
|
try {
|
|
var enciph = crypto.createCipher('aes-256-cbc', crypto_key);
|
|
var et = enciph.update(plainText, 'utf8', 'base64') + enciph.final('base64');
|
|
log.print('DB', 'Encrypted credentials into: ' + et);
|
|
return et;
|
|
} catch (err) {
|
|
log.error('DB', 'in encrypting: ' + err);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* ### decrypt
|
|
*/
|
|
function decrypt(crypticText) {
|
|
if(!crypticText) return null;
|
|
try {
|
|
var deciph = crypto.createDecipher('aes-256-cbc', crypto_key);
|
|
return deciph.update(crypticText, 'base64', 'utf8') + deciph.final('utf8');
|
|
} catch (err) {
|
|
log.error('DB', 'in decrypting: ' + err);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* ### replyHandler
|
|
* Abstraction answer handling for simple information replies from the DB.
|
|
* @param {String} action the action to be displayed in the output string.
|
|
*/
|
|
function replyHandler(action) {
|
|
return function(err, reply) {
|
|
if(err) log.error('DB', ' during "' + action + '": ' + err);
|
|
else log.print('DB', action + ': ' + reply);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* ### getSetRecords
|
|
* The general structure for modules is that the key is stored in a set.
|
|
* By fetching all set entries we can then fetch all modules, which is
|
|
* automated in this function.
|
|
*
|
|
* @param {String} set the set name how it is stored in the DB
|
|
* @param {function} funcSingle the function that fetches single entries from the DB
|
|
* @param {function} callback the function to be called on success or error, receives
|
|
* arguments (err, obj)
|
|
*/
|
|
function getSetRecords(set, funcSingle, callback) {
|
|
db.smembers(set, function(err, reply) {
|
|
if(err) log.error('DB', 'fetching ' + set + ': ' + err);
|
|
else {
|
|
if(reply.length === 0) {
|
|
callback(null, null);
|
|
} else {
|
|
var semaphore = reply.length, objReplies = {};
|
|
setTimeout(function() {
|
|
if(semaphore > 0) {
|
|
callback('Timeout fetching ' + set, null);
|
|
}
|
|
}, 1000);
|
|
for(var i = 0; i < reply.length; i++){
|
|
funcSingle(reply[i], function(prop) {
|
|
return function(err, reply) {
|
|
if(err) log.error('DB', ' fetching single element: ' + prop);
|
|
else {
|
|
objReplies[prop] = reply;
|
|
if(--semaphore === 0) callback(null, objReplies);
|
|
}
|
|
};
|
|
}(reply[i]));
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// @method shutDown()
|
|
|
|
// Shuts down the db link.
|
|
exports.shutDown = function() { db.quit(); };
|
|
|
|
// ## Action Modules
|
|
|
|
/**
|
|
* ### storeActionModule
|
|
* Store a string representation of an action module in the DB.
|
|
* @param {String} id the unique identifier of the module
|
|
* @param {String} data the string representation
|
|
*/
|
|
exports.storeActionModule = function(id, data) {
|
|
db.sadd('action_modules', id, replyHandler('storing action module key ' + id));
|
|
db.set('action_module_' + id, data, replyHandler('storing action module ' + id));
|
|
};
|
|
|
|
/**
|
|
* ### getActionModule(id, callback)
|
|
* Query the DB for an action module.
|
|
* @param {String} id the module id
|
|
* @param {function} callback the callback to receive the answer (err, obj)
|
|
*/
|
|
exports.getActionModule = function(id, callback) {
|
|
if(callback) db.get('action_module_' + id, callback);
|
|
};
|
|
|
|
/**
|
|
* ### getActionModules(callback)
|
|
* Fetch all action modules.
|
|
* @param {function} callback the callback to receive the answer (err, obj)
|
|
*/
|
|
exports.getActionModules = function(callback) {
|
|
getSetRecords('action_modules', exports.getActionModule, callback);
|
|
};
|
|
|
|
/**
|
|
* storeActionModuleAuth(id, data)
|
|
* Store a string representation of the authentication parameters for an action module.
|
|
* @param {String} id the unique identifier of the module
|
|
* @param {String} data the string representation
|
|
*/
|
|
exports.storeActionModuleAuth = function(id, data) {
|
|
if(data) {
|
|
db.sadd('action_modules_auth', id, replyHandler('storing action module auth key ' + id));
|
|
db.set('action_module_' + id +'_auth', encrypt(data), replyHandler('storing action module auth ' + id));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* ### getActionModuleAuth(id, callback)
|
|
* Query the DB for an action module authentication token.
|
|
* @param {String} id the module id
|
|
* @param {function} callback the callback to receive the answer (err, obj)
|
|
*/
|
|
exports.getActionModuleAuth = function(id, callback) {
|
|
if(callback) db.get('action_module_' + id + '_auth', function(err, txt) { callback(err, decrypt(txt)); });
|
|
};
|
|
|
|
// ## Event Modules
|
|
|
|
/**
|
|
* ### storeEventModule(id, data)
|
|
* Store a string representation of an event module in the DB.
|
|
* @param {String} id the unique identifier of the module
|
|
* @param {String} data the string representation
|
|
*/
|
|
exports.storeEventModule = function(id, data) {
|
|
db.sadd('event_modules', id, replyHandler('storing event module key ' + id));
|
|
db.set('event_module_' + id, data, replyHandler('storing event module ' + id));
|
|
};
|
|
|
|
/**
|
|
* ### getEventModule(id, callback)
|
|
* Query the DB for an event module.
|
|
* @param {String} id the module id
|
|
* @param {function} callback the callback to receive the answer (err, obj)
|
|
*/
|
|
exports.getEventModule = function(id, callback) {
|
|
if(callback) db.get('event_module_' + id, callback);
|
|
};
|
|
|
|
/**
|
|
* ### getEventModules(callback)
|
|
* Fetch all event modules.
|
|
* @param {function} callback the callback that receives the arguments (err, obj)
|
|
*/
|
|
exports.getEventModules = function(callback) {
|
|
getSetRecords('event_modules', exports.getEventModule, callback);
|
|
};
|
|
|
|
/**
|
|
* ### storeEventModuleAuth(id, data)
|
|
* Store a string representation of he authentication parameters for an event module.
|
|
* @param {String} id the unique identifier of the module
|
|
* @param {String} data the string representation
|
|
*/
|
|
exports.storeEventModuleAuth = function(id, data) {
|
|
if(data) {
|
|
db.sadd('event_modules_auth', id, replyHandler('storing event module auth key ' + id));
|
|
db.set('event_module_' + id +'_auth', encrypt(data), replyHandler('storing event module auth ' + id));
|
|
}
|
|
};
|
|
|
|
// @method getEventModuleAuth(id, callback)
|
|
|
|
// Query the DB for an event module authentication token.
|
|
// @param {String} id the module id
|
|
// @param {function} callback the callback to receive the answer (err, obj)
|
|
exports.getEventModuleAuth = function(id, callback) {
|
|
if(callback) db.get('event_module_' + id +'_auth', function(err, txt) { callback(err, decrypt(txt)); });
|
|
};
|
|
|
|
// ## Rules
|
|
|
|
// @method storeRule(id, data)
|
|
|
|
// Store a string representation of a rule in the DB.
|
|
// @param {String} id the unique identifier of the rule
|
|
// @param {String} data the string representation
|
|
exports.storeRule = function(id, data) {
|
|
db.sadd('rules', id, replyHandler('storing rule key ' + id));
|
|
db.set('rule_' + id, data, replyHandler('storing rule ' + id));
|
|
};
|
|
|
|
// @method getRule(id, callback)
|
|
|
|
// Query the DB for a rule.
|
|
// @param {String} id the rule id
|
|
// @param {function} callback the callback to receive the answer (err, obj)
|
|
exports.getRule = function(id, callback) {
|
|
db.get('rule_' + id, callback);
|
|
};
|
|
|
|
// @method getRules(callback)
|
|
|
|
// Fetch all rules from the database.
|
|
// @param {function} callback the callback to receive the answer (err, obj)
|
|
exports.getRules = function(callback) {
|
|
getSetRecords('rules', exports.getRule, callback);
|
|
};
|
|
|