diff --git a/packages/@aws-cdk/aws-apigateway/README.md b/packages/@aws-cdk/aws-apigateway/README.md index 4891862d00be3..69c074590dc1c 100644 --- a/packages/@aws-cdk/aws-apigateway/README.md +++ b/packages/@aws-cdk/aws-apigateway/README.md @@ -740,7 +740,51 @@ books.addMethod('GET', new apigateway.HttpIntegration('http://amazon.com'), { A full working example is shown below. -[Full token authorizer example](test/authorizers/integ.token-authorizer.lit.ts). +```ts +import * as path from 'path'; +import * as lambda from '@aws-cdk/aws-lambda'; +import { App, Stack } from '@aws-cdk/core'; +import { MockIntegration, PassthroughBehavior, RestApi, TokenAuthorizer, Cors } from '../../lib'; + +/// !show +const app = new App(); +const stack = new Stack(app, 'TokenAuthorizerInteg'); + +const authorizerFn = new lambda.Function(stack, 'MyAuthorizerFunction', { + runtime: lambda.Runtime.NODEJS_14_X, + handler: 'index.handler', + code: lambda.AssetCode.fromAsset(path.join(__dirname, 'integ.token-authorizer.handler')), +}); + +const authorizer = new TokenAuthorizer(stack, 'MyAuthorizer', { + handler: authorizerFn, +}); + +const restapi = new RestApi(stack, 'MyRestApi', { + cloudWatchRole: true, + defaultMethodOptions: { + authorizer, + }, + defaultCorsPreflightOptions: { + allowOrigins: Cors.ALL_ORIGINS, + }, +}); + + +restapi.root.addMethod('ANY', new MockIntegration({ + integrationResponses: [ + { statusCode: '200' }, + ], + passthroughBehavior: PassthroughBehavior.NEVER, + requestTemplates: { + 'application/json': '{ "statusCode": 200 }', + }, +}), { + methodResponses: [ + { statusCode: '200' }, + ], +}); +``` By default, the `TokenAuthorizer` looks for the authorization token in the request header with the key 'Authorization'. This can, however, be modified by changing the `identitySource` property. diff --git a/packages/@aws-cdk/aws-apigateway/lib/method.ts b/packages/@aws-cdk/aws-apigateway/lib/method.ts index b2b32f8aa752e..ff2debf4be728 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/method.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/method.ts @@ -186,7 +186,7 @@ export class Method extends Resource { const defaultMethodOptions = props.resource.defaultMethodOptions || {}; const authorizer = options.authorizer || defaultMethodOptions.authorizer; - const authorizerId = authorizer?.authorizerId; + const authorizerId = authorizer?.authorizerId ? authorizer.authorizerId : undefined; const authorizationTypeOption = options.authorizationType || defaultMethodOptions.authorizationType; const authorizationType = authorizer?.authorizationType || authorizationTypeOption || AuthorizationType.NONE; diff --git a/packages/@aws-cdk/aws-apigateway/lib/resource.ts b/packages/@aws-cdk/aws-apigateway/lib/resource.ts index cd0b2c38cc008..8d0074dfe4af4 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/resource.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/resource.ts @@ -4,7 +4,7 @@ import { CfnResource, CfnResourceProps } from './apigateway.generated'; import { Cors, CorsOptions } from './cors'; import { Integration } from './integration'; import { MockIntegration } from './integrations'; -import { Method, MethodOptions } from './method'; +import { Method, MethodOptions, AuthorizationType } from './method'; import { IRestApi, RestApi } from './restapi'; export interface IResource extends IResourceBase { @@ -296,6 +296,12 @@ export abstract class ResourceBase extends ResourceConstruct implements IResourc { statusCode: `${statusCode}`, responseParameters: integrationResponseParams, responseTemplates: renderResponseTemplate() }, ], }), { + authorizer: { + authorizerId: '', + authorizationType: AuthorizationType.NONE, + }, + apiKeyRequired: false, + authorizationType: AuthorizationType.NONE, methodResponses: [ { statusCode: `${statusCode}`, responseParameters: methodResponseParams }, ], diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.lit.ts b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.lit.ts deleted file mode 100644 index 5932b7a5a8a13..0000000000000 --- a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.lit.ts +++ /dev/null @@ -1,41 +0,0 @@ -import * as path from 'path'; -import * as lambda from '@aws-cdk/aws-lambda'; -import { App, Stack } from '@aws-cdk/core'; -import { MockIntegration, PassthroughBehavior, RestApi, TokenAuthorizer } from '../../lib'; - -/* - * Stack verification steps: - * * `curl -s -o /dev/null -w "%{http_code}" ` should return 401 - * * `curl -s -o /dev/null -w "%{http_code}" -H 'Authorization: deny' ` should return 403 - * * `curl -s -o /dev/null -w "%{http_code}" -H 'Authorization: allow' ` should return 200 - */ - -const app = new App(); -const stack = new Stack(app, 'TokenAuthorizerInteg'); - -const authorizerFn = new lambda.Function(stack, 'MyAuthorizerFunction', { - runtime: lambda.Runtime.NODEJS_14_X, - handler: 'index.handler', - code: lambda.AssetCode.fromAsset(path.join(__dirname, 'integ.token-authorizer.handler')), -}); - -const restapi = new RestApi(stack, 'MyRestApi', { cloudWatchRole: true }); - -const authorizer = new TokenAuthorizer(stack, 'MyAuthorizer', { - handler: authorizerFn, -}); - -restapi.root.addMethod('ANY', new MockIntegration({ - integrationResponses: [ - { statusCode: '200' }, - ], - passthroughBehavior: PassthroughBehavior.NEVER, - requestTemplates: { - 'application/json': '{ "statusCode": 200 }', - }, -}), { - methodResponses: [ - { statusCode: '200' }, - ], - authorizer, -}); diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.ts b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.ts new file mode 100644 index 0000000000000..19bed2089617e --- /dev/null +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.ts @@ -0,0 +1,127 @@ +import * as path from 'path'; +import * as lambda from '@aws-cdk/aws-lambda'; +import { App, Stack, Duration } from '@aws-cdk/core'; +import { IntegTest, ExpectedResult, Match } from '@aws-cdk/integ-tests'; +import { MockIntegration, PassthroughBehavior, RestApi, TokenAuthorizer, Cors } from '../../lib'; + +const app = new App(); +const stack = new Stack(app, 'TokenAuthorizerInteg'); + +const authorizerFn = new lambda.Function(stack, 'MyAuthorizerFunction', { + runtime: lambda.Runtime.NODEJS_14_X, + handler: 'index.handler', + code: lambda.AssetCode.fromAsset(path.join(__dirname, 'integ.token-authorizer.handler')), +}); + +const authorizer = new TokenAuthorizer(stack, 'MyAuthorizer', { + handler: authorizerFn, +}); + +const restapi = new RestApi(stack, 'MyRestApi', { + cloudWatchRole: true, + defaultMethodOptions: { + authorizer, + }, + defaultCorsPreflightOptions: { + allowOrigins: Cors.ALL_ORIGINS, + }, +}); + + +restapi.root.addMethod('ANY', new MockIntegration({ + integrationResponses: [ + { statusCode: '200' }, + ], + passthroughBehavior: PassthroughBehavior.NEVER, + requestTemplates: { + 'application/json': '{ "statusCode": 200 }', + }, +}), { + methodResponses: [ + { statusCode: '200' }, + ], +}); + +const integ = new IntegTest(app, 'apigw-token-auth', { + testCases: [stack], +}); +const hostName = `${restapi.restApiId}.execute-api.${stack.region}.${stack.urlSuffix}`; +const testFunc = new lambda.Function(stack, 'InvokeFunction', { + memorySize: 250, + timeout: Duration.seconds(10), + code: lambda.Code.fromInline(` +const https = require('https'); +const options = { + hostname: '${hostName}', + path: '/${restapi.deploymentStage.stageName}', +}; +exports.handler = async function(event) { + console.log(event); + options.method = event.method; + if ('authorization' in event) { + options.headers = { + Authorization: event.authorization, + }; + } + let dataString = ''; + const response = await new Promise((resolve, reject) => { + const req = https.request(options, (res) => { + res.on('data', data => { + dataString += data; + }) + res.on('end', () => { + resolve({ + statusCode: res.statusCode, + body: dataString, + }); + }) + }); + req.on('error', err => { + reject({ + statusCode: 500, + body: JSON.stringify({ + cause: 'Something went wrong', + error: err, + }) + }); + }); + req.end(); + }); + return response; +} +`), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_16_X, +}); + +const invokeGet = integ.assertions.invokeFunction({ + functionName: testFunc.functionName, + payload: JSON.stringify({ + method: 'GET', + authorization: 'allow', + }), +}); +invokeGet.expect(ExpectedResult.objectLike({ + Payload: Match.stringLikeRegexp('200'), +})); + +const invokeGetDeny = integ.assertions.invokeFunction({ + functionName: testFunc.functionName, + payload: JSON.stringify({ + method: 'GET', + authorization: 'deny', + }), +}); +invokeGetDeny.expect(ExpectedResult.objectLike({ + Payload: Match.stringLikeRegexp('User is not authorized to access this resource with an explicit deny'), +})); + +const invokeOptions = integ.assertions.invokeFunction({ + functionName: testFunc.functionName, + payload: JSON.stringify({ + method: 'OPTIONS', + }), +}); +invokeOptions.expect(ExpectedResult.objectLike({ + Payload: Match.stringLikeRegexp('204'), +})); diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/TokenAuthorizerInteg.assets.json b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/TokenAuthorizerInteg.assets.json similarity index 85% rename from packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/TokenAuthorizerInteg.assets.json rename to packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/TokenAuthorizerInteg.assets.json index e9587f517510e..02ff71cc0d01f 100644 --- a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/TokenAuthorizerInteg.assets.json +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/TokenAuthorizerInteg.assets.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "21.0.0", "files": { "fec8e8354e12687c5a4b843b4e269741f53dec634946869b276f7fd1017845c3": { "source": { @@ -14,7 +14,7 @@ } } }, - "d121ee9744a20c9af43e516c8fb4fe93d1ed9b26130e2db68ed9534c7104c866": { + "d48b90b340d35b9bc726b78e652d17148e2449f6f756e4377428635071f68d09": { "source": { "path": "TokenAuthorizerInteg.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "d121ee9744a20c9af43e516c8fb4fe93d1ed9b26130e2db68ed9534c7104c866.json", + "objectKey": "d48b90b340d35b9bc726b78e652d17148e2449f6f756e4377428635071f68d09.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/TokenAuthorizerInteg.template.json b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/TokenAuthorizerInteg.template.json similarity index 62% rename from packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/TokenAuthorizerInteg.template.json rename to packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/TokenAuthorizerInteg.template.json index 4f5a6b3ab83c4..3d2e9d31fafd1 100644 --- a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/TokenAuthorizerInteg.template.json +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/TokenAuthorizerInteg.template.json @@ -93,6 +93,66 @@ } } }, + "MyAuthorizer6575980E": { + "Type": "AWS::ApiGateway::Authorizer", + "Properties": { + "Name": "TokenAuthorizerIntegMyAuthorizer793B1D5F", + "RestApiId": { + "Ref": "MyRestApi2D1F47A9" + }, + "Type": "TOKEN", + "AuthorizerUri": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + ":", + { + "Fn::GetAtt": [ + "MyAuthorizerFunction70F1223E", + "Arn" + ] + } + ] + } + ] + }, + ":apigateway:", + { + "Fn::Select": [ + 3, + { + "Fn::Split": [ + ":", + { + "Fn::GetAtt": [ + "MyAuthorizerFunction70F1223E", + "Arn" + ] + } + ] + } + ] + }, + ":lambda:path/2015-03-31/functions/", + { + "Fn::GetAtt": [ + "MyAuthorizerFunction70F1223E", + "Arn" + ] + }, + "/invocations" + ] + ] + }, + "IdentitySource": "method.request.header.Authorization" + } + }, "MyRestApi2D1F47A9": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -148,7 +208,7 @@ "UpdateReplacePolicy": "Retain", "DeletionPolicy": "Retain" }, - "MyRestApiDeploymentB555B582dcff966d69deeda8d47e3bf409ce29cb": { + "MyRestApiDeploymentB555B582464879c8d1f9fcce2500f142532cdaec": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { @@ -157,7 +217,8 @@ "Description": "Automatically created by the RestApi construct" }, "DependsOn": [ - "MyRestApiANY05143F93" + "MyRestApiANY05143F93", + "MyRestApiOPTIONS43BD7BF4" ] }, "MyRestApiDeploymentStageprodC33B8E5F": { @@ -167,7 +228,7 @@ "Ref": "MyRestApi2D1F47A9" }, "DeploymentId": { - "Ref": "MyRestApiDeploymentB555B582dcff966d69deeda8d47e3bf409ce29cb" + "Ref": "MyRestApiDeploymentB555B582464879c8d1f9fcce2500f142532cdaec" }, "StageName": "prod" }, @@ -175,6 +236,48 @@ "MyRestApiAccount2FB6DB7A" ] }, + "MyRestApiOPTIONS43BD7BF4": { + "Type": "AWS::ApiGateway::Method", + "Properties": { + "HttpMethod": "OPTIONS", + "ResourceId": { + "Fn::GetAtt": [ + "MyRestApi2D1F47A9", + "RootResourceId" + ] + }, + "RestApiId": { + "Ref": "MyRestApi2D1F47A9" + }, + "AuthorizationType": "NONE", + "Integration": { + "IntegrationResponses": [ + { + "ResponseParameters": { + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'", + "method.response.header.Access-Control-Allow-Origin": "'*'", + "method.response.header.Access-Control-Allow-Methods": "'OPTIONS,GET,PUT,POST,DELETE,PATCH,HEAD'" + }, + "StatusCode": "204" + } + ], + "RequestTemplates": { + "application/json": "{ statusCode: 200 }" + }, + "Type": "MOCK" + }, + "MethodResponses": [ + { + "ResponseParameters": { + "method.response.header.Access-Control-Allow-Headers": true, + "method.response.header.Access-Control-Allow-Origin": true, + "method.response.header.Access-Control-Allow-Methods": true + }, + "StatusCode": "204" + } + ] + } + }, "MyRestApiANY05143F93": { "Type": "AWS::ApiGateway::Method", "Properties": { @@ -211,65 +314,80 @@ ] } }, - "MyAuthorizer6575980E": { - "Type": "AWS::ApiGateway::Authorizer", + "InvokeFunctionServiceRole3B980FD2": { + "Type": "AWS::IAM::Role", "Properties": { - "Name": "TokenAuthorizerIntegMyAuthorizer793B1D5F", - "RestApiId": { - "Ref": "MyRestApi2D1F47A9" + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" }, - "Type": "TOKEN", - "AuthorizerUri": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Fn::Select": [ - 1, - { - "Fn::Split": [ - ":", - { - "Fn::GetAtt": [ - "MyAuthorizerFunction70F1223E", - "Arn" - ] - } - ] - } - ] - }, - ":apigateway:", - { - "Fn::Select": [ - 3, - { - "Fn::Split": [ - ":", - { - "Fn::GetAtt": [ - "MyAuthorizerFunction70F1223E", - "Arn" - ] - } - ] - } - ] - }, - ":lambda:path/2015-03-31/functions/", - { - "Fn::GetAtt": [ - "MyAuthorizerFunction70F1223E", - "Arn" - ] - }, - "/invocations" + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] ] + } + ] + } + }, + "InvokeFunctionC517E46D": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": { + "Fn::Join": [ + "", + [ + "\nconst https = require('https');\nconst options = {\n hostname: '", + { + "Ref": "MyRestApi2D1F47A9" + }, + ".execute-api.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "',\n path: '/", + { + "Ref": "MyRestApiDeploymentStageprodC33B8E5F" + }, + "',\n};\nexports.handler = async function(event) {\n console.log(event);\n options.method = event.method;\n if ('authorization' in event) {\n options.headers = {\n Authorization: event.authorization,\n };\n }\n let dataString = '';\n const response = await new Promise((resolve, reject) => {\n const req = https.request(options, (res) => {\n res.on('data', data => {\n dataString += data;\n })\n res.on('end', () => {\n resolve({\n statusCode: res.statusCode,\n body: dataString,\n });\n })\n });\n req.on('error', err => {\n reject({\n statusCode: 500,\n body: JSON.stringify({\n cause: 'Something went wrong',\n error: err,\n })\n });\n });\n req.end();\n });\n return response;\n}\n" + ] + ] + } + }, + "Role": { + "Fn::GetAtt": [ + "InvokeFunctionServiceRole3B980FD2", + "Arn" ] }, - "IdentitySource": "method.request.header.Authorization" - } + "Handler": "index.handler", + "MemorySize": 250, + "Runtime": "nodejs16.x", + "Timeout": 10 + }, + "DependsOn": [ + "InvokeFunctionServiceRole3B980FD2" + ] } }, "Outputs": { @@ -298,6 +416,14 @@ ] ] } + }, + "ExportsOutputRefInvokeFunctionC517E46D32C855B5": { + "Value": { + "Ref": "InvokeFunctionC517E46D" + }, + "Export": { + "Name": "TokenAuthorizerInteg:ExportsOutputRefInvokeFunctionC517E46D32C855B5" + } } }, "Parameters": { diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/apigwtokenauthDefaultTestDeployAssert2CF60E05.assets.json b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/apigwtokenauthDefaultTestDeployAssert2CF60E05.assets.json new file mode 100644 index 0000000000000..5ff8adbfac7a7 --- /dev/null +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/apigwtokenauthDefaultTestDeployAssert2CF60E05.assets.json @@ -0,0 +1,32 @@ +{ + "version": "21.0.0", + "files": { + "456da4984f762c1c25e94bd5f2df6758d2b0884d0dae8ca59bb8f4e3de7c2136": { + "source": { + "path": "asset.456da4984f762c1c25e94bd5f2df6758d2b0884d0dae8ca59bb8f4e3de7c2136.bundle", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "456da4984f762c1c25e94bd5f2df6758d2b0884d0dae8ca59bb8f4e3de7c2136.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "663a8c1a16f9e427d0ecfe2215cb471b582dfce87e95f6bbf85d32c371692ece": { + "source": { + "path": "apigwtokenauthDefaultTestDeployAssert2CF60E05.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "663a8c1a16f9e427d0ecfe2215cb471b582dfce87e95f6bbf85d32c371692ece.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/apigwtokenauthDefaultTestDeployAssert2CF60E05.template.json b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/apigwtokenauthDefaultTestDeployAssert2CF60E05.template.json new file mode 100644 index 0000000000000..e1e122baa02da --- /dev/null +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/apigwtokenauthDefaultTestDeployAssert2CF60E05.template.json @@ -0,0 +1,353 @@ +{ + "Resources": { + "LambdaInvoke3deec958b1e945795e38da5fc2f86753": { + "Type": "Custom::DeployAssert@SdkCallLambdainvoke", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F", + "Arn" + ] + }, + "service": "Lambda", + "api": "invoke", + "expected": "{\"$ObjectLike\":{\"Payload\":{\"$StringLike\":\"200\"}}}", + "parameters": { + "FunctionName": { + "Fn::ImportValue": "TokenAuthorizerInteg:ExportsOutputRefInvokeFunctionC517E46D32C855B5" + }, + "Payload": "{\"method\":\"GET\",\"authorization\":\"allow\"}" + }, + "flattenResponse": "false", + "salt": "1665080757293" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "LambdaInvoke3deec958b1e945795e38da5fc2f86753InvokeCB0E5D28": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::ImportValue": "TokenAuthorizerInteg:ExportsOutputRefInvokeFunctionC517E46D32C855B5" + }, + "Principal": { + "Fn::GetAtt": [ + "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73", + "Arn" + ] + } + } + }, + "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ] + }, + "ManagedPolicyArns": [ + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + } + ], + "Policies": [ + { + "PolicyName": "Inline", + "PolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "lambda:Invoke" + ], + "Effect": "Allow", + "Resource": [ + "*" + ] + }, + { + "Action": [ + "lambda:InvokeFunction" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":lambda:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":function:", + { + "Fn::ImportValue": "TokenAuthorizerInteg:ExportsOutputRefInvokeFunctionC517E46D32C855B5" + } + ] + ] + } + ] + }, + { + "Action": [ + "lambda:Invoke" + ], + "Effect": "Allow", + "Resource": [ + "*" + ] + }, + { + "Action": [ + "lambda:InvokeFunction" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":lambda:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":function:", + { + "Fn::ImportValue": "TokenAuthorizerInteg:ExportsOutputRefInvokeFunctionC517E46D32C855B5" + } + ] + ] + } + ] + }, + { + "Action": [ + "lambda:Invoke" + ], + "Effect": "Allow", + "Resource": [ + "*" + ] + }, + { + "Action": [ + "lambda:InvokeFunction" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":lambda:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":function:", + { + "Fn::ImportValue": "TokenAuthorizerInteg:ExportsOutputRefInvokeFunctionC517E46D32C855B5" + } + ] + ] + } + ] + } + ] + } + } + ] + } + }, + "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Runtime": "nodejs14.x", + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "456da4984f762c1c25e94bd5f2df6758d2b0884d0dae8ca59bb8f4e3de7c2136.zip" + }, + "Timeout": 120, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73", + "Arn" + ] + } + } + }, + "LambdaInvoke8e1b9f979f2329abf1ed6574d33d391a": { + "Type": "Custom::DeployAssert@SdkCallLambdainvoke", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F", + "Arn" + ] + }, + "service": "Lambda", + "api": "invoke", + "expected": "{\"$ObjectLike\":{\"Payload\":{\"$StringLike\":\"User is not authorized to access this resource with an explicit deny\"}}}", + "parameters": { + "FunctionName": { + "Fn::ImportValue": "TokenAuthorizerInteg:ExportsOutputRefInvokeFunctionC517E46D32C855B5" + }, + "Payload": "{\"method\":\"GET\",\"authorization\":\"deny\"}" + }, + "flattenResponse": "false", + "salt": "1665080757294" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "LambdaInvoke8e1b9f979f2329abf1ed6574d33d391aInvokeCCB91944": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::ImportValue": "TokenAuthorizerInteg:ExportsOutputRefInvokeFunctionC517E46D32C855B5" + }, + "Principal": { + "Fn::GetAtt": [ + "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73", + "Arn" + ] + } + } + }, + "LambdaInvoke0532e3d95b2a56b147278c621e5800c4": { + "Type": "Custom::DeployAssert@SdkCallLambdainvoke", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F", + "Arn" + ] + }, + "service": "Lambda", + "api": "invoke", + "expected": "{\"$ObjectLike\":{\"Payload\":{\"$StringLike\":\"204\"}}}", + "parameters": { + "FunctionName": { + "Fn::ImportValue": "TokenAuthorizerInteg:ExportsOutputRefInvokeFunctionC517E46D32C855B5" + }, + "Payload": "{\"method\":\"OPTIONS\"}" + }, + "flattenResponse": "false", + "salt": "1665080757295" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "LambdaInvoke0532e3d95b2a56b147278c621e5800c4Invoke73472D9F": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::ImportValue": "TokenAuthorizerInteg:ExportsOutputRefInvokeFunctionC517E46D32C855B5" + }, + "Principal": { + "Fn::GetAtt": [ + "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73", + "Arn" + ] + } + } + } + }, + "Outputs": { + "AssertionResultsLambdaInvoke3deec958b1e945795e38da5fc2f86753": { + "Value": { + "Fn::GetAtt": [ + "LambdaInvoke3deec958b1e945795e38da5fc2f86753", + "assertion" + ] + } + }, + "AssertionResultsLambdaInvoke8e1b9f979f2329abf1ed6574d33d391a": { + "Value": { + "Fn::GetAtt": [ + "LambdaInvoke8e1b9f979f2329abf1ed6574d33d391a", + "assertion" + ] + } + }, + "AssertionResultsLambdaInvoke0532e3d95b2a56b147278c621e5800c4": { + "Value": { + "Fn::GetAtt": [ + "LambdaInvoke0532e3d95b2a56b147278c621e5800c4", + "assertion" + ] + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/asset.456da4984f762c1c25e94bd5f2df6758d2b0884d0dae8ca59bb8f4e3de7c2136.bundle/index.js b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/asset.456da4984f762c1c25e94bd5f2df6758d2b0884d0dae8ca59bb8f4e3de7c2136.bundle/index.js new file mode 100644 index 0000000000000..afcb0cbcfe30a --- /dev/null +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/asset.456da4984f762c1c25e94bd5f2df6758d2b0884d0dae8ca59bb8f4e3de7c2136.bundle/index.js @@ -0,0 +1,668 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// lib/assertions/providers/lambda-handler/index.ts +var lambda_handler_exports = {}; +__export(lambda_handler_exports, { + handler: () => handler +}); +module.exports = __toCommonJS(lambda_handler_exports); + +// ../assertions/lib/matcher.ts +var Matcher = class { + static isMatcher(x) { + return x && x instanceof Matcher; + } +}; +var MatchResult = class { + constructor(target) { + this.failures = []; + this.captures = /* @__PURE__ */ new Map(); + this.finalized = false; + this.target = target; + } + push(matcher, path, message) { + return this.recordFailure({ matcher, path, message }); + } + recordFailure(failure) { + this.failures.push(failure); + return this; + } + hasFailed() { + return this.failures.length !== 0; + } + get failCount() { + return this.failures.length; + } + compose(id, inner) { + const innerF = inner.failures; + this.failures.push(...innerF.map((f) => { + return { path: [id, ...f.path], message: f.message, matcher: f.matcher }; + })); + inner.captures.forEach((vals, capture) => { + vals.forEach((value) => this.recordCapture({ capture, value })); + }); + return this; + } + finished() { + if (this.finalized) { + return this; + } + if (this.failCount === 0) { + this.captures.forEach((vals, cap) => cap._captured.push(...vals)); + } + this.finalized = true; + return this; + } + toHumanStrings() { + return this.failures.map((r) => { + const loc = r.path.length === 0 ? "" : ` at ${r.path.join("")}`; + return "" + r.message + loc + ` (using ${r.matcher.name} matcher)`; + }); + } + recordCapture(options) { + let values = this.captures.get(options.capture); + if (values === void 0) { + values = []; + } + values.push(options.value); + this.captures.set(options.capture, values); + } +}; + +// ../assertions/lib/private/matchers/absent.ts +var AbsentMatch = class extends Matcher { + constructor(name) { + super(); + this.name = name; + } + test(actual) { + const result = new MatchResult(actual); + if (actual !== void 0) { + result.recordFailure({ + matcher: this, + path: [], + message: `Received ${actual}, but key should be absent` + }); + } + return result; + } +}; + +// ../assertions/lib/private/type.ts +function getType(obj) { + return Array.isArray(obj) ? "array" : typeof obj; +} + +// ../assertions/lib/match.ts +var Match = class { + static absent() { + return new AbsentMatch("absent"); + } + static arrayWith(pattern) { + return new ArrayMatch("arrayWith", pattern); + } + static arrayEquals(pattern) { + return new ArrayMatch("arrayEquals", pattern, { subsequence: false }); + } + static exact(pattern) { + return new LiteralMatch("exact", pattern, { partialObjects: false }); + } + static objectLike(pattern) { + return new ObjectMatch("objectLike", pattern); + } + static objectEquals(pattern) { + return new ObjectMatch("objectEquals", pattern, { partial: false }); + } + static not(pattern) { + return new NotMatch("not", pattern); + } + static serializedJson(pattern) { + return new SerializedJson("serializedJson", pattern); + } + static anyValue() { + return new AnyMatch("anyValue"); + } + static stringLikeRegexp(pattern) { + return new StringLikeRegexpMatch("stringLikeRegexp", pattern); + } +}; +var LiteralMatch = class extends Matcher { + constructor(name, pattern, options = {}) { + super(); + this.name = name; + this.pattern = pattern; + this.partialObjects = options.partialObjects ?? false; + if (Matcher.isMatcher(this.pattern)) { + throw new Error("LiteralMatch cannot directly contain another matcher. Remove the top-level matcher or nest it more deeply."); + } + } + test(actual) { + if (Array.isArray(this.pattern)) { + return new ArrayMatch(this.name, this.pattern, { subsequence: false, partialObjects: this.partialObjects }).test(actual); + } + if (typeof this.pattern === "object") { + return new ObjectMatch(this.name, this.pattern, { partial: this.partialObjects }).test(actual); + } + const result = new MatchResult(actual); + if (typeof this.pattern !== typeof actual) { + result.recordFailure({ + matcher: this, + path: [], + message: `Expected type ${typeof this.pattern} but received ${getType(actual)}` + }); + return result; + } + if (actual !== this.pattern) { + result.recordFailure({ + matcher: this, + path: [], + message: `Expected ${this.pattern} but received ${actual}` + }); + } + return result; + } +}; +var ArrayMatch = class extends Matcher { + constructor(name, pattern, options = {}) { + super(); + this.name = name; + this.pattern = pattern; + this.subsequence = options.subsequence ?? true; + this.partialObjects = options.partialObjects ?? false; + } + test(actual) { + if (!Array.isArray(actual)) { + return new MatchResult(actual).recordFailure({ + matcher: this, + path: [], + message: `Expected type array but received ${getType(actual)}` + }); + } + if (!this.subsequence && this.pattern.length !== actual.length) { + return new MatchResult(actual).recordFailure({ + matcher: this, + path: [], + message: `Expected array of length ${this.pattern.length} but received ${actual.length}` + }); + } + let patternIdx = 0; + let actualIdx = 0; + const result = new MatchResult(actual); + while (patternIdx < this.pattern.length && actualIdx < actual.length) { + const patternElement = this.pattern[patternIdx]; + const matcher = Matcher.isMatcher(patternElement) ? patternElement : new LiteralMatch(this.name, patternElement, { partialObjects: this.partialObjects }); + const matcherName = matcher.name; + if (this.subsequence && (matcherName == "absent" || matcherName == "anyValue")) { + throw new Error(`The Matcher ${matcherName}() cannot be nested within arrayWith()`); + } + const innerResult = matcher.test(actual[actualIdx]); + if (!this.subsequence || !innerResult.hasFailed()) { + result.compose(`[${actualIdx}]`, innerResult); + patternIdx++; + actualIdx++; + } else { + actualIdx++; + } + } + for (; patternIdx < this.pattern.length; patternIdx++) { + const pattern = this.pattern[patternIdx]; + const element = Matcher.isMatcher(pattern) || typeof pattern === "object" ? " " : ` [${pattern}] `; + result.recordFailure({ + matcher: this, + path: [], + message: `Missing element${element}at pattern index ${patternIdx}` + }); + } + return result; + } +}; +var ObjectMatch = class extends Matcher { + constructor(name, pattern, options = {}) { + super(); + this.name = name; + this.pattern = pattern; + this.partial = options.partial ?? true; + } + test(actual) { + if (typeof actual !== "object" || Array.isArray(actual)) { + return new MatchResult(actual).recordFailure({ + matcher: this, + path: [], + message: `Expected type object but received ${getType(actual)}` + }); + } + const result = new MatchResult(actual); + if (!this.partial) { + for (const a of Object.keys(actual)) { + if (!(a in this.pattern)) { + result.recordFailure({ + matcher: this, + path: [`/${a}`], + message: "Unexpected key" + }); + } + } + } + for (const [patternKey, patternVal] of Object.entries(this.pattern)) { + if (!(patternKey in actual) && !(patternVal instanceof AbsentMatch)) { + result.recordFailure({ + matcher: this, + path: [`/${patternKey}`], + message: `Missing key '${patternKey}' among {${Object.keys(actual).join(",")}}` + }); + continue; + } + const matcher = Matcher.isMatcher(patternVal) ? patternVal : new LiteralMatch(this.name, patternVal, { partialObjects: this.partial }); + const inner = matcher.test(actual[patternKey]); + result.compose(`/${patternKey}`, inner); + } + return result; + } +}; +var SerializedJson = class extends Matcher { + constructor(name, pattern) { + super(); + this.name = name; + this.pattern = pattern; + } + test(actual) { + const result = new MatchResult(actual); + if (getType(actual) !== "string") { + result.recordFailure({ + matcher: this, + path: [], + message: `Expected JSON as a string but found ${getType(actual)}` + }); + return result; + } + let parsed; + try { + parsed = JSON.parse(actual); + } catch (err) { + if (err instanceof SyntaxError) { + result.recordFailure({ + matcher: this, + path: [], + message: `Invalid JSON string: ${actual}` + }); + return result; + } else { + throw err; + } + } + const matcher = Matcher.isMatcher(this.pattern) ? this.pattern : new LiteralMatch(this.name, this.pattern); + const innerResult = matcher.test(parsed); + result.compose(`(${this.name})`, innerResult); + return result; + } +}; +var NotMatch = class extends Matcher { + constructor(name, pattern) { + super(); + this.name = name; + this.pattern = pattern; + } + test(actual) { + const matcher = Matcher.isMatcher(this.pattern) ? this.pattern : new LiteralMatch(this.name, this.pattern); + const innerResult = matcher.test(actual); + const result = new MatchResult(actual); + if (innerResult.failCount === 0) { + result.recordFailure({ + matcher: this, + path: [], + message: `Found unexpected match: ${JSON.stringify(actual, void 0, 2)}` + }); + } + return result; + } +}; +var AnyMatch = class extends Matcher { + constructor(name) { + super(); + this.name = name; + } + test(actual) { + const result = new MatchResult(actual); + if (actual == null) { + result.recordFailure({ + matcher: this, + path: [], + message: "Expected a value but found none" + }); + } + return result; + } +}; +var StringLikeRegexpMatch = class extends Matcher { + constructor(name, pattern) { + super(); + this.name = name; + this.pattern = pattern; + } + test(actual) { + const result = new MatchResult(actual); + const regex = new RegExp(this.pattern, "gm"); + if (typeof actual !== "string") { + result.recordFailure({ + matcher: this, + path: [], + message: `Expected a string, but got '${typeof actual}'` + }); + } + if (!regex.test(actual)) { + result.recordFailure({ + matcher: this, + path: [], + message: `String '${actual}' did not match pattern '${this.pattern}'` + }); + } + return result; + } +}; + +// lib/assertions/providers/lambda-handler/base.ts +var https = __toESM(require("https")); +var url = __toESM(require("url")); +var CustomResourceHandler = class { + constructor(event, context) { + this.event = event; + this.context = context; + this.timedOut = false; + this.timeout = setTimeout(async () => { + await this.respond({ + status: "FAILED", + reason: "Lambda Function Timeout", + data: this.context.logStreamName + }); + this.timedOut = true; + }, context.getRemainingTimeInMillis() - 1200); + this.event = event; + this.physicalResourceId = extractPhysicalResourceId(event); + } + async handle() { + try { + const response = await this.processEvent(this.event.ResourceProperties); + return response; + } catch (e) { + console.log(e); + throw e; + } finally { + clearTimeout(this.timeout); + } + } + respond(response) { + if (this.timedOut) { + return; + } + const cfResponse = { + Status: response.status, + Reason: response.reason, + PhysicalResourceId: this.physicalResourceId, + StackId: this.event.StackId, + RequestId: this.event.RequestId, + LogicalResourceId: this.event.LogicalResourceId, + NoEcho: false, + Data: response.data + }; + const responseBody = JSON.stringify(cfResponse); + console.log("Responding to CloudFormation", responseBody); + const parsedUrl = url.parse(this.event.ResponseURL); + const requestOptions = { + hostname: parsedUrl.hostname, + path: parsedUrl.path, + method: "PUT", + headers: { "content-type": "", "content-length": responseBody.length } + }; + return new Promise((resolve, reject) => { + try { + const request2 = https.request(requestOptions, resolve); + request2.on("error", reject); + request2.write(responseBody); + request2.end(); + } catch (e) { + reject(e); + } + }); + } +}; +function extractPhysicalResourceId(event) { + switch (event.RequestType) { + case "Create": + return event.LogicalResourceId; + case "Update": + case "Delete": + return event.PhysicalResourceId; + } +} + +// lib/assertions/providers/lambda-handler/assertion.ts +var AssertionHandler = class extends CustomResourceHandler { + async processEvent(request2) { + let actual = decodeCall(request2.actual); + const expected = decodeCall(request2.expected); + let result; + const matcher = new MatchCreator(expected).getMatcher(); + console.log(`Testing equality between ${JSON.stringify(request2.actual)} and ${JSON.stringify(request2.expected)}`); + const matchResult = matcher.test(actual); + matchResult.finished(); + if (matchResult.hasFailed()) { + result = { + failed: true, + assertion: JSON.stringify({ + status: "fail", + message: [ + ...matchResult.toHumanStrings(), + JSON.stringify(matchResult.target, void 0, 2) + ].join("\n") + }) + }; + if (request2.failDeployment) { + throw new Error(result.assertion); + } + } else { + result = { + assertion: JSON.stringify({ + status: "success" + }) + }; + } + return result; + } +}; +var MatchCreator = class { + constructor(obj) { + this.parsedObj = { + matcher: obj + }; + } + getMatcher() { + try { + const final = JSON.parse(JSON.stringify(this.parsedObj), function(_k, v) { + const nested = Object.keys(v)[0]; + switch (nested) { + case "$ArrayWith": + return Match.arrayWith(v[nested]); + case "$ObjectLike": + return Match.objectLike(v[nested]); + case "$StringLike": + return Match.stringLikeRegexp(v[nested]); + default: + return v; + } + }); + if (Matcher.isMatcher(final.matcher)) { + return final.matcher; + } + return Match.exact(final.matcher); + } catch { + return Match.exact(this.parsedObj.matcher); + } + } +}; +function decodeCall(call) { + if (!call) { + return void 0; + } + try { + const parsed = JSON.parse(call); + return parsed; + } catch (e) { + return call; + } +} + +// lib/assertions/providers/lambda-handler/utils.ts +function decode(object) { + return JSON.parse(JSON.stringify(object), (_k, v) => { + switch (v) { + case "TRUE:BOOLEAN": + return true; + case "FALSE:BOOLEAN": + return false; + default: + return v; + } + }); +} + +// lib/assertions/providers/lambda-handler/sdk.ts +function flatten(object) { + return Object.assign( + {}, + ...function _flatten(child, path = []) { + return [].concat(...Object.keys(child).map((key) => { + let childKey = Buffer.isBuffer(child[key]) ? child[key].toString("utf8") : child[key]; + if (typeof childKey === "string") { + childKey = isJsonString(childKey); + } + return typeof childKey === "object" && childKey !== null ? _flatten(childKey, path.concat([key])) : { [path.concat([key]).join(".")]: childKey }; + })); + }(object) + ); +} +var AwsApiCallHandler = class extends CustomResourceHandler { + async processEvent(request2) { + const AWS = require("aws-sdk"); + console.log(`AWS SDK VERSION: ${AWS.VERSION}`); + if (!Object.prototype.hasOwnProperty.call(AWS, request2.service)) { + throw Error(`Service ${request2.service} does not exist in AWS SDK version ${AWS.VERSION}.`); + } + const service = new AWS[request2.service](); + const response = await service[request2.api](request2.parameters && decode(request2.parameters)).promise(); + console.log(`SDK response received ${JSON.stringify(response)}`); + delete response.ResponseMetadata; + const respond = { + apiCallResponse: response + }; + const flatData = { + ...flatten(respond) + }; + const resp = request2.flattenResponse === "true" ? flatData : respond; + console.log(`Returning result ${JSON.stringify(resp)}`); + return resp; + } +}; +function isJsonString(value) { + try { + return JSON.parse(value); + } catch { + return value; + } +} + +// lib/assertions/providers/lambda-handler/types.ts +var ASSERT_RESOURCE_TYPE = "Custom::DeployAssert@AssertEquals"; +var SDK_RESOURCE_TYPE_PREFIX = "Custom::DeployAssert@SdkCall"; + +// lib/assertions/providers/lambda-handler/index.ts +async function handler(event, context) { + console.log(`Event: ${JSON.stringify({ ...event, ResponseURL: "..." })}`); + const provider = createResourceHandler(event, context); + try { + if (event.RequestType === "Delete") { + await provider.respond({ + status: "SUCCESS", + reason: "OK" + }); + return; + } + const result = await provider.handle(); + const actualPath = event.ResourceProperties.actualPath; + const actual = actualPath ? result[`apiCallResponse.${actualPath}`] : result.apiCallResponse; + if ("expected" in event.ResourceProperties) { + const assertion = new AssertionHandler({ + ...event, + ResourceProperties: { + ServiceToken: event.ServiceToken, + actual, + expected: event.ResourceProperties.expected + } + }, context); + try { + const assertionResult = await assertion.handle(); + await provider.respond({ + status: "SUCCESS", + reason: "OK", + data: { + ...assertionResult, + ...result + } + }); + return; + } catch (e) { + await provider.respond({ + status: "FAILED", + reason: e.message ?? "Internal Error" + }); + return; + } + } + await provider.respond({ + status: "SUCCESS", + reason: "OK", + data: result + }); + } catch (e) { + await provider.respond({ + status: "FAILED", + reason: e.message ?? "Internal Error" + }); + return; + } + return; +} +function createResourceHandler(event, context) { + if (event.ResourceType.startsWith(SDK_RESOURCE_TYPE_PREFIX)) { + return new AwsApiCallHandler(event, context); + } else if (event.ResourceType.startsWith(ASSERT_RESOURCE_TYPE)) { + return new AssertionHandler(event, context); + } else { + throw new Error(`Unsupported resource type "${event.ResourceType}`); + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + handler +}); diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/asset.fec8e8354e12687c5a4b843b4e269741f53dec634946869b276f7fd1017845c3.handler/index.d.ts b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/asset.fec8e8354e12687c5a4b843b4e269741f53dec634946869b276f7fd1017845c3.handler/index.d.ts similarity index 100% rename from packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/asset.fec8e8354e12687c5a4b843b4e269741f53dec634946869b276f7fd1017845c3.handler/index.d.ts rename to packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/asset.fec8e8354e12687c5a4b843b4e269741f53dec634946869b276f7fd1017845c3.handler/index.d.ts diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/asset.fec8e8354e12687c5a4b843b4e269741f53dec634946869b276f7fd1017845c3.handler/index.js b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/asset.fec8e8354e12687c5a4b843b4e269741f53dec634946869b276f7fd1017845c3.handler/index.js similarity index 100% rename from packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/asset.fec8e8354e12687c5a4b843b4e269741f53dec634946869b276f7fd1017845c3.handler/index.js rename to packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/asset.fec8e8354e12687c5a4b843b4e269741f53dec634946869b276f7fd1017845c3.handler/index.js diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/asset.fec8e8354e12687c5a4b843b4e269741f53dec634946869b276f7fd1017845c3.handler/index.ts b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/asset.fec8e8354e12687c5a4b843b4e269741f53dec634946869b276f7fd1017845c3.handler/index.ts similarity index 100% rename from packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/asset.fec8e8354e12687c5a4b843b4e269741f53dec634946869b276f7fd1017845c3.handler/index.ts rename to packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/asset.fec8e8354e12687c5a4b843b4e269741f53dec634946869b276f7fd1017845c3.handler/index.ts diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/cdk.out b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/cdk.out new file mode 100644 index 0000000000000..8ecc185e9dbee --- /dev/null +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"21.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/integ.json b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/integ.json new file mode 100644 index 0000000000000..e967d654f2819 --- /dev/null +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "21.0.0", + "testCases": { + "apigw-token-auth/DefaultTest": { + "stacks": [ + "TokenAuthorizerInteg" + ], + "assertionStack": "apigw-token-auth/DefaultTest/DeployAssert", + "assertionStackName": "apigwtokenauthDefaultTestDeployAssert2CF60E05" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/manifest.json b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/manifest.json new file mode 100644 index 0000000000000..d2bf3e547ad21 --- /dev/null +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/manifest.json @@ -0,0 +1,262 @@ +{ + "version": "21.0.0", + "artifacts": { + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + }, + "TokenAuthorizerInteg.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "TokenAuthorizerInteg.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "TokenAuthorizerInteg": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "TokenAuthorizerInteg.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/d48b90b340d35b9bc726b78e652d17148e2449f6f756e4377428635071f68d09.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "TokenAuthorizerInteg.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "TokenAuthorizerInteg.assets" + ], + "metadata": { + "/TokenAuthorizerInteg/MyAuthorizerFunction/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyAuthorizerFunctionServiceRole8A34C19E" + } + ], + "/TokenAuthorizerInteg/MyAuthorizerFunction/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyAuthorizerFunction70F1223E" + } + ], + "/TokenAuthorizerInteg/MyAuthorizerFunction/TokenAuthorizerIntegMyAuthorizer793B1D5F:Permissions": [ + { + "type": "aws:cdk:logicalId", + "data": "MyAuthorizerFunctionTokenAuthorizerIntegMyAuthorizer793B1D5FPermissions7557AE26" + } + ], + "/TokenAuthorizerInteg/MyAuthorizer/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyAuthorizer6575980E" + } + ], + "/TokenAuthorizerInteg/MyRestApi/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyRestApi2D1F47A9" + } + ], + "/TokenAuthorizerInteg/MyRestApi/CloudWatchRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyRestApiCloudWatchRoleD4042E8E" + } + ], + "/TokenAuthorizerInteg/MyRestApi/Account": [ + { + "type": "aws:cdk:logicalId", + "data": "MyRestApiAccount2FB6DB7A" + } + ], + "/TokenAuthorizerInteg/MyRestApi/Deployment/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyRestApiDeploymentB555B582464879c8d1f9fcce2500f142532cdaec" + } + ], + "/TokenAuthorizerInteg/MyRestApi/DeploymentStage.prod/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyRestApiDeploymentStageprodC33B8E5F" + } + ], + "/TokenAuthorizerInteg/MyRestApi/Endpoint": [ + { + "type": "aws:cdk:logicalId", + "data": "MyRestApiEndpoint4C55E4CB" + } + ], + "/TokenAuthorizerInteg/MyRestApi/Default/OPTIONS/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyRestApiOPTIONS43BD7BF4" + } + ], + "/TokenAuthorizerInteg/MyRestApi/Default/ANY/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyRestApiANY05143F93" + } + ], + "/TokenAuthorizerInteg/InvokeFunction/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "InvokeFunctionServiceRole3B980FD2" + } + ], + "/TokenAuthorizerInteg/InvokeFunction/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "InvokeFunctionC517E46D" + } + ], + "/TokenAuthorizerInteg/Exports/Output{\"Ref\":\"InvokeFunctionC517E46D\"}": [ + { + "type": "aws:cdk:logicalId", + "data": "ExportsOutputRefInvokeFunctionC517E46D32C855B5" + } + ], + "/TokenAuthorizerInteg/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/TokenAuthorizerInteg/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "TokenAuthorizerInteg" + }, + "apigwtokenauthDefaultTestDeployAssert2CF60E05.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "apigwtokenauthDefaultTestDeployAssert2CF60E05.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "apigwtokenauthDefaultTestDeployAssert2CF60E05": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "apigwtokenauthDefaultTestDeployAssert2CF60E05.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/663a8c1a16f9e427d0ecfe2215cb471b582dfce87e95f6bbf85d32c371692ece.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "apigwtokenauthDefaultTestDeployAssert2CF60E05.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "TokenAuthorizerInteg", + "apigwtokenauthDefaultTestDeployAssert2CF60E05.assets" + ], + "metadata": { + "/apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke3deec958b1e945795e38da5fc2f86753/Default/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaInvoke3deec958b1e945795e38da5fc2f86753" + } + ], + "/apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke3deec958b1e945795e38da5fc2f86753/Invoke": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaInvoke3deec958b1e945795e38da5fc2f86753InvokeCB0E5D28" + } + ], + "/apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke3deec958b1e945795e38da5fc2f86753/AssertionResults": [ + { + "type": "aws:cdk:logicalId", + "data": "AssertionResultsLambdaInvoke3deec958b1e945795e38da5fc2f86753" + } + ], + "/apigw-token-auth/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Role": [ + { + "type": "aws:cdk:logicalId", + "data": "SingletonFunction1488541a7b23466481b69b4408076b81Role37ABCE73" + } + ], + "/apigw-token-auth/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Handler": [ + { + "type": "aws:cdk:logicalId", + "data": "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F" + } + ], + "/apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke8e1b9f979f2329abf1ed6574d33d391a/Default/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaInvoke8e1b9f979f2329abf1ed6574d33d391a" + } + ], + "/apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke8e1b9f979f2329abf1ed6574d33d391a/Invoke": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaInvoke8e1b9f979f2329abf1ed6574d33d391aInvokeCCB91944" + } + ], + "/apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke8e1b9f979f2329abf1ed6574d33d391a/AssertionResults": [ + { + "type": "aws:cdk:logicalId", + "data": "AssertionResultsLambdaInvoke8e1b9f979f2329abf1ed6574d33d391a" + } + ], + "/apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke0532e3d95b2a56b147278c621e5800c4/Default/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaInvoke0532e3d95b2a56b147278c621e5800c4" + } + ], + "/apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke0532e3d95b2a56b147278c621e5800c4/Invoke": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaInvoke0532e3d95b2a56b147278c621e5800c4Invoke73472D9F" + } + ], + "/apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke0532e3d95b2a56b147278c621e5800c4/AssertionResults": [ + { + "type": "aws:cdk:logicalId", + "data": "AssertionResultsLambdaInvoke0532e3d95b2a56b147278c621e5800c4" + } + ], + "/apigw-token-auth/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/apigw-token-auth/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "apigw-token-auth/DefaultTest/DeployAssert" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/tree.json b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/tree.json new file mode 100644 index 0000000000000..2dc4bcb660eab --- /dev/null +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.integ.snapshot/tree.json @@ -0,0 +1,934 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.108" + } + }, + "TokenAuthorizerInteg": { + "id": "TokenAuthorizerInteg", + "path": "TokenAuthorizerInteg", + "children": { + "MyAuthorizerFunction": { + "id": "MyAuthorizerFunction", + "path": "TokenAuthorizerInteg/MyAuthorizerFunction", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "TokenAuthorizerInteg/MyAuthorizerFunction/ServiceRole", + "children": { + "Resource": { + "id": "Resource", + "path": "TokenAuthorizerInteg/MyAuthorizerFunction/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Code": { + "id": "Code", + "path": "TokenAuthorizerInteg/MyAuthorizerFunction/Code", + "children": { + "Stage": { + "id": "Stage", + "path": "TokenAuthorizerInteg/MyAuthorizerFunction/Code/Stage", + "constructInfo": { + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" + } + }, + "AssetBucket": { + "id": "AssetBucket", + "path": "TokenAuthorizerInteg/MyAuthorizerFunction/Code/AssetBucket", + "constructInfo": { + "fqn": "@aws-cdk/aws-s3.BucketBase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-s3-assets.Asset", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "TokenAuthorizerInteg/MyAuthorizerFunction/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "s3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "s3Key": "fec8e8354e12687c5a4b843b4e269741f53dec634946869b276f7fd1017845c3.zip" + }, + "role": { + "Fn::GetAtt": [ + "MyAuthorizerFunctionServiceRole8A34C19E", + "Arn" + ] + }, + "handler": "index.handler", + "runtime": "nodejs14.x" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + }, + "TokenAuthorizerIntegMyAuthorizer793B1D5F:Permissions": { + "id": "TokenAuthorizerIntegMyAuthorizer793B1D5F:Permissions", + "path": "TokenAuthorizerInteg/MyAuthorizerFunction/TokenAuthorizerIntegMyAuthorizer793B1D5F:Permissions", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", + "aws:cdk:cloudformation:props": { + "action": "lambda:InvokeFunction", + "functionName": { + "Fn::GetAtt": [ + "MyAuthorizerFunction70F1223E", + "Arn" + ] + }, + "principal": "apigateway.amazonaws.com", + "sourceArn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":execute-api:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":", + { + "Ref": "MyRestApi2D1F47A9" + }, + "/authorizers/", + { + "Ref": "MyAuthorizer6575980E" + } + ] + ] + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnPermission", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + }, + "MyAuthorizer": { + "id": "MyAuthorizer", + "path": "TokenAuthorizerInteg/MyAuthorizer", + "children": { + "Resource": { + "id": "Resource", + "path": "TokenAuthorizerInteg/MyAuthorizer/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::Authorizer", + "aws:cdk:cloudformation:props": { + "name": "TokenAuthorizerIntegMyAuthorizer793B1D5F", + "restApiId": { + "Ref": "MyRestApi2D1F47A9" + }, + "type": "TOKEN", + "authorizerUri": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + ":", + { + "Fn::GetAtt": [ + "MyAuthorizerFunction70F1223E", + "Arn" + ] + } + ] + } + ] + }, + ":apigateway:", + { + "Fn::Select": [ + 3, + { + "Fn::Split": [ + ":", + { + "Fn::GetAtt": [ + "MyAuthorizerFunction70F1223E", + "Arn" + ] + } + ] + } + ] + }, + ":lambda:path/2015-03-31/functions/", + { + "Fn::GetAtt": [ + "MyAuthorizerFunction70F1223E", + "Arn" + ] + }, + "/invocations" + ] + ] + }, + "identitySource": "method.request.header.Authorization" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigateway.CfnAuthorizer", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigateway.TokenAuthorizer", + "version": "0.0.0" + } + }, + "MyRestApi": { + "id": "MyRestApi", + "path": "TokenAuthorizerInteg/MyRestApi", + "children": { + "Resource": { + "id": "Resource", + "path": "TokenAuthorizerInteg/MyRestApi/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::RestApi", + "aws:cdk:cloudformation:props": { + "name": "MyRestApi" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigateway.CfnRestApi", + "version": "0.0.0" + } + }, + "CloudWatchRole": { + "id": "CloudWatchRole", + "path": "TokenAuthorizerInteg/MyRestApi/CloudWatchRole", + "children": { + "Resource": { + "id": "Resource", + "path": "TokenAuthorizerInteg/MyRestApi/CloudWatchRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "apigateway.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Account": { + "id": "Account", + "path": "TokenAuthorizerInteg/MyRestApi/Account", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::Account", + "aws:cdk:cloudformation:props": { + "cloudWatchRoleArn": { + "Fn::GetAtt": [ + "MyRestApiCloudWatchRoleD4042E8E", + "Arn" + ] + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigateway.CfnAccount", + "version": "0.0.0" + } + }, + "Deployment": { + "id": "Deployment", + "path": "TokenAuthorizerInteg/MyRestApi/Deployment", + "children": { + "Resource": { + "id": "Resource", + "path": "TokenAuthorizerInteg/MyRestApi/Deployment/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::Deployment", + "aws:cdk:cloudformation:props": { + "restApiId": { + "Ref": "MyRestApi2D1F47A9" + }, + "description": "Automatically created by the RestApi construct" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigateway.CfnDeployment", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigateway.Deployment", + "version": "0.0.0" + } + }, + "DeploymentStage.prod": { + "id": "DeploymentStage.prod", + "path": "TokenAuthorizerInteg/MyRestApi/DeploymentStage.prod", + "children": { + "Resource": { + "id": "Resource", + "path": "TokenAuthorizerInteg/MyRestApi/DeploymentStage.prod/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::Stage", + "aws:cdk:cloudformation:props": { + "restApiId": { + "Ref": "MyRestApi2D1F47A9" + }, + "deploymentId": { + "Ref": "MyRestApiDeploymentB555B582464879c8d1f9fcce2500f142532cdaec" + }, + "stageName": "prod" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigateway.CfnStage", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigateway.Stage", + "version": "0.0.0" + } + }, + "Endpoint": { + "id": "Endpoint", + "path": "TokenAuthorizerInteg/MyRestApi/Endpoint", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnOutput", + "version": "0.0.0" + } + }, + "Default": { + "id": "Default", + "path": "TokenAuthorizerInteg/MyRestApi/Default", + "children": { + "OPTIONS": { + "id": "OPTIONS", + "path": "TokenAuthorizerInteg/MyRestApi/Default/OPTIONS", + "children": { + "Resource": { + "id": "Resource", + "path": "TokenAuthorizerInteg/MyRestApi/Default/OPTIONS/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::Method", + "aws:cdk:cloudformation:props": { + "httpMethod": "OPTIONS", + "resourceId": { + "Fn::GetAtt": [ + "MyRestApi2D1F47A9", + "RootResourceId" + ] + }, + "restApiId": { + "Ref": "MyRestApi2D1F47A9" + }, + "authorizationType": "NONE", + "integration": { + "type": "MOCK", + "requestTemplates": { + "application/json": "{ statusCode: 200 }" + }, + "integrationResponses": [ + { + "statusCode": "204", + "responseParameters": { + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'", + "method.response.header.Access-Control-Allow-Origin": "'*'", + "method.response.header.Access-Control-Allow-Methods": "'OPTIONS,GET,PUT,POST,DELETE,PATCH,HEAD'" + } + } + ] + }, + "methodResponses": [ + { + "statusCode": "204", + "responseParameters": { + "method.response.header.Access-Control-Allow-Headers": true, + "method.response.header.Access-Control-Allow-Origin": true, + "method.response.header.Access-Control-Allow-Methods": true + } + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigateway.CfnMethod", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigateway.Method", + "version": "0.0.0" + } + }, + "ANY": { + "id": "ANY", + "path": "TokenAuthorizerInteg/MyRestApi/Default/ANY", + "children": { + "Resource": { + "id": "Resource", + "path": "TokenAuthorizerInteg/MyRestApi/Default/ANY/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::Method", + "aws:cdk:cloudformation:props": { + "httpMethod": "ANY", + "resourceId": { + "Fn::GetAtt": [ + "MyRestApi2D1F47A9", + "RootResourceId" + ] + }, + "restApiId": { + "Ref": "MyRestApi2D1F47A9" + }, + "authorizationType": "CUSTOM", + "authorizerId": { + "Ref": "MyAuthorizer6575980E" + }, + "integration": { + "type": "MOCK", + "requestTemplates": { + "application/json": "{ \"statusCode\": 200 }" + }, + "passthroughBehavior": "NEVER", + "integrationResponses": [ + { + "statusCode": "200" + } + ] + }, + "methodResponses": [ + { + "statusCode": "200" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigateway.CfnMethod", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigateway.Method", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigateway.ResourceBase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-apigateway.RestApi", + "version": "0.0.0" + } + }, + "InvokeFunction": { + "id": "InvokeFunction", + "path": "TokenAuthorizerInteg/InvokeFunction", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "TokenAuthorizerInteg/InvokeFunction/ServiceRole", + "children": { + "Resource": { + "id": "Resource", + "path": "TokenAuthorizerInteg/InvokeFunction/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "TokenAuthorizerInteg/InvokeFunction/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": { + "Fn::Join": [ + "", + [ + "\nconst https = require('https');\nconst options = {\n hostname: '", + { + "Ref": "MyRestApi2D1F47A9" + }, + ".execute-api.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "',\n path: '/", + { + "Ref": "MyRestApiDeploymentStageprodC33B8E5F" + }, + "',\n};\nexports.handler = async function(event) {\n console.log(event);\n options.method = event.method;\n if ('authorization' in event) {\n options.headers = {\n Authorization: event.authorization,\n };\n }\n let dataString = '';\n const response = await new Promise((resolve, reject) => {\n const req = https.request(options, (res) => {\n res.on('data', data => {\n dataString += data;\n })\n res.on('end', () => {\n resolve({\n statusCode: res.statusCode,\n body: dataString,\n });\n })\n });\n req.on('error', err => {\n reject({\n statusCode: 500,\n body: JSON.stringify({\n cause: 'Something went wrong',\n error: err,\n })\n });\n });\n req.end();\n });\n return response;\n}\n" + ] + ] + } + }, + "role": { + "Fn::GetAtt": [ + "InvokeFunctionServiceRole3B980FD2", + "Arn" + ] + }, + "handler": "index.handler", + "memorySize": 250, + "runtime": "nodejs16.x", + "timeout": 10 + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + }, + "Exports": { + "id": "Exports", + "path": "TokenAuthorizerInteg/Exports", + "children": { + "Output{\"Ref\":\"InvokeFunctionC517E46D\"}": { + "id": "Output{\"Ref\":\"InvokeFunctionC517E46D\"}", + "path": "TokenAuthorizerInteg/Exports/Output{\"Ref\":\"InvokeFunctionC517E46D\"}", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnOutput", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.108" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "apigw-token-auth": { + "id": "apigw-token-auth", + "path": "apigw-token-auth", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "apigw-token-auth/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "apigw-token-auth/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.108" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "apigw-token-auth/DefaultTest/DeployAssert", + "children": { + "LambdaInvoke3deec958b1e945795e38da5fc2f86753": { + "id": "LambdaInvoke3deec958b1e945795e38da5fc2f86753", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke3deec958b1e945795e38da5fc2f86753", + "children": { + "SdkProvider": { + "id": "SdkProvider", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke3deec958b1e945795e38da5fc2f86753/SdkProvider", + "children": { + "AssertionsProvider": { + "id": "AssertionsProvider", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke3deec958b1e945795e38da5fc2f86753/SdkProvider/AssertionsProvider", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.108" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.AssertionsProvider", + "version": "0.0.0" + } + }, + "Default": { + "id": "Default", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke3deec958b1e945795e38da5fc2f86753/Default", + "children": { + "Default": { + "id": "Default", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke3deec958b1e945795e38da5fc2f86753/Default/Default", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CustomResource", + "version": "0.0.0" + } + }, + "Invoke": { + "id": "Invoke", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke3deec958b1e945795e38da5fc2f86753/Invoke", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + }, + "AssertionResults": { + "id": "AssertionResults", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke3deec958b1e945795e38da5fc2f86753/AssertionResults", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnOutput", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.LambdaInvokeFunction", + "version": "0.0.0" + } + }, + "SingletonFunction1488541a7b23466481b69b4408076b81": { + "id": "SingletonFunction1488541a7b23466481b69b4408076b81", + "path": "apigw-token-auth/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81", + "children": { + "Staging": { + "id": "Staging", + "path": "apigw-token-auth/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Staging", + "constructInfo": { + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" + } + }, + "Role": { + "id": "Role", + "path": "apigw-token-auth/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Role", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + }, + "Handler": { + "id": "Handler", + "path": "apigw-token-auth/DefaultTest/DeployAssert/SingletonFunction1488541a7b23466481b69b4408076b81/Handler", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.108" + } + }, + "LambdaInvoke8e1b9f979f2329abf1ed6574d33d391a": { + "id": "LambdaInvoke8e1b9f979f2329abf1ed6574d33d391a", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke8e1b9f979f2329abf1ed6574d33d391a", + "children": { + "SdkProvider": { + "id": "SdkProvider", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke8e1b9f979f2329abf1ed6574d33d391a/SdkProvider", + "children": { + "AssertionsProvider": { + "id": "AssertionsProvider", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke8e1b9f979f2329abf1ed6574d33d391a/SdkProvider/AssertionsProvider", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.108" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.AssertionsProvider", + "version": "0.0.0" + } + }, + "Default": { + "id": "Default", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke8e1b9f979f2329abf1ed6574d33d391a/Default", + "children": { + "Default": { + "id": "Default", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke8e1b9f979f2329abf1ed6574d33d391a/Default/Default", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CustomResource", + "version": "0.0.0" + } + }, + "Invoke": { + "id": "Invoke", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke8e1b9f979f2329abf1ed6574d33d391a/Invoke", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + }, + "AssertionResults": { + "id": "AssertionResults", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke8e1b9f979f2329abf1ed6574d33d391a/AssertionResults", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnOutput", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.LambdaInvokeFunction", + "version": "0.0.0" + } + }, + "LambdaInvoke0532e3d95b2a56b147278c621e5800c4": { + "id": "LambdaInvoke0532e3d95b2a56b147278c621e5800c4", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke0532e3d95b2a56b147278c621e5800c4", + "children": { + "SdkProvider": { + "id": "SdkProvider", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke0532e3d95b2a56b147278c621e5800c4/SdkProvider", + "children": { + "AssertionsProvider": { + "id": "AssertionsProvider", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke0532e3d95b2a56b147278c621e5800c4/SdkProvider/AssertionsProvider", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.108" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.AssertionsProvider", + "version": "0.0.0" + } + }, + "Default": { + "id": "Default", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke0532e3d95b2a56b147278c621e5800c4/Default", + "children": { + "Default": { + "id": "Default", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke0532e3d95b2a56b147278c621e5800c4/Default/Default", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CustomResource", + "version": "0.0.0" + } + }, + "Invoke": { + "id": "Invoke", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke0532e3d95b2a56b147278c621e5800c4/Invoke", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + }, + "AssertionResults": { + "id": "AssertionResults", + "path": "apigw-token-auth/DefaultTest/DeployAssert/LambdaInvoke0532e3d95b2a56b147278c621e5800c4/AssertionResults", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnOutput", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.LambdaInvokeFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTest", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/cdk.out b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/cdk.out deleted file mode 100644 index 588d7b269d34f..0000000000000 --- a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/cdk.out +++ /dev/null @@ -1 +0,0 @@ -{"version":"20.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/integ.json b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/integ.json deleted file mode 100644 index fbc6c13c41b7d..0000000000000 --- a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/integ.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "version": "20.0.0", - "testCases": { - "integ.token-authorizer.lit": { - "stacks": [ - "TokenAuthorizerInteg" - ], - "diffAssets": false, - "stackUpdateWorkflow": true - } - }, - "synthContext": {}, - "enableLookups": false -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/manifest.json b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/manifest.json deleted file mode 100644 index 89fe27247229f..0000000000000 --- a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/manifest.json +++ /dev/null @@ -1,124 +0,0 @@ -{ - "version": "20.0.0", - "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, - "TokenAuthorizerInteg.assets": { - "type": "cdk:asset-manifest", - "properties": { - "file": "TokenAuthorizerInteg.assets.json", - "requiresBootstrapStackVersion": 6, - "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" - } - }, - "TokenAuthorizerInteg": { - "type": "aws:cloudformation:stack", - "environment": "aws://unknown-account/unknown-region", - "properties": { - "templateFile": "TokenAuthorizerInteg.template.json", - "validateOnSynth": false, - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", - "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/d121ee9744a20c9af43e516c8fb4fe93d1ed9b26130e2db68ed9534c7104c866.json", - "requiresBootstrapStackVersion": 6, - "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", - "additionalDependencies": [ - "TokenAuthorizerInteg.assets" - ], - "lookupRole": { - "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", - "requiresBootstrapStackVersion": 8, - "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" - } - }, - "dependencies": [ - "TokenAuthorizerInteg.assets" - ], - "metadata": { - "/TokenAuthorizerInteg/MyAuthorizerFunction/ServiceRole/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "MyAuthorizerFunctionServiceRole8A34C19E" - } - ], - "/TokenAuthorizerInteg/MyAuthorizerFunction/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "MyAuthorizerFunction70F1223E" - } - ], - "/TokenAuthorizerInteg/MyAuthorizerFunction/TokenAuthorizerIntegMyAuthorizer793B1D5F:Permissions": [ - { - "type": "aws:cdk:logicalId", - "data": "MyAuthorizerFunctionTokenAuthorizerIntegMyAuthorizer793B1D5FPermissions7557AE26" - } - ], - "/TokenAuthorizerInteg/MyRestApi/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "MyRestApi2D1F47A9" - } - ], - "/TokenAuthorizerInteg/MyRestApi/CloudWatchRole/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "MyRestApiCloudWatchRoleD4042E8E" - } - ], - "/TokenAuthorizerInteg/MyRestApi/Account": [ - { - "type": "aws:cdk:logicalId", - "data": "MyRestApiAccount2FB6DB7A" - } - ], - "/TokenAuthorizerInteg/MyRestApi/Deployment/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "MyRestApiDeploymentB555B582dcff966d69deeda8d47e3bf409ce29cb" - } - ], - "/TokenAuthorizerInteg/MyRestApi/DeploymentStage.prod/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "MyRestApiDeploymentStageprodC33B8E5F" - } - ], - "/TokenAuthorizerInteg/MyRestApi/Endpoint": [ - { - "type": "aws:cdk:logicalId", - "data": "MyRestApiEndpoint4C55E4CB" - } - ], - "/TokenAuthorizerInteg/MyRestApi/Default/ANY/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "MyRestApiANY05143F93" - } - ], - "/TokenAuthorizerInteg/MyAuthorizer/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "MyAuthorizer6575980E" - } - ], - "/TokenAuthorizerInteg/BootstrapVersion": [ - { - "type": "aws:cdk:logicalId", - "data": "BootstrapVersion" - } - ], - "/TokenAuthorizerInteg/CheckBootstrapVersion": [ - { - "type": "aws:cdk:logicalId", - "data": "CheckBootstrapVersion" - } - ] - }, - "displayName": "TokenAuthorizerInteg" - } - } -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/tree.json b/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/tree.json deleted file mode 100644 index c80d55847aa2d..0000000000000 --- a/packages/@aws-cdk/aws-apigateway/test/authorizers/token-authorizer.lit.integ.snapshot/tree.json +++ /dev/null @@ -1,490 +0,0 @@ -{ - "version": "tree-0.1", - "tree": { - "id": "App", - "path": "", - "children": { - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" - } - }, - "TokenAuthorizerInteg": { - "id": "TokenAuthorizerInteg", - "path": "TokenAuthorizerInteg", - "children": { - "MyAuthorizerFunction": { - "id": "MyAuthorizerFunction", - "path": "TokenAuthorizerInteg/MyAuthorizerFunction", - "children": { - "ServiceRole": { - "id": "ServiceRole", - "path": "TokenAuthorizerInteg/MyAuthorizerFunction/ServiceRole", - "children": { - "Resource": { - "id": "Resource", - "path": "TokenAuthorizerInteg/MyAuthorizerFunction/ServiceRole/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::IAM::Role", - "aws:cdk:cloudformation:props": { - "assumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "managedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", - "version": "0.0.0" - } - }, - "Code": { - "id": "Code", - "path": "TokenAuthorizerInteg/MyAuthorizerFunction/Code", - "children": { - "Stage": { - "id": "Stage", - "path": "TokenAuthorizerInteg/MyAuthorizerFunction/Code/Stage", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" - } - }, - "AssetBucket": { - "id": "AssetBucket", - "path": "TokenAuthorizerInteg/MyAuthorizerFunction/Code/AssetBucket", - "constructInfo": { - "fqn": "@aws-cdk/aws-s3.BucketBase", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-s3-assets.Asset", - "version": "0.0.0" - } - }, - "Resource": { - "id": "Resource", - "path": "TokenAuthorizerInteg/MyAuthorizerFunction/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::Lambda::Function", - "aws:cdk:cloudformation:props": { - "code": { - "s3Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "s3Key": "fec8e8354e12687c5a4b843b4e269741f53dec634946869b276f7fd1017845c3.zip" - }, - "role": { - "Fn::GetAtt": [ - "MyAuthorizerFunctionServiceRole8A34C19E", - "Arn" - ] - }, - "handler": "index.handler", - "runtime": "nodejs14.x" - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-lambda.CfnFunction", - "version": "0.0.0" - } - }, - "TokenAuthorizerIntegMyAuthorizer793B1D5F:Permissions": { - "id": "TokenAuthorizerIntegMyAuthorizer793B1D5F:Permissions", - "path": "TokenAuthorizerInteg/MyAuthorizerFunction/TokenAuthorizerIntegMyAuthorizer793B1D5F:Permissions", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", - "aws:cdk:cloudformation:props": { - "action": "lambda:InvokeFunction", - "functionName": { - "Fn::GetAtt": [ - "MyAuthorizerFunction70F1223E", - "Arn" - ] - }, - "principal": "apigateway.amazonaws.com", - "sourceArn": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":execute-api:", - { - "Ref": "AWS::Region" - }, - ":", - { - "Ref": "AWS::AccountId" - }, - ":", - { - "Ref": "MyRestApi2D1F47A9" - }, - "/authorizers/", - { - "Ref": "MyAuthorizer6575980E" - } - ] - ] - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-lambda.CfnPermission", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-lambda.Function", - "version": "0.0.0" - } - }, - "MyRestApi": { - "id": "MyRestApi", - "path": "TokenAuthorizerInteg/MyRestApi", - "children": { - "Resource": { - "id": "Resource", - "path": "TokenAuthorizerInteg/MyRestApi/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::ApiGateway::RestApi", - "aws:cdk:cloudformation:props": { - "name": "MyRestApi" - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-apigateway.CfnRestApi", - "version": "0.0.0" - } - }, - "CloudWatchRole": { - "id": "CloudWatchRole", - "path": "TokenAuthorizerInteg/MyRestApi/CloudWatchRole", - "children": { - "Resource": { - "id": "Resource", - "path": "TokenAuthorizerInteg/MyRestApi/CloudWatchRole/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::IAM::Role", - "aws:cdk:cloudformation:props": { - "assumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "apigateway.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "managedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs" - ] - ] - } - ] - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", - "version": "0.0.0" - } - }, - "Account": { - "id": "Account", - "path": "TokenAuthorizerInteg/MyRestApi/Account", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::ApiGateway::Account", - "aws:cdk:cloudformation:props": { - "cloudWatchRoleArn": { - "Fn::GetAtt": [ - "MyRestApiCloudWatchRoleD4042E8E", - "Arn" - ] - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-apigateway.CfnAccount", - "version": "0.0.0" - } - }, - "Deployment": { - "id": "Deployment", - "path": "TokenAuthorizerInteg/MyRestApi/Deployment", - "children": { - "Resource": { - "id": "Resource", - "path": "TokenAuthorizerInteg/MyRestApi/Deployment/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::ApiGateway::Deployment", - "aws:cdk:cloudformation:props": { - "restApiId": { - "Ref": "MyRestApi2D1F47A9" - }, - "description": "Automatically created by the RestApi construct" - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-apigateway.CfnDeployment", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-apigateway.Deployment", - "version": "0.0.0" - } - }, - "DeploymentStage.prod": { - "id": "DeploymentStage.prod", - "path": "TokenAuthorizerInteg/MyRestApi/DeploymentStage.prod", - "children": { - "Resource": { - "id": "Resource", - "path": "TokenAuthorizerInteg/MyRestApi/DeploymentStage.prod/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::ApiGateway::Stage", - "aws:cdk:cloudformation:props": { - "restApiId": { - "Ref": "MyRestApi2D1F47A9" - }, - "deploymentId": { - "Ref": "MyRestApiDeploymentB555B582dcff966d69deeda8d47e3bf409ce29cb" - }, - "stageName": "prod" - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-apigateway.CfnStage", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-apigateway.Stage", - "version": "0.0.0" - } - }, - "Endpoint": { - "id": "Endpoint", - "path": "TokenAuthorizerInteg/MyRestApi/Endpoint", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" - } - }, - "Default": { - "id": "Default", - "path": "TokenAuthorizerInteg/MyRestApi/Default", - "children": { - "ANY": { - "id": "ANY", - "path": "TokenAuthorizerInteg/MyRestApi/Default/ANY", - "children": { - "Resource": { - "id": "Resource", - "path": "TokenAuthorizerInteg/MyRestApi/Default/ANY/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::ApiGateway::Method", - "aws:cdk:cloudformation:props": { - "httpMethod": "ANY", - "resourceId": { - "Fn::GetAtt": [ - "MyRestApi2D1F47A9", - "RootResourceId" - ] - }, - "restApiId": { - "Ref": "MyRestApi2D1F47A9" - }, - "authorizationType": "CUSTOM", - "authorizerId": { - "Ref": "MyAuthorizer6575980E" - }, - "integration": { - "type": "MOCK", - "requestTemplates": { - "application/json": "{ \"statusCode\": 200 }" - }, - "passthroughBehavior": "NEVER", - "integrationResponses": [ - { - "statusCode": "200" - } - ] - }, - "methodResponses": [ - { - "statusCode": "200" - } - ] - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-apigateway.CfnMethod", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-apigateway.Method", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-apigateway.ResourceBase", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-apigateway.RestApi", - "version": "0.0.0" - } - }, - "MyAuthorizer": { - "id": "MyAuthorizer", - "path": "TokenAuthorizerInteg/MyAuthorizer", - "children": { - "Resource": { - "id": "Resource", - "path": "TokenAuthorizerInteg/MyAuthorizer/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::ApiGateway::Authorizer", - "aws:cdk:cloudformation:props": { - "name": "TokenAuthorizerIntegMyAuthorizer793B1D5F", - "restApiId": { - "Ref": "MyRestApi2D1F47A9" - }, - "type": "TOKEN", - "authorizerUri": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Fn::Select": [ - 1, - { - "Fn::Split": [ - ":", - { - "Fn::GetAtt": [ - "MyAuthorizerFunction70F1223E", - "Arn" - ] - } - ] - } - ] - }, - ":apigateway:", - { - "Fn::Select": [ - 3, - { - "Fn::Split": [ - ":", - { - "Fn::GetAtt": [ - "MyAuthorizerFunction70F1223E", - "Arn" - ] - } - ] - } - ] - }, - ":lambda:path/2015-03-31/functions/", - { - "Fn::GetAtt": [ - "MyAuthorizerFunction70F1223E", - "Arn" - ] - }, - "/invocations" - ] - ] - }, - "identitySource": "method.request.header.Authorization" - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-apigateway.CfnAuthorizer", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-apigateway.TokenAuthorizer", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" - } - } - }, - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" - } - } -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigateway/test/lambda-api.test.ts b/packages/@aws-cdk/aws-apigateway/test/lambda-api.test.ts index aa0a1e81b4779..23c5140c75137 100644 --- a/packages/@aws-cdk/aws-apigateway/test/lambda-api.test.ts +++ b/packages/@aws-cdk/aws-apigateway/test/lambda-api.test.ts @@ -270,6 +270,66 @@ describe('lambda api', () => { }); }); + test('LambdaRestApi defines a REST API with CORS enabled and defaultMethodOptions', () => { + // GIVEN + const stack = new cdk.Stack(); + + const handler = new lambda.Function(stack, 'handler', { + handler: 'index.handler', + code: lambda.Code.fromInline('boom'), + runtime: lambda.Runtime.NODEJS_14_X, + }); + + // WHEN + new apigw.LambdaRestApi(stack, 'lambda-rest-api', { + handler, + defaultMethodOptions: { + authorizationType: apigw.AuthorizationType.IAM, + }, + defaultCorsPreflightOptions: { + allowOrigins: ['https://aws.amazon.com'], + allowMethods: ['GET', 'PUT'], + }, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Method', { + HttpMethod: 'OPTIONS', + ResourceId: { Ref: 'lambdarestapiproxyE3AE07E3' }, + AuthorizationType: 'NONE', + AuthorizerId: Match.absent(), + ApiKeyRequired: Match.absent(), + Integration: { + IntegrationResponses: [ + { + ResponseParameters: { + 'method.response.header.Access-Control-Allow-Headers': "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'", + 'method.response.header.Access-Control-Allow-Origin': "'https://aws.amazon.com'", + 'method.response.header.Vary': "'Origin'", + 'method.response.header.Access-Control-Allow-Methods': "'GET,PUT'", + }, + StatusCode: '204', + }, + ], + RequestTemplates: { + 'application/json': '{ statusCode: 200 }', + }, + Type: 'MOCK', + }, + MethodResponses: [ + { + ResponseParameters: { + 'method.response.header.Access-Control-Allow-Headers': true, + 'method.response.header.Access-Control-Allow-Origin': true, + 'method.response.header.Vary': true, + 'method.response.header.Access-Control-Allow-Methods': true, + }, + StatusCode: '204', + }, + ], + }); + }); + test('LambdaRestApi allows passing GENERATE_IF_NEEDED as the physical name', () => { // GIVEN const stack = new cdk.Stack();