man changes and additions to webpages, module storing and rules forge. we're getting there...

This commit is contained in:
Dominic Bosch 2013-12-08 22:59:04 +01:00
parent ad362967ed
commit 2b4bfdc07e
30 changed files with 478 additions and 290 deletions

View file

@ -193,8 +193,8 @@ getSetRecords = ( set, fSingle, cb ) =>
log.error 'DB', new Error 'Empty key in DB: ' + prop
else
objReplies[prop] = data
if semaphore == 0
cb null, objReplies
if semaphore == 0
cb null, objReplies
fSingle reply, fCallback(reply) for reply in arrReply
###
@ -212,7 +212,7 @@ Store a string representation of an action module in the DB.
exports.storeActionModule = ( id, data ) =>
log.print 'DB', 'storeActionModule: ' + id
@db.sadd 'action-modules', id, replyHandler 'storing action module key ' + id
@db.set 'action-module:' + id, data, replyHandler 'storing action module ' + id
@db.hmset 'action-module:' + id, data, replyHandler 'storing action module ' + id
###
Query the DB for an action module and pass it to the callback(err, obj) function.
@ -223,7 +223,7 @@ Query the DB for an action module and pass it to the callback(err, obj) function
###
exports.getActionModule = ( id, cb ) =>
log.print 'DB', 'getActionModule: ' + id
@db.get 'action-module:' + id, cb
@db.hgetall 'action-module:' + id, cb
###
Fetch all action modules and hand them to the callback(err, obj) function.
@ -276,7 +276,7 @@ Store a string representation of an event module in the DB.
exports.storeEventModule = ( id, data ) =>
log.print 'DB', 'storeEventModule: ' + id
@db.sadd 'event-modules', id, replyHandler 'storing event module key ' + id
@db.set 'event-module:' + id, data, replyHandler 'storing event module ' + id
@db.hmset 'event-module:' + id, data, replyHandler 'storing event module ' + id
###
Query the DB for an event module and pass it to the callback(err, obj) function.
@ -287,7 +287,7 @@ Query the DB for an event module and pass it to the callback(err, obj) function.
###
exports.getEventModule = ( id, cb ) =>
log.print 'DB', 'getEventModule: ' + id
@db.get 'event_module:' + id, cb
@db.hgetall 'event-module:' + id, cb
###
Fetch all event modules and pass them to the callback(err, obj) function.
@ -296,7 +296,7 @@ Fetch all event modules and pass them to the callback(err, obj) function.
@param {function} cb
###
exports.getEventModules = ( cb ) ->
getSetRecords 'event_modules', exports.getEventModule, cb
getSetRecords 'event-modules', exports.getEventModule, cb
###
Store a string representation of he authentication parameters for an event module.

View file

@ -68,8 +68,10 @@ exports.addHandlers = ( fShutDown ) ->
app.use '/', express.static path.resolve __dirname, '..', 'webpages', 'public'
# - **`GET` to _"/admin"_:** Only admins can issue requests to this handler
app.get '/admin', requestHandler.handleAdmin
# - **`GET` to _"/forge\_modules"_:** Webpages that lets the user to create modules
# - **`GET` to _"/forge\_modules"_:** Webpage that lets the user create modules
app.get '/forge_modules', requestHandler.handleForgeModules
# - **`GET` to _"/forge\_rules"_:** Webpage that lets the user create rules
app.get '/forge_rules', requestHandler.handleForgeRules
# - **`GET` to _"/invoke\_event"_:** Webpage that lets the user invoke events
app.get '/invoke_event', requestHandler.handleInvokeEvent

View file

@ -31,16 +31,18 @@ crypto = require 'crypto-js'
# Prepare the admin command handlers which are invoked via HTTP requests.
objAdminCmds =
'loadrules': mm.loadRulesFromFS,
'loadaction': mm.loadActionModuleFromFS,
'loadactions': mm.loadActionModulesFromFS,
'loadevent': mm.loadEventModuleFromFS,
'loadrules': mm.loadRulesFromFS
'loadaction': mm.loadActionModuleFromFS
'loadactions': mm.loadActionModulesFromFS
'loadevent': mm.loadEventModuleFromFS
'loadevents': mm.loadEventModulesFromFS
# Prepare the user command handlers which are invoked via HTTP requests.
objUserCmds =
'store_action': mm.storeActionModule
'get_actionmodules': mm.getAllActionModules
'store_event': mm.storeEventModule
'get_eventmodules': mm.getAllEventModules
'store_rule': mm.storeRule
@ -63,7 +65,9 @@ admin command shutdown is issued.
@param {function} fShutdown
###
exports.addHandlers = ( fShutdown ) =>
objAdminCmds.shutdown = fShutdown
objAdminCmds.shutdown = ( args, answerHandler ) ->
answerHandler.answerSuccess 'Shutting down... BYE!'
setTimeout fShutdown, 500
###
@ -164,12 +168,15 @@ Renders a page depending on the user session and returns it.
@param {String} name
@param {Object} sess
###
renderPage = ( name, sess ) ->
renderPage = ( name, sess, msg ) ->
template = getHandlerFileAsString name
menubar = getHandlerFileAsString 'menubar'
menubar = getHandlerFileAsString 'part_menubar'
requires = getHandlerFileAsString 'part_requires'
view =
user: sess.user,
div_menubar: menubar
head_requires: requires,
div_menubar: menubar,
message: msg
mustache.render template, view
###
@ -189,6 +196,45 @@ sendLoginOrPage = ( pagename, req, resp ) ->
else
resp.sendfile getHandlerPath 'login'
###
Present the module forge to the user.
*Requires
the [request](http://nodejs.org/api/http.html#http_class_http_clientrequest)
and [response](http://nodejs.org/api/http.html#http_class_http_serverresponse)
objects.*
@public handleForgeModules( *req, resp* )
###
exports.handleForgeModules = ( req, resp ) ->
sendLoginOrPage 'forge_modules', req, resp
###
Present the rules forge to the user.
*Requires
the [request](http://nodejs.org/api/http.html#http_class_http_clientrequest)
and [response](http://nodejs.org/api/http.html#http_class_http_serverresponse)
objects.*
@public handleForgeRules( *req, resp* )
###
exports.handleForgeRules = ( req, resp ) ->
sendLoginOrPage 'forge_rules', req, resp
###
Present the event invoke page to the user.
*Requires
the [request](http://nodejs.org/api/http.html#http_class_http_clientrequest)
and [response](http://nodejs.org/api/http.html#http_class_http_serverresponse)
objects.*
@public handleInvokeEvent( *req, resp* )
###
exports.handleInvokeEvent = ( req, resp ) ->
sendLoginOrPage 'push_event', req, resp
###
Handles the user command requests.
@ -209,39 +255,11 @@ exports.handleUserCommand = ( req, resp ) ->
body += data
req.on 'end', ->
obj = qs.parse body
if objUserCmds[obj.command] is 'function'
resp.send 'Command accepted!'
objUserCmds[obj.command] req.session.user, obj
if typeof objUserCmds[obj.command] is 'function'
objUserCmds[obj.command] req.session.user, obj, answerHandler req, resp
else
resp.send 404, 'Command unknown!'
###
Present the module forge to the user.
*Requires
the [request](http://nodejs.org/api/http.html#http_class_http_clientrequest)
and [response](http://nodejs.org/api/http.html#http_class_http_serverresponse)
objects.*
@public handleForgeModules( *req, resp* )
###
exports.handleForgeModules = ( req, resp ) ->
sendLoginOrPage 'forge_modules', req, resp
###
Present the event invoke page to the user.
*Requires
the [request](http://nodejs.org/api/http.html#http_class_http_clientrequest)
and [response](http://nodejs.org/api/http.html#http_class_http_serverresponse)
objects.*
@public handleInvokeEvent( *req, resp* )
###
exports.handleInvokeEvent = ( req, resp ) ->
sendLoginOrPage 'push_event', req, resp
###
Handles the admin command requests.
@ -255,48 +273,44 @@ objects.*
exports.handleAdmin = ( req, resp ) ->
if req.session and req.session.user
if req.session.user.isAdmin is "true"
resp.send renderPage 'welcome', req.session
q = req.query
log.print 'RH', 'Received admin request: ' + req.originalUrl
if q.cmd
objAdminCmds[q.cmd]? q, answerHandler req, resp, true
else
resp.send 404, 'Command unknown!'
else
resp.send renderPage 'unauthorized', req.session
else
resp.sendfile getHandlerPath 'login'
onAdminCommand = ( req, response ) ->
q = req.query
log.print 'RH', 'Received admin request: ' + q
if q.cmd
fAdminCommands q, answerHandler response
#answerSuccess(response, 'Thank you, we try our best!');
else answerError response, 'I\'m not sure about what you want from me...'
answerHandler = (req, resp, ntbr) ->
request = req
response = resp
needsToBeRendered = ntbr
hasBeenAnswered = false
ret =
answerSuccess: (msg) ->
if not hasBeenAnswered
if needsToBeRendered
response.send renderPage 'command_answer', request.session, msg
else
response.send msg
hasBeenAnswered = true
,
answerError: (msg) ->
if not hasBeenAnswered
if needsToBeRendered
response.send 400, renderPage 'error', request.session, msg
else
response.send 400, msg
hasBeenAnswered = true
,
isAnswered: -> hasBeenAnswered
setTimeout(() ->
ret.answerError 'Strange... maybe try again?'
, 5000)
ret
###
admin commands handler receives all command arguments and an answerHandler
object that eases response handling to the HTTP request issuer.
@private fAdminCommands( *args, answHandler* )
###
fAdminCommands = ( args, answHandler ) ->
if args and args.cmd
adminCmds[args.cmd]? args, answHandler
else
log.print 'RH', 'No command in request'
###
The fAnsw function receives an answerHandler object as an argument when called
and returns an anonymous function
###
fAnsw = ( ah ) ->
###
The anonymous function checks whether the answerHandler was already used to
issue an answer, if no answer was provided we answer with an error message
###
() ->
if not ah.isAnswered()
ah.answerError 'Not handled...'
###
Delayed function call of the anonymous function that checks the answer handler
###
setTimeout fAnsw(answHandler), 2000

View file

@ -240,14 +240,14 @@ DB Interface
--semaphore;
if (err) {
err.addInfo = 'fetching single element: ' + prop;
return log.error('DB', err);
log.error('DB', err);
} else if (!data) {
return log.error('DB', new Error('Empty key in DB: ' + prop));
log.error('DB', new Error('Empty key in DB: ' + prop));
} else {
objReplies[prop] = data;
if (semaphore === 0) {
return cb(null, objReplies);
}
}
if (semaphore === 0) {
return cb(null, objReplies);
}
};
};
@ -278,7 +278,7 @@ DB Interface
exports.storeActionModule = function(id, data) {
log.print('DB', 'storeActionModule: ' + id);
_this.db.sadd('action-modules', id, replyHandler('storing action module key ' + id));
return _this.db.set('action-module:' + id, data, replyHandler('storing action module ' + id));
return _this.db.hmset('action-module:' + id, data, replyHandler('storing action module ' + id));
};
/*
@ -292,7 +292,7 @@ DB Interface
exports.getActionModule = function(id, cb) {
log.print('DB', 'getActionModule: ' + id);
return _this.db.get('action-module:' + id, cb);
return _this.db.hgetall('action-module:' + id, cb);
};
/*
@ -357,7 +357,7 @@ DB Interface
exports.storeEventModule = function(id, data) {
log.print('DB', 'storeEventModule: ' + id);
_this.db.sadd('event-modules', id, replyHandler('storing event module key ' + id));
return _this.db.set('event-module:' + id, data, replyHandler('storing event module ' + id));
return _this.db.hmset('event-module:' + id, data, replyHandler('storing event module ' + id));
};
/*
@ -371,7 +371,7 @@ DB Interface
exports.getEventModule = function(id, cb) {
log.print('DB', 'getEventModule: ' + id);
return _this.db.get('event_module:' + id, cb);
return _this.db.hgetall('event-module:' + id, cb);
};
/*
@ -383,7 +383,7 @@ DB Interface
exports.getEventModules = function(cb) {
return getSetRecords('event_modules', exports.getEventModule, cb);
return getSetRecords('event-modules', exports.getEventModule, cb);
};
/*

View file

@ -20,8 +20,8 @@ var fs = require('fs'),
function init() {
if(process.argv.length > 2) log({ logType: parseInt(process.argv[2]) || 0 });
var args = { logType: log.getLogType() };
ml = require('./module_loader')(args);
db = require('./db_interface')(args);
(ml = require('./module_loader'))(args);
(db = require('./db_interface'))(args);
initAdminCommands();
initMessageActions();
pollLoop();

View file

@ -59,6 +59,7 @@ HTTP Listener
app.use('/', express["static"](path.resolve(__dirname, '..', 'webpages', 'public')));
app.get('/admin', requestHandler.handleAdmin);
app.get('/forge_modules', requestHandler.handleForgeModules);
app.get('/forge_rules', requestHandler.handleForgeRules);
app.get('/invoke_event', requestHandler.handleInvokeEvent);
app.post('/event', requestHandler.handleEvent);
app.post('/login', requestHandler.handleLogin);

View file

@ -93,3 +93,9 @@ exports.error = function(module, err) {
exports.severe = function(module, err) {
printError(module, err, true);
};
exports.obj = function (varname, obj) {
var arrS = (new Error).stack.split('\n');
console.log('Dumping object "' + varname + '"' + arrS[2]);
console.log(obj);
};

View file

@ -0,0 +1 @@
// Store debug information on first compilation and return it to the user

View file

@ -13,25 +13,20 @@ exports = module.exports = function(args) {
exports.requireFromString = function(src, name, dir) {
if(!dir) dir = __dirname;
var id = path.resolve(dir, name, name + '.vm');
//FIXME load modules only into a safe environment with given modules, no access to whole application,
var vm = require('vm'),
// FIXME not log but debug module is required to provide information to the user
sandbox = {
id: id, // use this to gather kill info
needle: require('needle'),
log: log,
needle: require('needle')
exports: {}
};
var mod = vm.runInNewContext(src, sandbox, 'myfile.vm');
console.log(mod);
var m = new module.constructor(id, module);
m.paths = module.paths;
try {
m._compile(src);
} catch(err) {
err.addInfo = 'during compilation of module ' + name;
log.error('LM', err);
// log.error('LM', ' during compilation of ' + name + ': ' + err);
}
return m.exports;
//TODO child_process to run module!
// Define max runtime per loop as 10 seconds, after that the child will be killed
// 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?
var mod = vm.runInNewContext(src, sandbox, id + '.vm');
return sandbox.exports;
};
exports.loadModule = function(directory, name, callback) {

View file

@ -23,20 +23,47 @@ exports = module.exports = function(args) {
exports.addDBLink = function(db_link) {
db = db_link;
// funcLoadAction = fLoadAction;
// funcLoadRule = fLoadRule;
};
exports.storeEventModule = function (user, obj) {
log.print('MM', 'implement storeEventModule');
exports.storeEventModule = function (user, obj, answHandler) {
try {
// TODO in the future we might want to link the modules close to the user
// and allow for e.g. private modules
// we need a child process to run this code and kill it after invocation
var m = ml.requireFromString(obj.data, obj.id);
obj.methods = Object.keys(m);
answHandler.answerSuccess('Thank you for the event module!');
db.storeEventModule(obj.id, obj);
} catch (err) {
answHandler.answerError(err.message);
console.error(err);
}
};
exports.storeActionModule = function (user, obj) {
log.print('MM', 'implement storeActionModule');
exports.getAllEventModules = function ( user, obj, answHandler ) {
db.getEventModules(function(err, obj) {
if(err) answHandler.answerError('Failed fetching event modules: ' + err.message);
else answHandler.answerSuccess(obj);
});
};
exports.storeRule = function (user, obj) {
exports.storeActionModule = function (user, obj, answHandler) {
var m = ml.requireFromString(obj.data, obj.id);
obj.methods = Object.keys(m);
answHandler.answerSuccess('Thank you for the action module!');
db.storeActionModule(obj.id, obj);
};
exports.getAllActionModules = function ( user, obj, answHandler ) {
db.getActionModules(function(err, obj) {
if(err) answHandler.answerError('Failed fetching action modules: ' + err.message);
else answHandler.answerSuccess(obj);
});
};
exports.storeRule = function (user, obj, answHandler) {
log.print('MM', 'implement storeRule');
answHandler.answerSuccess('Thank you for the rule!');
};

View file

@ -8,7 +8,7 @@ Request Handler
(function() {
var crypto, db, exports, fAdminCommands, fs, getHandlerFileAsString, getHandlerPath, log, mm, mustache, objAdminCmds, objUserCmds, onAdminCommand, path, qs, renderPage, sendLoginOrPage,
var answerHandler, crypto, db, exports, fs, getHandlerFileAsString, getHandlerPath, log, mm, mustache, objAdminCmds, objUserCmds, path, qs, renderPage, sendLoginOrPage,
_this = this;
log = require('./logging');
@ -37,7 +37,9 @@ Request Handler
objUserCmds = {
'store_action': mm.storeActionModule,
'get_actionmodules': mm.getAllActionModules,
'store_event': mm.storeEventModule,
'get_eventmodules': mm.getAllEventModules,
'store_rule': mm.storeRule
};
@ -67,7 +69,10 @@ Request Handler
exports.addHandlers = function(fShutdown) {
return objAdminCmds.shutdown = fShutdown;
return objAdminCmds.shutdown = function(args, answerHandler) {
answerHandler.answerSuccess('Shutting down... BYE!');
return setTimeout(fShutdown, 500);
};
};
/*
@ -196,13 +201,16 @@ Request Handler
*/
renderPage = function(name, sess) {
var menubar, template, view;
renderPage = function(name, sess, msg) {
var menubar, requires, template, view;
template = getHandlerFileAsString(name);
menubar = getHandlerFileAsString('menubar');
menubar = getHandlerFileAsString('part_menubar');
requires = getHandlerFileAsString('part_requires');
view = {
user: sess.user,
div_menubar: menubar
head_requires: requires,
div_menubar: menubar,
message: msg
};
return mustache.render(template, view);
};
@ -228,6 +236,54 @@ Request Handler
}
};
/*
Present the module forge to the user.
*Requires
the [request](http://nodejs.org/api/http.html#http_class_http_clientrequest)
and [response](http://nodejs.org/api/http.html#http_class_http_serverresponse)
objects.*
@public handleForgeModules( *req, resp* )
*/
exports.handleForgeModules = function(req, resp) {
return sendLoginOrPage('forge_modules', req, resp);
};
/*
Present the rules forge to the user.
*Requires
the [request](http://nodejs.org/api/http.html#http_class_http_clientrequest)
and [response](http://nodejs.org/api/http.html#http_class_http_serverresponse)
objects.*
@public handleForgeRules( *req, resp* )
*/
exports.handleForgeRules = function(req, resp) {
return sendLoginOrPage('forge_rules', req, resp);
};
/*
Present the event invoke page to the user.
*Requires
the [request](http://nodejs.org/api/http.html#http_class_http_clientrequest)
and [response](http://nodejs.org/api/http.html#http_class_http_serverresponse)
objects.*
@public handleInvokeEvent( *req, resp* )
*/
exports.handleInvokeEvent = function(req, resp) {
return sendLoginOrPage('push_event', req, resp);
};
/*
Handles the user command requests.
@ -252,9 +308,8 @@ Request Handler
return req.on('end', function() {
var obj;
obj = qs.parse(body);
if (objUserCmds[obj.command] === 'function') {
resp.send('Command accepted!');
return objUserCmds[obj.command](req.session.user, obj);
if (typeof objUserCmds[obj.command] === 'function') {
return objUserCmds[obj.command](req.session.user, obj, answerHandler(req, resp));
} else {
return resp.send(404, 'Command unknown!');
}
@ -262,38 +317,6 @@ Request Handler
}
};
/*
Present the module forge to the user.
*Requires
the [request](http://nodejs.org/api/http.html#http_class_http_clientrequest)
and [response](http://nodejs.org/api/http.html#http_class_http_serverresponse)
objects.*
@public handleForgeModules( *req, resp* )
*/
exports.handleForgeModules = function(req, resp) {
return sendLoginOrPage('forge_modules', req, resp);
};
/*
Present the event invoke page to the user.
*Requires
the [request](http://nodejs.org/api/http.html#http_class_http_clientrequest)
and [response](http://nodejs.org/api/http.html#http_class_http_serverresponse)
objects.*
@public handleInvokeEvent( *req, resp* )
*/
exports.handleInvokeEvent = function(req, resp) {
return sendLoginOrPage('push_event', req, resp);
};
/*
Handles the admin command requests.
@ -307,9 +330,16 @@ Request Handler
exports.handleAdmin = function(req, resp) {
var q, _name;
if (req.session && req.session.user) {
if (req.session.user.isAdmin === "true") {
return resp.send(renderPage('welcome', req.session));
q = req.query;
log.print('RH', 'Received admin request: ' + req.originalUrl);
if (q.cmd) {
return typeof objAdminCmds[_name = q.cmd] === "function" ? objAdminCmds[_name](q, answerHandler(req, resp, true)) : void 0;
} else {
return resp.send(404, 'Command unknown!');
}
} else {
return resp.send(renderPage('unauthorized', req.session));
}
@ -318,56 +348,41 @@ Request Handler
}
};
onAdminCommand = function(req, response) {
var q;
q = req.query;
log.print('RH', 'Received admin request: ' + q);
if (q.cmd) {
return fAdminCommands(q, answerHandler(response));
} else {
return answerError(response, 'I\'m not sure about what you want from me...');
}
};
/*
admin commands handler receives all command arguments and an answerHandler
object that eases response handling to the HTTP request issuer.
@private fAdminCommands( *args, answHandler* )
*/
fAdminCommands = function(args, answHandler) {
var fAnsw, _name;
if (args && args.cmd) {
if (typeof adminCmds[_name = args.cmd] === "function") {
adminCmds[_name](args, answHandler);
}
} else {
log.print('RH', 'No command in request');
}
/*
The fAnsw function receives an answerHandler object as an argument when called
and returns an anonymous function
*/
fAnsw = function(ah) {
/*
The anonymous function checks whether the answerHandler was already used to
issue an answer, if no answer was provided we answer with an error message
*/
return function() {
if (!ah.isAnswered()) {
return ah.answerError('Not handled...');
answerHandler = function(req, resp, ntbr) {
var hasBeenAnswered, needsToBeRendered, request, response, ret;
request = req;
response = resp;
needsToBeRendered = ntbr;
hasBeenAnswered = false;
ret = {
answerSuccess: function(msg) {
if (!hasBeenAnswered) {
if (needsToBeRendered) {
response.send(renderPage('command_answer', request.session, msg));
} else {
response.send(msg);
}
}
};
return hasBeenAnswered = true;
},
answerError: function(msg) {
if (!hasBeenAnswered) {
if (needsToBeRendered) {
response.send(400, renderPage('error', request.session, msg));
} else {
response.send(400, msg);
}
}
return hasBeenAnswered = true;
},
isAnswered: function() {
return hasBeenAnswered;
}
};
/*
Delayed function call of the anonymous function that checks the answer handler
*/
return setTimeout(fAnsw(answHandler), 2000);
setTimeout(function() {
return ret.answerError('Strange... maybe try again?');
}, 5000);
return ret;
};
}).call(this);

View file

@ -42,7 +42,7 @@ exports.addDBLinkAndLoadActionsAndRules = function(db_link) {
var m;
for(var el in obj) {
log.print('EN', 'Loading Action Module from DB: ' + el);
try{
try {
m = ml.requireFromString(obj[el], el);
db.getActionModuleAuth(el, function(mod) {
return function(err, obj) {

View file

@ -23,11 +23,29 @@ exports = module.exports = function(args) {
exports.addDBLink = function(db_link) {
db = db_link;
//TODO Remove fLoadAction and fLoadRule and replace them with user commands
// funcLoadAction = fLoadAction;
// funcLoadRule = fLoadRule;
};
exports.storeEventModule = function (user, obj, answHandler) {
log.print('MM', 'implement storeEventModule');
answHandler.answerSuccess('Thank you for the event!');
};
exports.storeActionModule = function (user, obj, answHandler) {
log.print('MM', 'implement storeActionModule');
answHandler.answerSuccess('Thank you for the action!');
};
exports.storeRule = function (user, obj, answHandler) {
log.print('MM', 'implement storeRule');
answHandler.answerSuccess('Thank you for the rule!');
};
/*
* Legacy file system loaders
*/
/*
* Load Rules from fs
* ------------------
@ -35,8 +53,8 @@ exports.addDBLink = function(db_link) {
exports.loadRulesFromFS = function(args, answHandler) {
if(!args) args = {};
if(!args.name) args.name = 'rules';
// if(!funcLoadRule) log.error('ML', 'no rule loader function available');
// else {
if(!funcLoadRule) log.error('ML', 'no rule loader function available');
else {
fs.readFile(path.resolve(__dirname, '..', 'rules', args.name + '.json'), 'utf8', function (err, data) {
if (err) {
log.error('ML', 'Loading rules file: ' + args.name + '.json');
@ -55,7 +73,7 @@ exports.loadRulesFromFS = function(args, answHandler) {
log.error('ML', 'rules file was corrupt! (' + args.name + '.json)');
}
});
// }
}
};
/*
@ -79,7 +97,7 @@ function loadActionCallback(name, data, mod, auth) {
exports.loadActionModuleFromFS = function (args, answHandler) {
if(ml) {
if(args && args.name) {
answHandler.answerSuccess('Loading action module ' + args.name + '...');
answHandler.answerSuccess('Loading action module ' + args.name + '...');
ml.loadModule('mod_actions', args.name, loadActionCallback);
} else log.error('MM', 'Action Module name not provided!');
}
@ -87,7 +105,7 @@ exports.loadActionModuleFromFS = function (args, answHandler) {
exports.loadActionModulesFromFS = function(args, answHandler) {
if(ml) {
answHandler.answerSuccess('Loading action modules...');
answHandler.answerSuccess('Loading action modules...');
ml.loadModules('mod_actions', loadActionCallback);
}
};

View file

@ -6,9 +6,7 @@
var urlService = 'https://probinder.com/service/',
credentials = null;
log.print('PB', module);
log.print('PB', exports);
log.print('PB', module.exports);
function loadCredentials(cred) {
if(!cred || !cred.username || !cred.password) {
console.error('ERROR: ProBinder AM credentials file corrupt');

View file

@ -1,3 +0,0 @@
{
"test": "should stay"
}

View file

@ -1,3 +0,0 @@
{
"test": "should stay"
}

View file

@ -1,8 +1,6 @@
log.print('action testing.js');
log.print(module);
log.print(module.exports);
console.log(exports);
console.log(module.exports);
log.print('TT', 'action testing.js');
log.obj('exports', exports);
log.obj('this', this);
/*
// Hacking my own system...
console.log(module.parent.parent.children[0].exports.getEventModuleAuth('probinder',
@ -12,9 +10,9 @@ console.log(module.exports);
//FIXME do not try to delete a file and rely on it to exist, rather try to create it first! o check for its existance and then delete it
try {
fs.unlinkSync(path.resolve(__dirname, 'event_modules', 'malicious', 'test.json'));
console.error('VERY BAD! NEVER START THIS SERVER WITH A USER THAT HAS WRITE RIGHTS ANYWHERE!!!');
log.error('VERY BAD! NEVER START THIS SERVER WITH A USER THAT HAS WRITE RIGHTS ANYWHERE!!!');
} catch (err) {
console.log('VERY GOOD! USERS CANNOT WRITE ON YOUR DISK!');
log.print('VERY GOOD! USERS CANNOT WRITE ON YOUR DISK!');
}
throw new Error('Testing your error handling');

View file

@ -1,3 +0,0 @@
{
"test": "should stay"
}

View file

@ -1,3 +0,0 @@
{
"test": "should stay"
}

View file

@ -16,3 +16,8 @@ try {
//FIXME add several standard methods for testing (also rules to be inserted during testing)
throw new Error('Testing your error handling');
// FIXME catch these cases by instantiating a child process to run on a event retrieval
// then if the child_process doesn't end automatically after a certain time (statistics?)
// it ha sto be killed
// while (true) {}

View file

@ -1,17 +1,15 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Command "{{command}}" Result</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src='//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js' type='text/javascript'></script>
<title>Command Result</title>
{{{head_requires}}}
</head>
<body>
{{{div_menubar}}}
<div id="mainbody">
<div id="pagetitle">Hi {{user.username}}, that was unauthorized!</div>
<div id="pagetitle">Hi {{user.username}}, response to your command:</div>
<p>
Sorry this roles is missing for you.<br />
You only have these privileges: {{user.roles}}
{{message}}
</p>
</div>
</body>

View file

@ -0,0 +1,16 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Error!</title>
{{{head_requires}}}
</head>
<body>
{{{div_menubar}}}
<div id="mainbody">
<div id="pagetitle">Sorry {{user.username}}, there was an error!</div>
<p>
Error: {{message}}
</p>
</div>
</body>
</html>

View file

@ -2,9 +2,9 @@
<html>
<head>
<title>Forge A Module</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src='//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js' type='text/javascript'></script>
<script type = "text/template" id="templ_action">
{{{head_requires}}}
<script type = "text/template" id="templ_action">
exports.myOwnActionFunction = function( args ) {
var data = {
companyId: '961',
@ -13,21 +13,33 @@ exports.myOwnActionFunction = function( args ) {
};
needle.post('https://probinder.com/service/27/save', data);
};
</script>
<script type = "text/template" id="templ_event">
</script>
<script type = "text/template" id="templ_event">
exports.myOwnEventFunction = function( callback ) {
var myEvent = {
event: 'mail',
eventid: 'mail_0',
payload: {
subject: 'My mail event subject'
body: 'Complex text body'
}
}
callback( myEvent );
var myEvent = {
event: 'mail',
eventid: 'mail_0',
payload: {
subject: 'My mail event subject',
body: 'Complex text body'
}
};
callback( myEvent );
};
</script>
</script>
<script type = "text/template" id="templ_params">
[
username: {
description: "The username for the Web API"
},
password: {
description: "The password for the Web API"
}
]
</script>
</head>
<body>
{{{div_menubar}}}
@ -39,10 +51,25 @@ exports.myOwnEventFunction = function( callback ) {
<option value="1">Event Module</option>
</select>
</p>
<p>
<textarea id="textarea_module" rows="30" cols="100">
</textarea>
</p>
<p>
Module name: <input type="text" id="input_id" />
</p>
<p>
<textarea id="textarea_module" rows="20" cols="100">
</textarea>
</p>
<p>
Description of module:<br />
<textarea id="textarea_description" rows="2" cols="100">This module does...</textarea>
</p>
<p>
<!-- <input id="checkbox_public" type="checkbox"> Module is public, reusable for everybody<br />-->
<input id="checkbox_params" type="checkbox"> Module requires user-specific parameters
</p>
<p>
<textarea id="textarea_params" rows="10" cols="40">
</textarea>
</p>
<p>
<button id="but_submit">save</button>
</p>
@ -57,21 +84,35 @@ exports.myOwnEventFunction = function( callback ) {
}
});
$('#but_submit').click(function() {
var obj = { data: $('#textarea_event').val() };
if($('#select_type').val() === '0') obj.command = 'store_action';
else obj.command = 'store_event';
console.log('posting:');
console.log(obj);
$.post('usercommand', obj)
.done(function(data) {
alert(data);
})
.fail(function(err) {
console.log(err);
alert('Posting of module failed: ' + err.responseText);
});
if($('#input_id').val() === '') alert('Please enter a module name!');
else {
var obj = {
id: $('#input_id').val(),
data: $('#textarea_module').val(),
description: $('#textarea_description').val(),
// ispublic: $('#checkbox_public').is(':checked')
};
if($('#checkbox_params').is(':checked')) {
obj.params = $('#textarea_params').val();
}
if($('#select_type').val() === '0') obj.command = 'store_action';
else obj.command = 'store_event';
$.post('/usercommand', obj)
.done(function(data) {
alert(data);
})
.fail(function(err) {
console.error(err);
alert('Posting of module failed: ' + err.responseText);
});
}
});
$('#textarea_module').val($('#templ_action').html());
$('#checkbox_params').click(function() {
$('#textarea_params').toggle();
});
$('#textarea_module').val($('#templ_action').html());
$('#textarea_params').val($('#templ_params').html());
$('#textarea_params').hide();
</script>
</body>
</html>

View file

@ -0,0 +1,65 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Forge A Rule</title>
{{{head_requires}}}
</head>
<body>
{{{div_menubar}}}
<div id="mainbody">
<div id="pagetitle">Hi {{user.username}}, forge your own rules!</div>
<p>
<input type="radio" name="radio_event" id="radio_input" checked />
<input type="text" id="input_event" /><br />
<input type="radio" name="radio_event" id="radio_select" />
<select id="select_event">
</select>
</p>
<p>
<button id="but_submit">save</button>
</p>
</div>
<script type="text/javascript">
$('#but_submit').click(function() {
var obj = {
command : 'store_rule',
data: $('#textarea_event').val()
};
$.post('/usercommand', obj)
.done(function(data) {
alert(data);
})
.fail(function(err) {
console.log(err);
alert('Posting of rule failed: ' + err.responseText);
});
});
$.post('/usercommand', { command: 'get_actionmodules' })
.done(function(data) {
for(var el in data) {
}
});
$.post('/usercommand', { command: 'get_eventmodules' })
.done(function(data) {
for(var mod in data) {
var mthds = data[mod].methods;
if(mthds) {
var arr = mthds.split(',');
for(var i = 0; i < arr.length; i++) {
$('#select_event').append($('<option>').text(mod + '->' + arr[i]));
}
}
}
});
$('#input_event').focus(function() {
$('#radio_input').prop('checked', true);
});
$('#select_event').focus(function() {
$('#radio_select').prop('checked', true);
});
</script>
</body>
</html>

View file

@ -10,7 +10,7 @@
<div id="mainbody">
<div id="pagetitle">Login</div>
<table>
<tr><td>username: </td><td><input type="text" id="username" /></td></tr>
<tr><td>username: </td><td><input type="text" id="username" autofocus /></td></tr>
<tr><td>password: </td><td><input type="password" id="password" /></td></tr>
</table>
<button id="but_submit">login</button>
@ -18,7 +18,7 @@
<script>
$('#but_submit').click(function() {
var hashedPassword = (CryptoJS.SHA3($('#password').val(), { outputLength: 512 })).toString();
$.post('../login', { username: $('#username').val(), password: hashedPassword })
$.post('/login', { username: $('#username').val(), password: hashedPassword })
.done(function(data) {
window.location.href = document.URL;
})

View file

@ -3,9 +3,9 @@
<div id="menubar_logout">logout</div>
<script>
$('#menubar_logout').click(function() {
$.post('../logout').done(function() {
$.post('/logout').done(function() {
window.location.href = document.URL;
});
});
</script>
</div>
</div>

View file

@ -0,0 +1,3 @@
<link rel="stylesheet" type="text/css" href="style.css">
<script src='//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js' type='text/javascript'></script>

View file

@ -2,8 +2,7 @@
<html>
<head>
<title>Invoke an event</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src='//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js' type='text/javascript'></script>
{{{head_requires}}}
</head>
<body>
{{{div_menubar}}}
@ -27,7 +26,7 @@
<script>
$('#but_submit').click(function() {
$.post('../event', JSON.parse($('#textarea_event').val()))
$.post('/event', JSON.parse($('#textarea_event').val()))
.done(function(data) {
alert(data);
})

View file

@ -2,8 +2,7 @@
<html>
<head>
<title>Unauthorized {{user.username}}</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src='//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js' type='text/javascript'></script>
{{{head_requires}}}
</head>
<body>
{{{div_menubar}}}

View file

@ -2,8 +2,7 @@
<html>
<head>
<title>Welcome {{user.username}}!</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src='//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js' type='text/javascript'></script>
{{{head_requires}}}
</head>
<body>
{{{div_menubar}}}