UNPKG

swagger-routes

Version:

Generate Express or Restify route handlers from a Swagger specification

84 lines (72 loc) 2.83 kB
'use strict' const fileAuthorizers = require('./fileAuthorizers') exports.getAuthorizers = getAuthorizers exports.createAuthCheck = createAuthCheck function getAuthorizers(securityDefinitions, options) { return getDefinitionIds(securityDefinitions) .map(id => ({ id, auth: getAuthorizer(id, securityDefinitions[id], options) })) .reduce((authorizers, info) => authorizers.set(info.id, info.auth), new Map()) } function getDefinitionIds(security) { return Object.keys(security || {}) .filter(id => !id.startsWith('x-')) } function getAuthorizer(id, securityScheme, options) { let authorizer if (typeof options.authorizers.create === 'function') authorizer = options.authorizers.create(id, securityScheme) if (authorizer) fileAuthorizers.disableAuthorizer(id, options) else authorizer = requireAuthorizer(id, securityScheme, options) if (authorizer && authorizer.default) authorizer = authorizer.default return authorizer } function requireAuthorizer(id, securityScheme, options) { const fileInfo = fileAuthorizers.enableAuthorizer(id, securityScheme, options) try { return require(fileInfo.path) } catch(e) { return null } } function createAuthCheck(operation, authorizers) { const security = operation.security || [] if (!security.length) return null return function authorize(req, res, next) { return Promise.all(security.map(scheme => { const id = Object.keys(scheme)[0] if (!id || id.startsWith('x-')) return null return new Promise((resolve, reject) => { const authorizer = authorizers.get(id) if (typeof authorizer === 'function') { const requiredScopes = scheme[id] req.verifyScopes = function verifyScopes(scopes) { return verifyRequiredScopes(requiredScopes, scopes) } try { const result = authorizer(req, res, err => err ? reject(err) : resolve()) if (result && result.catch) result.catch(e => reject(e)) } catch(e) { reject(e) } } else { // Unable to determine at this point if authorized but don't // have correct scope(s), or if authorization is required. // Assume the latter. const e = new Error('Unauthorized') e.statusCode = e.status = 401 reject(e) } }) })) .then(() => next()) .catch(e => next(e)) } } function verifyRequiredScopes(requiredScopes, scopes) { if (!requiredScopes || !requiredScopes.length) return undefined if (!scopes) scopes = [] const hasRequiredScopes = requiredScopes.every(scope => scopes.indexOf(scope) !== -1) if (!hasRequiredScopes) { const e = new Error('Forbidden') e.statusCode = e.status = 403 e.requiredScopes = requiredScopes return e } return undefined }