From 308209f71aed7b8fe3a01659da7e7c7f73e7d470 Mon Sep 17 00:00:00 2001 From: MinRK Date: Mon, 7 Jul 2014 17:35:01 -0500 Subject: [PATCH] authenticate API requests to the proxy and add configproxy cli via mininimist --- multiuser/js/configproxy.js | 31 +++++++++++++++++------- multiuser/js/main.js | 48 +++++++++++++++++++++++++++++++++++-- multiuser/multiuser.py | 7 +++++- 3 files changed, 74 insertions(+), 12 deletions(-) diff --git a/multiuser/js/configproxy.js b/multiuser/js/configproxy.js index 4be21452..e88e9dbd 100644 --- a/multiuser/js/configproxy.js +++ b/multiuser/js/configproxy.js @@ -42,11 +42,28 @@ var json_handler = function (handler) { }; }; +var authorized = function (method) { + return function (req, res) { + console.log(req.headers); + auth = req.headers.authorization; + console.log(auth, this.auth_token); + if (!this.auth_token || auth == this.auth_token) { + return method.apply(this, arguments); + } else { + res.writeHead(403); + res.end(); + } + }; +}; + var ConfigurableProxy = function (options) { var that = this; this.options = options || {}; + this.auth_token = this.options.auth_token; + this.upstream_ip = this.options.upstream_ip || 'localhost'; this.upstream_port = this.options.upstream_port || 8001; - this.default_target = 'http://localhost:' + this.upstream_port; + + this.default_target = "http://" + this.upstream_ip + ":" + this.upstream_port; this.routes = {}; var proxy = this.proxy = httpProxy.createProxyServer({ @@ -57,15 +74,15 @@ var ConfigurableProxy = function (options) { this.handlers = [ [ /^\/api\/routes$/, { - get : bound(this, this.get_routes) + get : bound(this, authorized(this.get_routes)) } ], [ /^\/api\/routes(\/.*)$/, { - post : json_handler(bound(this, this.post_routes)), - 'delete' : bound(this, this.delete_routes) + post : json_handler(bound(this, authorized(this.post_routes))), + 'delete' : bound(this, authorized(this.delete_routes)) } ] ]; - this.server = http.createServer( + this.server = this.proxy_server = http.createServer( function (req, res) { try { return that.handle_request(req, res); @@ -80,10 +97,6 @@ var ConfigurableProxy = function (options) { this.server.on('upgrade', bound(this, this.handle_ws)); }; -ConfigurableProxy.prototype.listen = function (port) { - this.server.listen(port); -}; - ConfigurableProxy.prototype.fail = function (res, code, msg) { res.writeHead(code); res.write(msg); diff --git a/multiuser/js/main.js b/multiuser/js/main.js index acba0870..80efc8b8 100644 --- a/multiuser/js/main.js +++ b/multiuser/js/main.js @@ -1,6 +1,50 @@ #!/usr/bin/env node +/* +cli entrypoint for starting a Configurable Proxy +*/ +var fs = require('fs'); +var minimist = require('minimist'); var ConfigurableProxy = require('./configproxy.js').ConfigurableProxy; -var proxy = new ConfigurableProxy(); -proxy.listen(8000); +var argv = minimist(process.argv.slice(2), {boolean: ['h', 'help']}); + +if (argv.h || argv.help) { + console.log("help!"); + process.exit(); +} + +var options = {}; +if (argv.ssl_key) { + options.key = fs.readFileSync(argv.ssl_key); +} + +if (argv.ssl_cert) { + options.cert = fs.readFileSync(argv.ssl_cert); +} + +options.upstream_ip = argv.upstream_ip; +options.upstream_port = argv.upstream_port; +options.api_token = process.env.CONFIGPROXY_AUTH_TOKEN; + +var proxy = new ConfigurableProxy(options); + +var listen = {}; +listen.port = argv.port || 8000; +listen.ip = argv.ip; +listen.api_ip = argv.api_ip || 'localhost'; +listen.api_port = argv.api_port || listen.port + 1; + + +proxy.proxy_server.listen(listen.port, listen.ip); +// proxy.api_server(listen.api_port, listen.api_ip); + +console.log( + "Proxying " + (listen.ip || '*') + ":" + listen.port + + " to " + proxy.upstream_ip + ":" + proxy.upstream_port +); + +if (options.api_ip || options.api_port) { + console.log("API entry points on " + (listen.api_ip || '*') + ":" + listen.api_port); +} + diff --git a/multiuser/multiuser.py b/multiuser/multiuser.py index e990d1e6..413b2998 100644 --- a/multiuser/multiuser.py +++ b/multiuser/multiuser.py @@ -146,6 +146,9 @@ class SingleUserManager(LoggingConfigurable): users = Dict() routes_t = Unicode('http://localhost:8000/api/routes{uri}') single_user_t = Unicode('http://localhost:{port}') + proxy_auth_token = Unicode() + def _proxy_auth_token_default(self): + return str(uuid.uuid4()) def _wait_for_port(self, port, timeout=2): tic = time.time() @@ -157,7 +160,6 @@ class SingleUserManager(LoggingConfigurable): else: break - def get_session(self, user, **kwargs): if user not in self.users: kwargs['user'] = user @@ -178,6 +180,7 @@ class SingleUserManager(LoggingConfigurable): target=self.single_user_t.format(port=port), user=user, )), + headers={'Authorization': self.proxy_auth_token}, ) self._wait_for_port(port) r.raise_for_status() @@ -375,6 +378,8 @@ def main(): ) http_server = tornado.httpserver.HTTPServer(application) http_server.listen(options.port) + env = os.environ.copy() + env['CONFIGPROXY_AUTH_TOKEN'] = user_manager.proxy_auth_token proxy = Popen(["node", os.path.join(here, 'js', 'main.js')]) try: tornado.ioloop.IOLoop.instance().start()