From 9e3676ee8ca83aee500682f382e10b9d03660093 Mon Sep 17 00:00:00 2001 From: Michael Parsons Date: Tue, 4 Dec 2018 13:22:27 -0800 Subject: [PATCH] Cognito PreTokenGen Event (#95) * Adds support for pretokengen event. * link to the cognito events README files. * Iam -> IAM * Updated sample data with dummy values copied from * fix json synx error --- events/README.md | 6 ++++ .../README_Cognito_UserPools_PreTokenGen.md | 26 ++++++++++++++ events/cognito.go | 33 +++++++++++++++++ events/cognito_test.go | 26 ++++++++++++++ .../cognito-event-userpools-pretokengen.json | 36 +++++++++++++++++++ 5 files changed, 127 insertions(+) create mode 100644 events/README_Cognito_UserPools_PreTokenGen.md create mode 100644 events/testdata/cognito-event-userpools-pretokengen.json diff --git a/events/README.md b/events/README.md index f53ac869..9081a4bb 100644 --- a/events/README.md +++ b/events/README.md @@ -18,6 +18,12 @@ This package provides input types for Lambda functions that process AWS events. [Cognito Events](README_Cognito.md) +[Cognito PostConfirmation](README_Cognito_UserPools_PostConfirmation.md) + +[Cognito PreSignup](README_Cognito_UserPools_PreSignup.md) + +[Cognito PreTokenGen](README_Cognito_UserPools_PreTokenGen.md) + [Config Events](README_Config.md) [DynamoDB Events](README_DynamoDB.md) diff --git a/events/README_Cognito_UserPools_PreTokenGen.md b/events/README_Cognito_UserPools_PreTokenGen.md new file mode 100644 index 00000000..eddfcb4e --- /dev/null +++ b/events/README_Cognito_UserPools_PreTokenGen.md @@ -0,0 +1,26 @@ +# Sample Function + +The following is a sample Lambda function that receives Amazon Cognito User Pools pre-token-gen event as an input and writes some of the record data to CloudWatch Logs. (Note that by default anything written to Console will be logged as CloudWatch Logs events.) + +Please see instructions for setting up the Cognito triggers at https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html . + +```go +package main + +import ( + "fmt" + + "github.com/aws/aws-lambda-go/lambda" + "github.com/aws/aws-lambda-go/events" +) + +func handler(event events.CognitoEventUserPoolsPreTokenGen) (events.CognitoEventUserPoolsPreTokenGen, error) { + fmt.Printf("PreTokenGen of user: %s\n", event.UserName) + event.Response.ClaimOverrideDetails.ClaimsToSupress = []string{"family_name"} + return event, nil +} + +func main() { + lambda.Start(handler) +} +``` diff --git a/events/cognito.go b/events/cognito.go index 81903482..a518abf8 100644 --- a/events/cognito.go +++ b/events/cognito.go @@ -36,6 +36,14 @@ type CognitoEventUserPoolsPostConfirmation struct { Response CognitoEventUserPoolsPostConfirmationResponse `json:"response"` } +// CognitoEventUserPoolsPreTokenGen is sent by AWS Cognito User Pools when a user attempts to retrieve +// credentials, allowing a Lambda to perform insert, supress or override claims +type CognitoEventUserPoolsPreTokenGen struct { + CognitoEventUserPoolsHeader + Request CognitoEventUserPoolsPreTokenGenRequest `json:"request"` + Response CognitoEventUserPoolsPreTokenGenResponse `json:"response"` +} + // CognitoEventUserPoolsCallerContext contains information about the caller type CognitoEventUserPoolsCallerContext struct { AWSSDKVersion string `json:"awsSdkVersion"` @@ -73,3 +81,28 @@ type CognitoEventUserPoolsPostConfirmationRequest struct { // CognitoEventUserPoolsPostConfirmationResponse contains the response portion of a PostConfirmation event type CognitoEventUserPoolsPostConfirmationResponse struct { } + +// CognitoEventUserPoolsPreTokenGenRequest contains request portion of PreTokenGen event +type CognitoEventUserPoolsPreTokenGenRequest struct { + UserAttributes map[string]string `json:"userAttributes"` + GroupConfiguration GroupConfiguration `json:"groupConfiguration"` +} + +// CognitoEventUserPoolsPreTokenGenResponse containst the response portion of a PreTokenGen event +type CognitoEventUserPoolsPreTokenGenResponse struct { + ClaimsOverrideDetails ClaimsOverrideDetails `json:"claimsOverrideDetails"` +} + +// ClaimsOverrideDetails allows lambda to add, supress or override claims in the token +type ClaimsOverrideDetails struct { + GroupOverrideDetails GroupConfiguration `json:"groupOverrideDetails"` + ClaimsToAddOrOverride map[string]string `json:"claimsToAddOrOverride"` + ClaimsToSuppress []string `json:"claimsToSuppress"` +} + +// GroupConfiguration allows lambda to override groups, roles and set a perferred role +type GroupConfiguration struct { + GroupsToOverride []string `json:"groupsToOverride"` + IAMRolesToOverride []string `json:"iamRolesToOverride"` + PreferredRole *string `json:"preferredRole"` +} diff --git a/events/cognito_test.go b/events/cognito_test.go index 9ef77831..1f829957 100644 --- a/events/cognito_test.go +++ b/events/cognito_test.go @@ -85,3 +85,29 @@ func TestCognitoEventUserPoolsPostConfirmationMarshaling(t *testing.T) { test.AssertJsonsEqual(t, inputJSON, outputJSON) } + +func TestCognitoEventUserPoolsPreTokenGenMarshalingMalformedJson(t *testing.T) { + test.TestMalformedJson(t, CognitoEventUserPoolsPreTokenGen{}) +} + +func TestCognitoEventUserPoolsPreTokenGenMarshaling(t *testing.T) { + // read json from file + inputJSON, err := ioutil.ReadFile("./testdata/cognito-event-userpools-pretokengen.json") + if err != nil { + t.Errorf("could not open test file. details: %v", err) + } + + // de-serialize into CognitoEvent + var inputEvent CognitoEventUserPoolsPreTokenGen + 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) +} diff --git a/events/testdata/cognito-event-userpools-pretokengen.json b/events/testdata/cognito-event-userpools-pretokengen.json new file mode 100644 index 00000000..e6bf0e48 --- /dev/null +++ b/events/testdata/cognito-event-userpools-pretokengen.json @@ -0,0 +1,36 @@ +{ + "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" + }, + "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" + } + }, + "response": { + "claimsOverrideDetails": { + "claimsToAddOrOverride": { + "attribute_key2": "attribute_value2", + "attribute_key": "attribute_value" + }, + "claimsToSuppress": ["email"], + "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" + } + } + } +}