Testing of components manager done

This commit is contained in:
Dominic Bosch 2014-04-02 23:08:05 +02:00
parent d1361c900c
commit 1f4ee71cc5
25 changed files with 1192 additions and 1129 deletions

View file

@ -125,7 +125,7 @@ getModuleParams = ( user, oPayload, dbMod, callback ) ->
answ.message = oPayload answ.message = oPayload
callback answ callback answ
forgeModule = ( user, oPayload, dbMod, callback ) -> forgeModule = ( user, oPayload, dbMod, callback ) =>
answ = hasRequiredParams [ 'id', 'params', 'lang', 'data' ], oPayload answ = hasRequiredParams [ 'id', 'params', 'lang', 'data' ], oPayload
if answ.code isnt 200 if answ.code isnt 200
callback answ callback answ
@ -136,12 +136,12 @@ forgeModule = ( user, oPayload, dbMod, callback ) ->
answ.message = 'Event Poller module name already existing: ' + oPayload.id answ.message = 'Event Poller module name already existing: ' + oPayload.id
else else
src = oPayload.data src = oPayload.data
cm = dynmod.compileString src, oPayload.id, {}, oPayload.lang cm = dynmod.compileString src, user.username, oPayload.id, {}, oPayload.lang
answ = cm.answ answ = cm.answ
if answ.code is 200 if answ.code is 200
funcs = [] funcs = []
funcs.push name for name, id of cm.module 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 = answ.message =
"Event Poller module successfully stored! Found following function(s): #{ funcs }" "Event Poller module successfully stored! Found following function(s): #{ funcs }"
oPayload.functions = JSON.stringify funcs oPayload.functions = JSON.stringify funcs

View file

@ -103,4 +103,4 @@ exports.getLogConf = -> fetchProp 'log'
@public getCryptoKey() @public getCryptoKey()
### ###
exports.getCryptoKey = -> fetchProp 'crypto-key' exports.getKeygenPassphrase = -> fetchProp 'keygen-passphrase'

View file

@ -14,6 +14,28 @@ needle = require 'needle'
# - External Modules: [coffee-script](http://coffeescript.org/) # - External Modules: [coffee-script](http://coffeescript.org/)
cs = require 'coffee-script' 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 Module call
----------- -----------
@ -37,7 +59,7 @@ compile it first into JS.
@param {Object} params @param {Object} params
@param {String} lang @param {String} lang
### ###
exports.compileString = ( src, id, params, lang ) => exports.compileString = ( src, userId, moduleId, params, lang ) =>
answ = answ =
code: 200 code: 200
message: 'Successfully compiled' message: 'Successfully compiled'
@ -52,7 +74,7 @@ exports.compileString = ( src, id, params, lang ) =>
err.location.first_line err.location.first_line
#FIXME not log but debug module is required to provide information to the user #FIXME not log but debug module is required to provide information to the user
sandbox = 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 params: params
needle: needle needle: needle
log: console.log 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... #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? #kill the child each time? how to determine whether there's still a token in the module?
try try
vm.runInNewContext src, sandbox, id + '.vm' vm.runInNewContext src, sandbox, sandbox.id
catch err catch err
answ.code = 400 answ.code = 400
answ.message = 'Loading Module failed: ' + err.message answ.message = 'Loading Module failed: ' + err.message

View file

@ -2,10 +2,11 @@
Persistence Persistence
============ ============
> Handles the connection to the database and provides functionalities for > Handles the connection to the database and provides functionalities for event pollers,
> event pollers, action invokers, rules and the encrypted storing of authentication tokens. > action invokers, rules and the (hopefully encrypted) storing of user-specific parameters
> per module.
> General functionality as a wrapper for the module holds initialization, > 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. > 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 > By fetching all set entries we can then fetch all elements, which is
@ -22,14 +23,9 @@ Persistence
# **Loads Modules:** # **Loads Modules:**
# - External Modules: # - External Modules:
# [crypto-js](https://github.com/evanvosberg/crypto-js) and
# [redis](https://github.com/mranney/node_redis) # [redis](https://github.com/mranney/node_redis)
crypto = require 'crypto-js'
redis = require 'redis' 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<Iw;:DPV;4gy:qf]Zq{\"6sgK{,}^\"!]O;qBM3G?]h_`Psw=b6bVXKXry7*"
### ###
Module call Module call
----------- -----------
@ -91,6 +87,7 @@ exports.isConnected = ( cb ) =>
cb new Error 'DB | Connection to DB failed!' cb new Error 'DB | Connection to DB failed!'
setTimeout fCheckConnection, 100 setTimeout fCheckConnection, 100
### ###
Abstracts logging for simple action replies from the DB. Abstracts logging for simple action replies from the DB.
@ -104,6 +101,7 @@ replyHandler = ( action ) =>
else else
@log.info "DB | #{ action }: #{ reply }" @log.info "DB | #{ action }: #{ reply }"
### ###
Push an event into the event queue. Push an event into the event queue.
@ -130,6 +128,7 @@ exports.popEvent = ( cb ) =>
pcb err, JSON.parse obj pcb err, JSON.parse obj
@db.lpop 'event_queue', makeObj cb @db.lpop 'event_queue', makeObj cb
### ###
Purge the event queue. Purge the event queue.
@ -138,49 +137,6 @@ Purge the event queue.
exports.purgeEventQueue = () => exports.purgeEventQueue = () =>
@db.del 'event_queue', replyHandler 'purging event queue' @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 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 # is used to preprocess the answer to determine correct execution
fSingle reply, fCallback reply for reply in arrReply fSingle reply, fCallback reply for reply in arrReply
# TODO remove specific functions and allow direct access to instances of this class
class IndexedModules class IndexedModules
constructor: ( @setname, @log ) -> constructor: ( @setname, @log ) ->
@log.info "DB | (IdxedMods) Instantiated indexed modules for '#{ @setname }'" @log.info "DB | (IdxedMods) Instantiated indexed modules for '#{ @setname }'"
@ -249,6 +205,7 @@ class IndexedModules
### ###
Stores a module and links it to the user. Stores a module and links it to the user.
@private storeModule( *userId, oModule* ) @private storeModule( *userId, oModule* )
@param {String} userId @param {String} userId
@param {object} oModule @param {object} oModule
@ -317,10 +274,9 @@ class IndexedModules
replyHandler "srem '#{ mId }' from #{ @setname }s" replyHandler "srem '#{ mId }' from #{ @setname }s"
@db.del "#{ @setname }:#{ mId }", @db.del "#{ @setname }:#{ mId }",
replyHandler "del of '#{ @setname }:#{ mId }'" replyHandler "del of '#{ @setname }:#{ mId }'"
@unpublish mId
@db.smembers "#{ @setname }:#{ mId }:users", ( err, obj ) => @db.smembers "#{ @setname }:#{ mId }:users", ( err, obj ) =>
@unlinkModule mId, userId for userId in 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
# TODO remove from public modules # TODO remove from public modules
# TODO remove parameters # TODO remove parameters
# @log.info "DB | linkModule(#{ @setname }): #{ mId } to #{ userId }" # @log.info "DB | linkModule(#{ @setname }): #{ mId } to #{ userId }"
@ -329,17 +285,26 @@ class IndexedModules
# @db.sadd "user:#{ userId }:#{ @setname }s", mId, # @db.sadd "user:#{ userId }:#{ @setname }s", mId,
# replyHandler "Linking '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 }", @db.sadd "#{ @setname }-params", "#{ mId }:#{ userId }",
replyHandler "sadd '#{ mId }:#{ userId }' to '#{ @setname }-params'" 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 }'" replyHandler "set user params in '#{ @setname }-params:#{ mId }:#{ userId }'"
getUserParams: ( mId, userId, cb ) => getUserParams: ( mId, userId, cb ) =>
@log.info "DB | (IdxedMods) #{ @setname }.getUserParams( #{ mId }, #{ userId } )" @log.info "DB | (IdxedMods) #{ @setname }.getUserParams( #{ mId }, #{ userId } )"
@db.get "#{ @setname }-params:#{ mId }:#{ userId }", ( err, data ) -> @db.get "#{ @setname }-params:#{ mId }:#{ userId }", ( err, data ) ->
cb err, decrypt data cb err, data
getUserParamsIds: ( cb ) => getUserParamsIds: ( cb ) =>
@log.info "DB | (IdxedMods) #{ @setname }.getUserParamsIds()" @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 @param {Object} objUser
### ###
exports.storeUser = ( 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 }'" @log.info "DB | storeUser: '#{ objUser.username }'"
if objUser and objUser.username and objUser.password if objUser and objUser.username and objUser.password
@db.sadd 'users', objUser.username, @db.sadd 'users', objUser.username,

View file

@ -40,7 +40,7 @@ fs = require 'fs'
path = require 'path' path = require 'path'
cp = require 'child_process' 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' optimist = require 'optimist'
procCmds = {} procCmds = {}
@ -93,34 +93,35 @@ if argv.help
console.log optimist.help() console.log optimist.help()
process.exit() 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. This function is invoked right after the module is loaded and starts the server.
@private init() @private init()
### ###
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 = args =
logger: @log logger: @log

View file

@ -6,5 +6,6 @@
"io-level": "info", "io-level": "info",
"file-level": "info", "file-level": "info",
"file-path": "server.log" "file-path": "server.log"
} },
"keygen-passphrase": "[TODO this has to come from prompt when server is started!]"
} }

View file

@ -1,4 +1,5 @@
// Generated by CoffeeScript 1.6.3 // Generated by CoffeeScript 1.7.1
/* /*
Components Manager Components Manager
@ -6,12 +7,10 @@ Components Manager
> The components manager takes care of the dynamic JS modules and the rules. > 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, > 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. > then compiled into node modules and rules and used in the engine and event poller.
*/ */
(function() { (function() {
var commandFunctions, db, dynmod, events, exports, forgeModule, fs, getModuleParams, getModules, hasRequiredParams, path, vm, var commandFunctions, db, dynmod, events, exports, forgeModule, fs, getModuleParams, getModules, hasRequiredParams, path, vm;
_this = this;
db = require('./persistence'); db = require('./persistence');
@ -25,22 +24,25 @@ Components Manager
events = require('events'); events = require('events');
/* /*
Module call Module call
----------- -----------
Initializes the Components Manager and constructs a new Event Emitter. Initializes the Components Manager and constructs a new Event Emitter.
@param {Object} args @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). Add an event handler (eh) for a certain event (evt).
@ -52,23 +54,25 @@ Components Manager
@public addListener ( *evt, eh* ) @public addListener ( *evt, eh* )
@param {String} evt @param {String} evt
@param {function} eh @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. Processes a user request coming through the request-handler.
@ -83,8 +87,7 @@ Components Manager
@param {Object} user @param {Object} user
@param {Object} oReq @param {Object} oReq
@param {function} callback @param {function} callback
*/ */
exports.processRequest = function(user, oReq, callback) { exports.processRequest = function(user, oReq, callback) {
var dat, err; var dat, err;
@ -129,8 +132,7 @@ Components Manager
getModules = function(user, oPayload, dbMod, callback) { getModules = function(user, oPayload, dbMod, callback) {
return dbMod.getAvailableModuleIds(user.username, function(err, arrNames) { return dbMod.getAvailableModuleIds(user.username, function(err, arrNames) {
var answReq, fGetFunctions, id, oRes, sem, _i, _len, _results, var answReq, fGetFunctions, id, oRes, sem, _i, _len, _results;
_this = this;
oRes = {}; oRes = {};
answReq = function() { answReq = function() {
return callback({ return callback({
@ -142,16 +144,18 @@ Components Manager
if (sem === 0) { if (sem === 0) {
return answReq(); return answReq();
} else { } else {
fGetFunctions = function(id) { fGetFunctions = (function(_this) {
return dbMod.getModule(id, function(err, oModule) { return function(id) {
if (oModule) { return dbMod.getModule(id, function(err, oModule) {
oRes[id] = JSON.parse(oModule.functions); if (oModule) {
} oRes[id] = JSON.parse(oModule.functions);
if (--sem === 0) { }
return answReq(); if (--sem === 0) {
} return answReq();
}); }
}; });
};
})(this);
_results = []; _results = [];
for (_i = 0, _len = arrNames.length; _i < _len; _i++) { for (_i = 0, _len = arrNames.length; _i < _len; _i++) {
id = arrNames[_i]; id = arrNames[_i];
@ -175,42 +179,43 @@ Components Manager
} }
}; };
forgeModule = function(user, oPayload, dbMod, callback) { forgeModule = (function(_this) {
var answ, return function(user, oPayload, dbMod, callback) {
_this = this; var answ;
answ = hasRequiredParams(['id', 'params', 'lang', 'data'], oPayload); answ = hasRequiredParams(['id', 'params', 'lang', 'data'], oPayload);
if (answ.code !== 200) { if (answ.code !== 200) {
return callback(answ); return callback(answ);
} else { } else {
return dbMod.getModule(oPayload.id, function(err, mod) { return dbMod.getModule(oPayload.id, function(err, mod) {
var cm, funcs, id, name, src, _ref; var cm, funcs, id, name, src, _ref;
if (mod) { if (mod) {
answ.code = 409; answ.code = 409;
answ.message = 'Event Poller module name already existing: ' + oPayload.id; answ.message = 'Event Poller module name already existing: ' + oPayload.id;
} else { } else {
src = oPayload.data; src = oPayload.data;
cm = dynmod.compileString(src, oPayload.id, {}, oPayload.lang); cm = dynmod.compileString(src, user.username, oPayload.id, {}, oPayload.lang);
answ = cm.answ; answ = cm.answ;
if (answ.code === 200) { if (answ.code === 200) {
funcs = []; funcs = [];
_ref = cm.module; _ref = cm.module;
for (name in _ref) { for (name in _ref) {
id = _ref[name]; id = _ref[name];
funcs.push(name); funcs.push(name);
} }
_this.log.info("CM | Storing new module with functions " + funcs); _this.log.info("CM | Storing new module with functions " + (funcs.join()));
answ.message = "Event Poller module successfully stored! Found following function(s): " + funcs; answ.message = "Event Poller module successfully stored! Found following function(s): " + funcs;
oPayload.functions = JSON.stringify(funcs); oPayload.functions = JSON.stringify(funcs);
dbMod.storeModule(user.username, oPayload); dbMod.storeModule(user.username, oPayload);
if (oPayload["public"] === 'true') { if (oPayload["public"] === 'true') {
dbMod.publish(oPayload.id); dbMod.publish(oPayload.id);
}
} }
} }
} return callback(answ);
return callback(answ); });
}); }
} };
}; })(this);
commandFunctions = { commandFunctions = {
get_event_pollers: function(user, oPayload, callback) { get_event_pollers: function(user, oPayload, callback) {
@ -234,48 +239,50 @@ Components Manager
get_rules: function(user, oPayload, callback) { get_rules: function(user, oPayload, callback) {
return console.log('CM | Implement get_rules'); return console.log('CM | Implement get_rules');
}, },
forge_rule: function(user, oPayload, callback) { forge_rule: (function(_this) {
var answ; return function(user, oPayload, callback) {
answ = hasRequiredParams(['id', 'event', 'conditions', 'actions'], oPayload); var answ;
if (answ.code !== 200) { answ = hasRequiredParams(['id', 'event', 'conditions', 'actions'], oPayload);
return callback(answ); if (answ.code !== 200) {
} 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); 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); }).call(this);

View file

@ -1,20 +1,20 @@
// Generated by CoffeeScript 1.6.3 // Generated by CoffeeScript 1.7.1
/* /*
Configuration Configuration
============= =============
> Loads the configuration file and acts as an interface to it. > Loads the configuration file and acts as an interface to it.
*/ */
(function() { (function() {
var exports, fetchProp, fs, loadConfigFile, path, var exports, fetchProp, fs, loadConfigFile, path;
_this = this;
fs = require('fs'); fs = require('fs');
path = require('path'); path = require('path');
/* /*
Module call Module call
----------- -----------
@ -24,21 +24,23 @@ Configuration
be generated) and configPath for a custom configuration file path. be generated) and configPath for a custom configuration file path.
@param {Object} args @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. Tries to load a configuration file from the path relative to this module's parent folder.
@ -46,100 +48,105 @@ Configuration
@private loadConfigFile @private loadConfigFile
@param {String} configPath @param {String} configPath
*/ */
loadConfigFile = (function(_this) {
loadConfigFile = function(configPath) { return function(configPath) {
var confProperties, e, prop, _i, _len; var confProperties, e, prop, _i, _len;
_this.config = null; _this.config = null;
confProperties = ['log', 'http-port', 'db-port']; confProperties = ['log', 'http-port', 'db-port'];
try { try {
_this.config = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', configPath))); _this.config = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', configPath)));
_this.isReady = true; _this.isReady = true;
for (_i = 0, _len = confProperties.length; _i < _len; _i++) { for (_i = 0, _len = confProperties.length; _i < _len; _i++) {
prop = confProperties[_i]; prop = confProperties[_i];
if (!_this.config[prop]) { if (!_this.config[prop]) {
_this.isReady = false; _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 - ")))); })(this);
}
} catch (_error) {
e = _error;
_this.isReady = false;
if (!_this.nolog) {
return console.error("Failed loading config file: " + e.message);
}
}
};
/* /*
Fetch a property from the configuration Fetch a property from the configuration
@private fetchProp( *prop* ) @private fetchProp( *prop* )
@param {String} 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 ***Returns*** true if the config file is ready, else false
@public isReady() @public isReady()
*/ */
exports.isReady = (function(_this) {
return function() {
return _this.isReady;
};
})(this);
exports.isReady = function() {
return _this.isReady;
};
/* /*
***Returns*** the HTTP port ***Returns*** the HTTP port
@public getHttpPort() @public getHttpPort()
*/ */
exports.getHttpPort = function() { exports.getHttpPort = function() {
return fetchProp('http-port'); return fetchProp('http-port');
}; };
/* /*
***Returns*** the DB port* ***Returns*** the DB port*
@public getDBPort() @public getDBPort()
*/ */
exports.getDbPort = function() { exports.getDbPort = function() {
return fetchProp('db-port'); return fetchProp('db-port');
}; };
/* /*
***Returns*** the log conf object ***Returns*** the log conf object
@public getLogConf() @public getLogConf()
*/ */
exports.getLogConf = function() { exports.getLogConf = function() {
return fetchProp('log'); return fetchProp('log');
}; };
/* /*
***Returns*** the crypto key ***Returns*** the crypto key
@public getCryptoKey() @public getCryptoKey()
*/ */
exports.getKeygenPassphrase = function() {
exports.getCryptoKey = function() { return fetchProp('keygen-passphrase');
return fetchProp('crypto-key');
}; };
}).call(this); }).call(this);

View file

@ -1,16 +1,15 @@
// Generated by CoffeeScript 1.6.3 // Generated by CoffeeScript 1.7.1
/* /*
Dynamic Modules Dynamic Modules
=============== ===============
> Compiles CoffeeScript modules and loads JS modules in a VM, together > Compiles CoffeeScript modules and loads JS modules in a VM, together
> with only a few allowed node.js modules. > with only a few allowed node.js modules.
*/ */
(function() { (function() {
var cs, exports, needle, vm, var cs, exports, needle, vm;
_this = this;
vm = require('vm'); vm = require('vm');
@ -18,19 +17,22 @@ Dynamic Modules
cs = require('coffee-script'); cs = require('coffee-script');
/* /*
Module call Module call
----------- -----------
Initializes the dynamic module handler. Initializes the dynamic module handler.
@param {Object} args @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 Try to run a JS module from a string, together with the
@ -42,43 +44,44 @@ Dynamic Modules
@param {String} id @param {String} id
@param {Object} params @param {Object} params
@param {String} lang @param {String} lang
*/ */
exports.compileString = (function(_this) {
exports.compileString = function(src, id, params, lang) { return function(src, userId, moduleId, params, lang) {
var answ, err, ret, sandbox; var answ, err, ret, sandbox;
answ = { answ = {
code: 200, code: 200,
message: 'Successfully compiled' message: 'Successfully compiled'
}; };
if (lang === '0') { 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 { try {
src = cs.compile(src); vm.runInNewContext(src, sandbox, sandbox.id);
} catch (_error) { } catch (_error) {
err = _error; err = _error;
answ.code = 400; answ.code = 400;
answ.message = 'Compilation of CoffeeScript failed at line ' + err.location.first_line; answ.message = 'Loading Module failed: ' + err.message;
} }
} ret = {
sandbox = { answ: answ,
id: id, module: sandbox.exports
params: params, };
needle: needle, return ret;
log: console.log,
exports: {}
}; };
try { })(this);
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;
};
}).call(this); }).call(this);

View file

@ -1,4 +1,5 @@
// Generated by CoffeeScript 1.6.3 // Generated by CoffeeScript 1.7.1
/* /*
HTTP Listener HTTP Listener
@ -6,12 +7,10 @@ HTTP Listener
> Receives the HTTP requests to the server at the given port. The requests > 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 > (bound to a method) are then redirected to the appropriate handler which
> takes care of the request. > takes care of the request.
*/ */
(function() { (function() {
var app, exports, express, initRouting, path, qs, requestHandler, var app, exports, express, initRouting, path, qs, requestHandler;
_this = this;
requestHandler = require('./request-handler'); requestHandler = require('./request-handler');
@ -23,73 +22,77 @@ HTTP Listener
app = express(); app = express();
/* /*
Module call Module call
----------- -----------
Initializes the HTTP listener and its request handler. Initializes the HTTP listener and its request handler.
@param {Object} args @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. Initializes the request routing and starts listening on the given port.
@param {int} port @param {int} port
@private initRouting( *fShutDown* ) @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<Iw";
app.use(express.session({
secret: sess_sec
}));
_this.log.info('HL | no session backbone');
app.use('/', express["static"](path.resolve(__dirname, '..', 'webpages', 'public')));
app.get('/admin', requestHandler.handleAdmin);
app.get('/forge', requestHandler.handleForge);
app.post('/event', requestHandler.handleEvent);
app.post('/login', requestHandler.handleLogin);
app.post('/logout', requestHandler.handleLogout);
app.post('/usercommand', requestHandler.handleUserCommand);
app.post('/admincommand', requestHandler.handleAdminCommand);
server = app.listen(parseInt(port) || 8111);
server.on('listening', function() {
var addr;
addr = server.address();
if (addr.port !== port) {
return _this.shutDownSystem();
}
});
return server.on('error', function(err) {
initRouting = function(port) { /*
var server, sess_sec; Error handling of the express port listener requires special attention,
app.use(express.cookieParser()); thus we have to catch the error, which is issued if the port is already in use.
sess_sec = "149u*y8C:@kmN/520Gt\\v'+KFBnQ!\\r<>5X/xRI`sT<Iw"; */
app.use(express.session({ switch (err.errno) {
secret: sess_sec case 'EADDRINUSE':
})); _this.log.error(err, 'HL | http-port already in use, shutting down!');
_this.log.info('HL | no session backbone'); break;
app.use('/', express["static"](path.resolve(__dirname, '..', 'webpages', 'public'))); case 'EACCES':
app.get('/admin', requestHandler.handleAdmin); _this.log.error(err, 'HL | http-port not accessible, shutting down!');
app.get('/forge', requestHandler.handleForge); break;
app.post('/event', requestHandler.handleEvent); default:
app.post('/login', requestHandler.handleLogin); _this.log.error(err, 'HL | Error in server, shutting down!');
app.post('/logout', requestHandler.handleLogout); }
app.post('/usercommand', requestHandler.handleUserCommand);
app.post('/admincommand', requestHandler.handleAdminCommand);
server = app.listen(parseInt(port) || 8111);
server.on('listening', function() {
var addr;
addr = server.address();
if (addr.port !== port) {
return _this.shutDownSystem(); return _this.shutDownSystem();
} });
}); };
return server.on('error', function(err) { })(this);
/*
Error handling of the express port listener requires special attention,
thus we have to catch the error, which is issued if the port is already in use.
*/
switch (err.errno) {
case 'EADDRINUSE':
_this.log.error(err, 'HL | http-port already in use, shutting down!');
break;
case 'EACCES':
_this.log.error(err, 'HL | http-port not accessible, shutting down!');
break;
default:
_this.log.error(err, 'HL | Error in server, shutting down!');
}
return _this.shutDownSystem();
});
};
}).call(this); }).call(this);

View file

@ -1,7 +1,6 @@
// Generated by CoffeeScript 1.6.3 // Generated by CoffeeScript 1.7.1
(function() { (function() {
var bunyan, fs, path, var bunyan, fs, path;
_this = this;
fs = require('fs'); fs = require('fs');
@ -9,64 +8,66 @@
bunyan = require('bunyan'); bunyan = require('bunyan');
/* /*
Returns a bunyan logger according to the given arguments. Returns a bunyan logger according to the given arguments.
@public getLogger( *args* ) @public getLogger( *args* )
@param {Object} args @param {Object} args
*/ */
exports.getLogger = (function(_this) {
exports.getLogger = function(args) { return function(args) {
var e, emptylog, opt; var e, emptylog, opt;
emptylog = { emptylog = {
trace: function() {}, trace: function() {},
debug: function() {}, debug: function() {},
info: function() {}, info: function() {},
warn: function() {}, warn: function() {},
error: function() {}, error: function() {},
fatal: function() {} fatal: function() {}
}; };
args = args != null ? args : {}; args = args != null ? args : {};
if (args.nolog) { if (args.nolog) {
return emptylog; return emptylog;
} else { } else {
try {
opt = {
name: "webapi-eca"
};
if (args['mode'] === 'development') {
opt.src = true;
}
if (args['file-path']) {
_this.logPath = path.resolve(args['file-path']);
} else {
_this.logPath = path.resolve(__dirname, '..', 'logs', 'server.log');
}
try { try {
fs.writeFileSync(_this.logPath + '.temp', 'temp'); opt = {
fs.unlinkSync(_this.logPath + '.temp'); name: "webapi-eca"
};
if (args['mode'] === 'development') {
opt.src = true;
}
if (args['file-path']) {
_this.logPath = path.resolve(args['file-path']);
} else {
_this.logPath = path.resolve(__dirname, '..', 'logs', 'server.log');
}
try {
fs.writeFileSync(_this.logPath + '.temp', 'temp');
fs.unlinkSync(_this.logPath + '.temp');
} catch (_error) {
e = _error;
console.error("Log folder '" + _this.logPath + "' is not writable");
return emptylog;
}
opt.streams = [
{
level: args['io-level'],
stream: process.stdout
}, {
level: args['file-level'],
path: _this.logPath
}
];
return bunyan.createLogger(opt);
} catch (_error) { } catch (_error) {
e = _error; e = _error;
console.error("Log folder '" + _this.logPath + "' is not writable"); console.error(e);
return emptylog; return emptylog;
} }
opt.streams = [
{
level: args['io-level'],
stream: process.stdout
}, {
level: args['file-level'],
path: _this.logPath
}
];
return bunyan.createLogger(opt);
} catch (_error) {
e = _error;
console.error(e);
return emptylog;
} }
} };
}; })(this);
}).call(this); }).call(this);

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,5 @@
// Generated by CoffeeScript 1.6.3 // Generated by CoffeeScript 1.7.1
/* /*
Request Handler Request Handler
@ -7,12 +8,10 @@ Request Handler
> the [HTTP Listener](http-listener.html). It will handle user requests for > 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 > pages as well as POST requests such as user login, module storing, event
> invocation and also admin commands. > invocation and also admin commands.
*/ */
(function() { (function() {
var crypto, db, dirHandlers, exports, fs, getHandlerPath, getRemoteScripts, getScript, getTemplate, mustache, path, qs, renderPage, var crypto, db, dirHandlers, exports, fs, getHandlerPath, getRemoteScripts, getScript, getTemplate, mustache, path, qs, renderPage;
_this = this;
db = require('./persistence'); db = require('./persistence');
@ -28,32 +27,35 @@ Request Handler
dirHandlers = path.resolve(__dirname, '..', 'webpages', 'handlers'); dirHandlers = path.resolve(__dirname, '..', 'webpages', 'handlers');
exports = module.exports = function(args) { exports = module.exports = (function(_this) {
var fStoreUser, user, users; return function(args) {
_this.log = args.logger; var fStoreUser, user, users;
_this.userRequestHandler = args['request-service']; _this.log = args.logger;
_this.objAdminCmds = { _this.userRequestHandler = args['request-service'];
shutdown: function(obj, cb) { _this.objAdminCmds = {
var data; shutdown: function(obj, cb) {
data = { var data;
code: 200, data = {
message: 'Shutting down... BYE!' code: 200,
}; message: 'Shutting down... BYE!'
setTimeout(args['shutdown-function'], 500); };
return cb(null, data); 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); })(this);
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;
};
/* /*
Handles possible events that were posted to this server and pushes them into the Handles possible events that were posted to this server and pushes them into the
@ -65,8 +67,7 @@ Request Handler
objects.* objects.*
@public handleEvent( *req, resp* ) @public handleEvent( *req, resp* )
*/ */
exports.handleEvent = function(req, resp) { exports.handleEvent = function(req, resp) {
var body; var body;
@ -102,6 +103,7 @@ Request Handler
}); });
}; };
/* /*
Associates the user object with the session if login is successful. Associates the user object with the session if login is successful.
@ -111,32 +113,34 @@ Request Handler
objects.* objects.*
@public handleLogin( *req, resp* ) @public handleLogin( *req, resp* )
*/ */
exports.handleLogin = (function(_this) {
exports.handleLogin = function(req, resp) { return function(req, resp) {
var body; var body;
body = ''; body = '';
req.on('data', function(data) { req.on('data', function(data) {
return body += 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!');
}
}); });
}); 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 A post request retrieved on this handler causes the user object to be
@ -148,8 +152,7 @@ Request Handler
objects.* objects.*
@public handleLogout( *req, resp* ) @public handleLogout( *req, resp* )
*/ */
exports.handleLogout = function(req, resp) { exports.handleLogout = function(req, resp) {
if (req.session) { if (req.session) {
@ -158,25 +161,25 @@ Request Handler
} }
}; };
/* /*
Resolves the path to a handler webpage. Resolves the path to a handler webpage.
@private getHandlerPath( *name* ) @private getHandlerPath( *name* )
@param {String} name @param {String} name
*/ */
getHandlerPath = function(name) { getHandlerPath = function(name) {
return path.join(dirHandlers, name + '.html'); return path.join(dirHandlers, name + '.html');
}; };
/* /*
Fetches a template. Fetches a template.
@private getTemplate( *name* ) @private getTemplate( *name* )
@param {String} name @param {String} name
*/ */
getTemplate = function(name) { getTemplate = function(name) {
var pth; var pth;
@ -184,13 +187,13 @@ Request Handler
return fs.readFileSync(pth, 'utf8'); return fs.readFileSync(pth, 'utf8');
}; };
/* /*
Fetches a script. Fetches a script.
@private getScript( *name* ) @private getScript( *name* )
@param {String} name @param {String} name
*/ */
getScript = function(name) { getScript = function(name) {
var pth; var pth;
@ -198,13 +201,13 @@ Request Handler
return fs.readFileSync(pth, 'utf8'); return fs.readFileSync(pth, 'utf8');
}; };
/* /*
Fetches remote scripts snippets. Fetches remote scripts snippets.
@private getRemoteScripts( *name* ) @private getRemoteScripts( *name* )
@param {String} name @param {String} name
*/ */
getRemoteScripts = function(name) { getRemoteScripts = function(name) {
var pth; var pth;
@ -212,6 +215,7 @@ Request Handler
return fs.readFileSync(pth, 'utf8'); return fs.readFileSync(pth, 'utf8');
}; };
/* /*
Renders a page, with helps of mustache, depending on the user session and returns it. 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 {String} name
@param {Object} sess @param {Object} sess
@param {Object} msg @param {Object} msg
*/ */
renderPage = function(name, req, resp, msg) { renderPage = function(name, req, resp, msg) {
var code, content, data, err, menubar, page, pageElements, pathSkel, remote_scripts, script, skeleton; 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)); return resp.send(code, mustache.render(page, data));
}; };
/* /*
Present the desired forge page to the user. Present the desired forge page to the user.
@ -268,8 +272,7 @@ Request Handler
objects.* objects.*
@public handleForge( *req, resp* ) @public handleForge( *req, resp* )
*/ */
exports.handleForge = function(req, resp) { exports.handleForge = function(req, resp) {
var page; var page;
@ -280,6 +283,7 @@ Request Handler
return renderPage(page, req, resp); return renderPage(page, req, resp);
}; };
/* /*
Handles the user command requests. Handles the user command requests.
@ -289,27 +293,29 @@ Request Handler
objects.* objects.*
@public handleUser( *req, resp* ) @public handleUser( *req, resp* )
*/ */
exports.handleUserCommand = (function(_this) {
exports.handleUserCommand = function(req, resp) { return function(req, resp) {
var body; var body;
if (req.session && req.session.user) { if (req.session && req.session.user) {
body = ''; body = '';
req.on('data', function(data) { req.on('data', function(data) {
return body += 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);
}); });
}); return req.on('end', function() {
} else { var obj;
return resp.send(401, 'Login first!'); 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. Present the admin console to the user if he's allowed to see it.
@ -320,8 +326,7 @@ Request Handler
objects.* objects.*
@public handleForge( *req, resp* ) @public handleForge( *req, resp* )
*/ */
exports.handleAdmin = function(req, resp) { exports.handleAdmin = function(req, resp) {
var msg, page; var msg, page;
@ -336,6 +341,7 @@ Request Handler
return renderPage(page, req, resp, msg); return renderPage(page, req, resp, msg);
}; };
/* /*
Handles the admin command requests. Handles the admin command requests.
@ -345,31 +351,32 @@ Request Handler
objects.* objects.*
@public handleAdminCommand( *req, resp* ) @public handleAdminCommand( *req, resp* )
*/ */
exports.handleAdminCommand = (function(_this) {
exports.handleAdminCommand = function(req, resp) { return function(req, resp) {
var body; var body;
if (req.session && req.session.user && req.session.user.isAdmin === "true") { if (req.session && req.session.user && req.session.user.isAdmin === "true") {
body = ''; body = '';
req.on('data', function(data) { req.on('data', function(data) {
return body += data; return body += data;
}); });
return req.on('end', function() { return req.on('end', function() {
var obj; var obj;
obj = qs.parse(body); obj = qs.parse(body);
_this.log.info('RH | Received admin request: ' + obj.command); _this.log.info('RH | Received admin request: ' + obj.command);
if (obj.command && _this.objAdminCmds[obj.command]) { if (obj.command && _this.objAdminCmds[obj.command]) {
return _this.objAdminCmds[obj.command](obj, function(err, obj) { return _this.objAdminCmds[obj.command](obj, function(err, obj) {
return resp.send(obj.code, obj); return resp.send(obj.code, obj);
}); });
} else { } else {
return resp.send(404, 'Command unknown!'); return resp.send(404, 'Command unknown!');
} }
}); });
} else { } else {
return resp.send(401, 'You need to be logged in as admin!'); return resp.send(401, 'You need to be logged in as admin!');
} }
}; };
})(this);
}).call(this); }).call(this);

View file

@ -1,4 +1,5 @@
// Generated by CoffeeScript 1.6.3 // Generated by CoffeeScript 1.7.1
/* /*
WebAPI-ECA Engine WebAPI-ECA Engine
@ -9,12 +10,10 @@ WebAPI-ECA Engine
> node webapi-eca [opt] > node webapi-eca [opt]
> >
> See below in the optimist CLI preparation for allowed optional parameters `[opt]`. > See below in the optimist CLI preparation for allowed optional parameters `[opt]`.
*/ */
(function() { (function() {
var argv, cm, conf, cp, db, engine, fs, http, init, logger, nameEP, opt, optimist, path, procCmds, shutDown, usage, var argv, cm, conf, cp, db, engine, fs, http, init, logconf, logger, nameEP, opt, optimist, path, procCmds, shutDown, usage;
_this = this;
logger = require('./logging'); logger = require('./logging');
@ -40,10 +39,10 @@ WebAPI-ECA Engine
procCmds = {}; procCmds = {};
/* /*
Let's prepare the optimist CLI optional arguments `[opt]`: Let's prepare the optimist CLI optional arguments `[opt]`:
*/ */
usage = 'This runs your webapi-based ECA engine'; usage = 'This runs your webapi-based ECA engine';
@ -93,113 +92,128 @@ WebAPI-ECA Engine
process.exit(); 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. This function is invoked right after the module is loaded and starts the server.
@private init() @private init()
*/ */
init = (function(_this) {
init = function() { return function() {
var args, logconf; var args;
conf(argv.c); args = {
if (!conf.isReady()) { logger: _this.log,
console.error('FAIL: Config file not ready! Shutting down...'); logconf: logconf
process.exit(); };
} args['http-port'] = parseInt(argv.w || conf.getHttpPort());
logconf = conf.getLogConf(); args['db-port'] = parseInt(argv.d || conf.getDbPort());
if (argv.m) { _this.log.info('RS | Initialzing DB');
logconf['mode'] = argv.m; db(args);
} return db.isConnected(function(err) {
if (argv.i) { var cliArgs, poller;
logconf['io-level'] = argv.i; if (err) {
} _this.log.error('RS | No DB connection, shutting down system!');
if (argv.f) { return shutDown();
logconf['file-level'] = argv.f; } else {
} _this.log.info('RS | Initialzing engine');
if (argv.p) { engine(args);
logconf['file-path'] = argv.p; _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']];
if (argv.n) { poller = cp.fork(path.resolve(__dirname, nameEP), cliArgs);
logconf['nolog'] = argv.n; _this.log.info('RS | Initialzing module manager');
} cm(args);
try { cm.addListener('init', function(evt) {
fs.unlinkSync(path.resolve(__dirname, '..', 'logs', logconf['file-path'])); return poller.send({
} catch (_error) {} event: 'init',
_this.log = logger.getLogger(logconf); data: evt
_this.log.info('RS | STARTING SERVER'); });
args = { });
logger: _this.log, cm.addListener('newRule', function(evt) {
logconf: logconf 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()); })(this);
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);
}
});
};
/* /*
Shuts down the server. Shuts down the server.
@private shutDown() @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 When the server is run as a child process, this function handles messages
from the parent process (e.g. the testing suite) from the parent process (e.g. the testing suite)
*/ */
process.on('message', function(cmd) { process.on('message', function(cmd) {
return typeof procCmds[cmd] === "function" ? procCmds[cmd]() : void 0; return typeof procCmds[cmd] === "function" ? procCmds[cmd]() : void 0;

2
node_modules/my-cryptico/index.js generated vendored
View file

@ -5,4 +5,4 @@ var fs = require('fs');
var filedata = fs.readFileSync('./webpages/public/js/cryptico.js','utf8'); var filedata = fs.readFileSync('./webpages/public/js/cryptico.js','utf8');
eval(filedata); eval(filedata);
exports.cryptico = cryptico exports = module.exports = cryptico;

View file

@ -9,6 +9,8 @@
"url" : "https://github.com/dominicbosch/webapi-eca.git" "url" : "https://github.com/dominicbosch/webapi-eca.git"
}, },
"dependencies": { "dependencies": {
"bunyan": "0.22.1",
"coffee-script": "1.6.3",
"connect-redis": "1.4.6", "connect-redis": "1.4.6",
"crypto-js": "3.1.2", "crypto-js": "3.1.2",
"express": "3.4.8", "express": "3.4.8",
@ -18,8 +20,6 @@
"nodeunit": "0.8.4", "nodeunit": "0.8.4",
"redis": "0.10.0", "redis": "0.10.0",
"request": "2.33.0", "request": "2.33.0",
"coffee-script": "1.6.3",
"bunyan": "0.22.1",
"optimist": "0.6.1" "optimist": "0.6.1"
}, },
"__comment": { "__comment": {

View file

@ -31,6 +31,11 @@
"functions":"[\"newEvent\",\"randomNess\"]" "functions":"[\"newEvent\",\"randomNess\"]"
} }
}, },
"userparams": {
"epUpOne": {
"apikey": "testkey"
}
},
"rules": { "rules": {
"ruleOne": { "ruleOne": {
"id": "ruleOne_id", "id": "ruleOne_id",

View file

@ -1,5 +1,6 @@
fs = require 'fs' fs = require 'fs'
path = require 'path' path = require 'path'
try try
data = fs.readFileSync path.resolve( 'testing', 'files', 'testObjects.json' ), 'utf8' data = fs.readFileSync path.resolve( 'testing', 'files', 'testObjects.json' ), 'utf8'
try try
@ -12,10 +13,10 @@ catch err
logger = require path.join '..', 'js-coffee', 'logging' logger = require path.join '..', 'js-coffee', 'logging'
log = logger.getLogger log = logger.getLogger
nolog: true nolog: true
cm = require path.join '..', 'js-coffee', 'components-manager'
opts = opts =
logger: log logger: log
cm = require path.join '..', 'js-coffee', 'components-manager'
cm opts cm opts
db = require path.join '..', 'js-coffee', 'persistence' db = require path.join '..', 'js-coffee', 'persistence'
@ -24,11 +25,13 @@ db opts
oUser = objects.users.userOne oUser = objects.users.userOne
oRuleOne = objects.rules.ruleOne oRuleOne = objects.rules.ruleOne
oRuleTwo = objects.rules.ruleTwo oRuleTwo = objects.rules.ruleTwo
oEpOne = objects.eps.epOne
oEpTwo = objects.eps.epTwo
exports.tearDown = ( cb ) -> exports.tearDown = ( cb ) ->
db.deleteRule oRuleOne.id db.deleteRule oRuleOne.id
db.deleteRule oRuleTwo.id db.deleteRule oRuleTwo.id
cb() setTimeout cb, 100
exports.requestProcessing = exports.requestProcessing =
testEmptyPayload: ( test ) => testEmptyPayload: ( test ) =>
@ -84,33 +87,54 @@ exports.testListener = ( test ) =>
setTimeout fWaitForInit, 200 setTimeout fWaitForInit, 200
exports.moduleHandling = exports.moduleHandling =
tearDown: ( cb ) ->
db.eventPollers.deleteModule oEpOne.id
db.eventPollers.deleteModule oEpTwo.id
setTimeout cb, 100
testGetModules: ( test ) -> testGetModules: ( test ) ->
test.expect 2 test.expect 2
oModule = objects.eps.epOne db.eventPollers.storeModule oUser.username, oEpOne
db.eventPollers.storeModule oUser.username, oModule
request = request =
command: 'get_event_pollers' command: 'get_event_pollers'
cm.processRequest oUser, request, ( answ ) => cm.processRequest oUser, request, ( answ ) =>
test.strictEqual 200, answ.code, 'GetModules failed...' test.strictEqual 200, answ.code, 'GetModules failed...'
oExpected = {} oExpected = {}
oExpected[oModule.id] = JSON.parse oModule.functions oExpected[oEpOne.id] = JSON.parse oEpOne.functions
test.strictEqual JSON.stringify(oExpected), answ.message, test.strictEqual JSON.stringify(oExpected), answ.message,
'GetModules retrieved modules is not what we expected' 'GetModules retrieved modules is not what we expected'
console.log answ
test.done() test.done()
# testGetModuleParams: ( test ) -> testGetModuleParams: ( test ) ->
# test.expect 1 test.expect 2
# oModule = objects.eps.epOne db.eventPollers.storeModule oUser.username, oEpTwo
# db.eventPollers.storeModule oUser.username, oModule
# request =
# command: 'get_event_pollers'
# cm.processRequest oUser, request, ( answ ) => request =
# test.strictEqual 200, answ.code, 'Empty payload did not return 200' command: 'get_event_poller_params'
# console.log answ payload: '{"id": "' + oEpTwo.id + '"}'
# 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()

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.6.3 // Generated by CoffeeScript 1.7.1
(function() { (function() {
var fOnLoad; var fOnLoad;

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.6.3 // Generated by CoffeeScript 1.7.1
(function() { (function() {
var fOnLoad; var fOnLoad;

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.6.3 // Generated by CoffeeScript 1.7.1
(function() { (function() {
var fOnLoad; var fOnLoad;

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.6.3 // Generated by CoffeeScript 1.7.1
(function() { (function() {
var fOnLoad; var fOnLoad;

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.6.3 // Generated by CoffeeScript 1.7.1
(function() { (function() {
var fOnLoad; var fOnLoad;

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.6.3 // Generated by CoffeeScript 1.7.1
(function() { (function() {
var fOnLoad; var fOnLoad;

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.6.3 // Generated by CoffeeScript 1.7.1
(function() { (function() {
var fOnLoad; var fOnLoad;