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();