Skip to content

Commit 708da49

Browse files
author
Aleksander Dikanski
committed
Fix issue wit custom authorizers when using pseudo parameters plugin
1 parent e154c85 commit 708da49

File tree

3 files changed

+125
-8
lines changed

3 files changed

+125
-8
lines changed

lib/stackops/apiGateway.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -221,17 +221,16 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac
221221
});
222222

223223
// Audjust authorizer Uri and name (stage variables are not allowed in Uris here)
224+
const isExternalRefAuthorizerPredicate = part => _.startsWith(part, 'arn:aws:lambda') ||
225+
(_.has(part, 'Fn::Sub') && _.startsWith(part['Fn::Sub'], 'arn:aws:lambda'));
224226
_.forOwn(authorizers, (authorizer, name) => {
225227
const authorizerType = _.get(authorizer, 'Properties.Type');
226228
if (authorizerType === 'TOKEN' || authorizerType === 'REQUEST') {
227229
const uriParts = authorizer.Properties.AuthorizerUri['Fn::Join'][1];
228-
const isExternalRefAuthorizer = _.every(uriParts, part => !_.startsWith(part, 'arn:aws:lambda'));
229-
if (isExternalRefAuthorizer) {
230-
const funcIndex = _.findIndex(uriParts, part =>
231-
_.has(part, 'Fn::GetAtt') || _.startsWith(part, 'arn:aws:lambda'));
232-
233-
// Use the SERVERLESS_ALIAS stage variable to determine the called function alias
234-
uriParts.splice(funcIndex + 1, 0, ':${stageVariables.SERVERLESS_ALIAS}');
230+
const isExternalRefAuthorizer = _.some(uriParts, isExternalRefAuthorizerPredicate);
231+
if (!isExternalRefAuthorizer) {
232+
const funcIndex = _.findIndex(uriParts, part => _.startsWith(part, '/invocations'));
233+
uriParts.splice(funcIndex , 0, ':${stageVariables.SERVERLESS_ALIAS}');
235234
}
236235
}
237236

@@ -269,7 +268,7 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac
269268
const functionName = _.replace(name, /LambdaPermissionApiGateway$/, '');
270269
const versionName = _.find(_.keys(versions), version => _.startsWith(version, functionName));
271270
const aliasName = _.find(_.keys(aliases), alias => _.startsWith(alias, functionName));
272-
const isExternalRef = _.startsWith(permission.Properties.FunctionName, 'arn:aws:lambda');
271+
const isExternalRef = isExternalRefAuthorizerPredicate(permission.Properties.FunctionName);
273272

274273
// Adjust references and alias permissions
275274
if (!isExternalRef) {

test/data/auth-stack-2.json

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,21 @@
216216
}
217217
}
218218
},
219+
"ApiGatewayResourceFunc2": {
220+
"Type": "AWS::ApiGateway::Resource",
221+
"Properties": {
222+
"ParentId": {
223+
"Fn::GetAtt": [
224+
"ApiGatewayRestApi",
225+
"RootResourceId"
226+
]
227+
},
228+
"PathPart": "func1",
229+
"RestApiId": {
230+
"Ref": "ApiGatewayRestApi"
231+
}
232+
}
233+
},
219234
"ApiGatewayMethodFunc1Get": {
220235
"Type": "AWS::ApiGateway::Method",
221236
"Properties": {
@@ -258,6 +273,48 @@
258273
},
259274
"DependsOn": "TestauthApiGatewayAuthorizer"
260275
},
276+
"ApiGatewayMethodFunc2Get": {
277+
"Type": "AWS::ApiGateway::Method",
278+
"Properties": {
279+
"HttpMethod": "GET",
280+
"RequestParameters": {},
281+
"ResourceId": {
282+
"Ref": "ApiGatewayResourceFunc2"
283+
},
284+
"RestApiId": {
285+
"Ref": "ApiGatewayRestApi"
286+
},
287+
"AuthorizationType": "CUSTOM",
288+
"AuthorizerId": {
289+
"Ref": "PseudoParamCustomAuthApiGatewayAuthorizer"
290+
},
291+
"Integration": {
292+
"IntegrationHttpMethod": "POST",
293+
"Type": "AWS_PROXY",
294+
"Uri": {
295+
"Fn::Join": [
296+
"",
297+
[
298+
"arn:aws:apigateway:",
299+
{
300+
"Ref": "AWS::Region"
301+
},
302+
":lambda:path/2015-03-31/functions/",
303+
{
304+
"Fn::GetAtt": [
305+
"Testfct1LambdaFunction",
306+
"Arn"
307+
]
308+
},
309+
"/invocations"
310+
]
311+
]
312+
}
313+
},
314+
"MethodResponses": []
315+
},
316+
"DependsOn": "PseudoParamCustomAuthApiGatewayAuthorizer"
317+
},
261318
"TestauthApiGatewayAuthorizer": {
262319
"Type": "AWS::ApiGateway::Authorizer",
263320
"Properties": {
@@ -288,6 +345,34 @@
288345
"Type": "TOKEN"
289346
}
290347
},
348+
"PseudoParamCustomAuthApiGatewayAuthorizer": {
349+
"Type": "AWS::ApiGateway::Authorizer",
350+
"Properties": {
351+
"AuthorizerResultTtlInSeconds": 0,
352+
"IdentitySource": "method.request.header.Authorization",
353+
"Name": "testauth",
354+
"RestApiId": {
355+
"Ref": "ApiGatewayRestApi"
356+
},
357+
"AuthorizerUri": {
358+
"Fn::Join": [
359+
"",
360+
[
361+
"arn:aws:apigateway:",
362+
{
363+
"Ref": "AWS::Region"
364+
},
365+
":lambda:path/2015-03-31/functions/",
366+
{
367+
"Fn::Sub": "arn:aws:lambda:us-east-1:${AWS::AccountId}:function:custom-auth"
368+
},
369+
"/invocations"
370+
]
371+
]
372+
},
373+
"Type": "TOKEN"
374+
}
375+
},
291376
"TestauthApiGatewayRequestAuthorizer": {
292377
"Type": "AWS::ApiGateway::Authorizer",
293378
"Properties": {

test/stackops/apiGateway.test.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,39 @@ describe('API Gateway', () => {
699699
]));
700700

701701
});
702+
703+
it('should support externally referenced custom authorizers with Pseudo Parameters', () => {
704+
stackTemplate = _.cloneDeep(require('../data/auth-stack-2.json'));
705+
const template = serverless.service.provider.compiledCloudFormationTemplate = stackTemplate;
706+
const compiledAliasTemplate = serverless.service.provider.compiledCloudFormationAliasTemplate = aliasTemplate;
707+
return expect(awsAlias.aliasHandleApiGateway({}, [], {})).to.be.fulfilled
708+
.then(() => BbPromise.all([
709+
expect(template)
710+
.to.have.a.nested.property("Resources.ApiGatewayMethodFunc2Get.Properties.AuthorizerId")
711+
.that.deep.equals({ Ref: "PseudoParamCustomAuthApiGatewayAuthorizermyAlias" }),
712+
expect(template)
713+
.to.have.a.nested.property("Resources.ApiGatewayMethodFunc2Get.DependsOn")
714+
.that.equals("PseudoParamCustomAuthApiGatewayAuthorizermyAlias"),
715+
expect(template)
716+
.to.have.a.nested.property('Resources.PseudoParamCustomAuthApiGatewayAuthorizermyAlias.Properties.AuthorizerUri')
717+
.that.deep.equals({
718+
"Fn::Join": [
719+
"",
720+
[
721+
"arn:aws:apigateway:",
722+
{
723+
"Ref": "AWS::Region"
724+
},
725+
":lambda:path/2015-03-31/functions/",
726+
{
727+
"Fn::Sub": "arn:aws:lambda:us-east-1:${AWS::AccountId}:function:custom-auth"
728+
},
729+
"/invocations"
730+
]
731+
]}),
732+
]));
733+
734+
});
702735

703736
it('should transform string dependencies and references to authorizers', () => {
704737
const template = serverless.service.provider.compiledCloudFormationTemplate = stackTemplate;

0 commit comments

Comments
 (0)