volos-swagger
Advanced tools
Comparing version 0.0.1 to 0.1.0
'use strict'; | ||
// Swagger OAuth: http://developers-blog.helloreverb.com/enabling-oauth-with-swagger/ | ||
// todo: hook up the swagger oauth routes | ||
// todo: currently must *not* have same cache at global & operation levels | ||
var _ = require('underscore'); | ||
var debug = require('debug')('swagger'); | ||
var deploymentConfig; | ||
var swagger; | ||
var resourcesMap; // name -> volos resource | ||
@@ -15,9 +11,16 @@ var operationsMap; // operationId -> middleware chain | ||
var RESOURCES = 'x-volos-resources'; | ||
var APPLY = 'x-volos-apply'; | ||
var AUTH = 'x-volos-authorizations'; | ||
module.exports = middleware; | ||
// the middleware | ||
function middleware(volosConfig) { | ||
function middleware(swaggerObject) { | ||
deploymentConfig = volosConfig; | ||
resourcesMap = createResources(); | ||
if (swaggerObject) { | ||
swagger = swaggerObject; | ||
resourcesMap = createResources(); | ||
} | ||
operationsMap = {}; | ||
@@ -29,3 +32,9 @@ authorizationsMap = {}; | ||
if (debug.enabled) { debug('handle req: ' + req.path); } | ||
if (!getOperationId(req)) { return next(); } | ||
if (!(req.swagger && req.swagger.operation)) { return next(); } | ||
if (!swagger) { | ||
swagger = req.swagger.swaggerObject; | ||
resourcesMap = createResources(); | ||
} | ||
mwChain(req, res, next); | ||
@@ -38,14 +47,10 @@ }; | ||
var operationId = getOperationId(req); | ||
if (!operationId) { return next(); } | ||
var operation = req.swagger.operation; | ||
var authChain = operation.volos ? operation.volos.authChain : undefined; // cache | ||
var authChain = authorizationsMap[operationId]; | ||
if (!authChain) { | ||
// use the operation.authorizations if present, otherwise api.authorizations | ||
var authorizations = req.swagger.operation ? req.swagger.operation.authorizations : undefined; | ||
if (!authorizations) { | ||
authorizations = req.swagger.api ? req.swagger.api.authorizations : undefined; | ||
} | ||
if (debug.enabled) { debug('creating auth chain for: ' + operation.operationId); } | ||
var authorizations = operation[AUTH] || req.swagger.path[AUTH]; | ||
var middlewares = []; | ||
@@ -66,3 +71,5 @@ if (authorizations) { | ||
authChain = chain(middlewares); | ||
authorizationsMap[operationId] = authChain; | ||
if (!operation.volos) { operation.volos = {}; } | ||
operation.volos.authChain = authChain; | ||
} | ||
@@ -73,24 +80,16 @@ | ||
function getOperationId(req) { | ||
if (req.swagger && req.swagger.operation) { | ||
return req.swagger.operation.nickname; | ||
} else { | ||
debug('no operation defined for ' + req.path); | ||
return undefined; | ||
} | ||
} | ||
function applyMiddleware(req, res, next) { | ||
var operationId = getOperationId(req); | ||
if (!operationId) { return next(); } | ||
var operation = req.swagger.operation; | ||
var mwChain = operation.volos ? operation.volos.mwChain : undefined; // cache | ||
var mwChain = operationsMap[operationId]; | ||
if (!mwChain) { | ||
var specific = deploymentConfig.operations ? deploymentConfig.operations[operationId] : []; | ||
var global = deploymentConfig.global || []; | ||
if (debug.enabled) { debug('creating volos chain for: ' + operation.operationId); } | ||
var opMw = createMiddlewareChain(operation[APPLY] || []); | ||
var pathMw = createMiddlewareChain(req.swagger.path[APPLY] || []); | ||
mwChain = createMiddlewareChain(global.concat(specific)); | ||
operationsMap[operationId] = mwChain; | ||
mwChain = chain([opMw, pathMw]); | ||
if (!req.swagger.volos) { req.swagger.volos = {}; } | ||
operation.volos.mwChain = mwChain; | ||
} | ||
@@ -103,10 +102,13 @@ | ||
var middlewares = []; | ||
_.each(applications, function (application) { | ||
_.each(application, function(applicationOptions, resourceName) { | ||
var resource = resourcesMap[resourceName]; | ||
var mwDef = resource.connectMiddleware(); | ||
var mwFactory = mwDef.cache ? mwDef.cache : mwDef.apply; // quota is apply(), cache is cache() todo: standardize | ||
_.each(applications, function(applicationOptions, resourceName) { | ||
if (debug.enabled) { debug('chaining: ' + resourceName); } | ||
var resource = resourcesMap[resourceName]; | ||
var mwDef = resource.connectMiddleware(); | ||
var mwFactory = mwDef.cache || mwDef.apply; // quota is apply(), cache is cache() | ||
if (mwFactory) { | ||
var mw = mwFactory.apply(mwDef, applicationOptions || []); | ||
middlewares.push(mw); | ||
}); | ||
} else { | ||
if (debug.enabled) { debug('unknown middleware: ' + mwDef); } | ||
} | ||
}); | ||
@@ -141,3 +143,3 @@ | ||
_.each(deploymentConfig.resources, function(def, name) { | ||
_.each(swagger[RESOURCES], function(def, name) { | ||
var module = require(def.provider); | ||
@@ -144,0 +146,0 @@ var options = _.isArray(def.options) ? def.options : [def.options]; |
{ | ||
"name": "volos-swagger", | ||
"version": "0.0.1", | ||
"version": "0.1.0", | ||
"license": "MIT", | ||
@@ -13,12 +13,12 @@ "description": "Middleware for bridging swagger (via swagger-tools) and volos", | ||
"author": "Scott Ganyo <sganyo@apigee.com>", | ||
"license": "MIT", | ||
"main": "lib/connect-middleware.js", | ||
"dependencies": { | ||
"debug": "1.0.x", | ||
"underscore" : "1.6.x" | ||
"underscore": "1.6.x" | ||
}, | ||
"devDependencies": { | ||
"devDependencies": { | ||
"mocha": "1.19.x", | ||
"should": "3.1.x", | ||
"express": "3.4.x", | ||
"swagger-tools": "", | ||
"volos-cache-memory": "", | ||
@@ -25,0 +25,0 @@ "volos-quota-memory": "", |
@@ -33,7 +33,6 @@ /**************************************************************************** | ||
var ConnectMiddleware = require('../lib/connect-middleware'); | ||
var redisConfig = require('../../testconfig/testconfig-redis'); | ||
var oauth = redisConfig.oauth; | ||
var volosConfig = require('./support/volos.json'); | ||
var swagger = require('./support/swagger.json'); | ||
@@ -44,2 +43,4 @@ describe('Swagger Middleware', function() { | ||
var creator = redisConfig.fixtureCreator; | ||
var server = expressServer(); | ||
var count = 0; | ||
@@ -63,14 +64,3 @@ before(function(done) { | ||
var count = 0; | ||
var server; | ||
before(function(done) { | ||
var config = _.extend({}, volosConfig); | ||
delete(config.global); // just test operation-level stuff, not global stuff | ||
var middleware = new ConnectMiddleware(config); | ||
server = expressServer(middleware); | ||
done(); | ||
}); | ||
it('must access clean', function(done) { | ||
@@ -164,19 +154,30 @@ request(server) | ||
describe('Global', function() { | ||
describe('Path', function() { | ||
var count = 0; | ||
var server; | ||
it('must hit cache', function(done) { | ||
request(server) | ||
.get('/cachedPath') | ||
.end(function(err, res) { | ||
should.not.exist(err); | ||
res.status.should.eql(200); | ||
should.exist(res.header['cache-control']); | ||
res.body.count.should.equal(++count); | ||
var headers = res.headers; | ||
before(function(done) { | ||
var config = _.extend({}, volosConfig); | ||
delete(config.operations); // just test global stuff, not operations | ||
request(server) | ||
.get('/cachedPath') | ||
.end(function(err, res) { | ||
should.not.exist(err); | ||
res.status.should.eql(200); | ||
res.body.count.should.equal(count); | ||
_.keys(headers).length.should.equal(_.keys(res.headers).length); | ||
var middleware = new ConnectMiddleware(config); | ||
server = expressServer(middleware); | ||
done(); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should cache everything', function(done) { | ||
it('must hit quota', function(done) { | ||
request(server) | ||
.get('/clean') | ||
.get('/quotaPath') | ||
.end(function(err, res) { | ||
@@ -188,9 +189,16 @@ should.not.exist(err); | ||
request(server) | ||
.get('/clean') | ||
.get('/quotaPath') | ||
.end(function(err, res) { | ||
should.not.exist(err); | ||
res.status.should.eql(200); | ||
res.body.count.should.equal(count); | ||
res.body.count.should.equal(++count); | ||
done(); | ||
request(server) | ||
.get('/quotaPath') | ||
.end(function(err, res) { | ||
should.not.exist(err); | ||
res.status.should.eql(403); | ||
done(); | ||
}); | ||
}); | ||
@@ -200,10 +208,24 @@ }); | ||
it('must hit quota', function(done) { | ||
it('must handle auth', function(done) { | ||
request(server) | ||
.get('/quota') | ||
.get('/securedPath') | ||
.end(function(err, res) { | ||
should.not.exist(err); | ||
res.status.should.eql(403); | ||
res.status.should.eql(401); | ||
done(); | ||
getToken(function(err, token) { | ||
if (err) { return done(err); } | ||
request(server) | ||
.get('/securedPath') | ||
.set('Authorization', 'Bearer ' + token) | ||
.end(function(err, res) { | ||
should.not.exist(err); | ||
res.status.should.eql(200); | ||
res.body.count.should.equal(++count); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
@@ -210,0 +232,0 @@ }); |
@@ -28,50 +28,17 @@ /**************************************************************************** | ||
var assert = require('assert'); | ||
var swagger = require('swagger-tools').middleware.v2_0; | ||
var volos = require('../../'); | ||
var path = require('path'); | ||
module.exports = function(middleware) { | ||
var app = express(); | ||
var counter = 1; | ||
app.use(fakeSwagger); | ||
app.use(middleware); | ||
var swaggerObject = require('./swagger.json'); | ||
app.use(swagger.swaggerMetadata(swaggerObject)); | ||
app.use(volos()); | ||
app.get('/clean', | ||
function(req, resp) { | ||
resp.json({ count: counter++ }); | ||
}); | ||
app.use(swagger.swaggerRouter({ controllers: path.join(__dirname, 'controllers') })); | ||
app.get('/cached', | ||
function(req, resp) { | ||
resp.json({ count: counter++ }); | ||
}); | ||
app.get('/quota', | ||
function(req, resp) { | ||
resp.json({ count: counter++ }); | ||
}); | ||
app.get('/secured', | ||
function(req, resp) { | ||
resp.json({ count: counter++ }); | ||
}); | ||
return app; | ||
}; | ||
function fakeSwagger(req, res, next) { | ||
var nickname = req.path.substring(1); | ||
req.swagger = {}; | ||
req.swagger.operation = { nickname: nickname }; | ||
if (nickname === 'secured') { | ||
req.swagger.operation.authorizations = securedAuth; | ||
} | ||
next(); | ||
} | ||
var securedAuth = { | ||
"oauth2": [ | ||
{ | ||
"scope": "scope1", | ||
"description": "whatevs" | ||
} | ||
] | ||
}; |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
29315
8
786
7
1