From 94d8c44561d2b16dec36cb419f4dc2f5a1298623 Mon Sep 17 00:00:00 2001 From: Marak Date: Sun, 21 Feb 2016 14:54:48 -0500 Subject: [PATCH] [api] [fix] Scope env to session #171 * Scopes hot-code gateway to session env scope * Works for all hot-code gateways * Adds concept of `hookType` ( internal use ) --- lib/resources/hook/index.js | 8 +++++ lib/resources/hook/runHook.js | 66 +++++++++++++++++++++++++++++++---- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/lib/resources/hook/index.js b/lib/resources/hook/index.js index 48c74a1a..038ebaa1 100644 --- a/lib/resources/hook/index.js +++ b/lib/resources/hook/index.js @@ -126,6 +126,14 @@ hook.property('mschema', { "type": "object" }); +hook.property('hookType', { + "type": "string", + "description": "additional ( internal ) type classification for hooks. currently used to help manage hot-code gateways", + "enum": ["service", "gateway"], + "default": "service", + "required": false +}); + hook.property('sourceType', { "type": "string", "description": "the active type of source for the hook", diff --git a/lib/resources/hook/runHook.js b/lib/resources/hook/runHook.js index d8584394..597fac6d 100644 --- a/lib/resources/hook/runHook.js +++ b/lib/resources/hook/runHook.js @@ -1,5 +1,6 @@ var request = require('hyperquest'); var log = require("../log"); +var user = require("../user"); var cache = require("../cache"); var events = require('../events'); var Datastore = require("../datastore").Datastore; @@ -24,6 +25,7 @@ module['exports'] = function runHook (opts, callback) { untrustedService.name = h.name; untrustedService.owner = h.owner; untrustedService.schema = {}; + untrustedService.hookType = h.hookType || "service"; untrustedService.customTimeout = h.customTimeout || config.UNTRUSTED_HOOK_TIMEOUT; // TODO: clean up execution chain, normalize error handlers, // put entire sequence into async iterator @@ -112,10 +114,61 @@ module['exports'] = function runHook (opts, callback) { function _spawn () { // spawn hook service as child process in chroot jail - // TODO: generate one-time use keys for datastore and cache on spawn - hook.spawnService(untrustedService, req, output); - return hook.postprocessHook(err, opts, untrustedService); - // TODO: hook.postprocessHook(err, opts, userModule); + // Remark: Special case for hot-code gateways + // This is needed in order to scope the hot-code gateway to the logged in session user + // All hot-code gateways are currently owned by user "marak" + // We could have each user fork the hot-code gateways to mitigate this issue ( since it's just a hook), + // but that wouldn't be very convenient for the users + if (untrustedService.owner === "marak" && (untrustedService.hookType === "gateway")) { + req.env = {}; + + // this anonymous undefined check seems out of place + // we should probably be performing this higher in the processing chain + if (typeof req.session.user === "undefined") { + req.session.user = "anonymous"; + } + + // give anonymous users a fixed env ( we could configure this later ) + if (req.session.user === "anonymous") { + req.env = { + "anonymous-env-param1": "foo", + "anonymous-env-param2": "bar" + }; + return _finishSpawn(); + } + + // if a user session exists, attempt to lookup env for that user + // this will scope the hot-code gateway to the user's env + if (typeof req.headers === "object" && typeof req.headers["x-hookio-user-session-name"] === "string" && req.headers["x-hookio-user-session-name"].length > 0) { + var _name = req.headers["x-hookio-user-session-name"]; + user.find({ name: _name}, function (err, _user){ + if (err) { + return res.end(err.message); + } + if (_user.length === 0) { + return res.end('Could not find user ' + _name + '. Please contact support.'); + } + var u = _user[0]; + req.env = u.env || {}; + // TODO: refactor out key sorting into resource library + var keys = Object.keys(req.env).sort(); + var __env = {}; + keys.forEach(function(k){ + __env[k] = req.env[k]; + }); + req.env = __env; + return _finishSpawn(); + }) + } else { + return _finishSpawn(); + } + } else { + return _finishSpawn(); + } + function _finishSpawn () { + hook.spawnService(untrustedService, req, output); + return hook.postprocessHook(err, opts, untrustedService); + } // TODO: where is callback now? } } @@ -193,9 +246,10 @@ module['exports'] = function runHook (opts, callback) { } }); }); - }); + }); } - + + // TODO: move jsonResponse check to a more generalized location var acceptTypes = []; if (req.headers && req.headers.accept) {