From 08418b52edfe151d70cc86d90d1372defce14d89 Mon Sep 17 00:00:00 2001 From: "Eslam A. Hefnawy" Date: Wed, 20 Jul 2016 19:42:20 +0900 Subject: [PATCH] added permission to authorizer --- .../events/apiGateway/lib/authorizers.js | 70 +++++++++---------- .../compile/events/apiGateway/lib/methods.js | 2 +- .../events/apiGateway/lib/permissions.js | 24 +++++++ 3 files changed, 57 insertions(+), 39 deletions(-) diff --git a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/authorizers.js b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/authorizers.js index 6eb8c03bf..ec753f7ab 100644 --- a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/authorizers.js +++ b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/authorizers.js @@ -7,40 +7,36 @@ module.exports = { compileAuthorizers() { _.forEach(this.serverless.service.functions, (functionObject, functionName) => { functionObject.events.forEach(event => { - if (event.http && event.http.authorizers) { - event.http.authorizers.forEach(authorizer => { - let resultTtlInSeconds; - let authorizerName; - let identitySource; + if (event.http && event.http.authorizer) { + const authorizer = event.http.authorizer; + let resultTtlInSeconds; + let authorizerName; + let identitySource; - const extractedResourceId = this.resourceLogicalIds[event.http.path].match(/\d+$/)[0]; - const normalizedMethod = event.http.method[0].toUpperCase() + - event.http.method.substr(1).toLowerCase(); + if (typeof authorizer === 'string') { + authorizerName = authorizer; + resultTtlInSeconds = '300'; + identitySource = 'method.request.header.Auth'; + } else if (typeof authorizer === 'object') { + authorizerName = authorizer.name; + resultTtlInSeconds = authorizer.resultTtlInSeconds || '300'; + identitySource = authorizer.identitySource || 'method.request.header.Auth'; + } else { + const errorMessage = [ + `authorizer property in function ${functionName} is not an object nor a string.`, + ' The correct format is: authorizer: functionName', + ' OR an object containing a name property.', + ' Please check the docs for more info.', + ].join(''); + throw new this.serverless.classes + .Error(errorMessage); + } - if (typeof authorizer === 'string') { - authorizerName = authorizer; - resultTtlInSeconds = '300'; - identitySource = 'method.request.header.Auth'; - } else if (typeof authorizer === 'object') { - authorizerName = authorizer.name; - resultTtlInSeconds = authorizer.resultTtlInSeconds || '300'; - identitySource = authorizer.identitySource || 'method.request.header.Auth'; - } else { - const errorMessage = [ - `Authorizer item in function ${functionName} is not an object nor a string.`, - ' Please make sure each authorizer in the "authorizers"', - ' array is a string or an object.', - ' Please check the docs for more info.', - ].join(''); - throw new this.serverless.classes - .Error(errorMessage); - } + // validate referenced authorizer + // function exists in service + this.serverless.service.getFunction(authorizerName); - // validate referenced authorizer - // function exists in service - this.serverless.service.getFunction(authorizerName); - - const authorizerTemplate = ` + const authorizerTemplate = ` { "Type" : "AWS::ApiGateway::Authorizer", "Properties" : { @@ -59,14 +55,12 @@ module.exports = { } `; - const authorizerObject = { - [`${authorizerName}Authorizer`]: - JSON.parse(authorizerTemplate), - }; + const authorizerObject = { + [`${authorizerName}Authorizer`]: JSON.parse(authorizerTemplate), + }; - _.merge(this.serverless.service.resources.Resources, - authorizerObject); - }); + _.merge(this.serverless.service.resources.Resources, + authorizerObject); } }); }); diff --git a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/methods.js b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/methods.js index 632ff8f61..9700ea93f 100644 --- a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/methods.js +++ b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/methods.js @@ -118,7 +118,7 @@ module.exports = { // set authorizer config if available if (event.http.authorizer) { - const AuthorizerLogicalId = `${authorizerName}Authorizer`; + const AuthorizerLogicalId = `${event.http.authorizer}Authorizer`; methodTemplateJson.Properties.AuthorizationType = 'CUSTOM'; methodTemplateJson.Properties.AuthorizerId = { diff --git a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/permissions.js b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/permissions.js index 2ec265a44..572806ef3 100644 --- a/lib/plugins/aws/deploy/compile/events/apiGateway/lib/permissions.js +++ b/lib/plugins/aws/deploy/compile/events/apiGateway/lib/permissions.js @@ -50,6 +50,30 @@ module.exports = { }; _.merge(this.serverless.service.resources.Resources, newPermissionObject); + + // if authorizer is defined, we need to add + // permission to invoke this lambda function too + // TODO: if the authorizer function has http event, + // will that permision conflict? + if (event.http.authorizer) { + const authorizerPermissionTemplate = ` + { + "Type": "AWS::Lambda::Permission", + "Properties": { + "FunctionName": { "Fn::GetAtt": ["${event.http.authorizer}", "Arn"] }, + "Action": "lambda:InvokeFunction", + "Principal": "apigateway.amazonaws.com" + } + } + `; + const authorizerPermissionLogicalId = `${normalizedMethod}AuthPermissionApigEvent${this + .resourcePaths.indexOf(path)}`; + + const newAuthPermissionObject = { + [authorizerPermissionLogicalId]: JSON.parse(authorizerPermissionTemplate), + }; + _.merge(this.serverless.service.resources.Resources, newAuthPermissionObject); + } } }); });