From aee84a2ad68a4333b9af413563bbbcb26f6e766c Mon Sep 17 00:00:00 2001 From: Tolledo Date: Thu, 1 Oct 2020 11:09:25 -0700 Subject: [PATCH 1/2] Update apigatewayv2 request context --- events/apigw.go | 22 ++++- events/apigw_test.go | 98 ++++++++++++++++++- events/testdata/apigw-v2-request-iam.json | 60 ++++++++++++ ...n => apigw-v2-request-jwt-authorizer.json} | 0 .../apigw-v2-request-lambda-authorizer.json | 50 ++++++++++ 5 files changed, 227 insertions(+), 3 deletions(-) create mode 100644 events/testdata/apigw-v2-request-iam.json rename events/testdata/{apigw-v2-request.json => apigw-v2-request-jwt-authorizer.json} (100%) create mode 100644 events/testdata/apigw-v2-request-lambda-authorizer.json diff --git a/events/apigw.go b/events/apigw.go index ce7fa1cf..683537ab 100644 --- a/events/apigw.go +++ b/events/apigw.go @@ -80,7 +80,9 @@ type APIGatewayV2HTTPRequestContext struct { // APIGatewayV2HTTPRequestContextAuthorizerDescription contains authorizer information for the request context. type APIGatewayV2HTTPRequestContextAuthorizerDescription struct { - JWT APIGatewayV2HTTPRequestContextAuthorizerJWTDescription `json:"jwt"` + JWT *APIGatewayV2HTTPRequestContextAuthorizerJWTDescription `json:"jwt,omitempty"` + Lambda map[string]interface{} `json:"lambda,omitempty"` + IAM *APIGatewayV2HTTPRequestContextAuthorizerIAMDescription `json:"iam,omitempty"` } // APIGatewayV2HTTPRequestContextAuthorizerJWTDescription contains JWT authorizer information for the request context. @@ -89,6 +91,24 @@ type APIGatewayV2HTTPRequestContextAuthorizerJWTDescription struct { Scopes []string `json:"scopes,omitempty"` } +// APIGatewayV2HTTPRequestContextAuthorizerIAMDescription contains IAM information for the request context. +type APIGatewayV2HTTPRequestContextAuthorizerIAMDescription struct { + AccessKey string `json:"accessKey"` + AccountId string `json:"accountId"` + CallerId string `json:"callerId"` + CognitoIdentity APIGatewayV2HTTPRequestContextAuthorizerCognitoIdentity `json:"cognitoIdentity,omitempty"` + PrincipalOrgId string `json:"principalOrgId"` + UserArn string `json:"userArn"` + UserId string `json:"userId"` +} + +// APIGatewayV2HTTPRequestContextAuthorizerCognitoIdentity contains Cognito identity information for the request context. +type APIGatewayV2HTTPRequestContextAuthorizerCognitoIdentity struct { + Amr []string `json:"amr"` + IdentityId string `json:"identityId"` + IdentityPoolId string `json:"identityPoolId"` +} + // APIGatewayV2HTTPRequestContextHTTPDescription contains HTTP information for the request context. type APIGatewayV2HTTPRequestContextHTTPDescription struct { Method string `json:"method"` diff --git a/events/apigw_test.go b/events/apigw_test.go index 913306c3..bcf133c4 100644 --- a/events/apigw_test.go +++ b/events/apigw_test.go @@ -210,10 +210,10 @@ func TestApiGatewayRestApiOpenApiRequestMarshaling(t *testing.T) { assert.JSONEq(t, string(inputJSON), string(outputJSON)) } -func TestApiGatewayV2HTTPRequestMarshaling(t *testing.T) { +func TestApiGatewayV2HTTPRequestJWTAuthorizerMarshaling(t *testing.T) { // read json from file - inputJSON, err := ioutil.ReadFile("./testdata/apigw-v2-request.json") + inputJSON, err := ioutil.ReadFile("./testdata/apigw-v2-request-jwt-authorizer.json") if err != nil { t.Errorf("could not open test file. details: %v", err) } @@ -245,6 +245,100 @@ func TestApiGatewayV2HTTPRequestMarshaling(t *testing.T) { assert.JSONEq(t, string(inputJSON), string(outputJSON)) } +func TestApiGatewayV2HTTPRequestLambdaAuthorizerMarshaling(t *testing.T) { + + // read json from file + inputJSON, err := ioutil.ReadFile("./testdata/apigw-v2-request-lambda-authorizer.json") + if err != nil { + t.Errorf("could not open test file. details: %v", err) + } + + // de-serialize into Go object + var inputEvent APIGatewayV2HTTPRequest + if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { + t.Errorf("could not unmarshal event. details: %v", err) + } + + // validate custom authorizer context + authContext := inputEvent.RequestContext.Authorizer + if authContext.Lambda["key"] != "value" { + t.Errorf("could not extract authorizer information from Lambda authorizer: %v", authContext) + } + + // validate HTTP details + http := inputEvent.RequestContext.HTTP + if http.Path != "/my/path" { + t.Errorf("could not extract HTTP details: %v", http) + } + + // serialize to json + outputJSON, err := json.Marshal(inputEvent) + if err != nil { + t.Errorf("could not marshal event. details: %v", err) + } + + assert.JSONEq(t, string(inputJSON), string(outputJSON)) +} + +func TestApiGatewayV2HTTPRequestIAMMarshaling(t *testing.T) { + + // read json from file + inputJSON, err := ioutil.ReadFile("./testdata/apigw-v2-request-iam.json") + if err != nil { + t.Errorf("could not open test file. details: %v", err) + } + + // de-serialize into Go object + var inputEvent APIGatewayV2HTTPRequest + if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { + t.Errorf("could not unmarshal event. details: %v", err) + } + + // validate custom authorizer context + authContext := inputEvent.RequestContext.Authorizer + if authContext.IAM.AccessKey != "ARIA2ZJZYVUEREEIHAKY" { + t.Errorf("could not extract accessKey from IAM authorizer: %v", authContext) + } + if authContext.IAM.AccountId != "1234567890" { + t.Errorf("could not extract accountId from IAM authorizer: %v", authContext) + } + if authContext.IAM.CallerId != "AROA7ZJZYVRE7C3DUXHH6:CognitoIdentityCredentials" { + t.Errorf("could not extract callerId from IAM authorizer: %v", authContext) + } + if authContext.IAM.CognitoIdentity.Amr[0] != "foo" { + t.Errorf("could not extract amr from CognitoIdentity: %v", authContext) + } + if authContext.IAM.CognitoIdentity.IdentityId != "us-east-1:3f291106-8703-466b-8f2b-3ecee1ca56ce" { + t.Errorf("could not extract identityId from CognitoIdentity: %v", authContext) + } + if authContext.IAM.CognitoIdentity.IdentityPoolId != "us-east-1:4f291106-8703-466b-8f2b-3ecee1ca56ce" { + t.Errorf("could not extract identityPoolId from CognitoIdentity: %v", authContext) + } + if authContext.IAM.PrincipalOrgId != "AwsOrgId" { + t.Errorf("could not extract principalOrgId from IAM authorizer: %v", authContext) + } + if authContext.IAM.UserArn != "arn:aws:iam::1234567890:user/Admin" { + t.Errorf("could not extract userArn from IAM authorizer: %v", authContext) + } + if authContext.IAM.UserId != "AROA2ZJZYVRE7Y3TUXHH6" { + t.Errorf("could not extract userId from IAM authorizer: %v", authContext) + } + + // validate HTTP details + http := inputEvent.RequestContext.HTTP + if http.Path != "/my/path" { + t.Errorf("could not extract HTTP details: %v", http) + } + + // serialize to json + outputJSON, err := json.Marshal(inputEvent) + if err != nil { + t.Errorf("could not marshal event. details: %v", err) + } + + assert.JSONEq(t, string(inputJSON), string(outputJSON)) +} + func TestApiGatewayV2HTTPRequestNoAuthorizerMarshaling(t *testing.T) { // read json from file diff --git a/events/testdata/apigw-v2-request-iam.json b/events/testdata/apigw-v2-request-iam.json new file mode 100644 index 00000000..73d50d78 --- /dev/null +++ b/events/testdata/apigw-v2-request-iam.json @@ -0,0 +1,60 @@ +{ + "version": "2.0", + "routeKey": "$default", + "rawPath": "/my/path", + "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", + "cookies": [ + "cookie1", + "cookie2" + ], + "headers": { + "Header1": "value1", + "Header2": "value2" + }, + "queryStringParameters": { + "parameter1": "value1,value2", + "parameter2": "value" + }, + "pathParameters": { + "proxy": "hello/world" + }, + "requestContext": { + "routeKey": "$default", + "accountId": "123456789012", + "stage": "$default", + "requestId": "id", + "authorizer": { + "iam": { + "accessKey": "ARIA2ZJZYVUEREEIHAKY", + "accountId": "1234567890", + "callerId": "AROA7ZJZYVRE7C3DUXHH6:CognitoIdentityCredentials", + "cognitoIdentity": { + "amr" : ["foo"], + "identityId": "us-east-1:3f291106-8703-466b-8f2b-3ecee1ca56ce", + "identityPoolId": "us-east-1:4f291106-8703-466b-8f2b-3ecee1ca56ce" + }, + "principalOrgId": "AwsOrgId", + "userArn": "arn:aws:iam::1234567890:user/Admin", + "userId": "AROA2ZJZYVRE7Y3TUXHH6" + } + }, + "apiId": "api-id", + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "time": "12/Mar/2020:19:03:58+0000", + "timeEpoch": 1583348638390, + "http": { + "method": "GET", + "path": "/my/path", + "protocol": "HTTP/1.1", + "sourceIp": "IP", + "userAgent": "agent" + } + }, + "stageVariables": { + "stageVariable1": "value1", + "stageVariable2": "value2" + }, + "body": "{\r\n\t\"a\": 1\r\n}", + "isBase64Encoded": false +} diff --git a/events/testdata/apigw-v2-request.json b/events/testdata/apigw-v2-request-jwt-authorizer.json similarity index 100% rename from events/testdata/apigw-v2-request.json rename to events/testdata/apigw-v2-request-jwt-authorizer.json diff --git a/events/testdata/apigw-v2-request-lambda-authorizer.json b/events/testdata/apigw-v2-request-lambda-authorizer.json new file mode 100644 index 00000000..75d1574f --- /dev/null +++ b/events/testdata/apigw-v2-request-lambda-authorizer.json @@ -0,0 +1,50 @@ +{ + "version": "2.0", + "routeKey": "$default", + "rawPath": "/my/path", + "rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value", + "cookies": [ + "cookie1", + "cookie2" + ], + "headers": { + "Header1": "value1", + "Header2": "value2" + }, + "queryStringParameters": { + "parameter1": "value1,value2", + "parameter2": "value" + }, + "pathParameters": { + "proxy": "hello/world" + }, + "requestContext": { + "routeKey": "$default", + "accountId": "123456789012", + "stage": "$default", + "requestId": "id", + "authorizer": { + "lambda": { + "key": "value" + } + }, + "apiId": "api-id", + "domainName": "id.execute-api.us-east-1.amazonaws.com", + "domainPrefix": "id", + "time": "12/Mar/2020:19:03:58+0000", + "timeEpoch": 1583348638390, + "http": { + "method": "GET", + "path": "/my/path", + "protocol": "HTTP/1.1", + "sourceIp": "IP", + "userAgent": "agent" + } + }, + "stageVariables": { + "stageVariable1": "value1", + "stageVariable2": "value2" + }, + "body": "{\r\n\t\"a\": 1\r\n}", + "isBase64Encoded": false +} From 855955aaf40aa9748d15d8138b802ee5c90b3f90 Mon Sep 17 00:00:00 2001 From: Tolledo Date: Mon, 5 Oct 2020 09:48:54 -0700 Subject: [PATCH 2/2] Fix naming --- events/apigw.go | 16 ++++++++-------- events/apigw_test.go | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/events/apigw.go b/events/apigw.go index 683537ab..83b4cbc8 100644 --- a/events/apigw.go +++ b/events/apigw.go @@ -94,19 +94,19 @@ type APIGatewayV2HTTPRequestContextAuthorizerJWTDescription struct { // APIGatewayV2HTTPRequestContextAuthorizerIAMDescription contains IAM information for the request context. type APIGatewayV2HTTPRequestContextAuthorizerIAMDescription struct { AccessKey string `json:"accessKey"` - AccountId string `json:"accountId"` - CallerId string `json:"callerId"` + AccountID string `json:"accountId"` + CallerID string `json:"callerId"` CognitoIdentity APIGatewayV2HTTPRequestContextAuthorizerCognitoIdentity `json:"cognitoIdentity,omitempty"` - PrincipalOrgId string `json:"principalOrgId"` - UserArn string `json:"userArn"` - UserId string `json:"userId"` + PrincipalOrgID string `json:"principalOrgId"` + UserARN string `json:"userArn"` + UserID string `json:"userId"` } // APIGatewayV2HTTPRequestContextAuthorizerCognitoIdentity contains Cognito identity information for the request context. type APIGatewayV2HTTPRequestContextAuthorizerCognitoIdentity struct { - Amr []string `json:"amr"` - IdentityId string `json:"identityId"` - IdentityPoolId string `json:"identityPoolId"` + AMR []string `json:"amr"` + IdentityID string `json:"identityId"` + IdentityPoolID string `json:"identityPoolId"` } // APIGatewayV2HTTPRequestContextHTTPDescription contains HTTP information for the request context. diff --git a/events/apigw_test.go b/events/apigw_test.go index bcf133c4..cf1b82af 100644 --- a/events/apigw_test.go +++ b/events/apigw_test.go @@ -299,28 +299,28 @@ func TestApiGatewayV2HTTPRequestIAMMarshaling(t *testing.T) { if authContext.IAM.AccessKey != "ARIA2ZJZYVUEREEIHAKY" { t.Errorf("could not extract accessKey from IAM authorizer: %v", authContext) } - if authContext.IAM.AccountId != "1234567890" { + if authContext.IAM.AccountID != "1234567890" { t.Errorf("could not extract accountId from IAM authorizer: %v", authContext) } - if authContext.IAM.CallerId != "AROA7ZJZYVRE7C3DUXHH6:CognitoIdentityCredentials" { + if authContext.IAM.CallerID != "AROA7ZJZYVRE7C3DUXHH6:CognitoIdentityCredentials" { t.Errorf("could not extract callerId from IAM authorizer: %v", authContext) } - if authContext.IAM.CognitoIdentity.Amr[0] != "foo" { + if authContext.IAM.CognitoIdentity.AMR[0] != "foo" { t.Errorf("could not extract amr from CognitoIdentity: %v", authContext) } - if authContext.IAM.CognitoIdentity.IdentityId != "us-east-1:3f291106-8703-466b-8f2b-3ecee1ca56ce" { + if authContext.IAM.CognitoIdentity.IdentityID != "us-east-1:3f291106-8703-466b-8f2b-3ecee1ca56ce" { t.Errorf("could not extract identityId from CognitoIdentity: %v", authContext) } - if authContext.IAM.CognitoIdentity.IdentityPoolId != "us-east-1:4f291106-8703-466b-8f2b-3ecee1ca56ce" { + if authContext.IAM.CognitoIdentity.IdentityPoolID != "us-east-1:4f291106-8703-466b-8f2b-3ecee1ca56ce" { t.Errorf("could not extract identityPoolId from CognitoIdentity: %v", authContext) } - if authContext.IAM.PrincipalOrgId != "AwsOrgId" { + if authContext.IAM.PrincipalOrgID != "AwsOrgId" { t.Errorf("could not extract principalOrgId from IAM authorizer: %v", authContext) } - if authContext.IAM.UserArn != "arn:aws:iam::1234567890:user/Admin" { + if authContext.IAM.UserARN != "arn:aws:iam::1234567890:user/Admin" { t.Errorf("could not extract userArn from IAM authorizer: %v", authContext) } - if authContext.IAM.UserId != "AROA2ZJZYVRE7Y3TUXHH6" { + if authContext.IAM.UserID != "AROA2ZJZYVRE7Y3TUXHH6" { t.Errorf("could not extract userId from IAM authorizer: %v", authContext) }