diff --git a/coffee/components-manager.coffee b/coffee/components-manager.coffee index 261d478..627deaf 100644 --- a/coffee/components-manager.coffee +++ b/coffee/components-manager.coffee @@ -125,7 +125,7 @@ getModuleParams = ( user, oPayload, dbMod, callback ) -> answ.message = oPayload callback answ -forgeModule = ( user, oPayload, dbMod, callback ) -> +forgeModule = ( user, oPayload, dbMod, callback ) => answ = hasRequiredParams [ 'id', 'params', 'lang', 'data' ], oPayload if answ.code isnt 200 callback answ @@ -136,12 +136,12 @@ forgeModule = ( user, oPayload, dbMod, callback ) -> answ.message = 'Event Poller module name already existing: ' + oPayload.id else src = oPayload.data - cm = dynmod.compileString src, oPayload.id, {}, oPayload.lang + cm = dynmod.compileString src, user.username, oPayload.id, {}, oPayload.lang answ = cm.answ if answ.code is 200 funcs = [] funcs.push name for name, id of cm.module - @log.info "CM | Storing new module with functions #{ funcs }" + @log.info "CM | Storing new module with functions #{ funcs.join() }" answ.message = "Event Poller module successfully stored! Found following function(s): #{ funcs }" oPayload.functions = JSON.stringify funcs diff --git a/coffee/config.coffee b/coffee/config.coffee index 0452028..2f4461a 100644 --- a/coffee/config.coffee +++ b/coffee/config.coffee @@ -103,4 +103,4 @@ exports.getLogConf = -> fetchProp 'log' @public getCryptoKey() ### -exports.getCryptoKey = -> fetchProp 'crypto-key' +exports.getKeygenPassphrase = -> fetchProp 'keygen-passphrase' diff --git a/coffee/dynamic-modules.coffee b/coffee/dynamic-modules.coffee index 3b675fd..9d071fb 100644 --- a/coffee/dynamic-modules.coffee +++ b/coffee/dynamic-modules.coffee @@ -14,6 +14,28 @@ needle = require 'needle' # - External Modules: [coffee-script](http://coffeescript.org/) cs = require 'coffee-script' + + +# cryptico = require 'my-cryptico' + +# conf = require path.join '..', 'js-coffee', 'config' +# conf opts + +# passPhrase = conf.getKeygenPassphrase() +# numBits = 1024 +# console.log passPhrase + +# oPrivateRSAkey = cryptico.generateRSAKey passPhrase, numBits +# strPublicKey = cryptico.publicKeyString oPrivateRSAkey +# plainText = "Matt, I need you to help me with my Starcraft strategy." +# oEncrypted = cryptico.encrypt plainText, strPublicKey + +# console.log oEncrypted.cipher +# oDecrypted = cryptico.decrypt oEncrypted.cipher, oPrivateRSAkey +# console.log oDecrypted.plaintext + + + ### Module call ----------- @@ -37,7 +59,7 @@ compile it first into JS. @param {Object} params @param {String} lang ### -exports.compileString = ( src, id, params, lang ) => +exports.compileString = ( src, userId, moduleId, params, lang ) => answ = code: 200 message: 'Successfully compiled' @@ -52,7 +74,7 @@ exports.compileString = ( src, id, params, lang ) => err.location.first_line #FIXME not log but debug module is required to provide information to the user sandbox = - id: id #TODO the ID needs to be a combination of the module id and the user name + id: userId + '.' + moduleId + '.vm' params: params needle: needle log: console.log @@ -63,7 +85,7 @@ exports.compileString = ( src, id, params, lang ) => #it can still be active after that if there was a timing function or a callback used... #kill the child each time? how to determine whether there's still a token in the module? try - vm.runInNewContext src, sandbox, id + '.vm' + vm.runInNewContext src, sandbox, sandbox.id catch err answ.code = 400 answ.message = 'Loading Module failed: ' + err.message diff --git a/coffee/persistence.coffee b/coffee/persistence.coffee index cfc843f..8ca80ae 100644 --- a/coffee/persistence.coffee +++ b/coffee/persistence.coffee @@ -2,10 +2,11 @@ Persistence ============ -> Handles the connection to the database and provides functionalities for -> event pollers, action invokers, rules and the encrypted storing of authentication tokens. +> Handles the connection to the database and provides functionalities for event pollers, +> action invokers, rules and the (hopefully encrypted) storing of user-specific parameters +> per module. > General functionality as a wrapper for the module holds initialization, -> encryption/decryption, the retrieval of modules and shut down. +> 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 @@ -22,14 +23,9 @@ Persistence # **Loads Modules:** # - External Modules: -# [crypto-js](https://github.com/evanvosberg/crypto-js) and # [redis](https://github.com/mranney/node_redis) -crypto = require 'crypto-js' redis = require 'redis' -# yeah I know you know it now... good luck -crypto_key = "}f6y1y}B{.an$}2c$Yl.$mSnF\\HX149u*y8C:@kmN/520Gt\\v'+KFBnQ!\\r<>5X/xRI`sT cb new Error 'DB | Connection to DB failed!' setTimeout fCheckConnection, 100 + ### Abstracts logging for simple action replies from the DB. @@ -104,6 +101,7 @@ replyHandler = ( action ) => else @log.info "DB | #{ action }: #{ reply }" + ### Push an event into the event queue. @@ -129,7 +127,8 @@ exports.popEvent = ( cb ) => ( err, obj ) -> pcb err, JSON.parse obj @db.lpop 'event_queue', makeObj cb - + + ### Purge the event queue. @@ -138,49 +137,6 @@ Purge the event queue. exports.purgeEventQueue = () => @db.del 'event_queue', replyHandler 'purging event queue' -### -Hashes a string based on SHA-3-512. - -@private hash( *plainText* ) -@param {String} plainText -### -hash = ( plainText ) => - if !plainText? then return null - try - ( crypto.SHA3 plainText, { outputLength: 512 } ).toString() - catch err - @log.warn err, 'DB | during hashing' - null - - -### -Encrypts a string using the crypto key from the config file, based on aes-256-cbc. - -@private encrypt( *plainText* ) -@param {String} plainText -### -encrypt = ( plainText ) => - if !plainText? then return null - try - crypto.AES.encrypt plainText, crypto_key - catch err - @log.warn err, 'DB | during encryption' - null - -### -Decrypts an encrypted string and hands it back on success or null. - -@private decrypt( *crypticText* ) -@param {String} crypticText -### -decrypt = ( crypticText ) => - if !crypticText? then return null; - try - dec = crypto.AES.decrypt crypticText, crypto_key - dec.toString crypto.enc.Utf8 - catch err - @log.warn err, 'DB | during decryption' - null ### Fetches all linked data set keys from a linking set, fetches the single @@ -238,7 +194,7 @@ getSetRecords = ( set, fSingle, cb ) => # is used to preprocess the answer to determine correct execution fSingle reply, fCallback reply for reply in arrReply -# TODO remove specific functions and allow direct access to instances of this class + class IndexedModules constructor: ( @setname, @log ) -> @log.info "DB | (IdxedMods) Instantiated indexed modules for '#{ @setname }'" @@ -249,6 +205,7 @@ class IndexedModules ### Stores a module and links it to the user. + @private storeModule( *userId, oModule* ) @param {String} userId @param {object} oModule @@ -317,10 +274,9 @@ class IndexedModules replyHandler "srem '#{ mId }' from #{ @setname }s" @db.del "#{ @setname }:#{ mId }", replyHandler "del of '#{ @setname }:#{ mId }'" + @unpublish mId @db.smembers "#{ @setname }:#{ mId }:users", ( err, obj ) => - @unlinkModule mId, userId for userId in obj - #TODO check whether this unlink always fails! problems with db disconnect during testing... - #TODO remove published ids + @unlinkModule mId, userId for userId in obj # TODO remove from public modules # TODO remove parameters # @log.info "DB | linkModule(#{ @setname }): #{ mId } to #{ userId }" @@ -329,17 +285,26 @@ class IndexedModules # @db.sadd "user:#{ userId }:#{ @setname }s", mId, # replyHandler "Linking 'user:#{ userId }:#{ @setname }s' #{ mId }" - storeUserParams: ( mId, userId, data ) => - @log.info "DB | (IdxedMods) #{ @setname }.storeUserParams( #{ mId }, #{ userId }, data )" + ### + Stores user params for a module. They are expected to be RSA encrypted with helps of + the provided cryptico JS library and will only be decrypted right before the module is loaded! + + @private storeUserParams( *mId, userId, encData* ) + @param {String} mId + @param {String} userId + @param {object} encData + ### + storeUserParams: ( mId, userId, encData ) => + @log.info "DB | (IdxedMods) #{ @setname }.storeUserParams( #{ mId }, #{ userId }, encData )" @db.sadd "#{ @setname }-params", "#{ mId }:#{ userId }", replyHandler "sadd '#{ mId }:#{ userId }' to '#{ @setname }-params'" - @db.set "#{ @setname }-params:#{ mId }:#{ userId }", encrypt( data ), + @db.set "#{ @setname }-params:#{ mId }:#{ userId }", encData, replyHandler "set user params in '#{ @setname }-params:#{ mId }:#{ userId }'" getUserParams: ( mId, userId, cb ) => @log.info "DB | (IdxedMods) #{ @setname }.getUserParams( #{ mId }, #{ userId } )" @db.get "#{ @setname }-params:#{ mId }:#{ userId }", ( err, data ) -> - cb err, decrypt data + cb err, data getUserParamsIds: ( cb ) => @log.info "DB | (IdxedMods) #{ @setname }.getUserParamsIds()" @@ -565,8 +530,6 @@ The password should be hashed before it is passed to this function. @param {Object} objUser ### 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.info "DB | storeUser: '#{ objUser.username }'" if objUser and objUser.username and objUser.password @db.sadd 'users', objUser.username, diff --git a/coffee/webapi-eca.coffee b/coffee/webapi-eca.coffee index 3584474..0b9dde6 100644 --- a/coffee/webapi-eca.coffee +++ b/coffee/webapi-eca.coffee @@ -40,7 +40,7 @@ fs = require 'fs' path = require 'path' cp = require 'child_process' -# - External Module: [optimist](https://github.com/substack/node-optimist) +# - External Modules: [optimist](https://github.com/substack/node-optimist) optimist = require 'optimist' procCmds = {} @@ -93,34 +93,35 @@ if argv.help console.log optimist.help() process.exit() +conf argv.c +# > Check whether the config file is ready, which is required to start the server. +if !conf.isReady() + console.error 'FAIL: Config file not ready! Shutting down...' + process.exit() + +logconf = conf.getLogConf() + +if argv.m + logconf[ 'mode' ] = argv.m +if argv.i + logconf[ 'io-level' ] = argv.i +if argv.f + logconf[ 'file-level' ] = argv.f +if argv.p + logconf[ 'file-path' ] = argv.p +if argv.n + logconf[ 'nolog' ] = argv.n +try + fs.unlinkSync path.resolve __dirname, '..', 'logs', logconf[ 'file-path' ] +@log = logger.getLogger logconf +@log.info 'RS | STARTING SERVER' + ### This function is invoked right after the module is loaded and starts the server. @private init() ### init = => - conf argv.c - # > Check whether the config file is ready, which is required to start the server. - if !conf.isReady() - console.error 'FAIL: Config file not ready! Shutting down...' - process.exit() - - logconf = conf.getLogConf() - - if argv.m - logconf[ 'mode' ] = argv.m - if argv.i - logconf[ 'io-level' ] = argv.i - if argv.f - logconf[ 'file-level' ] = argv.f - if argv.p - logconf[ 'file-path' ] = argv.p - if argv.n - logconf[ 'nolog' ] = argv.n - try - fs.unlinkSync path.resolve __dirname, '..', 'logs', logconf[ 'file-path' ] - @log = logger.getLogger logconf - @log.info 'RS | STARTING SERVER' args = logger: @log diff --git a/config/system.json b/config/system.json index 473be0e..832d046 100644 --- a/config/system.json +++ b/config/system.json @@ -6,5 +6,6 @@ "io-level": "info", "file-level": "info", "file-path": "server.log" - } + }, + "keygen-passphrase": "[TODO this has to come from prompt when server is started!]" } \ No newline at end of file diff --git a/js-coffee/components-manager.js b/js-coffee/components-manager.js index 345554e..61d2217 100644 --- a/js-coffee/components-manager.js +++ b/js-coffee/components-manager.js @@ -1,4 +1,5 @@ -// Generated by CoffeeScript 1.6.3 +// Generated by CoffeeScript 1.7.1 + /* Components Manager @@ -6,12 +7,10 @@ Components Manager > The components manager takes care of the dynamic JS modules and the rules. > Event Poller and Action Invoker modules are loaded as strings and stored in the database, > then compiled into node modules and rules and used in the engine and event poller. -*/ - + */ (function() { - var commandFunctions, db, dynmod, events, exports, forgeModule, fs, getModuleParams, getModules, hasRequiredParams, path, vm, - _this = this; + var commandFunctions, db, dynmod, events, exports, forgeModule, fs, getModuleParams, getModules, hasRequiredParams, path, vm; db = require('./persistence'); @@ -25,22 +24,25 @@ Components Manager events = require('events'); + /* Module call ----------- Initializes the Components Manager and constructs a new Event Emitter. @param {Object} args - */ + */ + exports = module.exports = (function(_this) { + return function(args) { + _this.log = args.logger; + _this.ee = new events.EventEmitter(); + db(args); + dynmod(args); + return module.exports; + }; + })(this); - exports = module.exports = function(args) { - _this.log = args.logger; - _this.ee = new events.EventEmitter(); - db(args); - dynmod(args); - return module.exports; - }; /* Add an event handler (eh) for a certain event (evt). @@ -52,23 +54,25 @@ Components Manager @public addListener ( *evt, eh* ) @param {String} evt @param {function} eh - */ + */ + exports.addListener = (function(_this) { + return function(evt, eh) { + _this.ee.addListener(evt, eh); + if (evt === 'init') { + return db.getRules(function(err, obj) { + var id, rule, _results; + _results = []; + for (id in obj) { + rule = obj[id]; + _results.push(_this.ee.emit('init', rule)); + } + return _results; + }); + } + }; + })(this); - exports.addListener = function(evt, eh) { - _this.ee.addListener(evt, eh); - if (evt === 'init') { - return db.getRules(function(err, obj) { - var id, rule, _results; - _results = []; - for (id in obj) { - rule = obj[id]; - _results.push(_this.ee.emit('init', rule)); - } - return _results; - }); - } - }; /* Processes a user request coming through the request-handler. @@ -83,8 +87,7 @@ Components Manager @param {Object} user @param {Object} oReq @param {function} callback - */ - + */ exports.processRequest = function(user, oReq, callback) { var dat, err; @@ -129,8 +132,7 @@ Components Manager getModules = function(user, oPayload, dbMod, callback) { return dbMod.getAvailableModuleIds(user.username, function(err, arrNames) { - var answReq, fGetFunctions, id, oRes, sem, _i, _len, _results, - _this = this; + var answReq, fGetFunctions, id, oRes, sem, _i, _len, _results; oRes = {}; answReq = function() { return callback({ @@ -142,16 +144,18 @@ Components Manager if (sem === 0) { return answReq(); } else { - fGetFunctions = function(id) { - return dbMod.getModule(id, function(err, oModule) { - if (oModule) { - oRes[id] = JSON.parse(oModule.functions); - } - if (--sem === 0) { - return answReq(); - } - }); - }; + fGetFunctions = (function(_this) { + return function(id) { + return dbMod.getModule(id, function(err, oModule) { + if (oModule) { + oRes[id] = JSON.parse(oModule.functions); + } + if (--sem === 0) { + return answReq(); + } + }); + }; + })(this); _results = []; for (_i = 0, _len = arrNames.length; _i < _len; _i++) { id = arrNames[_i]; @@ -175,42 +179,43 @@ Components Manager } }; - forgeModule = function(user, oPayload, dbMod, callback) { - var answ, - _this = this; - answ = hasRequiredParams(['id', 'params', 'lang', 'data'], oPayload); - if (answ.code !== 200) { - return callback(answ); - } else { - return dbMod.getModule(oPayload.id, function(err, mod) { - var cm, funcs, id, name, src, _ref; - if (mod) { - answ.code = 409; - answ.message = 'Event Poller module name already existing: ' + oPayload.id; - } else { - src = oPayload.data; - cm = dynmod.compileString(src, oPayload.id, {}, oPayload.lang); - answ = cm.answ; - if (answ.code === 200) { - funcs = []; - _ref = cm.module; - for (name in _ref) { - id = _ref[name]; - funcs.push(name); - } - _this.log.info("CM | Storing new module with functions " + funcs); - answ.message = "Event Poller module successfully stored! Found following function(s): " + funcs; - oPayload.functions = JSON.stringify(funcs); - dbMod.storeModule(user.username, oPayload); - if (oPayload["public"] === 'true') { - dbMod.publish(oPayload.id); + forgeModule = (function(_this) { + return function(user, oPayload, dbMod, callback) { + var answ; + answ = hasRequiredParams(['id', 'params', 'lang', 'data'], oPayload); + if (answ.code !== 200) { + return callback(answ); + } else { + return dbMod.getModule(oPayload.id, function(err, mod) { + var cm, funcs, id, name, src, _ref; + if (mod) { + answ.code = 409; + answ.message = 'Event Poller module name already existing: ' + oPayload.id; + } else { + src = oPayload.data; + cm = dynmod.compileString(src, user.username, oPayload.id, {}, oPayload.lang); + answ = cm.answ; + if (answ.code === 200) { + funcs = []; + _ref = cm.module; + for (name in _ref) { + id = _ref[name]; + funcs.push(name); + } + _this.log.info("CM | Storing new module with functions " + (funcs.join())); + answ.message = "Event Poller module successfully stored! Found following function(s): " + funcs; + oPayload.functions = JSON.stringify(funcs); + dbMod.storeModule(user.username, oPayload); + if (oPayload["public"] === 'true') { + dbMod.publish(oPayload.id); + } } } - } - return callback(answ); - }); - } - }; + return callback(answ); + }); + } + }; + })(this); commandFunctions = { get_event_pollers: function(user, oPayload, callback) { @@ -234,48 +239,50 @@ Components Manager get_rules: function(user, oPayload, callback) { return console.log('CM | Implement get_rules'); }, - forge_rule: function(user, oPayload, callback) { - var answ; - answ = hasRequiredParams(['id', 'event', 'conditions', 'actions'], oPayload); - if (answ.code !== 200) { - return callback(answ); - } else { - return db.getRule(oPayload.id, function(err, oExisting) { - var arrParams, id, params, rule, strRule; - if (oExisting !== null) { - answ = { - code: 409, - message: 'Rule name already existing!' - }; - } else { - rule = { - id: oPayload.id, - event: oPayload.event, - conditions: oPayload.conditions, - actions: oPayload.actions - }; - strRule = JSON.stringify(rule); - db.storeRule(rule.id, strRule); - db.linkRule(rule.id, user.username); - db.activateRule(rule.id, user.username); - if (oPayload.event_params) { - db.eventPollers.storeUserParams(ep.module, user.username, oPayload.event_params); - } - arrParams = oPayload.action_params; - for (id in arrParams) { - params = arrParams[id]; - db.actionInvokers.storeUserParams(id, user.username, JSON.stringify(params)); - } - _this.ee.emit('newRule', strRule); - answ = { - code: 200, - message: 'Rule stored and activated!' - }; - } + forge_rule: (function(_this) { + return function(user, oPayload, callback) { + var answ; + answ = hasRequiredParams(['id', 'event', 'conditions', 'actions'], oPayload); + if (answ.code !== 200) { return callback(answ); - }); - } - } + } else { + return db.getRule(oPayload.id, function(err, oExisting) { + var arrParams, id, params, rule, strRule; + if (oExisting !== null) { + answ = { + code: 409, + message: 'Rule name already existing!' + }; + } else { + rule = { + id: oPayload.id, + event: oPayload.event, + conditions: oPayload.conditions, + actions: oPayload.actions + }; + strRule = JSON.stringify(rule); + db.storeRule(rule.id, strRule); + db.linkRule(rule.id, user.username); + db.activateRule(rule.id, user.username); + if (oPayload.event_params) { + db.eventPollers.storeUserParams(ep.module, user.username, oPayload.event_params); + } + arrParams = oPayload.action_params; + for (id in arrParams) { + params = arrParams[id]; + db.actionInvokers.storeUserParams(id, user.username, JSON.stringify(params)); + } + _this.ee.emit('newRule', strRule); + answ = { + code: 200, + message: 'Rule stored and activated!' + }; + } + return callback(answ); + }); + } + }; + })(this) }; }).call(this); diff --git a/js-coffee/config.js b/js-coffee/config.js index 8777084..e984a2e 100644 --- a/js-coffee/config.js +++ b/js-coffee/config.js @@ -1,20 +1,20 @@ -// Generated by CoffeeScript 1.6.3 +// Generated by CoffeeScript 1.7.1 + /* Configuration ============= > Loads the configuration file and acts as an interface to it. -*/ - + */ (function() { - var exports, fetchProp, fs, loadConfigFile, path, - _this = this; + var exports, fetchProp, fs, loadConfigFile, path; fs = require('fs'); path = require('path'); + /* Module call ----------- @@ -24,21 +24,23 @@ Configuration be generated) and configPath for a custom configuration file path. @param {Object} args - */ + */ + exports = module.exports = (function(_this) { + return function(args) { + args = args != null ? args : {}; + if (args.nolog) { + _this.nolog = true; + } + if (args.configPath) { + loadConfigFile(args.configPath); + } else { + loadConfigFile(path.join('config', 'system.json')); + } + return module.exports; + }; + })(this); - exports = module.exports = function(args) { - args = args != null ? args : {}; - if (args.nolog) { - _this.nolog = true; - } - if (args.configPath) { - loadConfigFile(args.configPath); - } else { - loadConfigFile(path.join('config', 'system.json')); - } - return module.exports; - }; /* Tries to load a configuration file from the path relative to this module's parent folder. @@ -46,100 +48,105 @@ Configuration @private loadConfigFile @param {String} configPath - */ + */ - - loadConfigFile = function(configPath) { - var confProperties, e, prop, _i, _len; - _this.config = null; - confProperties = ['log', 'http-port', 'db-port']; - try { - _this.config = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', configPath))); - _this.isReady = true; - for (_i = 0, _len = confProperties.length; _i < _len; _i++) { - prop = confProperties[_i]; - if (!_this.config[prop]) { - _this.isReady = false; + loadConfigFile = (function(_this) { + return function(configPath) { + var confProperties, e, prop, _i, _len; + _this.config = null; + confProperties = ['log', 'http-port', 'db-port']; + try { + _this.config = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', configPath))); + _this.isReady = true; + for (_i = 0, _len = confProperties.length; _i < _len; _i++) { + prop = confProperties[_i]; + if (!_this.config[prop]) { + _this.isReady = false; + } + } + if (!_this.isReady && !_this.nolog) { + return console.error("Missing property in config file, requires:\n" + (" - " + (confProperties.join("\n - ")))); + } + } catch (_error) { + e = _error; + _this.isReady = false; + if (!_this.nolog) { + return console.error("Failed loading config file: " + e.message); } } - if (!_this.isReady && !_this.nolog) { - return console.error("Missing property in config file, requires:\n" + (" - " + (confProperties.join("\n - ")))); - } - } catch (_error) { - e = _error; - _this.isReady = false; - if (!_this.nolog) { - return console.error("Failed loading config file: " + e.message); - } - } - }; + }; + })(this); + /* Fetch a property from the configuration @private fetchProp( *prop* ) @param {String} prop - */ + */ + fetchProp = (function(_this) { + return function(prop) { + var _ref; + return (_ref = _this.config) != null ? _ref[prop] : void 0; + }; + })(this); - fetchProp = function(prop) { - var _ref; - return (_ref = _this.config) != null ? _ref[prop] : void 0; - }; /* ***Returns*** true if the config file is ready, else false @public isReady() - */ + */ + exports.isReady = (function(_this) { + return function() { + return _this.isReady; + }; + })(this); - exports.isReady = function() { - return _this.isReady; - }; /* ***Returns*** the HTTP port @public getHttpPort() - */ - + */ exports.getHttpPort = function() { return fetchProp('http-port'); }; + /* ***Returns*** the DB port* @public getDBPort() - */ - + */ exports.getDbPort = function() { return fetchProp('db-port'); }; + /* ***Returns*** the log conf object @public getLogConf() - */ - + */ exports.getLogConf = function() { return fetchProp('log'); }; + /* ***Returns*** the crypto key @public getCryptoKey() - */ + */ - - exports.getCryptoKey = function() { - return fetchProp('crypto-key'); + exports.getKeygenPassphrase = function() { + return fetchProp('keygen-passphrase'); }; }).call(this); diff --git a/js-coffee/dynamic-modules.js b/js-coffee/dynamic-modules.js index 41d2988..b2fbfbf 100644 --- a/js-coffee/dynamic-modules.js +++ b/js-coffee/dynamic-modules.js @@ -1,16 +1,15 @@ -// Generated by CoffeeScript 1.6.3 +// Generated by CoffeeScript 1.7.1 + /* Dynamic Modules =============== > Compiles CoffeeScript modules and loads JS modules in a VM, together > with only a few allowed node.js modules. -*/ - + */ (function() { - var cs, exports, needle, vm, - _this = this; + var cs, exports, needle, vm; vm = require('vm'); @@ -18,19 +17,22 @@ Dynamic Modules cs = require('coffee-script'); + /* Module call ----------- Initializes the dynamic module handler. @param {Object} args - */ + */ + exports = module.exports = (function(_this) { + return function(args) { + _this.log = args.logger; + return module.exports; + }; + })(this); - exports = module.exports = function(args) { - _this.log = args.logger; - return module.exports; - }; /* Try to run a JS module from a string, together with the @@ -42,43 +44,44 @@ Dynamic Modules @param {String} id @param {Object} params @param {String} lang - */ + */ - - exports.compileString = function(src, id, params, lang) { - var answ, err, ret, sandbox; - answ = { - code: 200, - message: 'Successfully compiled' - }; - if (lang === '0') { + exports.compileString = (function(_this) { + return function(src, userId, moduleId, params, lang) { + var answ, err, ret, sandbox; + answ = { + code: 200, + message: 'Successfully compiled' + }; + if (lang === '0') { + try { + src = cs.compile(src); + } catch (_error) { + err = _error; + answ.code = 400; + answ.message = 'Compilation of CoffeeScript failed at line ' + err.location.first_line; + } + } + sandbox = { + id: userId + '.' + moduleId + '.vm', + params: params, + needle: needle, + log: console.log, + exports: {} + }; try { - src = cs.compile(src); + vm.runInNewContext(src, sandbox, sandbox.id); } catch (_error) { err = _error; answ.code = 400; - answ.message = 'Compilation of CoffeeScript failed at line ' + err.location.first_line; + answ.message = 'Loading Module failed: ' + err.message; } - } - sandbox = { - id: id, - params: params, - needle: needle, - log: console.log, - exports: {} + ret = { + answ: answ, + module: sandbox.exports + }; + return ret; }; - try { - vm.runInNewContext(src, sandbox, id + '.vm'); - } catch (_error) { - err = _error; - answ.code = 400; - answ.message = 'Loading Module failed: ' + err.message; - } - ret = { - answ: answ, - module: sandbox.exports - }; - return ret; - }; + })(this); }).call(this); diff --git a/js-coffee/http-listener.js b/js-coffee/http-listener.js index ba133cc..aa686b2 100644 --- a/js-coffee/http-listener.js +++ b/js-coffee/http-listener.js @@ -1,4 +1,5 @@ -// Generated by CoffeeScript 1.6.3 +// Generated by CoffeeScript 1.7.1 + /* HTTP Listener @@ -6,12 +7,10 @@ HTTP Listener > Receives the HTTP requests to the server at the given port. The requests > (bound to a method) are then redirected to the appropriate handler which > takes care of the request. -*/ - + */ (function() { - var app, exports, express, initRouting, path, qs, requestHandler, - _this = this; + var app, exports, express, initRouting, path, qs, requestHandler; requestHandler = require('./request-handler'); @@ -23,73 +22,77 @@ HTTP Listener app = express(); + /* Module call ----------- Initializes the HTTP listener and its request handler. @param {Object} args - */ + */ + exports = module.exports = (function(_this) { + return function(args) { + _this.log = args.logger; + _this.shutDownSystem = args['shutdown-function']; + requestHandler(args); + initRouting(args['http-port']); + return module.exports; + }; + })(this); - exports = module.exports = function(args) { - _this.log = args.logger; - _this.shutDownSystem = args['shutdown-function']; - requestHandler(args); - initRouting(args['http-port']); - return module.exports; - }; /* Initializes the request routing and starts listening on the given port. @param {int} port @private initRouting( *fShutDown* ) - */ + */ + initRouting = (function(_this) { + return function(port) { + var server, sess_sec; + app.use(express.cookieParser()); + sess_sec = "149u*y8C:@kmN/520Gt\\v'+KFBnQ!\\r<>5X/xRI`sT Handles the connection to the database and provides functionalities for -> event pollers, action invokers, rules and the encrypted storing of authentication tokens. +> Handles the connection to the database and provides functionalities for event pollers, +> action invokers, rules and the (hopefully encrypted) storing of user-specific parameters +> per module. > General functionality as a wrapper for the module holds initialization, -> encryption/decryption, the retrieval of modules and shut down. +> 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 @@ -17,19 +19,14 @@ Persistence > 'action-invokers' and then stored in the db with the key 'action-invoker:' + ID > (e.g. action-invoker:probinder). > -*/ - + */ (function() { - var IndexedModules, crypto, crypto_key, decrypt, encrypt, exports, getSetRecords, hash, redis, replyHandler, - _this = this, + var IndexedModules, exports, getSetRecords, redis, replyHandler, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - crypto = require('crypto-js'); - redis = require('redis'); - crypto_key = "}f6y1y}B{.an$}2c$Yl.$mSnF\\HX149u*y8C:@kmN/520Gt\\v'+KFBnQ!\\r<>5X/xRI`sT -1) { - _this.connRefused = true; - return _this.log.error(err, 'DB | Wrong port?'); + exports.initPort = (function(_this) { + return function(port) { + var _ref; + _this.connRefused = false; + if ((_ref = _this.db) != null) { + _ref.quit(); } - }); - exports.eventPollers.setDB(_this.db); - return exports.actionInvokers.setDB(_this.db); - }; + _this.db = redis.createClient(port, 'localhost', { + connect_timeout: 2000 + }); + _this.db.on('error', function(err) { + if (err.message.indexOf('ECONNREFUSED') > -1) { + _this.connRefused = true; + return _this.log.error(err, 'DB | Wrong port?'); + } + }); + exports.eventPollers.setDB(_this.db); + return exports.actionInvokers.setDB(_this.db); + }; + })(this); + /* Checks whether the db is connected and passes either an error on failure after @@ -77,173 +78,114 @@ Persistence @public isConnected( *cb* ) @param {function} cb - */ + */ - - exports.isConnected = function(cb) { - var fCheckConnection, numAttempts; - if (!_this.db) { - return cb(new Error('DB | DB initialization did not occur or failed miserably!')); - } else { - if (_this.db.connected) { - return cb(); + exports.isConnected = (function(_this) { + return function(cb) { + var fCheckConnection, numAttempts; + if (!_this.db) { + return cb(new Error('DB | DB initialization did not occur or failed miserably!')); } else { - numAttempts = 0; - fCheckConnection = function() { - var _ref; - if (_this.connRefused) { - if ((_ref = _this.db) != null) { - _ref.quit(); - } - return cb(new Error('DB | Connection refused! Wrong port?')); - } else { - if (_this.db.connected) { - _this.log.info('DB | Successfully connected to DB!'); - return cb(); - } else if (numAttempts++ < 10) { - return setTimeout(fCheckConnection, 100); + if (_this.db.connected) { + return cb(); + } else { + numAttempts = 0; + fCheckConnection = function() { + var _ref; + if (_this.connRefused) { + if ((_ref = _this.db) != null) { + _ref.quit(); + } + return cb(new Error('DB | Connection refused! Wrong port?')); } else { - return cb(new Error('DB | Connection to DB failed!')); + if (_this.db.connected) { + _this.log.info('DB | Successfully connected to DB!'); + return cb(); + } else if (numAttempts++ < 10) { + return setTimeout(fCheckConnection, 100); + } else { + return cb(new Error('DB | Connection to DB failed!')); + } } - } - }; - return setTimeout(fCheckConnection, 100); + }; + return setTimeout(fCheckConnection, 100); + } } - } - }; + }; + })(this); + /* Abstracts logging for simple action replies from the DB. @private replyHandler( *action* ) @param {String} action - */ + */ - - replyHandler = function(action) { - return function(err, reply) { - if (err) { - return _this.log.warn(err, "during '" + action + "'"); - } else { - return _this.log.info("DB | " + action + ": " + reply); - } + replyHandler = (function(_this) { + return function(action) { + return function(err, reply) { + if (err) { + return _this.log.warn(err, "during '" + action + "'"); + } else { + return _this.log.info("DB | " + action + ": " + reply); + } + }; }; - }; + })(this); + /* Push an event into the event queue. @public pushEvent( *oEvent* ) @param {Object} oEvent - */ + */ + exports.pushEvent = (function(_this) { + return function(oEvent) { + if (oEvent) { + _this.log.info("DB | Event pushed into the queue: '" + oEvent.eventid + "'"); + return _this.db.rpush('event_queue', JSON.stringify(oEvent)); + } else { + return _this.log.warn('DB | Why would you give me an empty event...'); + } + }; + })(this); - exports.pushEvent = function(oEvent) { - if (oEvent) { - _this.log.info("DB | Event pushed into the queue: '" + oEvent.eventid + "'"); - return _this.db.rpush('event_queue', JSON.stringify(oEvent)); - } else { - return _this.log.warn('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)); + exports.popEvent = (function(_this) { + return 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)); }; - return _this.db.lpop('event_queue', makeObj(cb)); - }; + })(this); + /* Purge the event queue. @public purgeEventQueue() - */ + */ + exports.purgeEventQueue = (function(_this) { + return function() { + return _this.db.del('event_queue', replyHandler('purging event queue')); + }; + })(this); - 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; - _this.log.warn(err, 'DB | during hashing'); - 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, crypto_key); - } catch (_error) { - err = _error; - _this.log.warn(err, 'DB | during encryption'); - 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, crypto_key); - return dec.toString(crypto.enc.Utf8); - } catch (_error) { - err = _error; - _this.log.warn(err, 'DB | during decryption'); - return null; - } - }; /* Fetches all linked data set keys from a linking set, fetches the single @@ -255,50 +197,51 @@ Persistence 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) { - _this.log.info("DB | Fetching set records: '" + set + "'"); - return _this.db.smembers(set, function(err, arrReply) { - var fCallback, objReplies, reply, semaphore, _i, _len, _results; - if (err) { - _this.log.warn(err, "DB | fetching '" + set + "'"); - 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) { - _this.log.warn(err, "DB | fetching single element: '" + prop + "'"); - } else if (!data) { - _this.log.warn(new Error("Empty key in DB: '" + prop + "'")); - } else { - objReplies[prop] = data; - } - if (semaphore === 0) { - return cb(null, objReplies); + getSetRecords = (function(_this) { + return function(set, fSingle, cb) { + _this.log.info("DB | Fetching set records: '" + set + "'"); + return _this.db.smembers(set, function(err, arrReply) { + var fCallback, objReplies, reply, semaphore, _i, _len, _results; + if (err) { + _this.log.warn(err, "DB | fetching '" + set + "'"); + 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) { + _this.log.warn(err, "DB | fetching single element: '" + prop + "'"); + } else if (!data) { + _this.log.warn(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))); + _results = []; + for (_i = 0, _len = arrReply.length; _i < _len; _i++) { + reply = arrReply[_i]; + _results.push(fSingle(reply, fCallback(reply))); + } + return _results; } - return _results; - } - }); - }; + }); + }; + })(this); IndexedModules = (function() { function IndexedModules(setname, log) { @@ -327,13 +270,14 @@ Persistence return this.log.info("DB | (IdxedMods) Registered new DB connection for '" + this.setname + "'"); }; + /* Stores a module and links it to the user. + @private storeModule( *userId, oModule* ) @param {String} userId @param {object} oModule - */ - + */ IndexedModules.prototype.storeModule = function(userId, oModule) { this.log.info("DB | (IdxedMods) " + this.setname + ".storeModule( " + userId + ", oModule )"); @@ -390,31 +334,44 @@ Persistence }; IndexedModules.prototype.deleteModule = function(mId) { - var _this = this; this.log.info("DB | (IdxedMods) " + this.setname + ".deleteModule( " + mId + " )"); this.db.srem("" + this.setname + "s", mId, replyHandler("srem '" + mId + "' from " + this.setname + "s")); this.db.del("" + this.setname + ":" + mId, replyHandler("del of '" + this.setname + ":" + mId + "'")); - return this.db.smembers("" + this.setname + ":" + mId + ":users", function(err, obj) { - var userId, _i, _len, _results; - _results = []; - for (_i = 0, _len = obj.length; _i < _len; _i++) { - userId = obj[_i]; - _results.push(_this.unlinkModule(mId, userId)); - } - return _results; - }); + this.unpublish(mId); + return this.db.smembers("" + this.setname + ":" + mId + ":users", (function(_this) { + return function(err, obj) { + var userId, _i, _len, _results; + _results = []; + for (_i = 0, _len = obj.length; _i < _len; _i++) { + userId = obj[_i]; + _results.push(_this.unlinkModule(mId, userId)); + } + return _results; + }; + })(this)); }; - IndexedModules.prototype.storeUserParams = function(mId, userId, data) { - this.log.info("DB | (IdxedMods) " + this.setname + ".storeUserParams( " + mId + ", " + userId + ", data )"); + + /* + Stores user params for a module. They are expected to be RSA encrypted with helps of + the provided cryptico JS library and will only be decrypted right before the module is loaded! + + @private storeUserParams( *mId, userId, encData* ) + @param {String} mId + @param {String} userId + @param {object} encData + */ + + IndexedModules.prototype.storeUserParams = function(mId, userId, encData) { + this.log.info("DB | (IdxedMods) " + this.setname + ".storeUserParams( " + mId + ", " + userId + ", encData )"); this.db.sadd("" + this.setname + "-params", "" + mId + ":" + userId, replyHandler("sadd '" + mId + ":" + userId + "' to '" + this.setname + "-params'")); - return this.db.set("" + this.setname + "-params:" + mId + ":" + userId, encrypt(data), replyHandler("set user params in '" + this.setname + "-params:" + mId + ":" + userId + "'")); + return this.db.set("" + this.setname + "-params:" + mId + ":" + userId, encData, replyHandler("set user params in '" + this.setname + "-params:" + mId + ":" + userId + "'")); }; IndexedModules.prototype.getUserParams = function(mId, userId, cb) { this.log.info("DB | (IdxedMods) " + this.setname + ".getUserParams( " + mId + ", " + userId + " )"); return this.db.get("" + this.setname + "-params:" + mId + ":" + userId, function(err, data) { - return cb(err, decrypt(data)); + return cb(err, data); }); }; @@ -433,9 +390,10 @@ Persistence })(); + /* - ## Rules - */ + *# Rules + */ /* @@ -444,39 +402,45 @@ Persistence @public getRule( *ruleId, cb* ) @param {String} ruleId @param {function} cb - */ + */ + exports.getRule = (function(_this) { + return function(ruleId, cb) { + _this.log.info("DB | getRule: '" + ruleId + "'"); + return _this.db.get("rule:" + ruleId, cb); + }; + })(this); - exports.getRule = function(ruleId, cb) { - _this.log.info("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(_this) { + return function(cb) { + _this.log.info('DB | Fetching all Rules'); + return getSetRecords('rules', exports.getRule, cb); + }; + })(this); - exports.getRules = function(cb) { - _this.log.info('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(_this) { + return function(cb) { + _this.log.info('DB | Fetching all Rule IDs'); + return _this.db.smembers('rules', cb); + }; + })(this); - exports.getRuleIds = function(cb) { - _this.log.info('DB | Fetching all Rule IDs'); - return _this.db.smembers('rules', cb); - }; /* Store a string representation of a rule in the DB. @@ -484,14 +448,16 @@ Persistence @public storeRule( *ruleId, data* ) @param {String} ruleId @param {String} data - */ + */ + exports.storeRule = (function(_this) { + return function(ruleId, data) { + _this.log.info("DB | storeRule: '" + ruleId + "'"); + _this.db.sadd('rules', "" + ruleId, replyHandler("storing rule key '" + ruleId + "'")); + return _this.db.set("rule:" + ruleId, data, replyHandler("storing rule '" + ruleId + "'")); + }; + })(this); - exports.storeRule = function(ruleId, data) { - _this.log.info("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. @@ -499,40 +465,42 @@ Persistence @public deleteRule( *ruleId, userId* ) @param {String} ruleId @param {String} userId - */ + */ + exports.deleteRule = (function(_this) { + return function(ruleId) { + _this.log.info("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")); + }; + })(this); - exports.deleteRule = function(ruleId) { - _this.log.info("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. @@ -540,14 +508,16 @@ Persistence @public linkRule( *ruleId, userId* ) @param {String} ruleId @param {String} userId - */ + */ + exports.linkRule = (function(_this) { + return function(ruleId, userId) { + _this.log.info("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 + "'")); + }; + })(this); - exports.linkRule = function(ruleId, userId) { - _this.log.info("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). @@ -555,13 +525,15 @@ Persistence @public getUserLinkRule( *userId, cb* ) @param {String} userId @param {function} cb - */ + */ + exports.getUserLinkedRules = (function(_this) { + return function(userId, cb) { + _this.log.info("DB | getUserLinkedRules: for user '" + userId + "'"); + return _this.db.smembers("user:" + userId + ":rules", cb); + }; + })(this); - exports.getUserLinkedRules = function(userId, cb) { - _this.log.info("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). @@ -569,13 +541,15 @@ Persistence @public getRuleLinkedUsers( *ruleId, cb* ) @param {String} ruleId @param {function} cb - */ + */ + exports.getRuleLinkedUsers = (function(_this) { + return function(ruleId, cb) { + _this.log.info("DB | getRuleLinkedUsers: for rule '" + ruleId + "'"); + return _this.db.smembers("rule:" + ruleId + ":users", cb); + }; + })(this); - exports.getRuleLinkedUsers = function(ruleId, cb) { - _this.log.info("DB | getRuleLinkedUsers: for rule '" + ruleId + "'"); - return _this.db.smembers("rule:" + ruleId + ":users", cb); - }; /* Delete an association of a rule to a user. @@ -583,14 +557,16 @@ Persistence @public unlinkRule( *ruleId, userId* ) @param {String} ruleId @param {String} userId - */ + */ + exports.unlinkRule = (function(_this) { + return function(ruleId, userId) { + _this.log.info("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 + "'")); + }; + })(this); - exports.unlinkRule = function(ruleId, userId) { - _this.log.info("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. @@ -598,14 +574,16 @@ Persistence @public activateRule( *ruleId, userId* ) @param {String} ruleId @param {String} userId - */ + */ + exports.activateRule = (function(_this) { + return function(ruleId, userId) { + _this.log.info("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 + "'")); + }; + })(this); - exports.activateRule = function(ruleId, userId) { - _this.log.info("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). @@ -613,13 +591,15 @@ Persistence @public getUserLinkRule( *userId, cb* ) @param {String} userId @param {function} cb - */ + */ + exports.getUserActivatedRules = (function(_this) { + return function(userId, cb) { + _this.log.info("DB | getUserActivatedRules: for user '" + userId + "'"); + return _this.db.smembers("user:" + userId + ":active-rules", cb); + }; + })(this); - exports.getUserActivatedRules = function(userId, cb) { - _this.log.info("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). @@ -627,13 +607,15 @@ Persistence @public getRuleActivatedUsers ( *ruleId, cb* ) @param {String} ruleId @param {function} cb - */ + */ + exports.getRuleActivatedUsers = (function(_this) { + return function(ruleId, cb) { + _this.log.info("DB | getRuleActivatedUsers: for rule '" + ruleId + "'"); + return _this.db.smembers("rule:" + ruleId + ":active-users", cb); + }; + })(this); - exports.getRuleActivatedUsers = function(ruleId, cb) { - _this.log.info("DB | getRuleActivatedUsers: for rule '" + ruleId + "'"); - return _this.db.smembers("rule:" + ruleId + ":active-users", cb); - }; /* Deactivate a rule. @@ -641,55 +623,59 @@ Persistence @public deactivateRule( *ruleId, userId* ) @param {String} ruleId @param {String} userId - */ + */ + exports.deactivateRule = (function(_this) { + return function(ruleId, userId) { + _this.log.info("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 + "'")); + }; + })(this); - exports.deactivateRule = function(ruleId, userId) { - _this.log.info("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) { - _this.log.info("DB | Fetching all active rules"); - return _this.db.smembers('users', function(err, obj) { - var fFetchActiveUserRules, result, semaphore, user, _i, _len, _results; - result = {}; - if (obj.length === 0) { - return cb(null, result); - } else { - semaphore = obj.length; - fFetchActiveUserRules = function(userId) { - return _this.db.smembers("user:" + user + ":active-rules", function(err, obj) { - if (obj.length > 0) { - 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)); + exports.getAllActivatedRuleIdsPerUser = (function(_this) { + return function(cb) { + _this.log.info("DB | Fetching all active rules"); + return _this.db.smembers('users', function(err, obj) { + var fFetchActiveUserRules, result, semaphore, user, _i, _len, _results; + result = {}; + if (obj.length === 0) { + return cb(null, result); + } else { + semaphore = obj.length; + fFetchActiveUserRules = function(userId) { + return _this.db.smembers("user:" + user + ":active-rules", function(err, obj) { + if (obj.length > 0) { + 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; } - return _results; - } - }); - }; + }); + }; + })(this); + /* - ## Users - */ + *# Users + */ /* @@ -698,32 +684,36 @@ Persistence @public storeUser( *objUser* ) @param {Object} objUser - */ + */ + exports.storeUser = (function(_this) { + return function(objUser) { + _this.log.info("DB | storeUser: '" + objUser.username + "'"); + if (objUser && objUser.username && objUser.password) { + _this.db.sadd('users', objUser.username, replyHandler("storing user key '" + objUser.username + "'")); + objUser.password = objUser.password; + return _this.db.hmset("user:" + objUser.username, objUser, replyHandler("storing user properties '" + objUser.username + "'")); + } else { + return _this.log.warn(new Error('DB | username or password was missing')); + } + }; + })(this); - exports.storeUser = function(objUser) { - _this.log.info("DB | storeUser: '" + objUser.username + "'"); - if (objUser && objUser.username && objUser.password) { - _this.db.sadd('users', objUser.username, replyHandler("storing user key '" + objUser.username + "'")); - objUser.password = objUser.password; - return _this.db.hmset("user:" + objUser.username, objUser, replyHandler("storing user properties '" + objUser.username + "'")); - } else { - return _this.log.warn(new Error('DB | username or password was missing')); - } - }; /* Fetch all user IDs and pass them to cb(err, obj). @public getUserIds( *cb* ) @param {function} cb - */ + */ + exports.getUserIds = (function(_this) { + return function(cb) { + _this.log.info("DB | getUserIds"); + return _this.db.smembers("users", cb); + }; + })(this); - exports.getUserIds = function(cb) { - _this.log.info("DB | getUserIds"); - return _this.db.smembers("users", cb); - }; /* Fetch a user by id and pass it to cb(err, obj). @@ -731,66 +721,70 @@ Persistence @public getUser( *userId, cb* ) @param {String} userId @param {function} cb - */ + */ + exports.getUser = (function(_this) { + return function(userId, cb) { + _this.log.info("DB | getUser: '" + userId + "'"); + return _this.db.hgetall("user:" + userId, cb); + }; + })(this); - exports.getUser = function(userId, cb) { - _this.log.info("DB | getUser: '" + userId + "'"); - return _this.db.hgetall("user:" + userId, cb); - }; /* Deletes a user and all his associated linked and active rules. @public deleteUser( *userId* ) @param {String} userId - */ + */ + exports.deleteUser = (function(_this) { + return function(userId) { + _this.log.info("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 + ":active-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; + }); + _this.db.del("user:" + userId + ":active-rules", replyHandler("Deleting user '" + userId + "' rules")); + _this.db.smembers("user:" + userId + ":roles", function(err, obj) { + var delRoleUser, id, _i, _len, _results; + delRoleUser = function(roleId) { + return _this.db.srem("role:" + roleId + ":users", userId, replyHandler("Deleting user key '" + userId + "' in role '" + roleId + "'")); + }; + _results = []; + for (_i = 0, _len = obj.length; _i < _len; _i++) { + id = obj[_i]; + _results.push(delRoleUser(id)); + } + return _results; + }); + return _this.db.del("user:" + userId + ":roles", replyHandler("Deleting user '" + userId + "' roles")); + }; + })(this); - exports.deleteUser = function(userId) { - _this.log.info("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 + ":active-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; - }); - _this.db.del("user:" + userId + ":active-rules", replyHandler("Deleting user '" + userId + "' rules")); - _this.db.smembers("user:" + userId + ":roles", function(err, obj) { - var delRoleUser, id, _i, _len, _results; - delRoleUser = function(roleId) { - return _this.db.srem("role:" + roleId + ":users", userId, replyHandler("Deleting user key '" + userId + "' in role '" + roleId + "'")); - }; - _results = []; - for (_i = 0, _len = obj.length; _i < _len; _i++) { - id = obj[_i]; - _results.push(delRoleUser(id)); - } - return _results; - }); - return _this.db.del("user:" + userId + ":roles", replyHandler("Deleting user '" + userId + "' roles")); - }; /* Checks the credentials and on success returns the user object to the @@ -802,34 +796,36 @@ Persistence @param {String} userId @param {String} password @param {function} cb - */ + */ - - exports.loginUser = function(userId, password, cb) { - var fCheck; - _this.log.info("DB | User '" + userId + "' tries to log in"); - fCheck = function(pw) { - return function(err, obj) { - if (err) { - return cb(err, null); - } else if (obj && obj.password) { - if (pw === obj.password) { - _this.log.info("DB | User '" + obj.username + "' logged in!"); - return cb(null, obj); + exports.loginUser = (function(_this) { + return function(userId, password, cb) { + var fCheck; + _this.log.info("DB | User '" + userId + "' tries to log in"); + fCheck = function(pw) { + return function(err, obj) { + if (err) { + return cb(err, null); + } else if (obj && obj.password) { + if (pw === obj.password) { + _this.log.info("DB | User '" + obj.username + "' logged in!"); + return cb(null, obj); + } else { + return cb(new Error('Wrong credentials!'), null); + } } else { - return cb(new Error('Wrong credentials!'), null); + return cb(new Error('User not found!'), null); } - } else { - return cb(new Error('User not found!'), null); - } + }; }; + return _this.db.hgetall("user:" + userId, fCheck(password)); }; - return _this.db.hgetall("user:" + userId, fCheck(password)); - }; + })(this); + /* - ## User Roles - */ + *# User Roles + */ /* @@ -838,15 +834,17 @@ Persistence @public storeUserRole( *userId, role* ) @param {String} userId @param {String} role - */ + */ + exports.storeUserRole = (function(_this) { + return function(userId, role) { + _this.log.info("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 + "'")); + }; + })(this); - exports.storeUserRole = function(userId, role) { - _this.log.info("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). @@ -854,13 +852,15 @@ Persistence @public getUserRoles( *userId* ) @param {String} userId @param {function} cb - */ + */ + exports.getUserRoles = (function(_this) { + return function(userId, cb) { + _this.log.info("DB | getUserRoles: '" + userId + "'"); + return _this.db.smembers("user:" + userId + ":roles", cb); + }; + })(this); - exports.getUserRoles = function(userId, cb) { - _this.log.info("DB | getUserRoles: '" + userId + "'"); - return _this.db.smembers("user:" + userId + ":roles", cb); - }; /* Fetch all users of a role and pass them to cb(err, obj). @@ -868,13 +868,15 @@ Persistence @public getUserRoles( *role* ) @param {String} role @param {function} cb - */ + */ + exports.getRoleUsers = (function(_this) { + return function(role, cb) { + _this.log.info("DB | getRoleUsers: '" + role + "'"); + return _this.db.smembers("role:" + role + ":users", cb); + }; + })(this); - exports.getRoleUsers = function(role, cb) { - _this.log.info("DB | getRoleUsers: '" + role + "'"); - return _this.db.smembers("role:" + role + ":users", cb); - }; /* Remove a role from a user. @@ -882,25 +884,28 @@ Persistence @public removeRoleFromUser( *role, userId* ) @param {String} role @param {String} userId - */ + */ + exports.removeUserRole = (function(_this) { + return function(userId, role) { + _this.log.info("DB | removeRoleFromUser: role '" + role + "', user '" + userId + "'"); + _this.db.srem("user:" + userId + ":roles", role, replyHandler("Removing role '" + role + "' from user '" + userId + "'")); + return _this.db.srem("role:" + role + ":users", userId, replyHandler("Removing user '" + userId + "' from role '" + role + "'")); + }; + })(this); - exports.removeUserRole = function(userId, role) { - _this.log.info("DB | removeRoleFromUser: role '" + role + "', user '" + userId + "'"); - _this.db.srem("user:" + userId + ":roles", role, replyHandler("Removing role '" + role + "' from user '" + userId + "'")); - return _this.db.srem("role:" + role + ":users", userId, replyHandler("Removing user '" + userId + "' from role '" + role + "'")); - }; /* Shuts down the db link. @public shutDown() - */ + */ - - exports.shutDown = function() { - var _ref; - return (_ref = _this.db) != null ? _ref.quit() : void 0; - }; + exports.shutDown = (function(_this) { + return function() { + var _ref; + return (_ref = _this.db) != null ? _ref.quit() : void 0; + }; + })(this); }).call(this); diff --git a/js-coffee/request-handler.js b/js-coffee/request-handler.js index 88a95de..212cdc0 100644 --- a/js-coffee/request-handler.js +++ b/js-coffee/request-handler.js @@ -1,4 +1,5 @@ -// Generated by CoffeeScript 1.6.3 +// Generated by CoffeeScript 1.7.1 + /* Request Handler @@ -7,12 +8,10 @@ Request Handler > the [HTTP Listener](http-listener.html). It will handle user requests for > pages as well as POST requests such as user login, module storing, event > invocation and also admin commands. -*/ - + */ (function() { - var crypto, db, dirHandlers, exports, fs, getHandlerPath, getRemoteScripts, getScript, getTemplate, mustache, path, qs, renderPage, - _this = this; + var crypto, db, dirHandlers, exports, fs, getHandlerPath, getRemoteScripts, getScript, getTemplate, mustache, path, qs, renderPage; db = require('./persistence'); @@ -28,32 +27,35 @@ Request Handler dirHandlers = path.resolve(__dirname, '..', 'webpages', 'handlers'); - exports = module.exports = function(args) { - var fStoreUser, user, users; - _this.log = args.logger; - _this.userRequestHandler = args['request-service']; - _this.objAdminCmds = { - shutdown: function(obj, cb) { - var data; - data = { - code: 200, - message: 'Shutting down... BYE!' - }; - setTimeout(args['shutdown-function'], 500); - return cb(null, data); + exports = module.exports = (function(_this) { + return function(args) { + var fStoreUser, user, users; + _this.log = args.logger; + _this.userRequestHandler = args['request-service']; + _this.objAdminCmds = { + shutdown: function(obj, cb) { + var data; + data = { + code: 200, + message: 'Shutting down... BYE!' + }; + setTimeout(args['shutdown-function'], 500); + return cb(null, data); + } + }; + db(args); + users = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', 'config', 'users.json'))); + fStoreUser = function(username, oUser) { + oUser.username = username; + return db.storeUser(oUser); + }; + for (user in users) { + fStoreUser(user, users[user]); } + return module.exports; }; - db(args); - users = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', 'config', 'users.json'))); - fStoreUser = function(username, oUser) { - oUser.username = username; - return db.storeUser(oUser); - }; - for (user in users) { - fStoreUser(user, users[user]); - } - return module.exports; - }; + })(this); + /* Handles possible events that were posted to this server and pushes them into the @@ -65,8 +67,7 @@ Request Handler objects.* @public handleEvent( *req, resp* ) - */ - + */ exports.handleEvent = function(req, resp) { var body; @@ -102,6 +103,7 @@ Request Handler }); }; + /* Associates the user object with the session if login is successful. @@ -111,32 +113,34 @@ Request Handler objects.* @public handleLogin( *req, resp* ) - */ + */ - - exports.handleLogin = function(req, resp) { - var body; - body = ''; - req.on('data', function(data) { - return body += data; - }); - return req.on('end', function() { - var obj; - obj = qs.parse(body); - return db.loginUser(obj.username, obj.password, function(err, usr) { - if (err) { - _this.log.warn("RH | AUTH-UH-OH ( " + obj.username + " ): " + err.message); - } else { - req.session.user = usr; - } - if (req.session.user) { - return resp.send('OK!'); - } else { - return resp.send(401, 'NO!'); - } + exports.handleLogin = (function(_this) { + return function(req, resp) { + var body; + body = ''; + req.on('data', function(data) { + return body += data; }); - }); - }; + return req.on('end', function() { + var obj; + obj = qs.parse(body); + return db.loginUser(obj.username, obj.password, function(err, usr) { + if (err) { + _this.log.warn("RH | AUTH-UH-OH ( " + obj.username + " ): " + err.message); + } else { + req.session.user = usr; + } + if (req.session.user) { + return resp.send('OK!'); + } else { + return resp.send(401, 'NO!'); + } + }); + }); + }; + })(this); + /* A post request retrieved on this handler causes the user object to be @@ -148,8 +152,7 @@ Request Handler objects.* @public handleLogout( *req, resp* ) - */ - + */ exports.handleLogout = function(req, resp) { if (req.session) { @@ -158,25 +161,25 @@ Request Handler } }; + /* Resolves the path to a handler webpage. @private getHandlerPath( *name* ) @param {String} name - */ - + */ getHandlerPath = function(name) { return path.join(dirHandlers, name + '.html'); }; + /* Fetches a template. @private getTemplate( *name* ) @param {String} name - */ - + */ getTemplate = function(name) { var pth; @@ -184,13 +187,13 @@ Request Handler return fs.readFileSync(pth, 'utf8'); }; + /* Fetches a script. @private getScript( *name* ) @param {String} name - */ - + */ getScript = function(name) { var pth; @@ -198,13 +201,13 @@ Request Handler return fs.readFileSync(pth, 'utf8'); }; + /* Fetches remote scripts snippets. @private getRemoteScripts( *name* ) @param {String} name - */ - + */ getRemoteScripts = function(name) { var pth; @@ -212,6 +215,7 @@ Request Handler return fs.readFileSync(pth, 'utf8'); }; + /* Renders a page, with helps of mustache, depending on the user session and returns it. @@ -219,8 +223,7 @@ Request Handler @param {String} name @param {Object} sess @param {Object} msg - */ - + */ renderPage = function(name, req, resp, msg) { var code, content, data, err, menubar, page, pageElements, pathSkel, remote_scripts, script, skeleton; @@ -259,6 +262,7 @@ Request Handler return resp.send(code, mustache.render(page, data)); }; + /* Present the desired forge page to the user. @@ -268,8 +272,7 @@ Request Handler objects.* @public handleForge( *req, resp* ) - */ - + */ exports.handleForge = function(req, resp) { var page; @@ -280,6 +283,7 @@ Request Handler return renderPage(page, req, resp); }; + /* Handles the user command requests. @@ -289,27 +293,29 @@ Request Handler objects.* @public handleUser( *req, resp* ) - */ + */ - - exports.handleUserCommand = function(req, resp) { - var body; - if (req.session && req.session.user) { - body = ''; - req.on('data', function(data) { - return body += data; - }); - return req.on('end', function() { - var obj; - obj = qs.parse(body); - return _this.userRequestHandler(req.session.user, obj, function(obj) { - return resp.send(obj.code, obj); + exports.handleUserCommand = (function(_this) { + return function(req, resp) { + var body; + if (req.session && req.session.user) { + body = ''; + req.on('data', function(data) { + return body += data; }); - }); - } else { - return resp.send(401, 'Login first!'); - } - }; + return req.on('end', function() { + var obj; + obj = qs.parse(body); + return _this.userRequestHandler(req.session.user, obj, function(obj) { + return resp.send(obj.code, obj); + }); + }); + } else { + return resp.send(401, 'Login first!'); + } + }; + })(this); + /* Present the admin console to the user if he's allowed to see it. @@ -320,8 +326,7 @@ Request Handler objects.* @public handleForge( *req, resp* ) - */ - + */ exports.handleAdmin = function(req, resp) { var msg, page; @@ -336,6 +341,7 @@ Request Handler return renderPage(page, req, resp, msg); }; + /* Handles the admin command requests. @@ -345,31 +351,32 @@ Request Handler objects.* @public handleAdminCommand( *req, resp* ) - */ + */ - - exports.handleAdminCommand = function(req, resp) { - var body; - if (req.session && req.session.user && req.session.user.isAdmin === "true") { - body = ''; - req.on('data', function(data) { - return body += data; - }); - return req.on('end', function() { - var obj; - obj = qs.parse(body); - _this.log.info('RH | Received admin request: ' + obj.command); - if (obj.command && _this.objAdminCmds[obj.command]) { - return _this.objAdminCmds[obj.command](obj, function(err, obj) { - return resp.send(obj.code, obj); - }); - } else { - return resp.send(404, 'Command unknown!'); - } - }); - } else { - return resp.send(401, 'You need to be logged in as admin!'); - } - }; + exports.handleAdminCommand = (function(_this) { + return function(req, resp) { + var body; + if (req.session && req.session.user && req.session.user.isAdmin === "true") { + body = ''; + req.on('data', function(data) { + return body += data; + }); + return req.on('end', function() { + var obj; + obj = qs.parse(body); + _this.log.info('RH | Received admin request: ' + obj.command); + if (obj.command && _this.objAdminCmds[obj.command]) { + return _this.objAdminCmds[obj.command](obj, function(err, obj) { + return resp.send(obj.code, obj); + }); + } else { + return resp.send(404, 'Command unknown!'); + } + }); + } else { + return resp.send(401, 'You need to be logged in as admin!'); + } + }; + })(this); }).call(this); diff --git a/js-coffee/webapi-eca.js b/js-coffee/webapi-eca.js index 76f78a2..987c06c 100644 --- a/js-coffee/webapi-eca.js +++ b/js-coffee/webapi-eca.js @@ -1,4 +1,5 @@ -// Generated by CoffeeScript 1.6.3 +// Generated by CoffeeScript 1.7.1 + /* WebAPI-ECA Engine @@ -9,12 +10,10 @@ WebAPI-ECA Engine > node webapi-eca [opt] > > See below in the optimist CLI preparation for allowed optional parameters `[opt]`. -*/ - + */ (function() { - var argv, cm, conf, cp, db, engine, fs, http, init, logger, nameEP, opt, optimist, path, procCmds, shutDown, usage, - _this = this; + var argv, cm, conf, cp, db, engine, fs, http, init, logconf, logger, nameEP, opt, optimist, path, procCmds, shutDown, usage; logger = require('./logging'); @@ -40,10 +39,10 @@ WebAPI-ECA Engine procCmds = {}; + /* Let's prepare the optimist CLI optional arguments `[opt]`: - */ - + */ usage = 'This runs your webapi-based ECA engine'; @@ -93,113 +92,128 @@ WebAPI-ECA Engine process.exit(); } + conf(argv.c); + + if (!conf.isReady()) { + console.error('FAIL: Config file not ready! Shutting down...'); + process.exit(); + } + + logconf = conf.getLogConf(); + + if (argv.m) { + logconf['mode'] = argv.m; + } + + if (argv.i) { + logconf['io-level'] = argv.i; + } + + if (argv.f) { + logconf['file-level'] = argv.f; + } + + if (argv.p) { + logconf['file-path'] = argv.p; + } + + if (argv.n) { + logconf['nolog'] = argv.n; + } + + try { + fs.unlinkSync(path.resolve(__dirname, '..', 'logs', logconf['file-path'])); + } catch (_error) {} + + this.log = logger.getLogger(logconf); + + this.log.info('RS | STARTING SERVER'); + + /* This function is invoked right after the module is loaded and starts the server. @private init() - */ + */ - - init = function() { - var args, logconf; - conf(argv.c); - if (!conf.isReady()) { - console.error('FAIL: Config file not ready! Shutting down...'); - process.exit(); - } - logconf = conf.getLogConf(); - if (argv.m) { - logconf['mode'] = argv.m; - } - if (argv.i) { - logconf['io-level'] = argv.i; - } - if (argv.f) { - logconf['file-level'] = argv.f; - } - if (argv.p) { - logconf['file-path'] = argv.p; - } - if (argv.n) { - logconf['nolog'] = argv.n; - } - try { - fs.unlinkSync(path.resolve(__dirname, '..', 'logs', logconf['file-path'])); - } catch (_error) {} - _this.log = logger.getLogger(logconf); - _this.log.info('RS | STARTING SERVER'); - args = { - logger: _this.log, - logconf: logconf + init = (function(_this) { + return function() { + var args; + args = { + logger: _this.log, + logconf: logconf + }; + args['http-port'] = parseInt(argv.w || conf.getHttpPort()); + args['db-port'] = parseInt(argv.d || conf.getDbPort()); + _this.log.info('RS | Initialzing DB'); + db(args); + return db.isConnected(function(err) { + var cliArgs, poller; + if (err) { + _this.log.error('RS | No DB connection, shutting down system!'); + return shutDown(); + } else { + _this.log.info('RS | Initialzing engine'); + engine(args); + _this.log.info('RS | Forking a child process for the event poller'); + cliArgs = [args.logconf['mode'], args.logconf['io-level'], args.logconf['file-level'], args.logconf['file-path'], args.logconf['nolog']]; + poller = cp.fork(path.resolve(__dirname, nameEP), cliArgs); + _this.log.info('RS | Initialzing module manager'); + cm(args); + cm.addListener('init', function(evt) { + return poller.send({ + event: 'init', + data: evt + }); + }); + cm.addListener('newRule', function(evt) { + return poller.send({ + event: 'newRule', + data: evt + }); + }); + cm.addListener('init', function(evt) { + return engine.internalEvent('init', evt); + }); + cm.addListener('newRule', function(evt) { + return engine.internalEvent('newRule', evt); + }); + _this.log.info('RS | Initialzing http listener'); + args['request-service'] = cm.processRequest; + args['shutdown-function'] = shutDown; + return http(args); + } + }); }; - args['http-port'] = parseInt(argv.w || conf.getHttpPort()); - args['db-port'] = parseInt(argv.d || conf.getDbPort()); - _this.log.info('RS | Initialzing DB'); - db(args); - return db.isConnected(function(err) { - var cliArgs, poller; - if (err) { - _this.log.error('RS | No DB connection, shutting down system!'); - return shutDown(); - } else { - _this.log.info('RS | Initialzing engine'); - engine(args); - _this.log.info('RS | Forking a child process for the event poller'); - cliArgs = [args.logconf['mode'], args.logconf['io-level'], args.logconf['file-level'], args.logconf['file-path'], args.logconf['nolog']]; - poller = cp.fork(path.resolve(__dirname, nameEP), cliArgs); - _this.log.info('RS | Initialzing module manager'); - cm(args); - cm.addListener('init', function(evt) { - return poller.send({ - event: 'init', - data: evt - }); - }); - cm.addListener('newRule', function(evt) { - return poller.send({ - event: 'newRule', - data: evt - }); - }); - cm.addListener('init', function(evt) { - return engine.internalEvent('init', evt); - }); - cm.addListener('newRule', function(evt) { - return engine.internalEvent('newRule', evt); - }); - _this.log.info('RS | Initialzing http listener'); - args['request-service'] = cm.processRequest; - args['shutdown-function'] = shutDown; - return http(args); - } - }); - }; + })(this); + /* Shuts down the server. @private shutDown() - */ + */ + shutDown = (function(_this) { + return function() { + _this.log.warn('RS | Received shut down command!'); + if (db != null) { + db.shutDown(); + } + if (engine != null) { + engine.shutDown(); + } + return process.exit(); + }; + })(this); - shutDown = function() { - _this.log.warn('RS | Received shut down command!'); - if (db != null) { - db.shutDown(); - } - if (engine != null) { - engine.shutDown(); - } - return process.exit(); - }; /* - ## Process Commands + *# Process Commands When the server is run as a child process, this function handles messages from the parent process (e.g. the testing suite) - */ - + */ process.on('message', function(cmd) { return typeof procCmds[cmd] === "function" ? procCmds[cmd]() : void 0; diff --git a/node_modules/my-cryptico/index.js b/node_modules/my-cryptico/index.js index 5b17d15..b0a93a7 100644 --- a/node_modules/my-cryptico/index.js +++ b/node_modules/my-cryptico/index.js @@ -5,4 +5,4 @@ var fs = require('fs'); var filedata = fs.readFileSync('./webpages/public/js/cryptico.js','utf8'); eval(filedata); -exports.cryptico = cryptico +exports = module.exports = cryptico; diff --git a/package.json b/package.json index 53237d0..5608ae1 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,8 @@ "url" : "https://github.com/dominicbosch/webapi-eca.git" }, "dependencies": { + "bunyan": "0.22.1", + "coffee-script": "1.6.3", "connect-redis": "1.4.6", "crypto-js": "3.1.2", "express": "3.4.8", @@ -18,8 +20,6 @@ "nodeunit": "0.8.4", "redis": "0.10.0", "request": "2.33.0", - "coffee-script": "1.6.3", - "bunyan": "0.22.1", "optimist": "0.6.1" }, "__comment": { diff --git a/testing/files/testObjects.json b/testing/files/testObjects.json index e7ee8ea..29bcaa2 100644 --- a/testing/files/testObjects.json +++ b/testing/files/testObjects.json @@ -31,6 +31,11 @@ "functions":"[\"newEvent\",\"randomNess\"]" } }, + "userparams": { + "epUpOne": { + "apikey": "testkey" + } + }, "rules": { "ruleOne": { "id": "ruleOne_id", diff --git a/testing/test_components-manager.coffee b/testing/test_components-manager.coffee index c519248..81b0c3f 100644 --- a/testing/test_components-manager.coffee +++ b/testing/test_components-manager.coffee @@ -1,5 +1,6 @@ fs = require 'fs' path = require 'path' + try data = fs.readFileSync path.resolve( 'testing', 'files', 'testObjects.json' ), 'utf8' try @@ -12,10 +13,10 @@ catch err logger = require path.join '..', 'js-coffee', 'logging' log = logger.getLogger nolog: true - -cm = require path.join '..', 'js-coffee', 'components-manager' opts = logger: log + +cm = require path.join '..', 'js-coffee', 'components-manager' cm opts db = require path.join '..', 'js-coffee', 'persistence' @@ -24,11 +25,13 @@ db opts oUser = objects.users.userOne oRuleOne = objects.rules.ruleOne oRuleTwo = objects.rules.ruleTwo +oEpOne = objects.eps.epOne +oEpTwo = objects.eps.epTwo exports.tearDown = ( cb ) -> db.deleteRule oRuleOne.id db.deleteRule oRuleTwo.id - cb() + setTimeout cb, 100 exports.requestProcessing = testEmptyPayload: ( test ) => @@ -84,33 +87,54 @@ exports.testListener = ( test ) => setTimeout fWaitForInit, 200 exports.moduleHandling = + tearDown: ( cb ) -> + db.eventPollers.deleteModule oEpOne.id + db.eventPollers.deleteModule oEpTwo.id + setTimeout cb, 100 + testGetModules: ( test ) -> test.expect 2 - oModule = objects.eps.epOne - db.eventPollers.storeModule oUser.username, oModule + db.eventPollers.storeModule oUser.username, oEpOne request = command: 'get_event_pollers' cm.processRequest oUser, request, ( answ ) => test.strictEqual 200, answ.code, 'GetModules failed...' oExpected = {} - oExpected[oModule.id] = JSON.parse oModule.functions + oExpected[oEpOne.id] = JSON.parse oEpOne.functions test.strictEqual JSON.stringify(oExpected), answ.message, 'GetModules retrieved modules is not what we expected' - - console.log answ test.done() - # testGetModuleParams: ( test ) -> - # test.expect 1 + testGetModuleParams: ( test ) -> + test.expect 2 - # oModule = objects.eps.epOne - # db.eventPollers.storeModule oUser.username, oModule - # request = - # command: 'get_event_pollers' + db.eventPollers.storeModule oUser.username, oEpTwo + + request = + command: 'get_event_poller_params' + payload: '{"id": "' + oEpTwo.id + '"}' - # cm.processRequest oUser, request, ( answ ) => - # test.strictEqual 200, answ.code, 'Empty payload did not return 200' - # console.log answ - # test.done() + cm.processRequest oUser, request, ( answ ) => + test.strictEqual 200, answ.code, + 'Required Module Parameters did not return 200' + test.strictEqual oEpTwo.params, answ.message, + 'Required Module Parameters did not match' + test.done() + + testForgeModule: ( test ) -> + test.expect 2 + + oTmp = {} + oTmp[key] = val for key, val of oEpTwo when key isnt 'functions' + request = + command: 'forge_event_poller' + payload: JSON.stringify oTmp + + cm.processRequest oUser, request, ( answ ) => + test.strictEqual 200, answ.code, 'Forging Module did not return 200' + + db.eventPollers.getModule oEpTwo.id, ( err, obj ) -> + test.deepEqual obj, oEpTwo, 'Forged Module is not what we expected' + test.done() diff --git a/webpages/handlers/js/admin.js b/webpages/handlers/js/admin.js index d133294..8d7b0aa 100644 --- a/webpages/handlers/js/admin.js +++ b/webpages/handlers/js/admin.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.6.3 +// Generated by CoffeeScript 1.7.1 (function() { var fOnLoad; diff --git a/webpages/handlers/js/error.js b/webpages/handlers/js/error.js index 2bb94fc..c97b3f0 100644 --- a/webpages/handlers/js/error.js +++ b/webpages/handlers/js/error.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.6.3 +// Generated by CoffeeScript 1.7.1 (function() { var fOnLoad; diff --git a/webpages/handlers/js/forge_action_invoker.js b/webpages/handlers/js/forge_action_invoker.js index d1073f2..d46edb9 100644 --- a/webpages/handlers/js/forge_action_invoker.js +++ b/webpages/handlers/js/forge_action_invoker.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.6.3 +// Generated by CoffeeScript 1.7.1 (function() { var fOnLoad; diff --git a/webpages/handlers/js/forge_event.js b/webpages/handlers/js/forge_event.js index 90e5936..4951d18 100644 --- a/webpages/handlers/js/forge_event.js +++ b/webpages/handlers/js/forge_event.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.6.3 +// Generated by CoffeeScript 1.7.1 (function() { var fOnLoad; diff --git a/webpages/handlers/js/forge_event_poller.js b/webpages/handlers/js/forge_event_poller.js index 3001d4b..edccd11 100644 --- a/webpages/handlers/js/forge_event_poller.js +++ b/webpages/handlers/js/forge_event_poller.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.6.3 +// Generated by CoffeeScript 1.7.1 (function() { var fOnLoad; diff --git a/webpages/handlers/js/forge_rule.js b/webpages/handlers/js/forge_rule.js index f0c22ef..fb43119 100644 --- a/webpages/handlers/js/forge_rule.js +++ b/webpages/handlers/js/forge_rule.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.6.3 +// Generated by CoffeeScript 1.7.1 (function() { var fOnLoad; diff --git a/webpages/handlers/js/login.js b/webpages/handlers/js/login.js index 0f62b66..348fc68 100644 --- a/webpages/handlers/js/login.js +++ b/webpages/handlers/js/login.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.6.3 +// Generated by CoffeeScript 1.7.1 (function() { var fOnLoad;