webapi-eca/coffee/request_handler.coffee

241 lines
6.6 KiB
CoffeeScript
Raw Normal View History

2013-11-26 22:24:15 +00:00
###
Request Handler
2013-11-26 22:24:15 +00:00
============
> TODO Add documentation
###
# **Requires:**
2013-11-26 22:24:15 +00:00
# - [Logging](logging.html)
2013-11-26 22:24:15 +00:00
log = require './logging'
# - [DB Interface](db_interface.html)
2013-11-26 22:24:15 +00:00
db = require './db_interface'
# - [Module Manager](module_manager.html)
2013-11-26 22:24:15 +00:00
mm = require './module_manager'
# - Node.js Modules: [fs](http://nodejs.org/api/fs.html),
# [path](http://nodejs.org/api/path.html) and
# [querystring](http://nodejs.org/api/querystring.html)
fs = require 'fs'
path = require 'path'
qs = require 'querystring'
# - External Modules: [mustache](https://github.com/janl/mustache.js) and
# [crypto-js](https://github.com/evanvosberg/crypto-js)
mustache = require 'mustache'
crypto = require 'crypto-js'
# Prepare the admin command handlers that are invoked via HTTP requests.
2013-11-26 22:24:15 +00:00
objAdminCmds =
'loadrules': mm.loadRulesFromFS,
'loadaction': mm.loadActionModuleFromFS,
'loadactions': mm.loadActionModulesFromFS,
'loadevent': mm.loadEventModuleFromFS,
'loadevents': mm.loadEventModulesFromFS
exports = module.exports = ( args ) ->
args = args ? {}
log args
db args
mm args
mm.addDBLink db
users = JSON.parse fs.readFileSync path.resolve __dirname, '..', 'config', 'users.json'
db.storeUser user for user in users
module.exports
###
This allows the parent to add handlers. The event handler will receive
the events that were received. The shutdown function will be called if the
admin command shutdown is issued.
2013-11-26 22:24:15 +00:00
@public addHandlers( *fShutdown* )
@param {function} fShutdown
###
exports.addHandlers = ( fShutdown ) =>
2013-11-26 22:24:15 +00:00
objAdminCmds.shutdown = fShutdown
###
Handles possible events that were posted to this server and pushes them into the
event queue.
*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 handleEvent( *req, resp* )
###
exports.handleEvent = ( req, resp ) =>
body = ''
req.on 'data', ( data ) ->
body += data
req.on 'end', =>
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 + '])!'
db.pushEvent obj
else
resp.writeHead 400, { "Content-Type": "text/plain" }
resp.send 'Your event was missing important parameters!'
2013-11-26 22:24:15 +00:00
###
*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.*
2013-11-26 22:24:15 +00:00
@public handleLogin( *req, resp* )
###
2013-11-26 22:24:15 +00:00
exports.handleLogin = ( req, resp ) ->
body = ''
req.on 'data', ( data ) -> body += data
req.on 'end', ->
if not req.session or not req.session.user
obj = qs.parse body
db.loginUser obj.username, obj.password, ( err, usr ) ->
if(err)
# Tapping on fingers, at least in log...
log.print 'RH', "AUTH-UH-OH (#{obj.username}): " + err.message
else
# no error, so we can associate the user object from the DB to the session
req.session.user = usr
2013-11-26 22:24:15 +00:00
if req.session.user
resp.send 'OK!'
2013-11-26 22:24:15 +00:00
else
resp.send 401, 'NO!'
2013-11-26 22:24:15 +00:00
else
resp.send 'Welcome ' + req.session.user.name + '!'
###
A post request retrieved on this handler causes the user object to be
purged from the session, thus the user will be logged out.
*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 handleLogout( *req, resp* )
###
exports.handleLogout = ( req, resp ) ->
if req.session
req.session.user = null
resp.send 'Bye!'
###
Resolves the path to a handler webpage.
@private getHandlerPath( *name* )
@param {String} name
###
getHandlerPath = ( name ) ->
path.resolve __dirname, '..', 'webpages', 'handlers', name + '.html'
###
Resolves the path to a handler webpage and returns it as a string.
@private getHandlerFileAsString( *name* )
@param {String} name
###
getHandlerFileAsString = ( name ) ->
fs.readFileSync getHandlerPath( name ), 'utf8'
###
*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 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
else
resp.sendfile getHandlerPath 'login'
###
*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 handleAdmin( *req, resp* )
###
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
else
unauthorized = getHandlerFileAsString 'unauthorized'
menubar = getHandlerFileAsString 'menubar'
view =
user: req.session.user,
div_menubar: menubar
resp.send mustache.render unauthorized, view
else
resp.sendfile getHandlerPath 'login'
2013-11-26 22:24:15 +00:00
onAdminCommand = ( req, response ) ->
q = req.query
log.print 'RH', 'Received admin request: ' + q
2013-11-26 22:24:15 +00:00
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...'
###
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'
2013-11-26 22:24:15 +00:00
###
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