Skip to content

feat: added contracts for cognito pre token generation v2_0 #1656

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions Libraries/src/Amazon.Lambda.CognitoEvents/AccessTokenGeneration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace Amazon.Lambda.CognitoEvents
{
/// <summary>
/// https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html
/// </summary>
[DataContract]
public class AccessTokenGeneration
{
/// <summary>
/// A map of one or more key-value pairs of claims to add or override. For group related claims, use
/// groupOverrideDetails instead.
/// </summary>
[DataMember(Name = "claimsToAddOrOverride")]
#if NETCOREAPP3_1_OR_GREATER
[System.Text.Json.Serialization.JsonPropertyName("claimsToAddOrOverride")]
# endif
public Dictionary<string, string> ClaimsToAddOrOverride { get; set; } = new Dictionary<string, string>();

/// <summary>
/// A list that contains claims to be suppressed from the identity token.
/// </summary>
[DataMember(Name = "claimsToSuppress")]
#if NETCOREAPP3_1_OR_GREATER
[System.Text.Json.Serialization.JsonPropertyName("claimsToSuppress")]
# endif
public List<string> ClaimsToSuppress { get; set; } = new List<string>();

/// <summary>
/// A list of OAuth 2.0 scopes that you want to add to the scope claim in your user's access token. You can't
/// add scope values that contain one or more blank-space characters.
/// </summary>
[DataMember(Name = "scopesToAdd")]
#if NETCOREAPP3_1_OR_GREATER
[System.Text.Json.Serialization.JsonPropertyName("scopesToAdd")]
# endif
public List<string> ScopesToAdd { get; set; } = new List<string>();

/// <summary>
/// A list of OAuth 2.0 scopes that you want to remove from the scope claim in your user's access token.
/// </summary>
[DataMember(Name = "scopesToSuppress")]
#if NETCOREAPP3_1_OR_GREATER
[System.Text.Json.Serialization.JsonPropertyName("scopesToSuppress")]
# endif
public List<string> ScopesToSuppress { get; set; } = new List<string>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Description>Amazon Lambda .NET Core support - CognitoEvents package.</Description>
<TargetFrameworks>netstandard2.0;netcoreapp3.1;net8.0</TargetFrameworks>
<AssemblyTitle>Amazon.Lambda.CognitoEvents</AssemblyTitle>
<VersionPrefix>2.2.0</VersionPrefix>
<VersionPrefix>2.3.0</VersionPrefix>
<AssemblyName>Amazon.Lambda.CognitoEvents</AssemblyName>
<PackageId>Amazon.Lambda.CognitoEvents</PackageId>
<PackageTags>AWS;Amazon;Lambda</PackageTags>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System.Runtime.Serialization;

namespace Amazon.Lambda.CognitoEvents
{
/// <summary>
/// https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html
/// </summary>
[DataContract]
public class ClaimsAndScopeOverrideDetails
{
/// <summary>
/// The claims that you want to override, add, or suppress in your user’s ID token.
/// </summary>
[DataMember(Name = "idTokenGeneration")]
#if NETCOREAPP3_1_OR_GREATER
[System.Text.Json.Serialization.JsonPropertyName("idTokenGeneration")]
# endif
public IdTokenGeneration IdTokenGeneration { get; set; } = new IdTokenGeneration();

/// <summary>
/// The claims and scopes that you want to override, add, or suppress in your user’s access token.
/// </summary>
[DataMember(Name = "accessTokenGeneration")]
#if NETCOREAPP3_1_OR_GREATER
[System.Text.Json.Serialization.JsonPropertyName("accessTokenGeneration")]
# endif
public AccessTokenGeneration AccessTokenGeneration { get; set; } = new AccessTokenGeneration();

/// <summary>
/// The output object containing the current group configuration. It includes groupsToOverride, iamRolesToOverride, and preferredRole.
/// </summary>
[DataMember(Name = "groupOverrideDetails")]
#if NETCOREAPP3_1_OR_GREATER
[System.Text.Json.Serialization.JsonPropertyName("groupOverrideDetails")]
# endif
public GroupConfiguration GroupOverrideDetails { get; set; } = new GroupConfiguration();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Amazon.Lambda.CognitoEvents
{
/// <summary>
/// https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html
/// </summary>
public class CognitoPreTokenGenerationV2Event : CognitoTriggerEvent<CognitoPreTokenGenerationV2Request, CognitoPreTokenGenerationV2Response>
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace Amazon.Lambda.CognitoEvents
{
/// <summary>
/// https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html
/// </summary>
public class CognitoPreTokenGenerationV2Request : CognitoTriggerRequest
{
/// <summary>
/// The input object containing the current group configuration. It includes groupsToOverride, iamRolesToOverride, and preferredRole.
/// </summary>
[DataMember(Name = "groupConfiguration")]
#if NETCOREAPP3_1_OR_GREATER
[System.Text.Json.Serialization.JsonPropertyName("groupConfiguration")]
# endif
public GroupConfiguration GroupConfiguration { get; set; } = new GroupConfiguration();

/// <summary>
/// One or more key-value pairs that you can provide as custom input to the Lambda function that you specify for the pre sign-up trigger. You can pass this data to your Lambda function by using the ClientMetadata parameter in the following API actions: AdminVerifyUser, AdminRespondToAuthChallenge, ForgotPassword, and SignUp.
/// </summary>
[DataMember(Name = "clientMetadata")]
#if NETCOREAPP3_1_OR_GREATER
[System.Text.Json.Serialization.JsonPropertyName("clientMetadata")]
# endif
public Dictionary<string, string> ClientMetadata { get; set; } = new Dictionary<string, string>();

/// <summary>
/// A list that contains the OAuth 2.0 user scopes.
/// </summary>
[DataMember(Name = "scopes")]
#if NETCOREAPP3_1_OR_GREATER
[System.Text.Json.Serialization.JsonPropertyName("scopes")]
# endif
public List<string> Scopes { get; set; } = new List<string>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Runtime.Serialization;

namespace Amazon.Lambda.CognitoEvents
{
/// <summary>
/// https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html
/// </summary>
public class CognitoPreTokenGenerationV2Response : CognitoTriggerResponse
{
/// <summary>
/// A container for all elements in a V2_0 trigger event.
/// </summary>
[DataMember(Name = "claimsAndScopeOverrideDetails")]
#if NETCOREAPP3_1_OR_GREATER
[System.Text.Json.Serialization.JsonPropertyName("claimsAndScopeOverrideDetails")]
# endif
public ClaimsAndScopeOverrideDetails ClaimsAndScopeOverrideDetails { get; set; } = new ClaimsAndScopeOverrideDetails();
}
}
30 changes: 30 additions & 0 deletions Libraries/src/Amazon.Lambda.CognitoEvents/IdTokenGeneration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace Amazon.Lambda.CognitoEvents
{
/// <summary>
/// https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html
/// </summary>
[DataContract]
public class IdTokenGeneration
{
/// <summary>
/// A map of one or more key-value pairs of claims to add or override. For group related claims, use groupOverrideDetails instead.
/// </summary>
[DataMember(Name = "claimsToAddOrOverride")]
#if NETCOREAPP3_1_OR_GREATER
[System.Text.Json.Serialization.JsonPropertyName("claimsToAddOrOverride")]
# endif
public Dictionary<string, string> ClaimsToAddOrOverride { get; set; } = new Dictionary<string, string>();

/// <summary>
/// A list that contains claims to be suppressed from the identity token.
/// </summary>
[DataMember(Name = "claimsToSuppress")]
#if NETCOREAPP3_1_OR_GREATER
[System.Text.Json.Serialization.JsonPropertyName("claimsToSuppress")]
# endif
public List<string> ClaimsToSuppress { get; set; } = new List<string>();
}
}
90 changes: 88 additions & 2 deletions Libraries/test/EventsTests.Shared/EventTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1069,6 +1069,92 @@ public void CognitoPreTokenGenerationEventTest(Type serializerType)
}
}

[Theory]
[InlineData(typeof(JsonSerializer))]
#if NETCOREAPP3_1_OR_GREATER
[InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))]
[InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
#endif
public void CognitoPreTokenGenerationV2EventTest(Type serializerType)
{
var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer;
using (var fileStream = LoadJsonTestFile("cognito-pretokengenerationv2-event.json"))
{
var cognitoPreTokenGenerationV2Event = serializer.Deserialize<CognitoPreTokenGenerationV2Event>(fileStream);

AssertBaseClass(cognitoPreTokenGenerationV2Event, eventVersion: "2");

Assert.Equal(2, cognitoPreTokenGenerationV2Event.Request.GroupConfiguration.GroupsToOverride.Count);
Assert.Equal("group1", cognitoPreTokenGenerationV2Event.Request.GroupConfiguration.GroupsToOverride[0]);
Assert.Equal("group2", cognitoPreTokenGenerationV2Event.Request.GroupConfiguration.GroupsToOverride[1]);

Assert.Equal(2, cognitoPreTokenGenerationV2Event.Request.GroupConfiguration.IamRolesToOverride.Count);
Assert.Equal("role1", cognitoPreTokenGenerationV2Event.Request.GroupConfiguration.IamRolesToOverride[0]);
Assert.Equal("role2", cognitoPreTokenGenerationV2Event.Request.GroupConfiguration.IamRolesToOverride[1]);

Assert.Equal("role", cognitoPreTokenGenerationV2Event.Request.GroupConfiguration.PreferredRole);

Assert.Equal(2, cognitoPreTokenGenerationV2Event.Request.ClientMetadata.Count);
Assert.Equal("metadata_1", cognitoPreTokenGenerationV2Event.Request.ClientMetadata.ToArray()[0].Key);
Assert.Equal("metadata_value_1", cognitoPreTokenGenerationV2Event.Request.ClientMetadata.ToArray()[0].Value);
Assert.Equal("metadata_2", cognitoPreTokenGenerationV2Event.Request.ClientMetadata.ToArray()[1].Key);
Assert.Equal("metadata_value_2", cognitoPreTokenGenerationV2Event.Request.ClientMetadata.ToArray()[1].Value);

Assert.Equal(2, cognitoPreTokenGenerationV2Event.Request.UserAttributes.Count);
Assert.Equal("attribute_1", cognitoPreTokenGenerationV2Event.Request.UserAttributes.ToArray()[0].Key);
Assert.Equal("attribute_value_1", cognitoPreTokenGenerationV2Event.Request.UserAttributes.ToArray()[0].Value);
Assert.Equal("attribute_2", cognitoPreTokenGenerationV2Event.Request.UserAttributes.ToArray()[1].Key);
Assert.Equal("attribute_value_2", cognitoPreTokenGenerationV2Event.Request.UserAttributes.ToArray()[1].Value);

Assert.Equal(2, cognitoPreTokenGenerationV2Event.Request.Scopes.Count);
Assert.Equal("scope_1", cognitoPreTokenGenerationV2Event.Request.Scopes.ToArray()[0]);
Assert.Equal("scope_2", cognitoPreTokenGenerationV2Event.Request.Scopes.ToArray()[1]);

Assert.Equal(2, cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.IdTokenGeneration.ClaimsToAddOrOverride.Count);
Assert.Equal("claim_1", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.IdTokenGeneration.ClaimsToAddOrOverride.ToArray()[0].Key);
Assert.Equal("claim_1_value_1", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.IdTokenGeneration.ClaimsToAddOrOverride.ToArray()[0].Value);
Assert.Equal("claim_2", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.IdTokenGeneration.ClaimsToAddOrOverride.ToArray()[1].Key);
Assert.Equal("claim_1_value_2", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.IdTokenGeneration.ClaimsToAddOrOverride.ToArray()[1].Value);
Assert.Equal(2, cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.IdTokenGeneration.ClaimsToSuppress.Count);
Assert.Equal("suppress1", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.IdTokenGeneration.ClaimsToSuppress[0]);
Assert.Equal("suppress2", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.IdTokenGeneration.ClaimsToSuppress[1]);

Assert.Equal(2, cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ClaimsToAddOrOverride.Count);
Assert.Equal("claim_1", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ClaimsToAddOrOverride.ToArray()[0].Key);
Assert.Equal("claim_1_value_1", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ClaimsToAddOrOverride.ToArray()[0].Value);
Assert.Equal("claim_2", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ClaimsToAddOrOverride.ToArray()[1].Key);
Assert.Equal("claim_1_value_2", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ClaimsToAddOrOverride.ToArray()[1].Value);
Assert.Equal(2, cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ClaimsToSuppress.Count);
Assert.Equal("suppress1", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ClaimsToSuppress[0]);
Assert.Equal("suppress2", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ClaimsToSuppress[1]);
Assert.Equal(2, cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ScopesToAdd.Count);
Assert.Equal("add1", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ScopesToAdd[0]);
Assert.Equal("add2", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ScopesToAdd[1]);
Assert.Equal(2, cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ScopesToSuppress.Count);
Assert.Equal("suppress1", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ScopesToSuppress[0]);
Assert.Equal("suppress2", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ScopesToSuppress[1]);

Assert.Equal(2, cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.GroupOverrideDetails.GroupsToOverride.Count);
Assert.Equal("group1", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.GroupOverrideDetails.GroupsToOverride[0]);
Assert.Equal("group2", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.GroupOverrideDetails.GroupsToOverride[1]);

Assert.Equal(2, cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.GroupOverrideDetails.IamRolesToOverride.Count);
Assert.Equal("role1", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.GroupOverrideDetails.IamRolesToOverride[0]);
Assert.Equal("role2", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.GroupOverrideDetails.IamRolesToOverride[1]);

Assert.Equal("role", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.GroupOverrideDetails.PreferredRole);

MemoryStream ms = new MemoryStream();
serializer.Serialize<CognitoPreTokenGenerationV2Event>(cognitoPreTokenGenerationV2Event, ms);
ms.Position = 0;
var json = new StreamReader(ms).ReadToEnd();

var original = JObject.Parse(File.ReadAllText("cognito-pretokengenerationv2-event.json"));
var serialized = JObject.Parse(json);
Assert.True(JToken.DeepEquals(serialized, original), "Serialized object is not the same as the original JSON");
}
}

[Theory]
[InlineData(typeof(JsonSerializer))]
#if NETCOREAPP3_1_OR_GREATER
Expand Down Expand Up @@ -1223,11 +1309,11 @@ public void CognitoCustomSmsSenderEventTest(Type serializerType)
}
}

private static void AssertBaseClass<TRequest, TResponse>(CognitoTriggerEvent<TRequest, TResponse> cognitoTriggerEvent)
private static void AssertBaseClass<TRequest, TResponse>(CognitoTriggerEvent<TRequest, TResponse> cognitoTriggerEvent, string eventVersion = "1")
where TRequest : CognitoTriggerRequest, new()
where TResponse : CognitoTriggerResponse, new()
{
Assert.Equal("1", cognitoTriggerEvent.Version);
Assert.Equal(eventVersion, cognitoTriggerEvent.Version);
Assert.Equal("us-east-1", cognitoTriggerEvent.Region);
Assert.Equal("us-east-1_id", cognitoTriggerEvent.UserPoolId);
Assert.Equal("username_uuid", cognitoTriggerEvent.UserName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<Content Include="$(MSBuildThisFileDirectory)cognito-custommessage-event.json" />
<Content Include="$(MSBuildThisFileDirectory)cognito-migrateuser-event.json" />
<Content Include="$(MSBuildThisFileDirectory)cognito-pretokengeneration-event.json" />
<Content Include="$(MSBuildThisFileDirectory)cognito-pretokengenerationv2-event.json" />
<Content Include="$(MSBuildThisFileDirectory)cognito-verifyauthchallenge-event.json" />
<Content Include="$(MSBuildThisFileDirectory)cognito-postconfirmation-event.json" />
<Content Include="$(MSBuildThisFileDirectory)cognito-postauthentication-event.json" />
Expand Down
Loading