oauth_reverse_proxy
Advanced tools
Comparing version 0.9.6 to 0.9.7
@@ -12,3 +12,3 @@ /** | ||
var oauth_reverse_proxy = require('./lib'); | ||
var logger = require('./lib/logger.js'); | ||
var logger = require('./lib/logger.js').getLogger(); | ||
@@ -15,0 +15,0 @@ /** |
@@ -7,3 +7,3 @@ var fs = require('fs'); | ||
var logger = require('./logger.js'); | ||
var logger = require('./logger.js').getLogger(); | ||
@@ -10,0 +10,0 @@ /** |
@@ -6,18 +6,15 @@ var util = require('util'); | ||
// Create a default logger to use if all else fails. | ||
module.exports = bunyan.createLogger({name: 'oauth_reverse_proxy'}); | ||
var default_logger = bunyan.createLogger({name: 'oauth_reverse_proxy'}); | ||
// TODO: Wire up file logging | ||
// Init the logger with a configuration object | ||
/* istanbul ignore next */ | ||
module.exports.init = function(config) { | ||
module.exports.getLogger = function(config) { | ||
// If no logger config is provided, there's nothing more to do. We'll just continue using the | ||
// default logger. | ||
if (!config.logger) return; | ||
if (!config) return default_logger; | ||
config.logger.streams.forEach(function(stream) { | ||
if (stream.stream === "process.stdout") stream.stream = process.stdout; | ||
else if (stream.stream === "process.stderr") stream.stream = process.stderr; | ||
}); | ||
module.exports = bunyan.createLogger(config.logger); | ||
return default_logger.child(config); | ||
}; |
var util = require('util'); | ||
var sprintf = require('../sprintf.js').sprintf; | ||
var logger = require('../logger.js'); | ||
var encoding = require('../encoding.js'); | ||
@@ -39,3 +38,3 @@ | ||
*/ | ||
function badrequest(req, res, message) { | ||
function badrequest(logger, req, res, message) { | ||
if (req && req.headers) { | ||
@@ -59,3 +58,3 @@ logger.info("Rejecting %s %s%s, error %s", req.method, req.headers.host, req.url, message); | ||
*/ | ||
function unauthorized(req, res, message) { | ||
function unauthorized(logger, req, res, message) { | ||
logger.info("Rejecting %s %s%s, error %s", req.method, req.headers.host, req.url, message); | ||
@@ -152,3 +151,2 @@ process.nextTick(function() { | ||
logger.trace("argument pairs:\n%s", util.inspect(argument_pairs)); | ||
return argument_pairs; | ||
@@ -202,4 +200,2 @@ } | ||
logger.debug("The parameter string is\n%s", args); | ||
return args; | ||
@@ -240,6 +236,4 @@ } | ||
} | ||
logger.trace("Timestamp\t%s", timestamp_str); | ||
var timestamp = parseInt(timestamp_str); | ||
if (isNaN(timestamp)) { | ||
logger.debug("Invalid timestamp: %s", timestamp); | ||
return false; | ||
@@ -252,5 +246,2 @@ } | ||
var valid = (Math.abs(now - timestamp) < MAX_AGE); | ||
if (!valid) { | ||
logger.debug("Request expired, age is %sms", (now - timestamp)); | ||
} | ||
return valid; | ||
@@ -276,3 +267,3 @@ }; | ||
if (!req || !req.headers || !req.method || !req.url) { | ||
return badrequest(req, res, 'Invalid request'); | ||
return badrequest(proxy.logger, req, res, 'Invalid request'); | ||
} | ||
@@ -288,3 +279,3 @@ | ||
return unauthorized(req, res, error_message); | ||
return unauthorized(proxy.logger, req, res, error_message); | ||
}; | ||
@@ -309,5 +300,5 @@ | ||
*/ | ||
exports.whitelistValidator = function(config){ | ||
exports.whitelistValidator = function(proxy){ | ||
var whitelist = new Whitelist(config); | ||
var whitelist = new Whitelist(proxy.config.whitelist); | ||
@@ -318,3 +309,3 @@ return function(req,res,next) { | ||
if(req.whitelist_passed) { | ||
logger.info("Proxying URL %s %s%s WHITELIST", req.method, req.headers.host, req.url); | ||
proxy.logger.info("Proxying URL %s %s%s WHITELIST", req.method, req.headers.host, req.url); | ||
} | ||
@@ -328,7 +319,7 @@ | ||
// written to the client, and this method will terminate with error. | ||
function validateOauthParams(oauth_params, keys, req, res) { | ||
function validateOauthParams(logger, oauth_params, keys, req, res) { | ||
// If we receive an auth header, fail if the auth header is not OAuth | ||
if (req.headers.authorization && req.headers.authorization.indexOf('OAuth') !== 0) { | ||
return badrequest(req, res, 'Authorization type is not OAuth'); | ||
return badrequest(logger, req, res, 'Authorization type is not OAuth'); | ||
} | ||
@@ -338,3 +329,3 @@ | ||
if (oauth_params[OAUTH_SIGNATURE_METHOD] !== 'HMAC-SHA1') { | ||
return badrequest(req, res, 'Only OAuth 1.0a with HMAC-SHA1 is supported'); | ||
return badrequest(logger, req, res, 'Only OAuth 1.0a with HMAC-SHA1 is supported'); | ||
} | ||
@@ -346,3 +337,3 @@ | ||
if (!oauth_params[REQUIRED_OAUTH_PARAMS[i]]) { | ||
return badrequest(req, res, 'Incomplete OAuth headers'); | ||
return badrequest(logger, req, res, 'Incomplete OAuth headers'); | ||
} | ||
@@ -353,3 +344,3 @@ } | ||
if (oauth_params.hasOwnProperty(OAUTH_VERSION) && oauth_params[OAUTH_VERSION] !== '1.0') { | ||
return badrequest(req, res, 'Incorrect OAuth version'); | ||
return badrequest(logger, req, res, 'Incorrect OAuth version'); | ||
} | ||
@@ -359,3 +350,3 @@ | ||
if (!validateTimestamp(oauth_params, req, res)) { | ||
return unauthorized(req, res, 'Request expired'); | ||
return unauthorized(logger, req, res, 'Request expired'); | ||
} | ||
@@ -365,3 +356,3 @@ | ||
if (!keys.hasOwnProperty(oauth_params[OAUTH_CONSUMER_KEY])) { | ||
return unauthorized(req, res, 'Invalid consumer key'); | ||
return unauthorized(logger, req, res, 'Invalid consumer key'); | ||
} | ||
@@ -376,4 +367,6 @@ | ||
*/ | ||
exports.oauthValidator = function(keys) { | ||
exports.oauthValidator = function(proxy) { | ||
var keys = proxy.keys; | ||
return function(req, res, next) { | ||
@@ -385,4 +378,4 @@ try { | ||
logger.trace("req.body:\n%s", util.inspect(req.body)); | ||
logger.trace("req.headers:\n%s", util.inspect(req.headers)); | ||
proxy.logger.trace("req.body:\n%s", util.inspect(req.body)); | ||
proxy.logger.trace("req.headers:\n%s", util.inspect(req.headers)); | ||
@@ -392,5 +385,5 @@ var oauth_params = {}; | ||
logger.trace("Parsed auth header into:\n%s", util.inspect(oauth_params)); | ||
proxy.logger.trace("Parsed auth header into:\n%s", util.inspect(oauth_params)); | ||
if (!validateOauthParams(oauth_params, keys, req, res)) { | ||
if (!validateOauthParams(proxy.logger, oauth_params, keys, req, res)) { | ||
// If oauth param validation fails, we can trust that an error response has already been | ||
@@ -415,8 +408,8 @@ // written to the client. | ||
var signature_base = signature_bases.shift(); | ||
logger.debug("Got signature_base\n%s", signature_base); | ||
proxy.logger.debug("Got signature_base\n%s", signature_base); | ||
var hash = crypto.createHmac("sha1", consumer_secret).update(signature_base).digest("base64"); | ||
logger.trace("Hash\t%s", hash); | ||
logger.trace("Sig\t%s", oauth_params[OAUTH_SIGNATURE]); | ||
proxy.logger.trace("Hash\t%s", hash); | ||
proxy.logger.trace("Sig\t%s", oauth_params[OAUTH_SIGNATURE]); | ||
@@ -427,3 +420,3 @@ if (oauth_params[OAUTH_SIGNATURE] === hash) { | ||
req.headers[CONSUMER_KEY_HEADER] = consumer_key; | ||
logger.info("Proxying %s %s%s, consumer key %s", req.method, req.headers.host, req.url, consumer_key); | ||
proxy.logger.info("Proxying %s %s%s, consumer key %s", req.method, req.headers.host, req.url, consumer_key); | ||
return next(); | ||
@@ -434,5 +427,6 @@ } | ||
// If we got here, neither of the signatures (http or https) matched, so we must return a 401. | ||
return unauthorized(req, res, "Signature mismatch"); | ||
return unauthorized(proxy.logger, req, res, "Signature mismatch"); | ||
} catch (e) { | ||
logger.error("Failed to handle request %s %s%s due to %s:\n%s", req.method, req.headers.host, req.url, e, e.stack); | ||
/* istanbul ignore else */ | ||
if (proxy && proxy.logger) proxy.logger.error("Failed to handle request %s %s%s due to %s:\n%s", req.method, req.headers.host, req.url, e, e.stack); | ||
res.writeHead(500, 'Internal error'); | ||
@@ -439,0 +433,0 @@ return res.end(); |
var fs = require('fs'); | ||
var util = require('util'); | ||
var logger = require('../logger.js'); | ||
var logger = require('../logger.js').getLogger(); | ||
@@ -6,0 +6,0 @@ /** |
@@ -15,4 +15,2 @@ var _ = require('underscore'); | ||
var logger = require('../logger.js'); | ||
var MAXIMUM_URL_LENGTH = 16*1024; | ||
@@ -50,3 +48,6 @@ | ||
logger.debug("Starting proxy on port %s", this.config.from_port); | ||
this.logger = require('../logger.js').getLogger({'service_name':this.config.service_name}); | ||
this.logger.debug("Starting proxy on port %s", this.config.from_port); | ||
} | ||
@@ -68,4 +69,5 @@ | ||
var whitelist_validator = authenticator.whitelistValidator(this_obj.config); | ||
var oauth_validator = authenticator.oauthValidator(this_obj.keys); | ||
var whitelist_validator = authenticator.whitelistValidator(this_obj); | ||
var oauth_validator = authenticator.oauthValidator(this_obj); | ||
var request_validator = authenticator.requestValidator(this_obj); | ||
var modify_host_header = header_modifier.modifyHostHeaders(this_obj.config.from_port, this_obj.config.to_port); | ||
@@ -78,3 +80,3 @@ | ||
// the URI and Host header can be matched against the expected values, if provided. | ||
authenticator.requestValidator(this_obj), | ||
request_validator, | ||
// Unpack the body of POSTs so we can use them in signatures. Note that this | ||
@@ -127,3 +129,3 @@ // will implicitly limit POST size to 1mb. We may wish to add configuration around | ||
proxy.on('error', function(err, req, res) { | ||
logger.info("Got error %s communicating with underlying server.", util.inspect(err)); | ||
this_obj.logger.info("Got error %s communicating with underlying server.", util.inspect(err)); | ||
res.writeHead(500, "Connection to " + this_obj.config.service_name + " failed"); | ||
@@ -137,3 +139,3 @@ res.end(); | ||
// Begin listening for incoming requests | ||
logger.info("Listening on port %s", this_obj.config.from_port); | ||
this_obj.logger.info("Listening on port %s", this_obj.config.from_port); | ||
this_obj.server.listen(this_obj.config.from_port); | ||
@@ -140,0 +142,0 @@ |
@@ -6,3 +6,3 @@ var _ = require('underscore'); | ||
var encoding = require('../encoding.js'); | ||
var logger = require('../logger.js'); | ||
var logger = require('../logger.js').getLogger(); | ||
@@ -30,4 +30,8 @@ var VALID_SECRET_PATTERN = /^[-_.=a-zA-Z0-9]+$/; | ||
// Keep track of the keys that were registered as of now so that we can compare against | ||
// the list we're about to load. Anything that remains in delete_me should be, like, deleted. | ||
var delete_me = {}; | ||
_.each(this_obj, function(value, key) { | ||
delete this_obj[key]; | ||
delete_me[key] = true; | ||
}); | ||
@@ -75,2 +79,4 @@ | ||
Object.defineProperty(this_obj, file_name, { value: encoding.encodeData(file_contents), configurable: true, enumerable: true }); | ||
// We don't want to delete this property, so delete it from delete_me. | ||
delete delete_me[file_name]; | ||
@@ -92,2 +98,7 @@ // Increment the key count | ||
for (var key_to_delete in delete_me) { | ||
logger.info("Deleting key %s", key_to_delete); | ||
delete this_obj[key_to_delete]; | ||
} | ||
// Set the count property of this object. | ||
@@ -94,0 +105,0 @@ this_obj.count = key_count; |
@@ -5,3 +5,3 @@ var _ = require('underscore'); | ||
var sprintf = require('../sprintf.js').sprintf; | ||
var logger = require('../logger.js'); | ||
var logger = require('../logger.js').getLogger(); | ||
@@ -51,4 +51,4 @@ /** | ||
*/ | ||
function Whitelist(config) { | ||
var whitelist_config = config.whitelist; | ||
function Whitelist(whitelist_config) { | ||
var whitelist_config; | ||
var predicates = []; | ||
@@ -55,0 +55,0 @@ Object.defineProperty(this, 'predicates', {value: predicates}); |
{ | ||
"name": "oauth_reverse_proxy", | ||
"description": "An OAuth 1.0a authenticating reverse proxy", | ||
"version": "0.9.6", | ||
"version": "0.9.7", | ||
"contributors": [ | ||
@@ -6,0 +6,0 @@ { |
var should = require('should'); | ||
var authenticator = require('../lib/proxy/authenticator.js'); | ||
var request_sender = require('./utils/request_sender.js'); | ||
@@ -124,9 +125,13 @@ | ||
var authenticator = require('../lib/proxy/authenticator.js'); | ||
// Create a stub proxy to pass into our validator functions. This needs to expose a logger and a set of keys. | ||
var stub_proxy = { | ||
keys: {'mock_key':'mock_secret'}, | ||
logger : require('../lib/logger.js').getLogger({'service_name': 'oauth_reverse_proxy request validation test'}) | ||
}; | ||
// The request validator function used in the connect workflow for node-http-proxy. | ||
var request_validator = authenticator.requestValidator(); | ||
var request_validator = authenticator.requestValidator(stub_proxy); | ||
// The oauth validator function used in the connect workflow for node-http-proxy. | ||
var oauth_validator = authenticator.oauthValidator({'mock_key':'mock_secret'}); | ||
var oauth_validator = authenticator.oauthValidator(stub_proxy); | ||
@@ -181,13 +186,2 @@ // Create a mock response that can be used to validate that the correct failure states are registered. | ||
it ('should reject a request with no url even though that should never ever happen', function(done) { | ||
var res = create_res(done, 400, 'Invalid request'); | ||
var req = {}; | ||
req.headers = {'host':'localhost'}; | ||
req.method = 'GET'; | ||
// Attempt to validate a hopelessly flawed request. | ||
request_validator(req, res, null); | ||
}); | ||
// We can finally populate our stub request with everything necessary to pass the test for a /livecheck route. | ||
@@ -194,0 +188,0 @@ // But we pass in a null next function knowing this will cause the validator to throw an exception. |
@@ -1,3 +0,2 @@ | ||
{ | ||
"whitelist": [{ | ||
[{ | ||
"path": "/livecheck" | ||
@@ -46,3 +45,3 @@ }, | ||
"methods": ["PUT"] | ||
}] | ||
} | ||
} | ||
] |
@@ -1,3 +0,3 @@ | ||
{ | ||
"whitelist": [{ | ||
[ | ||
{ | ||
"methods": ["GET","POST"], | ||
@@ -11,3 +11,3 @@ "path": "/livecheck" | ||
"path": "/v2/another/route" | ||
}] | ||
} | ||
} | ||
] |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
15825688
87
3166