mirror of
https://github.com/Hopiu/webapi-eca.git
synced 2026-04-05 15:41:00 +00:00
473 lines
12 KiB
JavaScript
473 lines
12 KiB
JavaScript
// Generated by CoffeeScript 1.6.3
|
|
/*
|
|
|
|
DB Interface
|
|
============
|
|
>Handles the connection to the database and provides functionalities for
|
|
>event/action modules, rules and the encrypted storing of authentication tokens.
|
|
>General functionality as a wrapper for the module holds initialization,
|
|
>encryption/decryption, the retrieval of modules and shut down.
|
|
>
|
|
>The general structure for linked data is that the key is stored in a set.
|
|
>By fetching all set entries we can then fetch all elements, which is
|
|
>automated in this function.
|
|
>For example 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).
|
|
>
|
|
*/
|
|
|
|
|
|
(function() {
|
|
'use strict';
|
|
/* Grab all required modules*/
|
|
|
|
var crypto, crypto_key, db, decrypt, encrypt, exports, getSetRecords, log, redis, replyHandler;
|
|
|
|
redis = require('redis');
|
|
|
|
crypto = require('crypto');
|
|
|
|
log = require('./logging');
|
|
|
|
crypto_key = null;
|
|
|
|
db = null;
|
|
|
|
/*
|
|
##Module call
|
|
|
|
Initializes the DB connection. Requires a valid configuration file which contains
|
|
a db port and a crypto key.
|
|
@param {Object} args
|
|
*/
|
|
|
|
|
|
exports = module.exports = function(args) {
|
|
var config;
|
|
args = args != null ? args : {};
|
|
log(args);
|
|
config = require('./config');
|
|
config(args);
|
|
crypto_key = config.getCryptoKey();
|
|
db = redis.createClient(config.getDBPort(), 'localhost', {
|
|
connect_timeout: 2000
|
|
});
|
|
return db.on("error", function(err) {
|
|
err.addInfo = 'message from DB';
|
|
return log.error('DB', err);
|
|
});
|
|
};
|
|
|
|
/*
|
|
Checks whether the db is connected and calls the callback function if successful,
|
|
or an error after ten attempts within five seconds.
|
|
|
|
@public isConnected( *cb* )
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.isConnected = function(cb) {
|
|
var fCheckConnection, numAttempts;
|
|
if (db.connected) {
|
|
return cb();
|
|
} else {
|
|
numAttempts = 0;
|
|
fCheckConnection = function() {
|
|
var e;
|
|
if (db.connected) {
|
|
log.print('DB', 'Successfully connected to DB!');
|
|
return cb();
|
|
} else if (numAttempts++ < 10) {
|
|
return setTimeout(fCheckConnection, 500);
|
|
} else {
|
|
e = new Error('Connection to DB failed!');
|
|
log.error('DB', e);
|
|
return cb(e);
|
|
}
|
|
};
|
|
return setTimeout(fCheckConnection, 500);
|
|
}
|
|
};
|
|
|
|
/*
|
|
Encrypts a string using the crypto key from the config file, based on aes-256-cbc.
|
|
|
|
@private encrypt( *plainText* )
|
|
@param {String} plainText
|
|
*/
|
|
|
|
|
|
encrypt = function(plainText) {
|
|
var enciph, err, et;
|
|
if (plainText == null) {
|
|
return null;
|
|
}
|
|
try {
|
|
enciph = crypto.createCipher('aes-256-cbc', crypto_key);
|
|
et = enciph.update(plainText, 'utf8', 'base64');
|
|
return et + enciph.final('base64');
|
|
} catch (_error) {
|
|
err = _error;
|
|
err.addInfo = 'during encryption';
|
|
log.error('DB', err);
|
|
return null;
|
|
}
|
|
};
|
|
|
|
/*
|
|
Decrypts an encrypted string and hands it back on success or null.
|
|
|
|
@private decrypt( *crypticText* )
|
|
@param {String} crypticText
|
|
*/
|
|
|
|
|
|
decrypt = function(crypticText) {
|
|
var deciph, dt, err;
|
|
if (crypticText == null) {
|
|
return null;
|
|
}
|
|
try {
|
|
deciph = crypto.createDecipher('aes-256-cbc', crypto_key);
|
|
dt = deciph.update(crypticText, 'base64', 'utf8');
|
|
return dt + deciph.final('utf8');
|
|
} catch (_error) {
|
|
err = _error;
|
|
err.addInfo = 'during decryption';
|
|
log.error('DB', err);
|
|
return null;
|
|
}
|
|
};
|
|
|
|
/*
|
|
Abstracts logging for simple action replies from the DB.
|
|
|
|
@private replyHandler( *action* )
|
|
@param {String} action
|
|
*/
|
|
|
|
|
|
replyHandler = function(action) {
|
|
return function(err, reply) {
|
|
if (err) {
|
|
err.addInfo = 'during "' + action + '"';
|
|
return log.error('DB', err);
|
|
} else {
|
|
return log.print('DB', action + ': ' + reply);
|
|
}
|
|
};
|
|
};
|
|
|
|
/*
|
|
Fetches all linked data set keys from a linking set, fetches the single data objects
|
|
via the provided function and returns the results to the callback function.
|
|
|
|
@private getSetRecords( *set, fSingle, cb* )
|
|
@param {String} set the set name how it is stored in the DB
|
|
@param {function} fSingle a function to retrieve a single data element per set entry
|
|
@param {function} cb the callback function that receives all the retrieved data or an error
|
|
*/
|
|
|
|
|
|
getSetRecords = function(set, funcSingle, cb) {
|
|
return db != null ? db.smembers(set, function(err, arrReply) {
|
|
var fCallback, objReplies, reply, semaphore, _i, _len, _results;
|
|
if (err) {
|
|
err.addInfo = 'fetching ' + set;
|
|
return log.error('DB', err);
|
|
} else if (arrReply.length === 0) {
|
|
return cb();
|
|
} else {
|
|
semaphore = arrReply.length;
|
|
objReplies = {};
|
|
setTimeout(function() {
|
|
if (semaphore > 0) {
|
|
return cb(new Error('Timeout fetching ' + set));
|
|
}
|
|
}, 2000);
|
|
fCallback = function(prop) {
|
|
return function(err, data) {
|
|
if (err) {
|
|
err.addInfo = 'fetching single element: ' + prop;
|
|
return log.error('DB', err);
|
|
} else {
|
|
objReplies[prop] = data;
|
|
if (--semaphore === 0) {
|
|
return cb(null, objReplies);
|
|
}
|
|
}
|
|
};
|
|
};
|
|
_results = [];
|
|
for (_i = 0, _len = arrReply.length; _i < _len; _i++) {
|
|
reply = arrReply[_i];
|
|
_results.push(fSingle(reply, fCallback(reply)));
|
|
}
|
|
return _results;
|
|
}
|
|
}) : void 0;
|
|
};
|
|
|
|
/*
|
|
@Function shutDown()
|
|
|
|
Shuts down the db link.
|
|
*/
|
|
|
|
|
|
/*exports.shutDown = function() { if(db) db.quit(); };
|
|
*/
|
|
|
|
|
|
/*
|
|
## Action Modules
|
|
|
|
@Function 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) {
|
|
if(db) {
|
|
db.sadd('action_modules', id, replyHandler('storing action module key ' + id));
|
|
db.set('action_module_' + id, data, replyHandler('storing action module ' + id));
|
|
}
|
|
};
|
|
*/
|
|
|
|
|
|
/*
|
|
@Function getActionModule(id, cb)
|
|
Query the DB for an action module.
|
|
@param {String} id the module id
|
|
@param {function} cb the cb to receive the answer (err, obj)
|
|
*/
|
|
|
|
|
|
/*exports.getActionModule = function(id, cb) {
|
|
if(cb && db) db.get('action_module_' + id, cb);
|
|
};
|
|
*/
|
|
|
|
|
|
/*
|
|
@Function getActionModules(cb)
|
|
Fetch all action modules.
|
|
@param {function} cb the cb to receive the answer (err, obj)
|
|
*/
|
|
|
|
|
|
/*exports.getActionModules = function(cb) {
|
|
getSetRecords('action_modules', exports.getActionModule, cb);
|
|
};
|
|
*/
|
|
|
|
|
|
/*
|
|
@Function 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) {
|
|
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));
|
|
}
|
|
};
|
|
*/
|
|
|
|
|
|
/*
|
|
@Function getActionModuleAuth(id, cb)
|
|
Query the DB for an action module authentication token.
|
|
@param {String} id the module id
|
|
@param {function} cb the cb to receive the answer (err, obj)
|
|
*/
|
|
|
|
|
|
/*exports.getActionModuleAuth = function(id, cb) {
|
|
if(cb && db) db.get('action_module_' + id + '_auth', function(id) {
|
|
return function(err, txt) { cb(err, decrypt(txt, 'action_module_' + id + '_auth')); };
|
|
}(id));
|
|
};
|
|
*/
|
|
|
|
|
|
/*
|
|
## Event Modules
|
|
|
|
@Function 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) {
|
|
if(db) {
|
|
db.sadd('event_modules', id, replyHandler('storing event module key ' + id));
|
|
db.set('event_module_' + id, data, replyHandler('storing event module ' + id));
|
|
}
|
|
};
|
|
*/
|
|
|
|
|
|
/*
|
|
@Function getEventModule(id, cb)
|
|
Query the DB for an event module.
|
|
@param {String} id the module id
|
|
@param {function} cb the cb to receive the answer (err, obj)
|
|
*/
|
|
|
|
|
|
/*exports.getEventModule = function(id, cb) {
|
|
if(cb && db) db.get('event_module_' + id, cb);
|
|
};
|
|
*/
|
|
|
|
|
|
/*
|
|
@Function getEventModules(cb)
|
|
Fetch all event modules.
|
|
@param {function} cb the cb that receives the arguments (err, obj)
|
|
*/
|
|
|
|
|
|
/*exports.getEventModules = function(cb) {
|
|
getSetRecords('event_modules', exports.getEventModule, cb);
|
|
};
|
|
*/
|
|
|
|
|
|
/*
|
|
@Function 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) {
|
|
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));
|
|
}
|
|
};
|
|
*/
|
|
|
|
|
|
/*
|
|
@Function getEventModuleAuth(id, cb)
|
|
|
|
Query the DB for an event module authentication token.
|
|
@param {String} id the module id
|
|
@param {function} cb the cb to receive the answer (err, obj)
|
|
*/
|
|
|
|
|
|
/*exports.getEventModuleAuth = function(id, cb) {
|
|
if(cb) db.get('event_module_' + id +'_auth', function(id) {
|
|
return function(err, txt) { cb(err, decrypt(txt, 'event_module_' + id + '_auth')); };
|
|
}(id));
|
|
};
|
|
*/
|
|
|
|
|
|
/*
|
|
## Rules
|
|
|
|
@Function 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) {
|
|
if(db) {
|
|
db.sadd('rules', id, replyHandler('storing rule key ' + id));
|
|
db.set('rule_' + id, data, replyHandler('storing rule ' + id));
|
|
}
|
|
};
|
|
*/
|
|
|
|
|
|
/*
|
|
@Function getRule(id, cb)
|
|
|
|
Query the DB for a rule.
|
|
@param {String} id the rule id
|
|
@param {function} cb the cb to receive the answer (err, obj)
|
|
*/
|
|
|
|
|
|
/*exports.getRule = function(id, cb) {
|
|
if(db) db.get('rule_' + id, cb);
|
|
};
|
|
*/
|
|
|
|
|
|
/*
|
|
@Function getRules(cb)
|
|
|
|
Fetch all rules from the database.
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
/*exports.getRules = function(cb) {
|
|
getSetRecords('rules', exports.getRule, cb);
|
|
};
|
|
*/
|
|
|
|
|
|
/*
|
|
@Function storeUser
|
|
|
|
@param {Object} objUser
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
/*exports.storeUser = function(objUser, cb) {
|
|
if(db && objUser && objUser.username && objUser.password) {
|
|
db.sadd('users', objUser.username, replyHandler('storing user key ' + objUser.username));
|
|
objUser.password = encrypt(objUser.password);
|
|
db.set('user:' + objUser.username, objUser, replyHandler('storing user properties ' + objUser.username));
|
|
}
|
|
};
|
|
*/
|
|
|
|
|
|
/*
|
|
Checks the credentials and on success returns the user object.
|
|
@param {Object} objUser
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
/* exports.loginUser = function(username, password, cb) {
|
|
if(typeof cb !== 'function') return;
|
|
if(db) db.get('user:' + username, function(p) {
|
|
return function(err, obj) {
|
|
if(err) cb(err);
|
|
else if(encrypt(obj.password) === p) cb(null, obj);
|
|
else cb(new Error('Wrong credentials!'));
|
|
};
|
|
}(password));
|
|
else cb(new Error('No database link available!'));
|
|
};
|
|
*/
|
|
|
|
|
|
}).call(this);
|