diff --git a/events/cognito.go b/events/cognito.go index f02619da..3d7bd4c4 100644 --- a/events/cognito.go +++ b/events/cognito.go @@ -54,12 +54,23 @@ type CognitoEventUserPoolsPreTokenGen struct { // CognitoEventUserPoolsPreTokenGenV2 is sent by Amazon Cognito User Pools when a user attempts to retrieve // credentials, allowing a Lambda to perform insert, suppress or override claims and scopes +// +// Deprecated: Use CognitoEventUserPoolsPreTokenGenV2_0 instead. +// This struct incorrectly restricts the ClaimsToAddOrOverride values as strings, but Cogntio supports any type. type CognitoEventUserPoolsPreTokenGenV2 struct { CognitoEventUserPoolsHeader Request CognitoEventUserPoolsPreTokenGenV2Request `json:"request"` Response CognitoEventUserPoolsPreTokenGenV2Response `json:"response"` } +// CognitoEventUserPoolsPreTokenGenV2_0 is sent by Amazon Cognito User Pools when a user attempts to retrieve +// credentials, allowing a Lambda to perform insert, suppress or override claims and scopes +type CognitoEventUserPoolsPreTokenGenV2_0 struct { + CognitoEventUserPoolsHeader + Request CognitoEventUserPoolsPreTokenGenRequestV2_0 `json:"request"` + Response CognitoEventUserPoolsPreTokenGenResponseV2_0 `json:"response"` +} + // CognitoEventUserPoolsPostAuthentication is sent by Amazon Cognito User Pools after a user is authenticated, // allowing the Lambda to add custom logic. type CognitoEventUserPoolsPostAuthentication struct { @@ -134,6 +145,8 @@ type CognitoEventUserPoolsPreTokenGenRequest struct { } // CognitoEventUserPoolsPreTokenGenV2Request contains request portion of V2 PreTokenGen event +// +// Deprecated: Use CognitoEventUserPoolsPreTokenGenRequestV2_0 instead type CognitoEventUserPoolsPreTokenGenV2Request struct { UserAttributes map[string]string `json:"userAttributes"` GroupConfiguration GroupConfiguration `json:"groupConfiguration"` @@ -141,16 +154,31 @@ type CognitoEventUserPoolsPreTokenGenV2Request struct { Scopes []string `json:"scopes"` } +// CognitoEventUserPoolsPreTokenGenRequestV2_0 contains request portion of V2 PreTokenGen event +type CognitoEventUserPoolsPreTokenGenRequestV2_0 struct { + UserAttributes map[string]string `json:"userAttributes"` + GroupConfiguration GroupConfigurationV2_0 `json:"groupConfiguration"` + ClientMetadata map[string]string `json:"clientMetadata,omitempty"` + Scopes []string `json:"scopes"` +} + // CognitoEventUserPoolsPreTokenGenResponse contains the response portion of a PreTokenGen event type CognitoEventUserPoolsPreTokenGenResponse struct { ClaimsOverrideDetails ClaimsOverrideDetails `json:"claimsOverrideDetails"` } // CognitoEventUserPoolsPreTokenGenV2Response contains the response portion of a V2 PreTokenGen event +// +// Deprecated: Use CognitoEventUserPoolsPreTokenGenResponseV2_0 instead type CognitoEventUserPoolsPreTokenGenV2Response struct { ClaimsAndScopeOverrideDetails ClaimsAndScopeOverrideDetails `json:"claimsAndScopeOverrideDetails"` } +// CognitoEventUserPoolsPreTokenGenResponseV2_0 contains the response portion of a V2 PreTokenGen event +type CognitoEventUserPoolsPreTokenGenResponseV2_0 struct { + ClaimsAndScopeOverrideDetails ClaimsAndScopeOverrideDetailsV2_0 `json:"claimsAndScopeOverrideDetails"` +} + // CognitoEventUserPoolsPostAuthenticationRequest contains the request portion of a PostAuthentication event type CognitoEventUserPoolsPostAuthenticationRequest struct { NewDeviceUsed bool `json:"newDeviceUsed"` @@ -179,19 +207,36 @@ type CognitoEventUserPoolsMigrateUserResponse struct { } // ClaimsAndScopeOverrideDetails allows lambda to add, suppress or override V2 claims and scopes in the token +// +// Deprecated: Use ClaimsAndScopeOverrideDetailsV2_0 instead type ClaimsAndScopeOverrideDetails struct { IDTokenGeneration IDTokenGeneration `json:"idTokenGeneration"` AccessTokenGeneration AccessTokenGeneration `json:"accessTokenGeneration"` GroupOverrideDetails GroupConfiguration `json:"groupOverrideDetails"` } +// ClaimsAndScopeOverrideDetailsV2 allows lambda to add, suppress or override V2 claims and scopes in the token +type ClaimsAndScopeOverrideDetailsV2_0 struct { + IDTokenGeneration IDTokenGenerationV2_0 `json:"idTokenGeneration"` + AccessTokenGeneration AccessTokenGenerationV2_0 `json:"accessTokenGeneration"` + GroupOverrideDetails GroupConfigurationV2_0 `json:"groupOverrideDetails"` +} + // IDTokenGeneration allows lambda to modify the ID token type IDTokenGeneration struct { ClaimsToAddOrOverride map[string]string `json:"claimsToAddOrOverride"` ClaimsToSuppress []string `json:"claimsToSuppress"` } +// IDTokenGenerationV2_0 allows lambda to modify the ID token +type IDTokenGenerationV2_0 struct { + ClaimsToAddOrOverride map[string]interface{} `json:"claimsToAddOrOverride"` + ClaimsToSuppress []string `json:"claimsToSuppress"` +} + // AccessTokenGeneration allows lambda to modify the access token +// +// Deprecated: Use AccessTokenGenerationV2_0 instead type AccessTokenGeneration struct { ClaimsToAddOrOverride map[string]string `json:"claimsToAddOrOverride"` ClaimsToSuppress []string `json:"claimsToSuppress"` @@ -199,6 +244,14 @@ type AccessTokenGeneration struct { ScopesToSuppress []string `json:"scopesToSuppress"` } +// AccessTokenGenerationV2_0 allows lambda to modify the access token +type AccessTokenGenerationV2_0 struct { + ClaimsToAddOrOverride map[string]interface{} `json:"claimsToAddOrOverride"` + ClaimsToSuppress []string `json:"claimsToSuppress"` + ScopesToAdd []string `json:"scopesToAdd"` + ScopesToSuppress []string `json:"scopesToSuppress"` +} + // ClaimsOverrideDetails allows lambda to add, suppress or override claims in the token type ClaimsOverrideDetails struct { GroupOverrideDetails GroupConfiguration `json:"groupOverrideDetails"` @@ -213,6 +266,13 @@ type GroupConfiguration struct { PreferredRole *string `json:"preferredRole"` } +// GroupConfigurationV2_0 allows lambda to override groups, roles and set a preferred role +type GroupConfigurationV2_0 struct { + GroupsToOverride []string `json:"groupsToOverride"` + IAMRolesToOverride []string `json:"iamRolesToOverride"` + PreferredRole *string `json:"preferredRole"` +} + // CognitoEventUserPoolsChallengeResult represents a challenge that is presented to the user in the authentication // process that is underway, along with the corresponding result. type CognitoEventUserPoolsChallengeResult struct { diff --git a/events/cognito_test.go b/events/cognito_test.go index 12cd1654..c363421c 100644 --- a/events/cognito_test.go +++ b/events/cognito_test.go @@ -162,6 +162,28 @@ func TestCognitoEventUserPoolsPreTokenGenV2Marshaling(t *testing.T) { test.AssertJsonsEqual(t, inputJSON, outputJSON) } +func TestCognitoEventUserPoolsPreTokenGenV2_0Marshaling(t *testing.T) { + // read json from file + inputJSON, err := ioutil.ReadFile("./testdata/cognito-event-userpools-pretokengen-v2_0.json") + if err != nil { + t.Errorf("could not open test file. details: %v", err) + } + + // de-serialize into CognitoEvent + var inputEvent CognitoEventUserPoolsPreTokenGenV2_0 + if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { + t.Errorf("could not unmarshal event. details: %v", err) + } + + // serialize to json + outputJSON, err := json.Marshal(inputEvent) + if err != nil { + t.Errorf("could not marshal event. details: %v", err) + } + + test.AssertJsonsEqual(t, inputJSON, outputJSON) +} + func TestCognitoEventUserPoolsDefineAuthChallengeMarshaling(t *testing.T) { var inputEvent CognitoEventUserPoolsDefineAuthChallenge test.AssertJsonFile(t, "./testdata/cognito-event-userpools-define-auth-challenge.json", &inputEvent) diff --git a/events/testdata/cognito-event-userpools-pretokengen-v2_0.json b/events/testdata/cognito-event-userpools-pretokengen-v2_0.json new file mode 100644 index 00000000..631f927a --- /dev/null +++ b/events/testdata/cognito-event-userpools-pretokengen-v2_0.json @@ -0,0 +1,73 @@ +{ + "version": "2", + "triggerSource": "TokenGeneration_Authentication", + "region": "us-east-1", + "userPoolId": "us-east-1_EXAMPLE", + "userName": "testuser", + "callerContext": { + "awsSdkVersion": "aws-sdk-unknown-unknown", + "clientId": "1example23456789" + }, + "request": { + "userAttributes": { + "sub": "a36036a8-9061-424d-a737-56d57dae7bc6", + "cognito:email_alias": "testuser@example.com", + "cognito:user_status": "CONFIRMED", + "email_verified": "true", + "email": "testuser@example.com" + }, + "groupConfiguration": { + "groupsToOverride": [], + "iamRolesToOverride": [], + "preferredRole": null + }, + "scopes": [ + "aws.cognito.signin.user.admin" + ] + }, + "response": { + "claimsAndScopeOverrideDetails": { + "idTokenGeneration": { + "claimsToAddOrOverride": { + "family_name": "xyz", + "favorite_number": 2 + }, + "claimsToSuppress": [ + "email", + "birthdate" + ] + }, + "accessTokenGeneration": { + "claimsToAddOrOverride": { + "family_name": "xyz", + "favorite_number": 2 + }, + "claimsToSuppress": [ + "email", + "birthdate" + ], + "scopesToAdd": [ + "scope1", + "scope2", + "scopeLomond" + ], + "scopesToSuppress": [ + "phone_number" + ] + }, + "groupOverrideDetails": { + "groupsToOverride": [ + "group-A", + "group-B", + "group-C" + ], + "iamRolesToOverride": [ + "arn:aws:iam::123456789012:role/sns_callerA", + "arn:aws:iam::123456789012:role/sns_callerB", + "arn:aws:iam::123456789012:role/sns_callerC" + ], + "preferredRole": "arn:aws:iam::123456789012:role/sns_caller" + } + } + } +}