// Generated by CoffeeScript 1.6.3 /* Request Handler ============ > The request handler (surprisingly) handles requests made through HTTP to > the [HTTP Listener](http-listener.html). It will handle user requests for > pages as well as POST requests such as user login, module storing, event > invocation and also admin commands. */ (function() { var answerHandler, crypto, db, dirHandlers, exports, fs, getHandlerPath, getRemoteScripts, getScript, getTemplate, mustache, path, qs, renderPage, _this = this; db = require('./persistence'); fs = require('fs'); path = require('path'); qs = require('querystring'); mustache = require('mustache'); crypto = require('crypto-js'); dirHandlers = path.resolve(__dirname, '..', 'webpages', 'handlers'); exports = module.exports = function(args) { var user, users, _i, _len; _this.log = args.logger; _this.userRequestHandler = args['request-service']; _this.objAdminCmds = { shutdown: function(args, answerHandler) { answerHandler.answerSuccess('Shutting down... BYE!'); return setTimeout(args['shutdown-function'], 500); } }; db(args); users = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', 'config', 'users.json'))); for (_i = 0, _len = users.length; _i < _len; _i++) { user = users[_i]; db.storeUser(user); } return module.exports; }; /* 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 = function(req, resp) { var body; body = ''; req.on('data', function(data) { return body += data; }); return req.on('end', function() { var obj; obj = qs.parse(body); if (obj && obj.event && obj.eventid) { resp.send('Thank you for the event: ' + obj.event + ' (' + obj.eventid + ')!'); return db.pushEvent(obj); } else { return resp.send(400, 'Your event was missing important parameters!'); } }); }; /* Associates the user object with the session if login is successful. *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 handleLogin( *req, resp* ) */ exports.handleLogin = function(req, resp) { var body; body = ''; req.on('data', function(data) { return body += data; }); return req.on('end', function() { var obj; obj = qs.parse(body); return db.loginUser(obj.username, obj.password, function(err, usr) { if (err) { _this.log.warn("RH | AUTH-UH-OH ( " + obj.username + " ): " + err.message); } else { req.session.user = usr; } if (req.session.user) { return resp.send('OK!'); } else { return resp.send(401, 'NO!'); } }); }); }; /* 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 = function(req, resp) { if (req.session) { req.session.user = null; return resp.send('Bye!'); } }; /* Resolves the path to a handler webpage. @private getHandlerPath( *name* ) @param {String} name */ getHandlerPath = function(name) { return path.join(dirHandlers, name + '.html'); }; /* Fetches a template. @private getTemplate( *name* ) @param {String} name */ getTemplate = function(name) { var pth; pth = path.join(dirHandlers, 'templates', name + '.html'); return fs.readFileSync(pth, 'utf8'); }; /* Fetches a script. @private getScript( *name* ) @param {String} name */ getScript = function(name) { var pth; pth = path.join(dirHandlers, 'js', name + '.js'); return fs.readFileSync(pth, 'utf8'); }; /* Fetches remote scripts snippets. @private getRemoteScripts( *name* ) @param {String} name */ getRemoteScripts = function(name) { var pth; pth = path.join(dirHandlers, 'remote-scripts', name + '.html'); return fs.readFileSync(pth, 'utf8'); }; /* Renders a page, with helps of mustache, depending on the user session and returns it. @private renderPage( *name, sess, msg* ) @param {String} name @param {Object} sess @param {Object} msg */ renderPage = function(name, req, resp, msg) { var code, content, data, err, menubar, pathSkel, remote_scripts, script, skeleton, view; pathSkel = path.join(dirHandlers, 'skeleton.html'); skeleton = fs.readFileSync(pathSkel, 'utf8'); code = 200; data = { message: msg }; try { script = getScript(name); } catch (_error) {} try { remote_scripts = getRemoteScripts(name); } catch (_error) {} try { content = getTemplate(name); } catch (_error) { err = _error; content = getTemplate('error'); script = getScript('error'); code = 404; data = { message: 'Invalid Page!' }; } content = mustache.render(content, data); if (req.session.user) { menubar = getTemplate('menubar'); } view = { user: req.session.user, content: content, script: script, remote_scripts: remote_scripts, menubar: menubar }; return resp.send(code, mustache.render(skeleton, view)); }; /* Present the desired forge 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 handleForge( *req, resp* ) */ exports.handleForge = function(req, resp) { var page; page = req.query.page; if (!req.session.user) { page = 'login'; } return renderPage(page, req, resp); }; /* 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) objects.* @public handleUser( *req, resp* ) */ exports.handleUserCommand = function(req, resp) { var body; if (!req.session || !req.session.user) { return resp.send(401, 'Login first!'); } else { body = ''; req.on('data', function(data) { return body += data; }); return req.on('end', function() { var obj; obj = qs.parse(body); return _this.userRequestHandler(req.session.user, obj, function(err, obj) { if (err) { return resp.send(404, 'Rethink your request!'); } else { return resp.send(obj); } }); }); } }; /* Present the admin console to the user if he's allowed to see it. *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 handleForge( *req, resp* ) */ exports.handleAdmin = function(req, resp) { var msg, page; if (!req.session.user) { page = 'login'; } else if (req.session.user.isAdmin !== "true") { page = 'login'; msg = 'You need to be admin!'; } else { page = 'admin'; } return renderPage(page, req, resp, msg); }; /* Handles the admin 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) objects.* @public handleAdminCommand( *req, resp* ) */ exports.handleAdminCommand = function(req, resp) { var q, _base, _name; if (req.session && req.session.user) { if (req.session.user.isAdmin === "true") { q = req.query; _this.log.info('RH | Received admin request: ' + req.originalUrl); if (q.cmd) { return typeof (_base = _this.objAdminCmds)[_name = q.cmd] === "function" ? _base[_name](q, answerHandler(req, resp, true)) : void 0; } else { return resp.send(404, 'Command unknown!'); } } else { return resp.send(renderPage('unauthorized', req.session)); } } else { return resp.sendfile(getHandlerPath('login')); } }; 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; } }; setTimeout(function() { return ret.answerError('Strange... maybe try again?'); }, 5000); return ret; }; }).call(this);