user command enhancements, module forge

This commit is contained in:
Dominic Bosch 2013-11-29 18:41:55 +01:00
parent 1342d0b2de
commit ad362967ed
12 changed files with 315 additions and 75 deletions

View file

@ -61,19 +61,28 @@ exports.addHandlers = ( fShutDown ) ->
log.print 'HL', 'no session backbone'
# **Accepted requests to paths:**
# GET Requests
# - **`GET` to _"/"_:** Static redirect to the _"webpages/public"_ directory
app.use '/', express.static path.resolve __dirname, '..', 'webpages', 'public'
# - **`POST` to _"/event"_:** Events coming from remote systems are passed to the engine
app.post '/event', requestHandler.handleEvent
# - **`GET` to _"/user"_:** User requests are possible for all users with an account
app.get '/user', requestHandler.handleUser
# - **`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
app.get '/forge_modules', requestHandler.handleForgeModules
# - **`GET` to _"/invoke\_event"_:** Webpage that lets the user invoke events
app.get '/invoke_event', requestHandler.handleInvokeEvent
# POST Requests
# - **`POST` to _"/event"_:** Events coming from remote systems are passed to the engine
app.post '/event', requestHandler.handleEvent
# - **`POST` to _"/login"_:** Credentials will be verified
app.post '/login', requestHandler.handleLogin
# - **`POST` to _"/logout"_:** User will be logged out
app.post '/logout', requestHandler.handleLogout
# - **`POST` to _"/user"_:** User requests are possible for all users with an account
app.post '/usercommand', requestHandler.handleUserCommand
try
http_port = config.getHttpPort()
if http_port

View file

@ -29,13 +29,19 @@ qs = require 'querystring'
mustache = require 'mustache'
crypto = require 'crypto-js'
# Prepare the admin command handlers that are invoked via HTTP requests.
# Prepare the admin command handlers which are invoked via HTTP requests.
objAdminCmds =
'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
'store_event': mm.storeEventModule
'store_rule': mm.storeRule
exports = module.exports = ( args ) ->
@ -79,7 +85,7 @@ exports.handleEvent = ( req, resp ) =>
obj = qs.parse body
# If required event properties are present we process the event #
if obj and obj.event and obj.eventid
resp.send 'Thank you for the event (' + obj.event + '[' + obj.eventid + '])!'
resp.send 'Thank you for the event: ' + obj.event + ' (' + obj.eventid + ')!'
db.pushEvent obj
else
resp.writeHead 400, { "Content-Type": "text/plain" }
@ -152,6 +158,41 @@ getHandlerFileAsString = ( name ) ->
fs.readFileSync getHandlerPath( name ), 'utf8'
###
Renders a page depending on the user session and returns it.
@private renderPage( *name, sess* )
@param {String} name
@param {Object} sess
###
renderPage = ( name, sess ) ->
template = getHandlerFileAsString name
menubar = getHandlerFileAsString 'menubar'
view =
user: sess.user,
div_menubar: menubar
mustache.render template, view
###
Sends the desired page or the login 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 renderPageOrLogin( *req, resp, pagename* )
@param {String} pagename
###
sendLoginOrPage = ( pagename, req, resp ) ->
if req.session and req.session.user
resp.send renderPage pagename, req.session
else
resp.sendfile getHandlerPath 'login'
###
Handles the user command requests.
*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)
@ -159,19 +200,50 @@ objects.*
@public handleUser( *req, resp* )
###
exports.handleUser = ( req, resp ) ->
if req.session and req.session.user
welcome = getHandlerFileAsString 'welcome'
menubar = getHandlerFileAsString 'menubar'
view = {
user: req.session.user,
div_menubar: menubar
}
resp.send mustache.render welcome, view
exports.handleUserCommand = ( req, resp ) ->
if not req.session or not req.session.user
resp.send 401, 'Login first!'
else
resp.sendfile getHandlerPath 'login'
body = ''
req.on 'data', ( data ) ->
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
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.
*Requires
the [request](http://nodejs.org/api/http.html#http_class_http_clientrequest)
@ -183,19 +255,9 @@ objects.*
exports.handleAdmin = ( req, resp ) ->
if req.session and req.session.user
if req.session.user.isAdmin is "true"
welcome = getHandlerFileAsString 'welcome'
menubar = getHandlerFileAsString 'menubar'
view =
user: req.session.user,
div_menubar: menubar
resp.send mustache.render welcome, view
resp.send renderPage 'welcome', req.session
else
unauthorized = getHandlerFileAsString 'unauthorized'
menubar = getHandlerFileAsString 'menubar'
view =
user: req.session.user,
div_menubar: menubar
resp.send mustache.render unauthorized, view
resp.send renderPage 'unauthorized', req.session
else
resp.sendfile getHandlerPath 'login'

View file

@ -29,8 +29,6 @@ exports = module.exports = function(args) {
*/
exports.addDBLinkAndLoadActionsAndRules = function(db_link) {
db = db_link;
if(!db) log.error('EN', 'No DB!');
console.log(db);
if(ml && db) db.getActionModules(function(err, obj) {
if(err) log.error('EN', 'retrieving Action Modules from DB!');
else {
@ -109,10 +107,6 @@ function pollQueue() {
}
setTimeout(pollQueue, 50); //TODO adapt to load
});
// var evt = qEvents.dequeue();
// if(evt) {
// processEvent(evt);
// }
}
}
@ -173,6 +167,7 @@ function invokeAction(evt, action) {
var srvc = listActionModules[arrModule[0]];
if(srvc && srvc[arrModule[1]]) {
//FIXME preprocessing not only on data
//FIXME no preprocessing at all, why don't we just pass the whole event to the action?'
preprocessActionArguments(evt.payload, action.arguments, actionargs);
try {
if(srvc[arrModule[1]]) srvc[arrModule[1]](actionargs);

View file

@ -57,11 +57,13 @@ HTTP Listener
}));
log.print('HL', 'no session backbone');
app.use('/', express["static"](path.resolve(__dirname, '..', 'webpages', 'public')));
app.post('/event', requestHandler.handleEvent);
app.get('/user', requestHandler.handleUser);
app.get('/admin', requestHandler.handleAdmin);
app.get('/forge_modules', requestHandler.handleForgeModules);
app.get('/invoke_event', requestHandler.handleInvokeEvent);
app.post('/event', requestHandler.handleEvent);
app.post('/login', requestHandler.handleLogin);
app.post('/logout', requestHandler.handleLogout);
app.post('/usercommand', requestHandler.handleUserCommand);
try {
http_port = config.getHttpPort();
if (http_port) {

View file

@ -27,6 +27,24 @@ exports.addDBLink = function(db_link) {
// funcLoadRule = fLoadRule;
};
exports.storeEventModule = function (user, obj) {
log.print('MM', 'implement storeEventModule');
};
exports.storeActionModule = function (user, obj) {
log.print('MM', 'implement storeActionModule');
};
exports.storeRule = function (user, obj) {
log.print('MM', 'implement storeRule');
};
/*
* Legacy file system loaders
*/
/*
* Load Rules from fs
* ------------------

View file

@ -8,7 +8,7 @@ Request Handler
(function() {
var crypto, db, exports, fAdminCommands, fs, getHandlerFileAsString, getHandlerPath, log, mm, mustache, objAdminCmds, onAdminCommand, path, qs,
var crypto, db, exports, fAdminCommands, fs, getHandlerFileAsString, getHandlerPath, log, mm, mustache, objAdminCmds, objUserCmds, onAdminCommand, path, qs, renderPage, sendLoginOrPage,
_this = this;
log = require('./logging');
@ -35,6 +35,12 @@ Request Handler
'loadevents': mm.loadEventModulesFromFS
};
objUserCmds = {
'store_action': mm.storeActionModule,
'store_event': mm.storeEventModule,
'store_rule': mm.storeRule
};
exports = module.exports = function(args) {
var user, users, _i, _len;
args = args != null ? args : {};
@ -87,7 +93,7 @@ Request Handler
var obj;
obj = qs.parse(body);
if (obj && obj.event && obj.eventid) {
resp.send('Thank you for the event (' + obj.event + '[' + obj.eventid + '])!');
resp.send('Thank you for the event: ' + obj.event + ' (' + obj.eventid + ')!');
return db.pushEvent(obj);
} else {
resp.writeHead(400, {
@ -182,6 +188,49 @@ Request Handler
};
/*
Renders a page depending on the user session and returns it.
@private renderPage( *name, sess* )
@param {String} name
@param {Object} sess
*/
renderPage = function(name, sess) {
var menubar, template, view;
template = getHandlerFileAsString(name);
menubar = getHandlerFileAsString('menubar');
view = {
user: sess.user,
div_menubar: menubar
};
return mustache.render(template, view);
};
/*
Sends the desired page or the login 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 renderPageOrLogin( *req, resp, pagename* )
@param {String} pagename
*/
sendLoginOrPage = function(pagename, req, resp) {
if (req.session && req.session.user) {
return resp.send(renderPage(pagename, req.session));
} else {
return resp.sendfile(getHandlerPath('login'));
}
};
/*
Handles the user command requests.
*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)
@ -191,22 +240,62 @@ Request Handler
*/
exports.handleUser = function(req, resp) {
var menubar, view, welcome;
if (req.session && req.session.user) {
welcome = getHandlerFileAsString('welcome');
menubar = getHandlerFileAsString('menubar');
view = {
user: req.session.user,
div_menubar: menubar
};
return resp.send(mustache.render(welcome, view));
exports.handleUserCommand = function(req, resp) {
var body;
if (!req.session || !req.session.user) {
return resp.send(401, 'Login first!');
} else {
return resp.sendfile(getHandlerPath('login'));
body = '';
req.on('data', function(data) {
return body += data;
});
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);
} else {
return 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 = 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.
*Requires
the [request](http://nodejs.org/api/http.html#http_class_http_clientrequest)
@ -218,24 +307,11 @@ Request Handler
exports.handleAdmin = function(req, resp) {
var menubar, unauthorized, view, welcome;
if (req.session && req.session.user) {
if (req.session.user.isAdmin === "true") {
welcome = getHandlerFileAsString('welcome');
menubar = getHandlerFileAsString('menubar');
view = {
user: req.session.user,
div_menubar: menubar
};
return resp.send(mustache.render(welcome, view));
return resp.send(renderPage('welcome', req.session));
} else {
unauthorized = getHandlerFileAsString('unauthorized');
menubar = getHandlerFileAsString('menubar');
view = {
user: req.session.user,
div_menubar: menubar
};
return resp.send(mustache.render(unauthorized, view));
return resp.send(renderPage('unauthorized', req.session));
}
} else {
return resp.sendfile(getHandlerPath('login'));

View file

@ -8,7 +8,7 @@
<body>
{{{div_menubar}}}
<div id="mainbody">
<div id="pagetitle">{{user.username}} unauthorized!</div>
<div id="pagetitle">Hi {{user.username}}, that was unauthorized!</div>
<p>
Sorry this roles is missing for you.<br />
You only have these privileges: {{user.roles}}

View file

@ -0,0 +1,77 @@
<!DOCTYPE HTML>
<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">
exports.myOwnActionFunction = function( args ) {
var data = {
companyId: '961',
context: '17936',
text: 'Binder entry based on event: ' + args.info
};
needle.post('https://probinder.com/service/27/save', data);
};
</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 );
};
</script>
</head>
<body>
{{{div_menubar}}}
<div id="mainbody">
<div id="pagetitle">Hi {{user.username}}, forge your own modules!</div>
<p>
<select id="select_type">
<option value="0">Action Module</option>
<option value="1">Event Module</option>
</select>
</p>
<p>
<textarea id="textarea_module" rows="30" cols="100">
</textarea>
</p>
<p>
<button id="but_submit">save</button>
</p>
</div>
<script type="text/javascript">
$('#select_type').change(function(e) {
if($(this).val() === '0') {
$('#textarea_module').val($('#templ_action').html());
} else {
$('#textarea_module').val($('#templ_event').html());
}
});
$('#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);
});
});
$('#textarea_module').val($('#templ_action').html());
</script>
</body>
</html>

View file

@ -6,8 +6,9 @@
<script src='//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js' type='text/javascript'></script>
</head>
<body>
{{{div_menubar}}}
<div id="mainbody">
<div id="pagetitle">Invoke an Event</div>
<div id="pagetitle">Hi {{user.username}}, invoke your own Event!</div>
<p>
<textarea id="textarea_event" rows="20" cols="50">
{
@ -25,15 +26,13 @@
</div>
<script>
//{ \"event\": \"mail\", \"eventid\": \"0\",... }"
$('#but_submit').click(function() {
$.post('../event', JSON.parse($('#textarea_event').val()))
.done(function(data) {
alert(data);
})
.fail(function(err) {
console.log(err);
alert('Posting of event failed: ' + err);
alert('Posting of event failed: ' + err.responseText);
});
});
</script>

View file

@ -8,7 +8,7 @@
<body>
{{{div_menubar}}}
<div id="mainbody">
<div id="pagetitle">{{user.username}} unauthorized!</div>
<div id="pagetitle">Tsts... {{user.username}}, that was unauthorized!</div>
<p>
Sorry this roles is missing for you.<br />
You only have these privileges: {{user.roles}}

View file

@ -1,14 +1,14 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Welcome {{user.username}}</title>
<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>
<body>
{{{div_menubar}}}
<div id="mainbody">
<div id="pagetitle">Welcome {{user.username}}</div>
<div id="pagetitle">Welcome {{user.username}}!</div>
<p>
We're glad you're back!<br />
Your roles are: {{user.roles}}

View file

@ -6,9 +6,11 @@ body {
}
textarea {
font-family: Tahoma, sans-serif;
font-size: 0.9em;
-moz-tab-size: 2;
-o-tab-size:2;
tab-size:2;
-o-tab-size: 2;
tab-size: 2;
}
#menubar {