diff --git a/README.md b/README.md index a75e99a..8f1311e 100644 --- a/README.md +++ b/README.md @@ -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 _ diff --git a/coffee/config.coffee b/coffee/config.coffee index d0e40af..db9fda2 100644 --- a/coffee/config.coffee +++ b/coffee/config.coffee @@ -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 diff --git a/coffee/db_interface.coffee b/coffee/db_interface.coffee index 9a7c4d3..d382340 100644 --- a/coffee/db_interface.coffee +++ b/coffee/db_interface.coffee @@ -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 diff --git a/compile_testing.sh b/compile_testing.sh deleted file mode 100755 index 09a259f..0000000 --- a/compile_testing.sh +++ /dev/null @@ -1,3 +0,0 @@ -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -echo "Started listening on file changes to compile them!..." -coffee -wc $DIR/testing/ diff --git a/js-coffee/db_interface.js b/js-coffee/db_interface.js index f7d7cae..95f1f00 100644 --- a/js-coffee/db_interface.js +++ b/js-coffee/db_interface.js @@ -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)); }; /* diff --git a/package.json b/package.json index 7d64d65..5c88cfb 100644 --- a/package.json +++ b/package.json @@ -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" + } } } } \ No newline at end of file diff --git a/run_coffee_server.sh b/run_coffee_server.sh deleted file mode 100755 index 2e17819..0000000 --- a/run_coffee_server.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -node $DIR/js-coffee/server diff --git a/create_doc.js b/run_doc.sh old mode 100644 new mode 100755 similarity index 98% rename from create_doc.js rename to run_doc.sh index 5de0041..08a505e --- a/create_doc.js +++ b/run_doc.sh @@ -1,3 +1,4 @@ +#!/usr/bin/env node /* * # groc Documentation * Create the documentation to be displayed through the webserver. diff --git a/run_server.sh b/run_server.sh index 4743381..2e17819 100755 --- a/run_server.sh +++ b/run_server.sh @@ -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 diff --git a/run_tests.js b/run_tests.sh old mode 100644 new mode 100755 similarity index 73% rename from run_tests.js rename to run_tests.sh index 74e1e68..d3232bf --- a/run_tests.js +++ b/run_tests.sh @@ -1 +1,2 @@ +#!/usr/bin/env node require('nodeunit').reporters.default.run(['testing']); \ No newline at end of file diff --git a/testing/test_config.coffee b/testing/test_config.coffee index 0c1f735..bbafbc3 100644 --- a/testing/test_config.coffee +++ b/testing/test_config.coffee @@ -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() diff --git a/testing/test_config.js b/testing/test_config.js deleted file mode 100644 index d8a838b..0000000 --- a/testing/test_config.js +++ /dev/null @@ -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); diff --git a/testing/test_db_interface.coffee b/testing/test_db_interface.coffee index 4fad77f..adb1709 100644 --- a/testing/test_db_interface.coffee +++ b/testing/test_db_interface.coffee @@ -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() \ No newline at end of file diff --git a/testing/test_db_interface.js b/testing/test_db_interface.js deleted file mode 100644 index 1d74bda..0000000 --- a/testing/test_db_interface.js +++ /dev/null @@ -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);