Skip to content

Commit c9e9a75

Browse files
committed
Allow load of security handlers from module using "securityHandlersModule" property on swagger_security fitting
1 parent 169a33a commit c9e9a75

File tree

5 files changed

+125
-58
lines changed

5 files changed

+125
-58
lines changed

fittings/swagger_security.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,28 @@ var debug = require('debug')('swagger:swagger_security');
44
var async = require('async');
55
var helpers = require('../lib/helpers');
66
var _ = require('lodash');
7+
var path = require('path');
78

89
module.exports = function create(fittingDef, bagpipes) {
910

1011
debug('config: %j', fittingDef);
1112

13+
var runner = bagpipes.config.swaggerNodeRunner;
14+
15+
if (fittingDef.securityHandlersModule && !runner.config.securityHandlers) {
16+
17+
var appRoot = runner.config.swagger.appRoot;
18+
var handlersPath = path.resolve(appRoot, fittingDef.securityHandlersModule);
19+
20+
runner.securityHandlers = require(handlersPath);
21+
debug('loaded handlers: %s from: %s', Object.keys(runner.securityHandlers), handlersPath);
22+
}
23+
1224
return function swagger_security(context, cb) {
1325

1426
debug('exec');
1527

16-
var handlers = bagpipes.config.swaggerNodeRunner.securityHandlers || {};
28+
var handlers = runner.securityHandlers || {};
1729
var req = context.request;
1830
var operation = req.swagger.operation;
1931

index.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,7 @@ var SWAGGER_SELECTED_PIPE = 'x-swagger-pipe';
3939
var SWAGGER_ROUTER_CONTROLLER = 'x-swagger-router-controller';
4040
var DEFAULT_FITTINGS_DIRS = [ 'api/fittings' ];
4141
var DEFAULT_VIEWS_DIRS = [ 'api/views' ];
42-
var DEFAULT_APP_PATHS = { // relative to appRoot
43-
swaggerFile: 'api/swagger/swagger.yaml',
44-
controllersDir: 'api/controllers',
45-
mockControllersDir: 'api/mocks',
46-
helpers: 'api/helpers'
47-
};
42+
var DEFAULT_SWAGGER_FILE = 'api/swagger/swagger.yaml'; // relative to appRoot
4843

4944
/*
5045
SwaggerNode config priority:
@@ -188,7 +183,7 @@ function Runner(appJsConfig, cb) {
188183

189184
var self = this;
190185
var swayOpts = {
191-
definition: appJsConfig.swagger || appJsConfig.swaggerFile || this.resolveAppPath(DEFAULT_APP_PATHS.swaggerFile)
186+
definition: appJsConfig.swagger || appJsConfig.swaggerFile || this.resolveAppPath(DEFAULT_SWAGGER_FILE)
192187
};
193188

194189
// sway uses Promises
@@ -275,10 +270,14 @@ function createPipes(self) {
275270
name: 'swagger_validator',
276271
validateReponse: true
277272
},
273+
_swagger_security: {
274+
name: 'swagger_security',
275+
securityHandlersModule: 'api/helpers/securityHandlers'
276+
},
278277
swagger_controllers: [
279278
'cors',
280279
'swagger_params_parser',
281-
'swagger_security',
280+
'_swagger_security',
282281
'_swagger_validate',
283282
'express_compatibility',
284283
'_router'
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module.exports = {
2+
api_key: function failure(req, res, next) {
3+
if (req.swagger.params.name.value === 'Scott') {
4+
next();
5+
} else {
6+
next(new Error('no way!'));
7+
}
8+
}
9+
};

test/assets/project/config/default.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,16 @@ swagger:
1919
name: swagger_validator
2020
validateResponse: true
2121

22+
_swagger_security:
23+
name: swagger_security
24+
securityHandlersModule: api/helpers/securityHandlers
25+
2226
# pipe for all swagger-node controllers
2327
swagger_controllers:
2428
- onError: json_error_handler
2529
- cors
2630
- swagger_params_parser
27-
- swagger_security
31+
- _swagger_security
2832
- _swagger_validate
2933
- express_compatibility
3034
- _router

test/lib/common.js

Lines changed: 91 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -213,68 +213,111 @@ module.exports = function() {
213213

214214
describe('security', function() {
215215

216-
it('should deny when missing handler', function(done) {
217-
request(this.app)
218-
.get('/hello_secured')
219-
.set('Accept', 'application/json')
220-
.expect(403)
221-
.expect('Content-Type', /json/)
222-
.end(function(err, res) {
223-
should.not.exist(err);
216+
describe('loaded from path', function() {
224217

225-
res.body.should.have.properties({
226-
code: 'server_error',
227-
message: 'Unknown security handler: api_key'
218+
it('should deny when swagger-tools handler denies', function(done) {
219+
220+
request(this.app)
221+
.get('/hello_secured')
222+
.set('Accept', 'application/json')
223+
.expect(403)
224+
.expect('Content-Type', /json/)
225+
.end(function(err, res) {
226+
should.not.exist(err);
227+
228+
res.body.should.have.properties({
229+
code: 'server_error',
230+
message: 'no way!'
231+
});
232+
233+
done();
228234
});
235+
});
229236

230-
done();
231-
});
237+
it('should allow when swagger-tools handler accepts', function(done) {
238+
239+
request(this.app)
240+
.get('/hello_secured?name=Scott')
241+
.set('Accept', 'application/json')
242+
.expect(200)
243+
.expect('Content-Type', /json/)
244+
.end(function(err, res) {
245+
should.not.exist(err);
246+
res.body.should.eql('Hello, Scott!');
247+
248+
done();
249+
});
250+
});
232251
});
233252

234-
it('should deny when swagger-tools handler denies', function(done) {
253+
describe('explicit in config', function() {
235254

236-
this.runner.securityHandlers = {
237-
api_key: function(req, secDef, key, cb) {
238-
cb(new Error('no way!'));
239-
}
240-
};
255+
it('should deny when missing handler', function(done) {
241256

242-
request(this.app)
243-
.get('/hello_secured')
244-
.set('Accept', 'application/json')
245-
.expect(403)
246-
.expect('Content-Type', /json/)
247-
.end(function(err, res) {
248-
should.not.exist(err);
257+
this.runner.securityHandlers = { };
249258

250-
res.body.should.have.properties({
251-
code: 'server_error',
252-
message: 'no way!'
259+
request(this.app)
260+
.get('/hello_secured')
261+
.set('Accept', 'application/json')
262+
.expect(403)
263+
.expect('Content-Type', /json/)
264+
.end(function(err, res) {
265+
should.not.exist(err);
266+
267+
res.body.should.have.properties({
268+
code: 'server_error',
269+
message: 'Unknown security handler: api_key'
270+
});
271+
272+
done();
253273
});
274+
});
254275

255-
done();
256-
});
257-
});
276+
it('should deny when swagger-tools handler denies', function(done) {
258277

259-
it('should allow when swagger-tools handler accepts', function(done) {
278+
this.runner.securityHandlers = {
279+
api_key: function(req, secDef, key, cb) {
280+
cb(new Error('no way!'));
281+
}
282+
};
260283

261-
this.runner.securityHandlers = {
262-
api_key: function(req, secDef, key, cb) {
263-
cb();
264-
}
265-
};
284+
request(this.app)
285+
.get('/hello_secured')
286+
.set('Accept', 'application/json')
287+
.expect(403)
288+
.expect('Content-Type', /json/)
289+
.end(function(err, res) {
290+
should.not.exist(err);
266291

267-
request(this.app)
268-
.get('/hello_secured')
269-
.set('Accept', 'application/json')
270-
.expect(200)
271-
.expect('Content-Type', /json/)
272-
.end(function(err, res) {
273-
should.not.exist(err);
274-
res.body.should.eql('Hello, stranger!');
292+
res.body.should.have.properties({
293+
code: 'server_error',
294+
message: 'no way!'
295+
});
275296

276-
done();
277-
});
297+
done();
298+
});
299+
});
300+
301+
it('should allow when swagger-tools handler accepts', function(done) {
302+
303+
this.runner.securityHandlers = {
304+
api_key: function(req, secDef, key, cb) {
305+
cb();
306+
}
307+
};
308+
309+
request(this.app)
310+
.get('/hello_secured')
311+
.set('Accept', 'application/json')
312+
.expect(200)
313+
.expect('Content-Type', /json/)
314+
.end(function(err, res) {
315+
should.not.exist(err);
316+
res.body.should.eql('Hello, stranger!');
317+
318+
done();
319+
});
320+
});
278321
});
279322
});
280323

0 commit comments

Comments
 (0)