From c2cc0108f3a090b6afedc8afa1560657c495fbb4 Mon Sep 17 00:00:00 2001 From: Iain Cole <iain@twitch.tv> Date: Thu, 25 Jul 2019 21:15:33 -0700 Subject: [PATCH 1/2] Allow Arn Principal for lambda grantInvoke --- .../@aws-cdk/aws-lambda/lib/function-base.ts | 4 ++ .../@aws-cdk/aws-lambda/test/test.lambda.ts | 41 +++++++++++++------ 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/packages/@aws-cdk/aws-lambda/lib/function-base.ts b/packages/@aws-cdk/aws-lambda/lib/function-base.ts index 623fabb68820a..69002279621a8 100644 --- a/packages/@aws-cdk/aws-lambda/lib/function-base.ts +++ b/packages/@aws-cdk/aws-lambda/lib/function-base.ts @@ -285,6 +285,10 @@ export abstract class FunctionBase extends Resource implements IFunction { return (principal as iam.ServicePrincipal).service; } + if (`arn` in principal) { + return (principal as iam.ArnPrincipal).arn; + } + throw new Error(`Invalid principal type for Lambda permission statement: ${principal.constructor.name}. ` + 'Supported: AccountPrincipal, ServicePrincipal'); } diff --git a/packages/@aws-cdk/aws-lambda/test/test.lambda.ts b/packages/@aws-cdk/aws-lambda/test/test.lambda.ts index 09a36697952a9..6ba7330548a7c 100644 --- a/packages/@aws-cdk/aws-lambda/test/test.lambda.ts +++ b/packages/@aws-cdk/aws-lambda/test/test.lambda.ts @@ -186,19 +186,6 @@ export = { test.done(); }, - 'fails if the principal is not a service or account principals'(test: Test) { - const stack = new cdk.Stack(); - const fn = newTestLambda(stack); - - test.throws(() => fn.addPermission('F1', { principal: new iam.ArnPrincipal('just:arn') }), - /Invalid principal type for Lambda permission statement/); - - fn.addPermission('S1', { principal: new iam.ServicePrincipal('my-service') }); - fn.addPermission('S2', { principal: new iam.AccountPrincipal('account') }); - - test.done(); - }, - 'BYORole'(test: Test) { // GIVEN const stack = new cdk.Stack(); @@ -1074,6 +1061,34 @@ export = { test.done(); }, + 'grantInvoke with an arn principal'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const fn = new lambda.Function(stack, 'Function', { + code: lambda.Code.inline('xxx'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_8_10, + }); + const account = new iam.ArnPrincipal('arn:aws:iam::123456789012:role/someRole'); + + // WHEN + fn.grantInvoke(account); + + // THEN + expect(stack).to(haveResource('AWS::Lambda::Permission', { + Action: 'lambda:InvokeFunction', + FunctionName: { + 'Fn::GetAtt': [ + 'Function76856677', + 'Arn' + ] + }, + Principal: 'arn:aws:iam::123456789012:role/someRole' + })); + + test.done(); + }, + 'Can use metricErrors on a lambda Function'(test: Test) { // GIVEN const stack = new cdk.Stack(); From 6e5b796a3b2f20a8df175ba1d4d130a446d95e5c Mon Sep 17 00:00:00 2001 From: Iain Cole <iain@twitch.tv> Date: Thu, 1 Aug 2019 14:59:45 -0700 Subject: [PATCH 2/2] Add lambda grantInvoke principal test back and fix comment --- packages/@aws-cdk/aws-lambda/lib/function-base.ts | 2 +- packages/@aws-cdk/aws-lambda/test/test.lambda.ts | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-lambda/lib/function-base.ts b/packages/@aws-cdk/aws-lambda/lib/function-base.ts index 69002279621a8..3bbda22f1b465 100644 --- a/packages/@aws-cdk/aws-lambda/lib/function-base.ts +++ b/packages/@aws-cdk/aws-lambda/lib/function-base.ts @@ -290,7 +290,7 @@ export abstract class FunctionBase extends Resource implements IFunction { } throw new Error(`Invalid principal type for Lambda permission statement: ${principal.constructor.name}. ` + - 'Supported: AccountPrincipal, ServicePrincipal'); + 'Supported: AccountPrincipal, ArnPrincipal, ServicePrincipal'); } } diff --git a/packages/@aws-cdk/aws-lambda/test/test.lambda.ts b/packages/@aws-cdk/aws-lambda/test/test.lambda.ts index 6ba7330548a7c..7cb3fee771356 100644 --- a/packages/@aws-cdk/aws-lambda/test/test.lambda.ts +++ b/packages/@aws-cdk/aws-lambda/test/test.lambda.ts @@ -186,6 +186,20 @@ export = { test.done(); }, + 'fails if the principal is not a service, account or arn principal'(test: Test) { + const stack = new cdk.Stack(); + const fn = newTestLambda(stack); + + test.throws(() => fn.addPermission('F1', { principal: new iam.OrganizationPrincipal('org') }), + /Invalid principal type for Lambda permission statement/); + + fn.addPermission('S1', { principal: new iam.ServicePrincipal('my-service') }); + fn.addPermission('S2', { principal: new iam.AccountPrincipal('account') }); + fn.addPermission('S3', { principal: new iam.ArnPrincipal('my:arn') }); + + test.done(); + }, + 'BYORole'(test: Test) { // GIVEN const stack = new cdk.Stack();