Skip to content

Commit

Permalink
Add Event Definition for CognitoEventUserPoolsPreTokenGenV2 (#764)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
benbpyle authored Dec 29, 2023
1 parent ee7dcd7 commit 3b32d09
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 0 deletions.
79 changes: 79 additions & 0 deletions lambda-events/src/event/cognito/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,65 @@ pub struct CognitoEventUserPoolsPreTokenGenResponse {
pub claims_override_details: Option<ClaimsOverrideDetails>,
}

/// `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<String, String>,
pub group_configuration: GroupConfiguration,
#[serde(deserialize_with = "deserialize_lambda_map")]
#[serde(default)]
pub client_metadata: HashMap<String, String>,
pub scopes: Vec<String>,
}

#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CognitoEventUserPoolsPreTokenGenResponseV2 {
pub claims_and_scope_override_details: Option<ClaimsAndScopeOverrideDetailsV2>,
}

/// `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<CognitoIdTokenGenerationV2>,
pub access_token_generation: Option<CognitoAccessTokenGenerationV2>,
}

/// `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<String, String>,
pub claims_to_suppress: Vec<String>,
}

/// `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<String, String>,
pub claims_to_suppress: Vec<String>,
pub scopes_to_add: Vec<String>,
pub scopes_to_suppress: Vec<String>,
}

/// `CognitoEventUserPoolsPostAuthenticationRequest` contains the request portion of a PostAuthentication event
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
Expand Down Expand Up @@ -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() {
Expand All @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
@@ -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
}
}
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
}

0 comments on commit 3b32d09

Please sign in to comment.