Skip to content

Commit 326401a

Browse files
Added support for Cognito pre token generation with access token customization (#538)
* Fixed Cognito service name and added event structure for Cognito pre token generation event V2 * gofmt -s -w . * Add sample data and serde test * Tweak the test data to avoid having to break response marshaling compatability of the GroupConfiguration struct --------- Co-authored-by: Bryan Moffatt <[email protected]> Co-authored-by: Bryan Moffatt <[email protected]>
1 parent 30d7c7e commit 326401a

File tree

3 files changed

+150
-15
lines changed

3 files changed

+150
-15
lines changed

events/cognito.go

+57-15
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
package events
44

5-
// CognitoEvent contains data from an event sent from AWS Cognito Sync
5+
// CognitoEvent contains data from an event sent from Amazon Cognito Sync
66
type CognitoEvent struct {
77
DatasetName string `json:"datasetName"`
88
DatasetRecords map[string]CognitoDatasetRecord `json:"datasetRecords"`
@@ -13,54 +13,62 @@ type CognitoEvent struct {
1313
Version int `json:"version"`
1414
}
1515

16-
// CognitoDatasetRecord represents a record from an AWS Cognito Sync event
16+
// CognitoDatasetRecord represents a record from an Amazon Cognito Sync event
1717
type CognitoDatasetRecord struct {
1818
NewValue string `json:"newValue"`
1919
OldValue string `json:"oldValue"`
2020
Op string `json:"op"`
2121
}
2222

23-
// CognitoEventUserPoolsPreSignup is sent by AWS Cognito User Pools when a user attempts to register
23+
// CognitoEventUserPoolsPreSignup is sent by Amazon Cognito User Pools when a user attempts to register
2424
// (sign up), allowing a Lambda to perform custom validation to accept or deny the registration request
2525
type CognitoEventUserPoolsPreSignup struct {
2626
CognitoEventUserPoolsHeader
2727
Request CognitoEventUserPoolsPreSignupRequest `json:"request"`
2828
Response CognitoEventUserPoolsPreSignupResponse `json:"response"`
2929
}
3030

31-
// CognitoEventUserPoolsPreAuthentication is sent by AWS Cognito User Pools when a user submits their information
31+
// CognitoEventUserPoolsPreAuthentication is sent by Amazon Cognito User Pools when a user submits their information
3232
// to be authenticated, allowing you to perform custom validations to accept or deny the sign in request.
3333
type CognitoEventUserPoolsPreAuthentication struct {
3434
CognitoEventUserPoolsHeader
3535
Request CognitoEventUserPoolsPreAuthenticationRequest `json:"request"`
3636
Response CognitoEventUserPoolsPreAuthenticationResponse `json:"response"`
3737
}
3838

39-
// CognitoEventUserPoolsPostConfirmation is sent by AWS Cognito User Pools after a user is confirmed,
39+
// CognitoEventUserPoolsPostConfirmation is sent by Amazon Cognito User Pools after a user is confirmed,
4040
// allowing the Lambda to send custom messages or add custom logic.
4141
type CognitoEventUserPoolsPostConfirmation struct {
4242
CognitoEventUserPoolsHeader
4343
Request CognitoEventUserPoolsPostConfirmationRequest `json:"request"`
4444
Response CognitoEventUserPoolsPostConfirmationResponse `json:"response"`
4545
}
4646

47-
// CognitoEventUserPoolsPreTokenGen is sent by AWS Cognito User Pools when a user attempts to retrieve
47+
// CognitoEventUserPoolsPreTokenGen is sent by Amazon Cognito User Pools when a user attempts to retrieve
4848
// credentials, allowing a Lambda to perform insert, suppress or override claims
4949
type CognitoEventUserPoolsPreTokenGen struct {
5050
CognitoEventUserPoolsHeader
5151
Request CognitoEventUserPoolsPreTokenGenRequest `json:"request"`
5252
Response CognitoEventUserPoolsPreTokenGenResponse `json:"response"`
5353
}
5454

55-
// CognitoEventUserPoolsPostAuthentication is sent by AWS Cognito User Pools after a user is authenticated,
55+
// CognitoEventUserPoolsPreTokenGenV2 is sent by Amazon Cognito User Pools when a user attempts to retrieve
56+
// credentials, allowing a Lambda to perform insert, suppress or override claims and scopes
57+
type CognitoEventUserPoolsPreTokenGenV2 struct {
58+
CognitoEventUserPoolsHeader
59+
Request CognitoEventUserPoolsPreTokenGenV2Request `json:"request"`
60+
Response CognitoEventUserPoolsPreTokenGenV2Response `json:"response"`
61+
}
62+
63+
// CognitoEventUserPoolsPostAuthentication is sent by Amazon Cognito User Pools after a user is authenticated,
5664
// allowing the Lambda to add custom logic.
5765
type CognitoEventUserPoolsPostAuthentication struct {
5866
CognitoEventUserPoolsHeader
5967
Request CognitoEventUserPoolsPostAuthenticationRequest `json:"request"`
6068
Response CognitoEventUserPoolsPostAuthenticationResponse `json:"response"`
6169
}
6270

63-
// CognitoEventUserPoolsMigrateUser is sent by AWS Cognito User Pools when a user does not exist in the
71+
// CognitoEventUserPoolsMigrateUser is sent by Amazon Cognito User Pools when a user does not exist in the
6472
// user pool at the time of sign-in with a password, or in the forgot-password flow.
6573
type CognitoEventUserPoolsMigrateUser struct {
6674
CognitoEventUserPoolsHeader
@@ -74,7 +82,7 @@ type CognitoEventUserPoolsCallerContext struct {
7482
ClientID string `json:"clientId"`
7583
}
7684

77-
// CognitoEventUserPoolsHeader contains common data from events sent by AWS Cognito User Pools
85+
// CognitoEventUserPoolsHeader contains common data from events sent by Amazon Cognito User Pools
7886
type CognitoEventUserPoolsHeader struct {
7987
Version string `json:"version"`
8088
TriggerSource string `json:"triggerSource"`
@@ -125,11 +133,24 @@ type CognitoEventUserPoolsPreTokenGenRequest struct {
125133
ClientMetadata map[string]string `json:"clientMetadata"`
126134
}
127135

128-
// CognitoEventUserPoolsPreTokenGenResponse containst the response portion of a PreTokenGen event
136+
// CognitoEventUserPoolsPreTokenGenV2Request contains request portion of V2 PreTokenGen event
137+
type CognitoEventUserPoolsPreTokenGenV2Request struct {
138+
UserAttributes map[string]string `json:"userAttributes"`
139+
GroupConfiguration GroupConfiguration `json:"groupConfiguration"`
140+
ClientMetadata map[string]string `json:"clientMetadata,omitempty"`
141+
Scopes []string `json:"scopes"`
142+
}
143+
144+
// CognitoEventUserPoolsPreTokenGenResponse contains the response portion of a PreTokenGen event
129145
type CognitoEventUserPoolsPreTokenGenResponse struct {
130146
ClaimsOverrideDetails ClaimsOverrideDetails `json:"claimsOverrideDetails"`
131147
}
132148

149+
// CognitoEventUserPoolsPreTokenGenV2Response contains the response portion of a V2 PreTokenGen event
150+
type CognitoEventUserPoolsPreTokenGenV2Response struct {
151+
ClaimsAndScopeOverrideDetails ClaimsAndScopeOverrideDetails `json:"claimsAndScopeOverrideDetails"`
152+
}
153+
133154
// CognitoEventUserPoolsPostAuthenticationRequest contains the request portion of a PostAuthentication event
134155
type CognitoEventUserPoolsPostAuthenticationRequest struct {
135156
NewDeviceUsed bool `json:"newDeviceUsed"`
@@ -157,14 +178,35 @@ type CognitoEventUserPoolsMigrateUserResponse struct {
157178
ForceAliasCreation bool `json:"forceAliasCreation"`
158179
}
159180

181+
// ClaimsAndScopeOverrideDetails allows lambda to add, suppress or override V2 claims and scopes in the token
182+
type ClaimsAndScopeOverrideDetails struct {
183+
IDTokenGeneration IDTokenGeneration `json:"idTokenGeneration"`
184+
AccessTokenGeneration AccessTokenGeneration `json:"accessTokenGeneration"`
185+
GroupOverrideDetails GroupConfiguration `json:"groupOverrideDetails"`
186+
}
187+
188+
// IDTokenGeneration allows lambda to modify the ID token
189+
type IDTokenGeneration struct {
190+
ClaimsToAddOrOverride map[string]string `json:"claimsToAddOrOverride"`
191+
ClaimsToSuppress []string `json:"claimsToSuppress"`
192+
}
193+
194+
// AccessTokenGeneration allows lambda to modify the access token
195+
type AccessTokenGeneration struct {
196+
ClaimsToAddOrOverride map[string]string `json:"claimsToAddOrOverride"`
197+
ClaimsToSuppress []string `json:"claimsToSuppress"`
198+
ScopesToAdd []string `json:"scopesToAdd"`
199+
ScopesToSuppress []string `json:"scopesToSuppress"`
200+
}
201+
160202
// ClaimsOverrideDetails allows lambda to add, suppress or override claims in the token
161203
type ClaimsOverrideDetails struct {
162204
GroupOverrideDetails GroupConfiguration `json:"groupOverrideDetails"`
163205
ClaimsToAddOrOverride map[string]string `json:"claimsToAddOrOverride"`
164206
ClaimsToSuppress []string `json:"claimsToSuppress"`
165207
}
166208

167-
// GroupConfiguration allows lambda to override groups, roles and set a perferred role
209+
// GroupConfiguration allows lambda to override groups, roles and set a preferred role
168210
type GroupConfiguration struct {
169211
GroupsToOverride []string `json:"groupsToOverride"`
170212
IAMRolesToOverride []string `json:"iamRolesToOverride"`
@@ -194,7 +236,7 @@ type CognitoEventUserPoolsDefineAuthChallengeResponse struct {
194236
FailAuthentication bool `json:"failAuthentication"`
195237
}
196238

197-
// CognitoEventUserPoolsDefineAuthChallenge sent by AWS Cognito User Pools to initiate custom authentication flow
239+
// CognitoEventUserPoolsDefineAuthChallenge sent by Amazon Cognito User Pools to initiate custom authentication flow
198240
type CognitoEventUserPoolsDefineAuthChallenge struct {
199241
CognitoEventUserPoolsHeader
200242
Request CognitoEventUserPoolsDefineAuthChallengeRequest `json:"request"`
@@ -216,7 +258,7 @@ type CognitoEventUserPoolsCreateAuthChallengeResponse struct {
216258
ChallengeMetadata string `json:"challengeMetadata"`
217259
}
218260

219-
// CognitoEventUserPoolsCreateAuthChallenge sent by AWS Cognito User Pools to create a challenge to present to the user
261+
// CognitoEventUserPoolsCreateAuthChallenge sent by Amazon Cognito User Pools to create a challenge to present to the user
220262
type CognitoEventUserPoolsCreateAuthChallenge struct {
221263
CognitoEventUserPoolsHeader
222264
Request CognitoEventUserPoolsCreateAuthChallengeRequest `json:"request"`
@@ -236,15 +278,15 @@ type CognitoEventUserPoolsVerifyAuthChallengeResponse struct {
236278
AnswerCorrect bool `json:"answerCorrect"`
237279
}
238280

239-
// CognitoEventUserPoolsVerifyAuthChallenge sent by AWS Cognito User Pools to verify if the response from the end user
281+
// CognitoEventUserPoolsVerifyAuthChallenge sent by Amazon Cognito User Pools to verify if the response from the end user
240282
// for a custom Auth Challenge is valid or not
241283
type CognitoEventUserPoolsVerifyAuthChallenge struct {
242284
CognitoEventUserPoolsHeader
243285
Request CognitoEventUserPoolsVerifyAuthChallengeRequest `json:"request"`
244286
Response CognitoEventUserPoolsVerifyAuthChallengeResponse `json:"response"`
245287
}
246288

247-
// CognitoEventUserPoolsCustomMessage is sent by AWS Cognito User Pools before a verification or MFA message is sent,
289+
// CognitoEventUserPoolsCustomMessage is sent by Amazon Cognito User Pools before a verification or MFA message is sent,
248290
// allowing a user to customize the message dynamically.
249291
type CognitoEventUserPoolsCustomMessage struct {
250292
CognitoEventUserPoolsHeader

events/cognito_test.go

+22
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,28 @@ func TestCognitoEventUserPoolsPreTokenGenMarshaling(t *testing.T) {
140140
test.AssertJsonsEqual(t, inputJSON, outputJSON)
141141
}
142142

143+
func TestCognitoEventUserPoolsPreTokenGenV2Marshaling(t *testing.T) {
144+
// read json from file
145+
inputJSON, err := ioutil.ReadFile("./testdata/cognito-event-userpools-pretokengen-v2.json")
146+
if err != nil {
147+
t.Errorf("could not open test file. details: %v", err)
148+
}
149+
150+
// de-serialize into CognitoEvent
151+
var inputEvent CognitoEventUserPoolsPreTokenGenV2
152+
if err := json.Unmarshal(inputJSON, &inputEvent); err != nil {
153+
t.Errorf("could not unmarshal event. details: %v", err)
154+
}
155+
156+
// serialize to json
157+
outputJSON, err := json.Marshal(inputEvent)
158+
if err != nil {
159+
t.Errorf("could not marshal event. details: %v", err)
160+
}
161+
162+
test.AssertJsonsEqual(t, inputJSON, outputJSON)
163+
}
164+
143165
func TestCognitoEventUserPoolsDefineAuthChallengeMarshaling(t *testing.T) {
144166
var inputEvent CognitoEventUserPoolsDefineAuthChallenge
145167
test.AssertJsonFile(t, "./testdata/cognito-event-userpools-define-auth-challenge.json", &inputEvent)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
{
2+
"version": "2",
3+
"triggerSource": "TokenGeneration_Authentication",
4+
"region": "us-west-2",
5+
"userPoolId": "us-east-1_EXAMPLE",
6+
"userName": "brcotter",
7+
"callerContext": {
8+
"awsSdkVersion": "aws-sdk-unknown-unknown",
9+
"clientId": "1example23456789"
10+
},
11+
"request": {
12+
"userAttributes": {
13+
"sub": "a36036a8-9061-424d-a737-56d57dae7bc6",
14+
"cognito:email_alias": "[email protected]",
15+
"cognito:user_status": "CONFIRMED",
16+
"email_verified": "true",
17+
"email": "[email protected]"
18+
},
19+
"groupConfiguration": {
20+
"groupsToOverride": [],
21+
"iamRolesToOverride": [],
22+
"preferredRole": null
23+
},
24+
"scopes": [
25+
"aws.cognito.signin.user.admin"
26+
]
27+
},
28+
"response": {
29+
"claimsAndScopeOverrideDetails": {
30+
"idTokenGeneration": {
31+
"claimsToAddOrOverride": {
32+
"family_name": "xyz"
33+
},
34+
"claimsToSuppress": [
35+
"email",
36+
"birthdate"
37+
]
38+
},
39+
"accessTokenGeneration": {
40+
"claimsToAddOrOverride": {
41+
"family_name": "xyz"
42+
},
43+
"claimsToSuppress": [
44+
"email",
45+
"birthdate"
46+
],
47+
"scopesToAdd": [
48+
"scope1",
49+
"scope2",
50+
"scopeLomond"
51+
],
52+
"scopesToSuppress": [
53+
"phone_number"
54+
]
55+
},
56+
"groupOverrideDetails": {
57+
"groupsToOverride": [
58+
"group-A",
59+
"group-B",
60+
"group-C"
61+
],
62+
"iamRolesToOverride": [
63+
"arn:aws:iam::123456789012:role/sns_callerA",
64+
"arn:aws:iam::123456789012:role/sns_callerB",
65+
"arn:aws:iam::123456789012:role/sns_callerC"
66+
],
67+
"preferredRole": "arn:aws:iam::123456789012:role/sns_caller"
68+
}
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)