mirror of
https://github.com/Hopiu/webapi-eca.git
synced 2026-03-16 22:10:31 +00:00
1038 lines
29 KiB
JavaScript
1038 lines
29 KiB
JavaScript
// Generated by CoffeeScript 1.6.3
|
|
/*
|
|
|
|
DB Interface
|
|
============
|
|
> Handles the connection to the database and provides functionalities for
|
|
> event pollers, action invokers, 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 invokers are registered in an
|
|
> unordered set in the database, from where they can be retrieved again. For example
|
|
> a new action invoker has its ID (e.g 'probinder') first registered in the set
|
|
> 'action-invokers' and then stored in the db with the key 'action-invoker:' + ID
|
|
> (e.g. action-invoker:probinder).
|
|
>
|
|
*/
|
|
|
|
|
|
(function() {
|
|
var IndexedModules, crypto, decrypt, encrypt, exports, getSetRecords, hash, log, redis, replyHandler,
|
|
_this = this,
|
|
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
|
|
|
log = require('./logging');
|
|
|
|
crypto = require('crypto-js');
|
|
|
|
redis = require('redis');
|
|
|
|
/*
|
|
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, _ref;
|
|
args = args != null ? args : {};
|
|
log(args);
|
|
config = require('./config');
|
|
config(args);
|
|
if ((_ref = _this.db) != null) {
|
|
_ref.quit();
|
|
}
|
|
if (config.isReady()) {
|
|
_this.crypto_key = config.getCryptoKey();
|
|
_this.db = redis.createClient(config.getDBPort(), 'localhost', {
|
|
connect_timeout: 2000
|
|
});
|
|
_this.db.on('error', function(err) {
|
|
err.addInfo = 'message from DB';
|
|
return log.error('DB', err);
|
|
});
|
|
_this.ep = new IndexedModules('event-poller', _this.db);
|
|
return _this.ai = new IndexedModules('action-invoker', _this.db);
|
|
} else {
|
|
return log.error('DB', 'Initialization failed because of missing config file!');
|
|
}
|
|
};
|
|
|
|
/*
|
|
Checks whether the db is connected and passes either an error on failure after
|
|
ten attempts within five seconds, or nothing on success to the callback(err).
|
|
|
|
@public isConnected( *cb* )
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.isConnected = function(cb) {
|
|
var fCheckConnection, numAttempts;
|
|
if (_this.db.connected) {
|
|
return cb();
|
|
} else {
|
|
numAttempts = 0;
|
|
fCheckConnection = function() {
|
|
if (_this.db.connected) {
|
|
log.print('DB', 'Successfully connected to DB!');
|
|
return cb();
|
|
} else if (numAttempts++ < 10) {
|
|
return setTimeout(fCheckConnection, 100);
|
|
} else {
|
|
return cb(new Error('Connection to DB failed!'));
|
|
}
|
|
};
|
|
return setTimeout(fCheckConnection, 100);
|
|
}
|
|
};
|
|
|
|
/*
|
|
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);
|
|
}
|
|
};
|
|
};
|
|
|
|
/*
|
|
Push an event into the event queue.
|
|
|
|
@public pushEvent( *oEvent* )
|
|
@param {Object} oEvent
|
|
*/
|
|
|
|
|
|
exports.pushEvent = function(oEvent) {
|
|
if (oEvent) {
|
|
log.print('DB', "Event pushed into the queue: '" + oEvent.eventid + "'");
|
|
return _this.db.rpush('event_queue', JSON.stringify(oEvent));
|
|
} else {
|
|
return log.error('DB', 'Why would you give me an empty event...');
|
|
}
|
|
};
|
|
|
|
/*
|
|
Pop an event from the event queue and pass it to cb(err, obj).
|
|
|
|
@public popEvent( *cb* )
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.popEvent = function(cb) {
|
|
var makeObj;
|
|
makeObj = function(pcb) {
|
|
return function(err, obj) {
|
|
return pcb(err, JSON.parse(obj));
|
|
};
|
|
};
|
|
return _this.db.lpop('event_queue', makeObj(cb));
|
|
};
|
|
|
|
/*
|
|
Purge the event queue.
|
|
|
|
@public purgeEventQueue()
|
|
*/
|
|
|
|
|
|
exports.purgeEventQueue = function() {
|
|
return _this.db.del('event_queue', replyHandler('purging event queue'));
|
|
};
|
|
|
|
/*
|
|
Hashes a string based on SHA-3-512.
|
|
|
|
@private hash( *plainText* )
|
|
@param {String} plainText
|
|
*/
|
|
|
|
|
|
hash = function(plainText) {
|
|
var err;
|
|
if (plainText == null) {
|
|
return null;
|
|
}
|
|
try {
|
|
return (crypto.SHA3(plainText, {
|
|
outputLength: 512
|
|
})).toString();
|
|
} catch (_error) {
|
|
err = _error;
|
|
err.addInfo = 'during hashing';
|
|
log.error('DB', err);
|
|
return null;
|
|
}
|
|
};
|
|
|
|
/*
|
|
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 err;
|
|
if (plainText == null) {
|
|
return null;
|
|
}
|
|
try {
|
|
return crypto.AES.encrypt(plainText, _this.crypto_key);
|
|
} 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 dec, err;
|
|
if (crypticText == null) {
|
|
return null;
|
|
}
|
|
try {
|
|
dec = crypto.AES.decrypt(crypticText, _this.crypto_key);
|
|
return dec.toString(crypto.enc.Utf8);
|
|
} catch (_error) {
|
|
err = _error;
|
|
err.addInfo = 'during decryption';
|
|
log.error('DB', err);
|
|
return null;
|
|
}
|
|
};
|
|
|
|
/*
|
|
Fetches all linked data set keys from a linking set, fetches the single
|
|
data objects via the provided function and returns the results to cb(err, obj).
|
|
|
|
@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(err, obj) function that receives all
|
|
the retrieved data or an error
|
|
*/
|
|
|
|
|
|
getSetRecords = function(set, fSingle, cb) {
|
|
log.print('DB', "Fetching set records: '" + set + "'");
|
|
return _this.db.smembers(set, function(err, arrReply) {
|
|
var fCallback, objReplies, reply, semaphore, _i, _len, _results;
|
|
if (err) {
|
|
err.addInfo = "fetching '" + set + "'";
|
|
log.error('DB', err);
|
|
return cb(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) {
|
|
--semaphore;
|
|
if (err) {
|
|
err.addInfo = "fetching single element: '" + prop + "'";
|
|
log.error('DB', err);
|
|
} else if (!data) {
|
|
log.error('DB', new Error("Empty key in DB: '" + prop + "'"));
|
|
} 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;
|
|
}
|
|
});
|
|
};
|
|
|
|
IndexedModules = (function() {
|
|
function IndexedModules(setname, db) {
|
|
this.setname = setname;
|
|
this.db = db;
|
|
this.deleteParameters = __bind(this.deleteParameters, this);
|
|
this.getParametersIds = __bind(this.getParametersIds, this);
|
|
this.getParameters = __bind(this.getParameters, this);
|
|
this.storeParameters = __bind(this.storeParameters, this);
|
|
this.deleteModule = __bind(this.deleteModule, this);
|
|
this.getModules = __bind(this.getModules, this);
|
|
this.getModuleIds = __bind(this.getModuleIds, this);
|
|
this.getModule = __bind(this.getModule, this);
|
|
this.storeModule = __bind(this.storeModule, this);
|
|
log.print('DB', "Instantiated indexed modules for '" + this.setname + "'");
|
|
}
|
|
|
|
IndexedModules.prototype.storeModule = function(mId, data) {
|
|
log.print('DB', "storeModule(" + this.setname + "): " + mId);
|
|
this.db.sadd("" + this.setname + "s", mId, replyHandler("Storing '" + this.setname + "' key '" + mId + "'"));
|
|
return this.db.set("" + this.setname + ":" + mId, data, replyHandler("Storing '" + this.setname + ":" + mId + "'"));
|
|
};
|
|
|
|
IndexedModules.prototype.getModule = function(mId, cb) {
|
|
log.print('DB', "getModule('" + this.setname + "): " + mId + "'");
|
|
return this.db.get("" + this.setname + ":" + mId, cb);
|
|
};
|
|
|
|
IndexedModules.prototype.getModuleIds = function(cb) {
|
|
log.print('DB', "getModuleIds(" + this.setname + ")");
|
|
return this.db.smembers("" + this.setname + "s", cb);
|
|
};
|
|
|
|
IndexedModules.prototype.getModules = function(cb) {
|
|
log.print('DB', "getModules(" + this.setname + ")");
|
|
return getSetRecords("" + this.setname + "s", this.getModule, cb);
|
|
};
|
|
|
|
IndexedModules.prototype.deleteModule = function(mId) {
|
|
log.print('DB', "deleteModule(" + this.setname + "): " + mId);
|
|
this.db.srem("" + this.setname + "s", mId, replyHandler("Deleting '" + this.setname + "' key '" + mId + "'"));
|
|
return this.db.del("" + this.setname + ":" + mId, replyHandler("Deleting '" + this.setname + ":" + mId + "'"));
|
|
};
|
|
|
|
IndexedModules.prototype.storeParameters = function(mId, userId, data) {
|
|
log.print('DB', "storeParameters(" + this.setname + "): '" + mId + ":" + userId + "'");
|
|
this.db.sadd("" + this.setname + "-params", "" + mId + ":" + userId, replyHandler("Storing '" + this.setname + "' module parameters key '" + mId + "'"));
|
|
return this.db.set("" + this.setname + "-params:" + mId + ":" + userId, encrypt(data), replyHandler("Storing '" + this.setname + "' module parameters '" + mId + ":" + userId + "'"));
|
|
};
|
|
|
|
IndexedModules.prototype.getParameters = function(mId, userId, cb) {
|
|
log.print('DB', "getParameters(" + this.setname + "): '" + mId + ":" + userId + "'");
|
|
return this.db.get("" + this.setname + "-params:" + mId + ":" + userId, function(err, data) {
|
|
return cb(err, decrypt(data));
|
|
});
|
|
};
|
|
|
|
IndexedModules.prototype.getParametersIds = function(cb) {
|
|
log.print('DB', "getParametersIds(" + this.setname + ")");
|
|
return this.db.smembers("" + this.setname + "-params", cb);
|
|
};
|
|
|
|
IndexedModules.prototype.deleteParameters = function(mId, userId) {
|
|
log.print('DB', "deleteParameters(" + this.setname + "): '" + mId + ":" + userId + "'");
|
|
this.db.srem("" + this.setname + "-params", "" + mId + ":" + userId, replyHandler("Deleting '" + this.setname + "-params' key '" + mId + ":" + userId + "'"));
|
|
return this.db.del("" + this.setname + "-params:" + mId + ":" + userId, replyHandler("Deleting '" + this.setname + "-params:" + mId + ":" + userId + "'"));
|
|
};
|
|
|
|
return IndexedModules;
|
|
|
|
})();
|
|
|
|
/*
|
|
## Action Invokers
|
|
*/
|
|
|
|
|
|
/*
|
|
Store a string representation of an action invoker in the DB.
|
|
|
|
@public storeActionInvoker ( *aiId, data* )
|
|
@param {String} aiId
|
|
@param {String} data
|
|
*/
|
|
|
|
|
|
exports.storeActionInvoker = function(aiId, data) {
|
|
return _this.ai.storeModule(aiId, data);
|
|
};
|
|
|
|
/*
|
|
Query the DB for an action invoker and pass it to cb(err, obj).
|
|
|
|
@public getActionInvoker( *aiId, cb* )
|
|
@param {String} aiId
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.getActionInvoker = function(aiId, cb) {
|
|
return _this.ai.getModule(aiId, cb);
|
|
};
|
|
|
|
/*
|
|
Fetch all action invoker IDs and hand them to cb(err, obj).
|
|
|
|
@public getActionInvokerIds( *cb* )
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.getActionInvokerIds = function(cb) {
|
|
return _this.ai.getModuleIds(cb);
|
|
};
|
|
|
|
/*
|
|
Fetch all action invokers and hand them to cb(err, obj).
|
|
|
|
@public getActionInvokers( *cb* )
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.getActionInvokers = function(cb) {
|
|
return _this.ai.getModules(cb);
|
|
};
|
|
|
|
/*
|
|
Fetch all action invokers and hand them to cb(err, obj).
|
|
|
|
@public getActionInvokers( *cb* )
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.deleteActionInvoker = function(aiId) {
|
|
return _this.ai.deleteModule(aiId);
|
|
};
|
|
|
|
/*
|
|
Store user-specific action invoker parameters .
|
|
|
|
@public storeActionParams( *userId, aiId, data* )
|
|
@param {String} userId
|
|
@param {String} aiId
|
|
@param {String} data
|
|
*/
|
|
|
|
|
|
exports.storeActionParams = function(aiId, userId, data) {
|
|
return _this.ai.storeParameters(aiId, userId, data);
|
|
};
|
|
|
|
/*
|
|
Query the DB for user-specific action module parameters,
|
|
and pass it to cb(err, obj).
|
|
|
|
@public getActionParams( *userId, aiId, cb* )
|
|
@param {String} userId
|
|
@param {String} aiId
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.getActionParams = function(aiId, userId, cb) {
|
|
return _this.ai.getParameters(aiId, userId, cb);
|
|
};
|
|
|
|
/*
|
|
Fetch all action params IDs and hand them to cb(err, obj).
|
|
|
|
@public getActionParamsIds( *cb* )
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.getActionParamsIds = function(cb) {
|
|
return _this.ai.getParametersIds(cb);
|
|
};
|
|
|
|
/*
|
|
Fetch all action modules and hand them to cb(err, obj).
|
|
|
|
@public deleteActionParams( *cb* )
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.deleteActionParams = function(aiId, userId) {
|
|
return _this.ai.deleteParameters(aiId, userId);
|
|
};
|
|
|
|
/*
|
|
## Event Pollers
|
|
*/
|
|
|
|
|
|
/*
|
|
Store a string representation of an event poller in the DB.
|
|
|
|
@public storeEventPoller ( *epId, data* )
|
|
@param {String} epId
|
|
@param {String} data
|
|
*/
|
|
|
|
|
|
exports.storeEventPoller = function(epId, data) {
|
|
return _this.ep.storeModule(epId, data);
|
|
};
|
|
|
|
/*
|
|
Query the DB for an event poller and pass it to cb(err, obj).
|
|
|
|
@public getEventPoller( *epId, cb* )
|
|
@param {String} epId
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.getEventPoller = function(epId, cb) {
|
|
return _this.ep.getModule(epId, cb);
|
|
};
|
|
|
|
/*
|
|
Fetch all event poller IDs and hand them to cb(err, obj).
|
|
|
|
@public getEventPollerIds( *cb* )
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.getEventPollerIds = function(cb) {
|
|
return _this.ep.getModuleIds(cb);
|
|
};
|
|
|
|
/*
|
|
Fetch all event pollers and hand them to cb(err, obj).
|
|
|
|
@public getEventPollers( *cb* )
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.getEventPollers = function(cb) {
|
|
return _this.ep.getModules(cb);
|
|
};
|
|
|
|
/*
|
|
Fetch all event pollers and hand them to cb(err, obj).
|
|
|
|
@public getEventPollers( *cb* )
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.deleteEventPoller = function(epId) {
|
|
return _this.ep.deleteModule(epId);
|
|
};
|
|
|
|
/*
|
|
Store user-specific event poller parameters .
|
|
|
|
@public storeEventParams( *userId, epId, data* )
|
|
@param {String} userId
|
|
@param {String} epId
|
|
@param {String} data
|
|
*/
|
|
|
|
|
|
exports.storeEventParams = function(epId, userId, data) {
|
|
return _this.ep.storeParameters(epId, userId, data);
|
|
};
|
|
|
|
/*
|
|
Query the DB for user-specific event module parameters,
|
|
and pass it to cb(err, obj).
|
|
|
|
@public getEventParams( *userId, epId, cb* )
|
|
@param {String} userId
|
|
@param {String} epId
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.getEventParams = function(epId, userId, cb) {
|
|
return _this.ep.getParameters(epId, userId, cb);
|
|
};
|
|
|
|
/*
|
|
Fetch all event params IDs and hand them to cb(err, obj).
|
|
|
|
@public getEventParamsIds( *cb* )
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.getEventParamsIds = function(cb) {
|
|
return _this.ep.getParametersIds(cb);
|
|
};
|
|
|
|
/*
|
|
Fetch all event modules and hand them to cb(err, obj).
|
|
|
|
@public deleteEventParams( *cb* )
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.deleteEventParams = function(epId, userId) {
|
|
return _this.ep.deleteParameters(epId, userId);
|
|
};
|
|
|
|
/*
|
|
## Rules
|
|
*/
|
|
|
|
|
|
/*
|
|
Query the DB for a rule and pass it to cb(err, obj).
|
|
|
|
@public getRule( *ruleId, cb* )
|
|
@param {String} ruleId
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.getRule = function(ruleId, cb) {
|
|
log.print('DB', "getRule: '" + ruleId + "'");
|
|
return _this.db.get("rule:" + ruleId, cb);
|
|
};
|
|
|
|
/*
|
|
Fetch all rules and pass them to cb(err, obj).
|
|
|
|
@public getRules( *cb* )
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.getRules = function(cb) {
|
|
log.print('DB', 'Fetching all Rules');
|
|
return getSetRecords('rules', exports.getRule, cb);
|
|
};
|
|
|
|
/*
|
|
Fetch all rule IDs and hand it to cb(err, obj).
|
|
|
|
@public getRuleIds( *cb* )
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.getRuleIds = function(cb) {
|
|
log.print('DB', 'Fetching all Rule IDs');
|
|
return _this.db.smembers('rules', cb);
|
|
};
|
|
|
|
/*
|
|
Store a string representation of a rule in the DB.
|
|
|
|
@public storeRule( *ruleId, data* )
|
|
@param {String} ruleId
|
|
@param {String} data
|
|
*/
|
|
|
|
|
|
exports.storeRule = function(ruleId, data) {
|
|
log.print('DB', "storeRule: '" + ruleId + "'");
|
|
_this.db.sadd('rules', "" + ruleId, replyHandler("storing rule key '" + ruleId + "'"));
|
|
return _this.db.set("rule:" + ruleId, data, replyHandler("storing rule '" + ruleId + "'"));
|
|
};
|
|
|
|
/*
|
|
Delete a string representation of a rule.
|
|
|
|
@public deleteRule( *ruleId, userId* )
|
|
@param {String} ruleId
|
|
@param {String} userId
|
|
*/
|
|
|
|
|
|
exports.deleteRule = function(ruleId) {
|
|
log.print('DB', "deleteRule: '" + ruleId + "'");
|
|
_this.db.srem("rules", ruleId, replyHandler("Deleting rule key '" + ruleId + "'"));
|
|
_this.db.del("rule:" + ruleId, replyHandler("Deleting rule '" + ruleId + "'"));
|
|
_this.db.smembers("rule:" + ruleId + ":users", function(err, obj) {
|
|
var delLinkedUserRule, id, _i, _len, _results;
|
|
delLinkedUserRule = function(userId) {
|
|
return _this.db.srem("user:" + userId + ":rules", ruleId, replyHandler("Deleting rule key '" + ruleId + "'' in linked user '" + userId + "'"));
|
|
};
|
|
_results = [];
|
|
for (_i = 0, _len = obj.length; _i < _len; _i++) {
|
|
id = obj[_i];
|
|
_results.push(delLinkedUserRule(id));
|
|
}
|
|
return _results;
|
|
});
|
|
_this.db.del("rule:" + ruleId + ":users", replyHandler("Deleting rule '" + ruleId + "' users"));
|
|
_this.db.smembers("rule:" + ruleId + ":active-users", function(err, obj) {
|
|
var delActiveUserRule, id, _i, _len, _results;
|
|
delActiveUserRule = function(userId) {
|
|
return _this.db.srem("user:" + userId + ":active-rules", ruleId, replyHandler("Deleting rule key '" + ruleId + "' in active user '" + userId + "'"));
|
|
};
|
|
_results = [];
|
|
for (_i = 0, _len = obj.length; _i < _len; _i++) {
|
|
id = obj[_i];
|
|
_results.push(delActiveUserRule(id));
|
|
}
|
|
return _results;
|
|
});
|
|
return _this.db.del("rule:" + ruleId + ":active-users", replyHandler("Deleting rule '" + ruleId + "' active users"));
|
|
};
|
|
|
|
/*
|
|
Associate a rule to a user.
|
|
|
|
@public linkRule( *ruleId, userId* )
|
|
@param {String} ruleId
|
|
@param {String} userId
|
|
*/
|
|
|
|
|
|
exports.linkRule = function(ruleId, userId) {
|
|
log.print('DB', "linkRule: '" + ruleId + "' for user '" + userId + "'");
|
|
_this.db.sadd("rule:" + ruleId + ":users", userId, replyHandler("storing user '" + userId + "' for rule key '" + ruleId + "'"));
|
|
return _this.db.sadd("user:" + userId + ":rules", ruleId, replyHandler("storing rule key '" + ruleId + "' for user '" + userId + "'"));
|
|
};
|
|
|
|
/*
|
|
Get rules linked to a user and hand it to cb(err, obj).
|
|
|
|
@public getUserLinkRule( *userId, cb* )
|
|
@param {String} userId
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.getUserLinkedRules = function(userId, cb) {
|
|
log.print('DB', "getUserLinkedRules: for user '" + userId + "'");
|
|
return _this.db.smembers("user:" + userId + ":rules", cb);
|
|
};
|
|
|
|
/*
|
|
Get users linked to a rule and hand it to cb(err, obj).
|
|
|
|
@public getRuleLinkedUsers( *ruleId, cb* )
|
|
@param {String} ruleId
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.getRuleLinkedUsers = function(ruleId, cb) {
|
|
log.print('DB', "getRuleLinkedUsers: for rule '" + ruleId + "'");
|
|
return _this.db.smembers("rule:" + ruleId + ":users", cb);
|
|
};
|
|
|
|
/*
|
|
Delete an association of a rule to a user.
|
|
|
|
@public unlinkRule( *ruleId, userId* )
|
|
@param {String} ruleId
|
|
@param {String} userId
|
|
*/
|
|
|
|
|
|
exports.unlinkRule = function(ruleId, userId) {
|
|
log.print('DB', "unlinkRule: '" + ruleId + ":" + userId + "'");
|
|
_this.db.srem("rule:" + ruleId + ":users", userId, replyHandler("removing user '" + userId + "' for rule key '" + ruleId + "'"));
|
|
return _this.db.srem("user:" + userId + ":rules", ruleId, replyHandler("removing rule key '" + ruleId + "' for user '" + userId + "'"));
|
|
};
|
|
|
|
/*
|
|
Activate a rule.
|
|
|
|
@public activateRule( *ruleId, userId* )
|
|
@param {String} ruleId
|
|
@param {String} userId
|
|
*/
|
|
|
|
|
|
exports.activateRule = function(ruleId, userId) {
|
|
log.print('DB', "activateRule: '" + ruleId + "' for '" + userId + "'");
|
|
_this.db.sadd("rule:" + ruleId + ":active-users", userId, replyHandler("storing activated user '" + userId + "' in rule '" + ruleId + "'"));
|
|
return _this.db.sadd("user:" + userId + ":active-rules", ruleId, replyHandler("storing activated rule '" + ruleId + "' in user '" + userId + "'"));
|
|
};
|
|
|
|
/*
|
|
Get rules activated for a user and hand it to cb(err, obj).
|
|
|
|
@public getUserLinkRule( *userId, cb* )
|
|
@param {String} userId
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.getUserActivatedRules = function(userId, cb) {
|
|
log.print('DB', "getUserActivatedRules: for user '" + userId + "'");
|
|
return _this.db.smembers("user:" + userId + ":active-rules", cb);
|
|
};
|
|
|
|
/*
|
|
Get users activated for a rule and hand it to cb(err, obj).
|
|
|
|
@public getRuleActivatedUsers ( *ruleId, cb* )
|
|
@param {String} ruleId
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.getRuleActivatedUsers = function(ruleId, cb) {
|
|
log.print('DB', "getRuleLinkedUsers: for rule '" + ruleId + "'");
|
|
return _this.db.smembers("rule:" + ruleId + ":active-users", cb);
|
|
};
|
|
|
|
/*
|
|
Deactivate a rule.
|
|
|
|
@public deactivateRule( *ruleId, userId* )
|
|
@param {String} ruleId
|
|
@param {String} userId
|
|
*/
|
|
|
|
|
|
exports.deactivateRule = function(ruleId, userId) {
|
|
log.print('DB', "deactivateRule: '" + ruleId + "' for '" + userId + "'");
|
|
_this.db.srem("rule:" + ruleId + ":active-users", userId, replyHandler("removing activated user '" + userId + "' in rule '" + ruleId + "'"));
|
|
return _this.db.srem("user:" + userId + ":active-rules", ruleId, replyHandler("removing activated rule '" + ruleId + "' in user '" + userId + "'"));
|
|
};
|
|
|
|
/*
|
|
Fetch all active ruleIds and pass them to cb(err, obj).
|
|
|
|
@public getAllActivatedRuleIds( *cb* )
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.getAllActivatedRuleIdsPerUser = function(cb) {
|
|
log.print('DB', "Fetching all active rules");
|
|
return _this.db.smembers('users', function(err, obj) {
|
|
var fFetchActiveUserRules, result, semaphore, user, _i, _len, _results;
|
|
result = {};
|
|
console.log('checking length');
|
|
if (obj.length === 0) {
|
|
console.log('length cehcked is 0');
|
|
return cb(null, result);
|
|
} else {
|
|
console.log('length cehcked');
|
|
semaphore = obj.length;
|
|
fFetchActiveUserRules = function(userId) {
|
|
return _this.db.smembers("user:" + user + ":active-rules", function(err, obj) {
|
|
console.log(obj);
|
|
console.log(obj.length);
|
|
if (obj.length === 0) {
|
|
console.log('is 0');
|
|
} else {
|
|
result[userId] = obj;
|
|
}
|
|
if (--semaphore === 0) {
|
|
return cb(null, result);
|
|
}
|
|
});
|
|
};
|
|
_results = [];
|
|
for (_i = 0, _len = obj.length; _i < _len; _i++) {
|
|
user = obj[_i];
|
|
_results.push(fFetchActiveUserRules(user));
|
|
}
|
|
return _results;
|
|
}
|
|
});
|
|
};
|
|
|
|
/*
|
|
Fetch all active rules and pass them to cb(err, obj).
|
|
|
|
@public getAllActivatedRules( *cb* )
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.getAllActivatedRules = function(cb) {
|
|
var fCb;
|
|
log.print('DB', "Fetching all active rules");
|
|
fCb = function(err, obj) {
|
|
console.log('fetched something');
|
|
console.log(err);
|
|
return console.log(obj);
|
|
};
|
|
return _this.db.smembers('users', function(err, obj) {
|
|
var user, _i, _len, _results;
|
|
_results = [];
|
|
for (_i = 0, _len = obj.length; _i < _len; _i++) {
|
|
user = obj[_i];
|
|
_results.push(getSetRecords("user:" + user + ":active-rules", exports.getRule, fCb));
|
|
}
|
|
return _results;
|
|
});
|
|
};
|
|
|
|
/*
|
|
Store a user object (needs to be a flat structure).
|
|
|
|
@public storeUser( *objUser* )
|
|
@param {Object} objUser
|
|
*/
|
|
|
|
|
|
exports.storeUser = function(objUser) {
|
|
log.print('DB', "storeUser: '" + objUser.username + "'");
|
|
if (objUser && objUser.username && objUser.password) {
|
|
_this.db.sadd('users', objUser.username, replyHandler("storing user key '" + objUser.username + "'"));
|
|
objUser.password = hash(objUser.password);
|
|
return _this.db.hmset("user:" + objUser.username, objUser, replyHandler("storing user properties '" + objUser.username + "'"));
|
|
} else {
|
|
return log.error('DB', new Error('username or password was missing'));
|
|
}
|
|
};
|
|
|
|
/*
|
|
Associate a role with a user.
|
|
|
|
@public storeUserRole( *userId, role* )
|
|
@param {String} userId
|
|
@param {String} role
|
|
*/
|
|
|
|
|
|
exports.storeUserRole = function(userId, role) {
|
|
log.print('DB', "storeUserRole: '" + userId + ":" + role + "'");
|
|
_this.db.sadd('roles', role, replyHandler("adding role '" + role + "' to role index set"));
|
|
_this.db.sadd("user:" + userId + ":roles", role, replyHandler("adding role '" + role + "' to user '" + userId + "'"));
|
|
return _this.db.sadd("role:" + role + ":users", userId, replyHandler("adding user '" + userId + "' to role '" + role + "'"));
|
|
};
|
|
|
|
/*
|
|
Fetch all roles of a user and pass them to cb(err, obj).
|
|
|
|
@public getUserRoles( *userId* )
|
|
@param {String} userId
|
|
*/
|
|
|
|
|
|
exports.getUserRoles = function(userId) {
|
|
log.print('DB', "getUserRole: '" + userId + "'");
|
|
return _this.db.get("user-roles:" + userId, cb);
|
|
};
|
|
|
|
/*
|
|
Fetch all users of a role and pass them to cb(err, obj).
|
|
|
|
@public getUserRoles( *role* )
|
|
@param {String} role
|
|
*/
|
|
|
|
|
|
exports.getRoleUsers = function(role) {
|
|
log.print('DB', "getRoleUsers: '" + role + "'");
|
|
return _this.db.get("role-users:" + role, cb);
|
|
};
|
|
|
|
/*
|
|
Checks the credentials and on success returns the user object to the
|
|
callback(err, obj) function. The password has to be hashed (SHA-3-512)
|
|
beforehand by the instance closest to the user that enters the password,
|
|
because we only store hashes of passwords for safety reasons.
|
|
|
|
@public loginUser( *userId, password, cb* )
|
|
@param {String} userId
|
|
@param {String} password
|
|
@param {function} cb
|
|
*/
|
|
|
|
|
|
exports.loginUser = function(userId, password, cb) {
|
|
var fCheck;
|
|
log.print('DB', "User '" + userId + "' tries to log in");
|
|
fCheck = function(pw) {
|
|
return function(err, obj) {
|
|
if (err) {
|
|
return cb(err);
|
|
} else if (obj && obj.password) {
|
|
if (pw === obj.password) {
|
|
log.print('DB', "User '" + obj.username + "' logged in!");
|
|
return cb(null, obj);
|
|
} else {
|
|
return cb(new Error('Wrong credentials!'));
|
|
}
|
|
} else {
|
|
return cb(new Error('User not found!'));
|
|
}
|
|
};
|
|
};
|
|
return _this.db.hgetall("user:" + userId, fCheck(password));
|
|
};
|
|
|
|
/*
|
|
Deletes a user and all his associated linked and active rules.
|
|
|
|
@public deleteUser( *userId* )
|
|
@param {String} userId
|
|
*/
|
|
|
|
|
|
exports.deleteUser = function(userId) {
|
|
log.print('DB', "deleteUser: '" + userId + "'");
|
|
_this.db.srem("users", userId, replyHandler("Deleting user key '" + userId + "'"));
|
|
_this.db.del("user:" + userId, replyHandler("Deleting user '" + userId + "'"));
|
|
_this.db.smembers("user:" + userId + ":rules", function(err, obj) {
|
|
var delLinkedRuleUser, id, _i, _len, _results;
|
|
delLinkedRuleUser = function(ruleId) {
|
|
return _this.db.srem("rule:" + ruleId + ":users", userId, replyHandler("Deleting user key '" + userId + "' in linked rule '" + ruleId + "'"));
|
|
};
|
|
_results = [];
|
|
for (_i = 0, _len = obj.length; _i < _len; _i++) {
|
|
id = obj[_i];
|
|
_results.push(delLinkedRuleUser(id));
|
|
}
|
|
return _results;
|
|
});
|
|
_this.db.del("user:" + userId + ":rules", replyHandler("Deleting user '" + userId + "' rules"));
|
|
_this.db.smembers("user:" + userId + ":rules", function(err, obj) {
|
|
var delActivatedRuleUser, id, _i, _len, _results;
|
|
delActivatedRuleUser = function(ruleId) {
|
|
return _this.db.srem("rule:" + ruleId + ":active-users", userId, replyHandler("Deleting user key '" + userId + "' in active rule '" + ruleId + "'"));
|
|
};
|
|
_results = [];
|
|
for (_i = 0, _len = obj.length; _i < _len; _i++) {
|
|
id = obj[_i];
|
|
_results.push(delActivatedRuleUser(id));
|
|
}
|
|
return _results;
|
|
});
|
|
return _this.db.del("user:" + userId + ":active-rules", replyHandler("Deleting user '" + userId + "' rules"));
|
|
};
|
|
|
|
/*
|
|
Shuts down the db link.
|
|
|
|
@public shutDown()
|
|
*/
|
|
|
|
|
|
exports.shutDown = function() {
|
|
return _this.db.quit();
|
|
};
|
|
|
|
}).call(this);
|