From 3b32d090d12b8c790d499224a2eee10f0d460b22 Mon Sep 17 00:00:00 2001 From: Benjamen Pyle Date: Fri, 29 Dec 2023 10:42:52 -0600 Subject: [PATCH] Add Event Definition for CognitoEventUserPoolsPreTokenGenV2 (#764) The added structs allow for the processing of Version 2 Cognito PreToken generation in a Lambda The V2 payloads allow for customization of the Access Token in addition to the ID Token which was already supported --- lambda-events/src/event/cognito/mod.rs | 79 +++++++++++++++++++ ...ent-userpools-pretokengen-v2-incoming.json | 33 ++++++++ ...ognito-event-userpools-pretokengen-v2.json | 58 ++++++++++++++ 3 files changed, 170 insertions(+) create mode 100644 lambda-events/src/fixtures/example-cognito-event-userpools-pretokengen-v2-incoming.json create mode 100644 lambda-events/src/fixtures/example-cognito-event-userpools-pretokengen-v2.json diff --git a/lambda-events/src/event/cognito/mod.rs b/lambda-events/src/event/cognito/mod.rs index 614f5278..decc31a5 100644 --- a/lambda-events/src/event/cognito/mod.rs +++ b/lambda-events/src/event/cognito/mod.rs @@ -213,6 +213,65 @@ pub struct CognitoEventUserPoolsPreTokenGenResponse { pub claims_override_details: Option, } +/// `CognitoEventUserPoolsPreTokenGenV2` is sent by AWS Cognito User Pools when a user attempts to retrieve +/// credentials, allowing a Lambda to perform insert, suppress or override claims. This is the Version 2 Payload +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct CognitoEventUserPoolsPreTokenGenV2 { + #[serde(rename = "CognitoEventUserPoolsHeader")] + #[serde(flatten)] + pub cognito_event_user_pools_header: CognitoEventUserPoolsHeader, + pub request: CognitoEventUserPoolsPreTokenGenRequestV2, + pub response: CognitoEventUserPoolsPreTokenGenResponseV2, +} + +/// `CognitoEventUserPoolsPreTokenGenRequestV2` contains request portion of PreTokenGenV2 event +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct CognitoEventUserPoolsPreTokenGenRequestV2 { + #[serde(deserialize_with = "deserialize_lambda_map")] + #[serde(default)] + pub user_attributes: HashMap, + pub group_configuration: GroupConfiguration, + #[serde(deserialize_with = "deserialize_lambda_map")] + #[serde(default)] + pub client_metadata: HashMap, + pub scopes: Vec, +} + +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct CognitoEventUserPoolsPreTokenGenResponseV2 { + pub claims_and_scope_override_details: Option, +} + +/// `ClaimsAndScopeOverrideDetailsV2` allows lambda to add, suppress or override claims in the token +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct ClaimsAndScopeOverrideDetailsV2 { + pub group_override_details: GroupConfiguration, + pub id_token_generation: Option, + pub access_token_generation: Option, +} + +/// `CognitoIdTokenGenerationV2` allows lambda to customize the ID Token before generation +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct CognitoIdTokenGenerationV2 { + pub claims_to_add_or_override: HashMap, + pub claims_to_suppress: Vec, +} + +/// `CognitoAccessTokenGenerationV2` allows lambda to customize the Access Token before generation +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct CognitoAccessTokenGenerationV2 { + pub claims_to_add_or_override: HashMap, + pub claims_to_suppress: Vec, + pub scopes_to_add: Vec, + pub scopes_to_suppress: Vec, +} + /// `CognitoEventUserPoolsPostAuthenticationRequest` contains the request portion of a PostAuthentication event #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] @@ -608,6 +667,16 @@ mod test { assert_eq!(parsed, reparsed); } + #[test] + #[cfg(feature = "cognito")] + fn example_cognito_event_userpools_pretokengen_v2_incoming() { + let data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-v2-incoming.json"); + let parsed: CognitoEventUserPoolsPreTokenGenV2 = serde_json::from_slice(data).unwrap(); + let output: String = serde_json::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsPreTokenGenV2 = serde_json::from_slice(output.as_bytes()).unwrap(); + assert_eq!(parsed, reparsed); + } + #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_pretokengen() { @@ -618,6 +687,16 @@ mod test { assert_eq!(parsed, reparsed); } + #[test] + #[cfg(feature = "cognito")] + fn example_cognito_event_userpools_v2_pretokengen() { + let data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-v2.json"); + let parsed: CognitoEventUserPoolsPreTokenGenV2 = serde_json::from_slice(data).unwrap(); + let output: String = serde_json::to_string(&parsed).unwrap(); + let reparsed: CognitoEventUserPoolsPreTokenGenV2 = serde_json::from_slice(output.as_bytes()).unwrap(); + assert_eq!(parsed, reparsed); + } + #[test] #[cfg(feature = "cognito")] fn example_cognito_event_userpools_verify_auth_challenge() { diff --git a/lambda-events/src/fixtures/example-cognito-event-userpools-pretokengen-v2-incoming.json b/lambda-events/src/fixtures/example-cognito-event-userpools-pretokengen-v2-incoming.json new file mode 100644 index 00000000..3376d6e0 --- /dev/null +++ b/lambda-events/src/fixtures/example-cognito-event-userpools-pretokengen-v2-incoming.json @@ -0,0 +1,33 @@ +{ + "version": "1", + "triggerSource": "PreTokenGen", + "region": "region", + "userPoolId": "userPoolId", + "userName": "userName", + "callerContext": { + "awsSdkVersion": "calling aws sdk with version", + "clientId": "apps client id" + }, + "request": { + "userAttributes": { + "email": "email", + "phone_number": "phone_number" + }, + "scopes": ["scope-1", "scope-2"], + "groupConfiguration": { + "groupsToOverride": ["group-A", "group-B", "group-C"], + "iamRolesToOverride": [ + "arn:aws:iam::XXXXXXXXXXXX:role/sns_callerA", + "arn:aws:iam::XXXXXXXXX:role/sns_callerB", + "arn:aws:iam::XXXXXXXXXX:role/sns_callerC" + ], + "preferredRole": "arn:aws:iam::XXXXXXXXXXX:role/sns_caller" + }, + "clientMetadata": { + "exampleMetadataKey": "example metadata value" + } + }, + "response": { + "claimsOverrideDetails": null + } +} diff --git a/lambda-events/src/fixtures/example-cognito-event-userpools-pretokengen-v2.json b/lambda-events/src/fixtures/example-cognito-event-userpools-pretokengen-v2.json new file mode 100644 index 00000000..f7ccfe2f --- /dev/null +++ b/lambda-events/src/fixtures/example-cognito-event-userpools-pretokengen-v2.json @@ -0,0 +1,58 @@ +{ + "version": "1", + "triggerSource": "PreTokenGen", + "region": "region", + "userPoolId": "userPoolId", + "userName": "userName", + "callerContext": { + "awsSdkVersion": "calling aws sdk with version", + "clientId": "apps client id" + }, + "request": { + "userAttributes": { + "email": "email", + "phone_number": "phone_number" + }, + "scopes": ["scope-1", "scope-2"], + "groupConfiguration": { + "groupsToOverride": ["group-A", "group-B", "group-C"], + "iamRolesToOverride": [ + "arn:aws:iam::XXXXXXXXXXXX:role/sns_callerA", + "arn:aws:iam::XXXXXXXXX:role/sns_callerB", + "arn:aws:iam::XXXXXXXXXX:role/sns_callerC" + ], + "preferredRole": "arn:aws:iam::XXXXXXXXXXX:role/sns_caller" + }, + "clientMetadata": { + "exampleMetadataKey": "example metadata value" + } + }, + "response": { + "claimsAndScopeOverrideDetails": { + "idTokenGeneration": { + "claimsToAddOrOverride": { + "string": "string" + }, + "claimsToSuppress": ["string", "string"] + }, + "accessTokenGeneration": { + "claimsToAddOrOverride": { + "attribute_key2": "attribute_value2", + "attribute_key": "attribute_value" + }, + "claimsToSuppress": ["email", "phone"], + "scopesToAdd": ["scope-B", "scope-B"], + "scopesToSuppress": ["scope-C", "scope-D"] + }, + "groupOverrideDetails": { + "groupsToOverride": ["group-A", "group-B", "group-C"], + "iamRolesToOverride": [ + "arn:aws:iam::XXXXXXXXXXXX:role/sns_callerA", + "arn:aws:iam::XXXXXXXXX:role/sns_callerB", + "arn:aws:iam::XXXXXXXXXX:role/sns_callerC" + ], + "preferredRole": "arn:aws:iam::XXXXXXXXXXX:role/sns_caller" + } + } + } +}