dependecy update and resultig bug fixes

This commit is contained in:
Dominic Bosch 2014-02-04 16:40:32 +01:00
parent 88e248ad52
commit 42e80e32e7
14 changed files with 311 additions and 448 deletions

View file

@ -1,8 +1,5 @@
README: webapi-eca
==================
# TODO Remake
> A Modular ECA Engine Server which acts as a middleware between WebAPI's.
> This folder continues examples of an ECA engine and how certain use cases
> could be implemented together with a rules language.
@ -39,6 +36,8 @@ Edit the configuration file:
vi config/config.json
Apply your settings, for example:
# TODO Remake
{
"http_port": 8125,
@ -49,7 +48,7 @@ Apply your settings, for example:
Start the server:
node js/server
run_server.sh
*Congratulations, your own WebAPI based ECA engine server is now up and running!*
@ -59,11 +58,17 @@ Optional command line tools:
Create the doc *(to be accessed via the webserver, e.g.: localhost:8125/doc/)*:
node create_doc
> **WARNING:**
> *manual adjustment of `./node_modules/groc/lib/styles/default/docPage.jade` required until groc is fixed:*
> *`!!! 5` needs to be relaced with `doctype html`*
run_doc.sh
Run test suite:
node run_tests
run_tests.sh
_

View file

@ -29,7 +29,7 @@ exports = module.exports = ( args ) ->
if typeof args.configPath is 'string'
loadConfigFile args.configPath
else
loadConfigFile path.join('config', 'config.json')
loadConfigFile path.join 'config', 'config.json'
module.exports
###
@ -47,11 +47,11 @@ loadConfigFile = ( configPath ) =>
@config.crypto_key and @config.session_secret
log.print 'CF', 'config file loaded successfully'
else
log.error 'CF', new Error("""Missing property in config file, requires:
log.error 'CF', new Error """Missing property in config file, requires:
- http_port
- db_port
- crypto_key
- session_secret""")
- session_secret"""
catch e
e.addInfo = 'no config ready'
log.error 'CF', e

View file

@ -83,21 +83,21 @@ Abstracts logging for simple action replies from the DB.
replyHandler = ( action ) ->
( err, reply ) ->
if err
err.addInfo = 'during "' + action + '"'
err.addInfo = "during \"#{ action }\""
log.error 'DB', err
else
log.print 'DB', action + ': ' + reply
log.print 'DB', "#{ action }: #{ reply }"
###
Push an event into the event queue.
@public pushEvent( *event* )
@param {Object} event
@public pushEvent( *oEvent* )
@param {Object} oEvent
###
exports.pushEvent = ( event ) =>
if event
log.print 'DB', 'Event pushed into the queue: ' + event.eventid
@db.rpush 'event_queue', JSON.stringify( event )
exports.pushEvent = ( oEvent ) =>
if oEvent
log.print 'DB', "Event pushed into the queue: #{ oEvent.eventid }"
@db.rpush 'event_queue', JSON.stringify( oEvent )
else
log.error 'DB', 'Why would you give me an empty event...'
@ -182,10 +182,10 @@ via the provided function and returns the results to the callback(err, obj) func
@param {function} cb the callback(err, obj) function that receives all the retrieved data or an error
###
getSetRecords = ( set, fSingle, cb ) =>
log.print 'DB', 'Fetching set records: ' + set
log.print 'DB', "Fetching set records: #{ set }"
@db.smembers set, ( err, arrReply ) ->
if err
err.addInfo = 'fetching ' + set
err.addInfo = "fetching #{ set }"
log.error 'DB', err
else if arrReply.length == 0
cb()
@ -194,16 +194,16 @@ getSetRecords = ( set, fSingle, cb ) =>
objReplies = {}
setTimeout ->
if semaphore > 0
cb new Error('Timeout fetching ' + set)
cb new Error "Timeout fetching #{ set }"
, 2000
fCallback = ( prop ) ->
( err, data ) ->
--semaphore
if err
err.addInfo = 'fetching single element: ' + prop
err.addInfo = "fetching single element: #{ prop }"
log.error 'DB', err
else if not data
log.error 'DB', new Error 'Empty key in DB: ' + prop
log.error 'DB', new Error "Empty key in DB: #{ prop }"
else
objReplies[ prop ] = data
if semaphore == 0
@ -212,31 +212,31 @@ getSetRecords = ( set, fSingle, cb ) =>
###
## Action Modules
#TODO Rename Action Modules into something like Action Caller
###
###
Store a string representation of an action module in the DB.
@public storeActionModule ( *id, data* )
@param {String} id
@public storeActionModule ( *amId, data* )
@param {String} amId
@param {String} data
###
# FIXME can the data be an object?
exports.storeActionModule = ( id, data ) =>
log.print 'DB', 'storeActionModule: ' + id
@db.sadd 'action-modules', id, replyHandler 'storing action module key ' + id
@db.set 'action-module:' + id, data, replyHandler 'storing action module ' + id
exports.storeActionModule = ( amId, data ) =>
log.print 'DB', "storeActionModule: #{ amId }"
@db.sadd 'action-modules', amId, replyHandler "storing action module key #{ amId }"
@db.set "action-module:#{ amId }", data, replyHandler "storing action module #{ amId }"
###
Query the DB for an action module and pass it to the callback(err, obj) function.
@public getActionModule( *id, cb* )
@param {String} id
@public getActionModule( *amId, cb* )
@param {String} amId
@param {function} cb
###
exports.getActionModule = ( id, cb ) =>
log.print 'DB', 'getActionModule: ' + id
@db.get 'action-module:' + id, cb
exports.getActionModule = ( amId, cb ) =>
log.print 'DB', "getActionModule: #{ amId }"
@db.get "action-module:#{ amId }", cb
###
Fetch all action modules and hand them to the callback(err, obj) function.
@ -250,57 +250,58 @@ exports.getActionModules = ( cb ) ->
###
Store user-specific action module parameters .
@public storeActionParams( *userId, moduleId, data* )
@public storeActionParams( *userId, amId, data* )
@param {String} userId
@param {String} moduleId
@param {String} amId
@param {String} data
###
exports.storeActionParams = ( userId, moduleId, data ) =>
log.print 'DB', 'storeActionParams: ' + moduleId + ':' + userId
@db.set 'action-params:' + moduleId + ':' + userId, hash(data),
replyHandler 'storing action params ' + moduleId + ':' + userId
exports.storeActionParams = ( userId, amId, data ) =>
log.print 'DB', "storeActionParams: #{ amId }:#{ userId }"
@db.set "action-params:#{ amId }:#{ userId }", hash(data),
replyHandler "storing action params #{ amId }:#{ userId }"
###
Query the DB for user-specific action module parameters,
and pass it to the callback(err, obj) function.
@public getActionParams( *userId, moduleId, cb* )
@public getActionParams( *userId, amId, cb* )
@param {String} userId
@param {String} moduleId
@param {String} amId
@param {function} cb
###
exports.getActionParams = ( userId, moduleId, cb ) =>
log.print 'DB', 'getActionParams: ' + moduleId + ':' + userId
@db.get 'action-params:' + moduleId + ':' + userId, ( err, data ) ->
exports.getActionParams = ( userId, amId, cb ) =>
log.print 'DB', "getActionParams: #{ amId }:#{ userId }"
@db.get "action-params:#{ amId }:#{ userId }", ( err, data ) ->
cb err, decrypt data
###
## Event Modules
#TODO rename event modules to event puller or something like that
###
###
Store a string representation of an event module in the DB.
@public storeEventModule( *id, data* )
@param {String} id
@public storeEventModule( *emId, data* )
@param {String} emId
@param {String} data
###
exports.storeEventModule = ( id, data ) =>
log.print 'DB', 'storeEventModule: ' + id
@db.sadd 'event-modules', id, replyHandler 'storing event module key ' + id
@db.set 'event-module:' + id, data, replyHandler 'storing event module ' + id
exports.storeEventModule = ( emId, data ) =>
log.print 'DB', "storeEventModule: #{ emId }"
@db.sadd 'event-modules', emId, replyHandler "storing event module key #{ emId }"
@db.set 'event-module:#{ emId }', data, replyHandler "storing event module #{ emId }"
###
Query the DB for an event module and pass it to the callback(err, obj) function.
@public getEventModule( *id, cb* )
@param {String} id
@public getEventModule( *emId, cb* )
@param {String} emId
@param {function} cb
###
exports.getEventModule = ( id, cb ) =>
log.print 'DB', 'getEventModule: ' + id
@db.get 'event-module:' + id, cb
exports.getEventModule = ( emId, cb ) =>
log.print 'DB', "getEventModule: #{ emId }"
@db.get "event-module:#{ emId }", cb
###
Fetch all event modules and pass them to the callback(err, obj) function.
@ -314,29 +315,29 @@ exports.getEventModules = ( cb ) ->
###
Store a string representation of user-specific parameters for an event module.
@public storeEventParams( *userId, moduleId, data* )
@public storeEventParams( *userId, emId, data* )
@param {String} userId
@param {String} moduleId
@param {String} emId
@param {Object} data
###
# TODO is used, remove unused ones
exports.storeEventParams = ( userId, moduleId, data ) =>
log.print 'DB', 'storeEventParams: ' + moduleId + ':' + userId
exports.storeEventParams = ( userId, emId, data ) =>
log.print 'DB', "storeEventParams: #{ emId }:#{ userId }"
# TODO encryption based on user specific key?
@db.set 'event-params:' + moduleId + ':' + userId, encrypt(data),
replyHandler 'storing event auth ' + moduleId + ':' + userId
@db.set "event-params:#{ emId }:#{ userId }", encrypt(data),
replyHandler "storing event auth #{ emId }:#{ userId }"
###
Query the DB for an action module authentication token, associated with a user.
@public getEventAuth( *userId, moduleId, data* )
@public getEventAuth( *userId, emId, data* )
@param {String} userId
@param {String} moduleId
@param {String} emId
@param {function} cb
###
exports.getEventAuth = ( userId, moduleId, cb ) =>
log.print 'DB', 'getEventAuth: ' + moduleId + ':' + userId
@db.get 'event-auth:' + moduleId + ':' + userId, ( err, data ) ->
exports.getEventAuth = ( userId, emId, cb ) =>
log.print 'DB', "getEventAuth: #{ emId }:#{ userId }"
@db.get "event-auth:#{ emId }:#{ userId }", ( err, data ) ->
cb err, decrypt data
@ -353,22 +354,22 @@ Store a string representation of a rule in the DB.
@param {String} data
###
exports.storeRule = ( ruleId, userId, data ) =>
log.print 'DB', 'storeRule: ' + ruleId
@db.sadd 'rules', ruleId + ':' + user, replyHandler 'storing rule key "' + ruleId + ':' + user + '"'
@db.sadd 'user-set:' + user + ':rules', ruleId, replyHandler 'storing rule key to "user:' + user + ':rules"'
@db.sadd 'rule-set:' + ruleId + ':users', user, replyHandler 'storing user key to "rule:' + ruleId + ':users"'
@db.set 'rule:' + ruleId + ':' + user, data, replyHandler 'storing rule "' + ruleId + ':' + user + '"'
log.print 'DB', "storeRule: #{ ruleId }"
@db.sadd 'rules', "#{ ruleId }:#{ userId }", replyHandler "storing rule key \"#{ ruleId }:#{ userId }\""
@db.sadd "user-set:#{ userId }:rules", ruleId, replyHandler "storing rule key to \"user:#{ userId }:rules\""
@db.sadd "rule-set:#{ ruleId }:users", user, replyHandler "storing user key to \"rule:#{ ruleId }:users\""
@db.set "rule:#{ ruleId }:#{ userId }", data, replyHandler "storing rule \"#{ ruleId }:#{ userId }\""
###
Query the DB for a rule and pass it to the callback(err, obj) function.
@public getRule( *id, cb* )
@param {String} id
@public getRule( *ruleId, cb* )
@param {String} ruleId
@param {function} cb
###
exports.getRule = ( id, cb ) =>
log.print 'DB', 'getRule: ' + id
@db.get 'rule:' + id, cb
exports.getRule = ( ruleId, cb ) =>
log.print 'DB', "getRule: #{ ruleId }"
@db.get "rule:#{ ruleId }", cb
###
Fetch all rules from the database and pass them to the callback function.
@ -389,36 +390,36 @@ Store a user object (needs to be a flat structure).
exports.storeUser = ( objUser ) =>
#TODO Only store user if not already existing, or at least only then add a private key
#for his encryption. we would want to have one private key per user, right?
log.print 'DB', 'storeUser: ' + objUser.username
log.print 'DB', "storeUser: #{ objUser.username }"
if objUser and objUser.username and objUser.password
@db.sadd 'users', objUser.username, replyHandler 'storing user key ' + objUser.username
@db.sadd 'users', objUser.username, replyHandler "storing user key #{ objUser.username }"
objUser.password = hash objUser.password
@db.hmset 'user:' + objUser.username, objUser, replyHandler 'storing user properties ' + objUser.username
@db.hmset "user:#{ objUser.username }", objUser, replyHandler "storing user properties #{ objUser.username }"
else
log.error 'DB', new Error 'username or password was missing'
###
Associate a role with a user.
@public storeUserRole( *username, role* )
@param {String} username
@public storeUserRole( *userId, role* )
@param {String} userId
@param {String} role
###
exports.storeUserRole = ( userId, roleId ) =>
log.print 'DB', 'storeUserRole: ' + username + ':' + role
@db.sadd 'roles', role, replyHandler 'adding role ' + role + ' to role index set'
@db.sadd 'user:' + userId + ':roles', role, replyHandler 'adding role ' + role + ' to user ' + username
@db.sadd 'role:' + roleId + ':users', username, replyHandler 'adding user ' + username + ' to role ' + role
exports.storeUserRole = ( userId, role ) =>
log.print 'DB', "storeUserRole: #{ userId }:#{ role }"
@db.sadd 'roles', role, replyHandler "adding role #{ role } to role index set"
@db.sadd "user:#{ userId }:roles", role, replyHandler "adding role #{ role } to user #{ userId }"
@db.sadd "role:#{ role }:users", userId, replyHandler "adding user #{ userId } to role #{ role }"
###
Fetch all roles of a user and pass them to the callback(err, obj)
@public getUserRoles( *username* )
@param {String} username
@public getUserRoles( *userId* )
@param {String} userId
###
exports.getUserRoles = ( username ) =>
log.print 'DB', 'getUserRole: ' + username
@db.get 'user-roles:' + username, cb
exports.getUserRoles = ( userId ) =>
log.print 'DB', "getUserRole: #{ userId }"
@db.get "user-roles:#{ userId }", cb
###
Fetch all users of a role and pass them to the callback(err, obj)
@ -427,8 +428,8 @@ Fetch all users of a role and pass them to the callback(err, obj)
@param {String} role
###
exports.getRoleUsers = ( role ) =>
log.print 'DB', 'getRoleUsers: ' + role
@db.get 'role-users:' + role, cb
log.print 'DB', "getRoleUsers: #{ role }"
@db.get "role-users:#{ role }", cb
###
Checks the credentials and on success returns the user object to the
@ -436,27 +437,27 @@ 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( *username, password, cb* )
@param {String} username
@public loginUser( *userId, password, cb* )
@param {String} userId
@param {String} password
@param {function} cb
###
#TODO verify and test whole function
exports.loginUser = ( username, password, cb ) =>
log.print 'DB', 'User "' + username + '" tries to log in'
exports.loginUser = ( userId, password, cb ) =>
log.print 'DB', "User \"#{ userId }\" tries to log in"
fCheck = ( pw ) ->
( err, obj ) ->
if err
cb err
else if obj and obj.password
if pw == obj.password
log.print 'DB', 'User "' + obj.username + '" logged in!'
log.print 'DB', "User \"#{ obj.username }\" logged in!"
cb null, obj
else
cb new Error 'Wrong credentials!'
else
cb new Error 'User not found!'
@db.hgetall 'user:' + username, fCheck password
@db.hgetall "user:#{ userId }", fCheck password
#TODO implement functions required for user sessions and the rule activation

View file

@ -1,3 +0,0 @@
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
echo "Started listening on file changes to compile them!..."
coffee -wc $DIR/testing/

View file

@ -103,10 +103,10 @@ DB Interface
replyHandler = function(action) {
return function(err, reply) {
if (err) {
err.addInfo = 'during "' + action + '"';
err.addInfo = "during \"" + action + "\"";
return log.error('DB', err);
} else {
return log.print('DB', action + ': ' + reply);
return log.print('DB', "" + action + ": " + reply);
}
};
};
@ -114,15 +114,15 @@ DB Interface
/*
Push an event into the event queue.
@public pushEvent( *event* )
@param {Object} event
@public pushEvent( *oEvent* )
@param {Object} oEvent
*/
exports.pushEvent = function(event) {
if (event) {
log.print('DB', 'Event pushed into the queue: ' + event.eventid);
return _this.db.rpush('event_queue', JSON.stringify(event));
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...');
}
@ -244,11 +244,11 @@ DB Interface
getSetRecords = function(set, fSingle, cb) {
log.print('DB', 'Fetching set records: ' + set);
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;
err.addInfo = "fetching " + set;
return log.error('DB', err);
} else if (arrReply.length === 0) {
return cb();
@ -257,17 +257,17 @@ DB Interface
objReplies = {};
setTimeout(function() {
if (semaphore > 0) {
return cb(new Error('Timeout fetching ' + set));
return cb(new Error("Timeout fetching " + set));
}
}, 2000);
fCallback = function(prop) {
return function(err, data) {
--semaphore;
if (err) {
err.addInfo = 'fetching single element: ' + prop;
err.addInfo = "fetching single element: " + prop;
log.error('DB', err);
} else if (!data) {
log.error('DB', new Error('Empty key in DB: ' + prop));
log.error('DB', new Error("Empty key in DB: " + prop));
} else {
objReplies[prop] = data;
}
@ -288,36 +288,37 @@ DB Interface
/*
## Action Modules
#TODO Rename Action Modules into something like Action Caller
*/
/*
Store a string representation of an action module in the DB.
@public storeActionModule ( *id, data* )
@param {String} id
@public storeActionModule ( *amId, data* )
@param {String} amId
@param {String} data
*/
exports.storeActionModule = function(id, data) {
log.print('DB', 'storeActionModule: ' + id);
_this.db.sadd('action-modules', id, replyHandler('storing action module key ' + id));
return _this.db.set('action-module:' + id, data, replyHandler('storing action module ' + id));
exports.storeActionModule = function(amId, data) {
log.print('DB', "storeActionModule: " + amId);
_this.db.sadd('action-modules', amId, replyHandler("storing action module key " + amId));
return _this.db.set("action-module:" + amId, data, replyHandler("storing action module " + amId));
};
/*
Query the DB for an action module and pass it to the callback(err, obj) function.
@public getActionModule( *id, cb* )
@param {String} id
@public getActionModule( *amId, cb* )
@param {String} amId
@param {function} cb
*/
exports.getActionModule = function(id, cb) {
log.print('DB', 'getActionModule: ' + id);
return _this.db.get('action-module:' + id, cb);
exports.getActionModule = function(amId, cb) {
log.print('DB', "getActionModule: " + amId);
return _this.db.get("action-module:" + amId, cb);
};
/*
@ -335,68 +336,69 @@ DB Interface
/*
Store user-specific action module parameters .
@public storeActionParams( *userId, moduleId, data* )
@public storeActionParams( *userId, amId, data* )
@param {String} userId
@param {String} moduleId
@param {String} amId
@param {String} data
*/
exports.storeActionParams = function(userId, moduleId, data) {
log.print('DB', 'storeActionParams: ' + moduleId + ':' + userId);
return _this.db.set('action-params:' + moduleId + ':' + userId, hash(data), replyHandler('storing action params ' + moduleId + ':' + userId));
exports.storeActionParams = function(userId, amId, data) {
log.print('DB', "storeActionParams: " + amId + ":" + userId);
return _this.db.set("action-params:" + amId + ":" + userId, hash(data), replyHandler("storing action params " + amId + ":" + userId));
};
/*
Query the DB for user-specific action module parameters,
and pass it to the callback(err, obj) function.
@public getActionParams( *userId, moduleId, cb* )
@public getActionParams( *userId, amId, cb* )
@param {String} userId
@param {String} moduleId
@param {String} amId
@param {function} cb
*/
exports.getActionParams = function(userId, moduleId, cb) {
log.print('DB', 'getActionParams: ' + moduleId + ':' + userId);
return _this.db.get('action-params:' + moduleId + ':' + userId, function(err, data) {
exports.getActionParams = function(userId, amId, cb) {
log.print('DB', "getActionParams: " + amId + ":" + userId);
return _this.db.get("action-params:" + amId + ":" + userId, function(err, data) {
return cb(err, decrypt(data));
});
};
/*
## Event Modules
#TODO rename event modules to event puller or something like that
*/
/*
Store a string representation of an event module in the DB.
@public storeEventModule( *id, data* )
@param {String} id
@public storeEventModule( *emId, data* )
@param {String} emId
@param {String} data
*/
exports.storeEventModule = function(id, data) {
log.print('DB', 'storeEventModule: ' + id);
_this.db.sadd('event-modules', id, replyHandler('storing event module key ' + id));
return _this.db.set('event-module:' + id, data, replyHandler('storing event module ' + id));
exports.storeEventModule = function(emId, data) {
log.print('DB', "storeEventModule: " + emId);
_this.db.sadd('event-modules', emId, replyHandler("storing event module key " + emId));
return _this.db.set('event-module:#{ emId }', data, replyHandler("storing event module " + emId));
};
/*
Query the DB for an event module and pass it to the callback(err, obj) function.
@public getEventModule( *id, cb* )
@param {String} id
@public getEventModule( *emId, cb* )
@param {String} emId
@param {function} cb
*/
exports.getEventModule = function(id, cb) {
log.print('DB', 'getEventModule: ' + id);
return _this.db.get('event-module:' + id, cb);
exports.getEventModule = function(emId, cb) {
log.print('DB', "getEventModule: " + emId);
return _this.db.get("event-module:" + emId, cb);
};
/*
@ -414,31 +416,31 @@ DB Interface
/*
Store a string representation of user-specific parameters for an event module.
@public storeEventParams( *userId, moduleId, data* )
@public storeEventParams( *userId, emId, data* )
@param {String} userId
@param {String} moduleId
@param {String} emId
@param {Object} data
*/
exports.storeEventParams = function(userId, moduleId, data) {
log.print('DB', 'storeEventParams: ' + moduleId + ':' + userId);
return _this.db.set('event-params:' + moduleId + ':' + userId, encrypt(data), replyHandler('storing event auth ' + moduleId + ':' + userId));
exports.storeEventParams = function(userId, emId, data) {
log.print('DB', "storeEventParams: " + emId + ":" + userId);
return _this.db.set("event-params:" + emId + ":" + userId, encrypt(data), replyHandler("storing event auth " + emId + ":" + userId));
};
/*
Query the DB for an action module authentication token, associated with a user.
@public getEventAuth( *userId, moduleId, data* )
@public getEventAuth( *userId, emId, data* )
@param {String} userId
@param {String} moduleId
@param {String} emId
@param {function} cb
*/
exports.getEventAuth = function(userId, moduleId, cb) {
log.print('DB', 'getEventAuth: ' + moduleId + ':' + userId);
return _this.db.get('event-auth:' + moduleId + ':' + userId, function(err, data) {
exports.getEventAuth = function(userId, emId, cb) {
log.print('DB', "getEventAuth: " + emId + ":" + userId);
return _this.db.get("event-auth:" + emId + ":" + userId, function(err, data) {
return cb(err, decrypt(data));
});
};
@ -459,25 +461,25 @@ DB Interface
exports.storeRule = function(ruleId, userId, data) {
log.print('DB', 'storeRule: ' + ruleId);
_this.db.sadd('rules', ruleId + ':' + user, replyHandler('storing rule key "' + ruleId + ':' + user + '"'));
_this.db.sadd('user-set:' + user + ':rules', ruleId, replyHandler('storing rule key to "user:' + user + ':rules"'));
_this.db.sadd('rule-set:' + ruleId + ':users', user, replyHandler('storing user key to "rule:' + ruleId + ':users"'));
return _this.db.set('rule:' + ruleId + ':' + user, data, replyHandler('storing rule "' + ruleId + ':' + user + '"'));
log.print('DB', "storeRule: " + ruleId);
_this.db.sadd('rules', "" + ruleId + ":" + userId, replyHandler("storing rule key \"" + ruleId + ":" + userId + "\""));
_this.db.sadd("user-set:" + userId + ":rules", ruleId, replyHandler("storing rule key to \"user:" + userId + ":rules\""));
_this.db.sadd("rule-set:" + ruleId + ":users", user, replyHandler("storing user key to \"rule:" + ruleId + ":users\""));
return _this.db.set("rule:" + ruleId + ":" + userId, data, replyHandler("storing rule \"" + ruleId + ":" + userId + "\""));
};
/*
Query the DB for a rule and pass it to the callback(err, obj) function.
@public getRule( *id, cb* )
@param {String} id
@public getRule( *ruleId, cb* )
@param {String} ruleId
@param {function} cb
*/
exports.getRule = function(id, cb) {
log.print('DB', 'getRule: ' + id);
return _this.db.get('rule:' + id, cb);
exports.getRule = function(ruleId, cb) {
log.print('DB', "getRule: " + ruleId);
return _this.db.get("rule:" + ruleId, cb);
};
/*
@ -502,11 +504,11 @@ DB Interface
exports.storeUser = function(objUser) {
log.print('DB', 'storeUser: ' + objUser.username);
log.print('DB', "storeUser: " + objUser.username);
if (objUser && objUser.username && objUser.password) {
_this.db.sadd('users', objUser.username, replyHandler('storing user key ' + objUser.username));
_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));
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'));
}
@ -515,30 +517,30 @@ DB Interface
/*
Associate a role with a user.
@public storeUserRole( *username, role* )
@param {String} username
@public storeUserRole( *userId, role* )
@param {String} userId
@param {String} role
*/
exports.storeUserRole = function(userId, roleId) {
log.print('DB', 'storeUserRole: ' + username + ':' + 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 ' + username));
return _this.db.sadd('role:' + roleId + ':users', username, replyHandler('adding user ' + username + ' to role ' + 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 the callback(err, obj)
@public getUserRoles( *username* )
@param {String} username
@public getUserRoles( *userId* )
@param {String} userId
*/
exports.getUserRoles = function(username) {
log.print('DB', 'getUserRole: ' + username);
return _this.db.get('user-roles:' + username, cb);
exports.getUserRoles = function(userId) {
log.print('DB', "getUserRole: " + userId);
return _this.db.get("user-roles:" + userId, cb);
};
/*
@ -550,8 +552,8 @@ DB Interface
exports.getRoleUsers = function(role) {
log.print('DB', 'getRoleUsers: ' + role);
return _this.db.get('role-users:' + role, cb);
log.print('DB', "getRoleUsers: " + role);
return _this.db.get("role-users:" + role, cb);
};
/*
@ -560,23 +562,23 @@ DB Interface
beforehand by the instance closest to the user that enters the password,
because we only store hashes of passwords for safety reasons.
@public loginUser( *username, password, cb* )
@param {String} username
@public loginUser( *userId, password, cb* )
@param {String} userId
@param {String} password
@param {function} cb
*/
exports.loginUser = function(username, password, cb) {
exports.loginUser = function(userId, password, cb) {
var fCheck;
log.print('DB', 'User "' + username + '" tries to log in');
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!');
log.print('DB', "User \"" + obj.username + "\" logged in!");
return cb(null, obj);
} else {
return cb(new Error('Wrong credentials!'));
@ -586,7 +588,7 @@ DB Interface
}
};
};
return _this.db.hgetall('user:' + username, fCheck(password));
return _this.db.hgetall("user:" + userId, fCheck(password));
};
/*

View file

@ -11,13 +11,13 @@
"dependencies": {
"connect-redis": "1.4.6",
"crypto-js": "3.1.2",
"express": "3.4.0",
"express": "3.4.8",
"groc": "0.6.1",
"mustache": "0.7.3",
"needle": "0.6.1",
"nodeunit": "0.8.2",
"redis": "0.9.0",
"request": "2.27.0",
"mustache": "0.8.1",
"needle": "0.6.3",
"nodeunit": "0.8.4",
"redis": "0.10.0",
"request": "2.33.0",
"coffee-script": "1.6.3"
},
"__comment": {
@ -25,7 +25,31 @@
"glob" :"3.2.7",
"docco": "0.6.2",
"socket.io": "0.9.16",
"contextify": "0.1.6"
"contextify": "0.1.6",
"dependencies_safe": {
"connect-redis": "1.4.6",
"crypto-js": "3.1.2",
"express": "3.4.0",
"groc": "0.6.1",
"mustache": "0.7.3",
"needle": "0.6.1",
"nodeunit": "0.8.4",
"redis": "0.9.0",
"request": "2.27.0",
"coffee-script": "1.6.3"
},
"dependencies_new": {
"connect-redis": "1.4.6",
"crypto-js": "3.1.2",
"express": "3.4.8",
"groc": "0.6.1",
"mustache": "0.8.1",
"needle": "0.6.3",
"nodeunit": "0.8.4",
"redis": "0.10.0",
"request": "2.33.0",
"coffee-script": "1.6.3"
}
}
}
}

View file

@ -1,3 +0,0 @@
#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
node $DIR/js-coffee/server

1
create_doc.js → run_doc.sh Normal file → Executable file
View file

@ -1,3 +1,4 @@
#!/usr/bin/env node
/*
* # groc Documentation
* Create the documentation to be displayed through the webserver.

View file

@ -1,3 +1,3 @@
#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
node $DIR/js/server > $DIR/js/server.log 2>&1 &
node $DIR/js-coffee/server

1
run_tests.js → run_tests.sh Normal file → Executable file
View file

@ -1 +1,2 @@
#!/usr/bin/env node
require('nodeunit').reporters.default.run(['testing']);

View file

@ -1,32 +1,34 @@
path = require 'path'
exports.setUp = ( cb ) =>
@conf = require '../js-coffee/config'
@conf
logType: 2
cb()
@conf = require path.join '..', 'js-coffee', 'config'
@conf
logType: 2
cb()
exports.testRequire = ( test ) =>
test.expect 1
test.ok @conf.isReady(), 'File does not exist!'
test.done()
test.expect 1
test.ok @conf.isReady(), 'File does not exist!'
test.done()
exports.testParameters = ( test ) =>
test.expect 4
test.ok @conf.getHttpPort(), 'HTTP port does not exist!'
test.ok @conf.getDBPort(), 'DB port does not exist!'
test.ok @conf.getCryptoKey(), 'Crypto key does not exist!'
test.ok @conf.getSessionSecret(), 'Session Secret does not exist!'
test.done()
test.expect 4
test.ok @conf.getHttpPort(), 'HTTP port does not exist!'
test.ok @conf.getDBPort(), 'DB port does not exist!'
test.ok @conf.getCryptoKey(), 'Crypto key does not exist!'
test.ok @conf.getSessionSecret(), 'Session Secret does not exist!'
test.done()
exports.testDifferentConfigFile = ( test ) =>
test.expect 1
@conf
configPath: 'testing/jsonWrongConfig.json'
test.ok @conf.isReady(), 'Different path not loaded!'
test.done()
test.expect 1
@conf
configPath: 'testing/jsonWrongConfig.json'
test.ok @conf.isReady(), 'Different path not loaded!'
test.done()
exports.testNoConfigFile = ( test ) =>
test.expect 1
@conf
configPath: 'wrongpath.file'
test.strictEqual @conf.isReady(), false, 'Wrong path still loaded!'
test.done()
test.expect 1
@conf
configPath: 'wrongpath.file'
test.strictEqual @conf.isReady(), false, 'Wrong path still loaded!'
test.done()

View file

@ -1,46 +0,0 @@
// Generated by CoffeeScript 1.6.3
(function() {
var _this = this;
exports.setUp = function(cb) {
_this.conf = require('../js-coffee/config');
_this.conf({
logType: 2
});
return cb();
};
exports.testRequire = function(test) {
test.expect(1);
test.ok(_this.conf.isReady(), 'File does not exist!');
return test.done();
};
exports.testParameters = function(test) {
test.expect(4);
test.ok(_this.conf.getHttpPort(), 'HTTP port does not exist!');
test.ok(_this.conf.getDBPort(), 'DB port does not exist!');
test.ok(_this.conf.getCryptoKey(), 'Crypto key does not exist!');
test.ok(_this.conf.getSessionSecret(), 'Session Secret does not exist!');
return test.done();
};
exports.testDifferentConfigFile = function(test) {
test.expect(1);
_this.conf({
configPath: 'testing/jsonWrongConfig.json'
});
test.ok(_this.conf.isReady(), 'Different path not loaded!');
return test.done();
};
exports.testNoConfigFile = function(test) {
test.expect(1);
_this.conf({
configPath: 'wrongpath.file'
});
test.strictEqual(_this.conf.isReady(), false, 'Wrong path still loaded!');
return test.done();
};
}).call(this);

View file

@ -32,8 +32,11 @@ exports.availability =
test.done()
testPurgeQueue: ( test ) =>
evt =
eventid: '1'
event: 'mail'
test.expect 2
@db.pushEvent @evt1
@db.pushEvent evt
@db.purgeEventQueue()
@db.popEvent ( err, obj ) =>
test.ifError err, 'Error during pop after purging!'
@ -85,9 +88,9 @@ exports.events =
testMultiplePushAndPops: ( test ) =>
test.expect 6
numForks = 2
isFinished = () ->
test.done() if --numForks is 0
semaphore = 2
forkEnds = () ->
test.done() if --semaphore is 0
@db.pushEvent @evt1
@db.pushEvent @evt2
@ -96,33 +99,73 @@ exports.events =
test.ifError err, 'Error during multiple push and pop!'
test.notStrictEqual obj, null, 'There was no event in the queue!'
test.deepEqual @evt1, obj, 'Wrong event in queue!'
isFinished()
forkEnds()
@db.popEvent ( err, obj ) =>
test.ifError err, 'Error during multiple push and pop!'
test.notStrictEqual obj, null, 'There was no event in the queue!'
test.deepEqual @evt2, obj, 'Wrong event in queue!'
isFinished()
forkEnds()
exports.action_modules =
test: (test) =>
test.ok false, 'implement testing!'
exports.action_modules =
setUp: ( cb ) =>
@action1 = '
exports.testFunctionOne = function( args ) {
var data = {
companyId: \'961\',
context: \'17936\',
text: \'Binder entry based on event: \' + args.info
};
needle.post(\'https://probinder.com/service/27/save\', data);
};'
@action2 = '
// This is just a console.log which should fail
console.log(\'Why is this being printed??\');
exports.testFunctionTwo = function( args ) {
// empty function)
};'
cb()
testStoreModule: ( test ) =>
test.expect 1
fStore = ->
@db.storeActionModule 'test-action-module_null', null
@db.storeActionModule 'test-action-module_1', @action1
test.throws fStore, Error, 'Storing Action Module should not throw an error'
test.done()
testFetchModule: ( test ) =>
test.expect 0
test.done()
testFetchModules: ( test ) =>
test.expect 0
test.done()
testStoreParams: ( test ) =>
test.expect 0
test.done()
testFetchParams: ( test ) =>
test.expect 0
test.done()
exports.event_modules =
test: (test) =>
test: ( test ) =>
test.expect 0
test.done()
exports.rules =
test: (test) =>
test: ( test ) =>
test.expect 0
test.done()
exports.users =
test: (test) =>
test: ( test ) =>
test.expect 0
test.done()
exports.tearDown = ( cb ) =>
@db.shutDown()
cb()

View file

@ -1,164 +0,0 @@
// Generated by CoffeeScript 1.6.3
(function() {
var _this = this;
exports.setUp = function(cb) {
_this.db = require('../js-coffee/db_interface');
_this.db({
logType: 2
});
return cb();
};
exports.availability = {
testRequire: function(test) {
test.expect(1);
test.ok(_this.db, 'DB interface loaded');
return test.done();
},
testConnect: function(test) {
test.expect(1);
return _this.db.isConnected(function(err) {
test.ifError(err, 'Connection failed!');
return test.done();
});
},
testNoConfig: function(test) {
test.expect(1);
_this.db({
configPath: 'nonexistingconf.file'
});
return _this.db.isConnected(function(err) {
test.ok(err, 'Still connected!?');
return test.done();
});
},
testWrongConfig: function(test) {
test.expect(1);
_this.db({
configPath: 'testing/jsonWrongConfig.json'
});
return _this.db.isConnected(function(err) {
test.ok(err, 'Still connected!?');
return test.done();
});
},
testPurgeQueue: function(test) {
test.expect(2);
_this.db.pushEvent(_this.evt1);
_this.db.purgeEventQueue();
return _this.db.popEvent(function(err, obj) {
test.ifError(err, 'Error during pop after purging!');
test.strictEqual(obj, null, 'There was an event in the queue!?');
return test.done();
});
}
};
exports.events = {
setUp: function(cb) {
_this.evt1 = {
eventid: '1',
event: 'mail'
};
_this.evt2 = {
eventid: '2',
event: 'mail'
};
_this.db.purgeEventQueue();
return cb();
},
testEmptyPopping: function(test) {
test.expect(2);
return _this.db.popEvent(function(err, obj) {
test.ifError(err, 'Error during pop after purging!');
test.strictEqual(obj, null, 'There was an event in the queue!?');
return test.done();
});
},
testEmptyPushing: function(test) {
test.expect(2);
_this.db.pushEvent(null);
return _this.db.popEvent(function(err, obj) {
test.ifError(err, 'Error during non-empty pushing!');
test.strictEqual(obj, null, 'There was an event in the queue!?');
return test.done();
});
},
testPushing: function(test) {
var fPush;
test.expect(1);
fPush = function() {
this.db.pushEvent(null);
return this.db.pushEvent(this.evt1);
};
test.throws(fPush, Error, 'This should not throw an error');
return test.done();
},
testNonEmptyPopping: function(test) {
test.expect(3);
_this.db.pushEvent(_this.evt1);
return _this.db.popEvent(function(err, obj) {
test.ifError(err, 'Error during non-empty popping!');
test.notStrictEqual(obj, null, 'There was no event in the queue!');
test.deepEqual(_this.evt1, obj, 'Wrong event in queue!');
return test.done();
});
},
testMultiplePushAndPops: function(test) {
var isFinished, numForks;
test.expect(6);
numForks = 2;
isFinished = function() {
if (--numForks === 0) {
return test.done();
}
};
_this.db.pushEvent(_this.evt1);
_this.db.pushEvent(_this.evt2);
_this.db.popEvent(function(err, obj) {
test.ifError(err, 'Error during multiple push and pop!');
test.notStrictEqual(obj, null, 'There was no event in the queue!');
test.deepEqual(_this.evt1, obj, 'Wrong event in queue!');
return isFinished();
});
return _this.db.popEvent(function(err, obj) {
test.ifError(err, 'Error during multiple push and pop!');
test.notStrictEqual(obj, null, 'There was no event in the queue!');
test.deepEqual(_this.evt2, obj, 'Wrong event in queue!');
return isFinished();
});
}
};
exports.action_modules = {
test: function(test) {
test.ok(false, 'implement testing!');
return test.done();
}
};
exports.event_modules = {
test: function(test) {
return test.done();
}
};
exports.rules = {
test: function(test) {
return test.done();
}
};
exports.users = {
test: function(test) {
return test.done();
}
};
exports.tearDown = function(cb) {
_this.db.shutDown();
return cb();
};
}).call(this);