From 64d401c708f0c1cf680191f9d9e44a8dce0faf60 Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Tue, 14 Jan 2025 14:12:02 +0530 Subject: [PATCH 01/27] Initial changes for AppSyncEvent --- Libraries/Libraries.sln | 15 ++- .../Amazon.Lambda.AppSyncEvents.csproj | 20 ++++ .../AppSyncEvent.cs | 92 +++++++++++++++++++ .../src/Amazon.Lambda.AppSyncEvents/README.md | 18 ++++ .../EventsTests.NET6/EventsTests.NET6.csproj | 1 + .../EventsTests.NETCore31.csproj | 1 + .../test/EventsTests.Shared/EventTests.cs | 35 +++++++ .../EventsTests.Shared.projitems | 1 + .../EventsTests.Shared/appsync-event.json | 61 ++++++++++++ 9 files changed, 240 insertions(+), 4 deletions(-) create mode 100644 Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj create mode 100644 Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs create mode 100644 Libraries/src/Amazon.Lambda.AppSyncEvents/README.md create mode 100644 Libraries/test/EventsTests.Shared/appsync-event.json diff --git a/Libraries/Libraries.sln b/Libraries/Libraries.sln index 3df1056d9..b63125e33 100644 --- a/Libraries/Libraries.sln +++ b/Libraries/Libraries.sln @@ -123,17 +123,19 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestMinimalAPIApp", "test\T EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Amazon.Lambda.MQEvents", "src\Amazon.Lambda.MQEvents\Amazon.Lambda.MQEvents.csproj", "{BF85932E-2DFF-41CD-8090-A672468B8FBB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amazon.Lambda.LexV2Events", "src\Amazon.Lambda.LexV2Events\Amazon.Lambda.LexV2Events.csproj", "{3C6AABF5-0372-41E0-874F-DF18ECCC7FB6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Amazon.Lambda.LexV2Events", "src\Amazon.Lambda.LexV2Events\Amazon.Lambda.LexV2Events.csproj", "{3C6AABF5-0372-41E0-874F-DF18ECCC7FB6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest", "test\Amazon.Lambda.RuntimeSupport.Tests\CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest\CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.csproj", "{0BD83939-458C-4EF5-8663-7098AD1200F2}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest", "test\Amazon.Lambda.RuntimeSupport.Tests\CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest\CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.csproj", "{0BD83939-458C-4EF5-8663-7098AD1200F2}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestExecutableServerlessApp", "test\TestExecutableServerlessApp\TestExecutableServerlessApp.csproj", "{DD378063-C54A-44C7-9A6F-32A6A1AE94B3}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestServerlessApp.NET8", "test\TestServerlessApp.NET8\TestServerlessApp.NET8.csproj", "{7300983D-8FCE-42EA-9B9E-B1C5347D15D8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SnapshotRestore.Registry", "src\SnapshotRestore.Registry\SnapshotRestore.Registry.csproj", "{7261A438-8C1D-47AD-98B0-7678F72E4382}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SnapshotRestore.Registry", "src\SnapshotRestore.Registry\SnapshotRestore.Registry.csproj", "{7261A438-8C1D-47AD-98B0-7678F72E4382}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SnapshotRestore.Registry.Tests", "test\SnapshotRestore.Registry.Tests\SnapshotRestore.Registry.Tests.csproj", "{A699E183-D0D4-4F26-A0A7-88DA5607F455}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SnapshotRestore.Registry.Tests", "test\SnapshotRestore.Registry.Tests\SnapshotRestore.Registry.Tests.csproj", "{A699E183-D0D4-4F26-A0A7-88DA5607F455}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Amazon.Lambda.AppSyncEvents", "src\Amazon.Lambda.AppSyncEvents\Amazon.Lambda.AppSyncEvents.csproj", "{99F39E49-1FD0-4EF5-BF4B-8F2473FB8198}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -369,6 +371,10 @@ Global {A699E183-D0D4-4F26-A0A7-88DA5607F455}.Debug|Any CPU.Build.0 = Debug|Any CPU {A699E183-D0D4-4F26-A0A7-88DA5607F455}.Release|Any CPU.ActiveCfg = Release|Any CPU {A699E183-D0D4-4F26-A0A7-88DA5607F455}.Release|Any CPU.Build.0 = Release|Any CPU + {99F39E49-1FD0-4EF5-BF4B-8F2473FB8198}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {99F39E49-1FD0-4EF5-BF4B-8F2473FB8198}.Debug|Any CPU.Build.0 = Debug|Any CPU + {99F39E49-1FD0-4EF5-BF4B-8F2473FB8198}.Release|Any CPU.ActiveCfg = Release|Any CPU + {99F39E49-1FD0-4EF5-BF4B-8F2473FB8198}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -435,6 +441,7 @@ Global {7300983D-8FCE-42EA-9B9E-B1C5347D15D8} = {1DE4EE60-45BA-4EF7-BE00-B9EB861E4C69} {7261A438-8C1D-47AD-98B0-7678F72E4382} = {AAB54E74-20B1-42ED-BC3D-CE9F7BC7FD12} {A699E183-D0D4-4F26-A0A7-88DA5607F455} = {1DE4EE60-45BA-4EF7-BE00-B9EB861E4C69} + {99F39E49-1FD0-4EF5-BF4B-8F2473FB8198} = {AAB54E74-20B1-42ED-BC3D-CE9F7BC7FD12} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {503678A4-B8D1-4486-8915-405A3E9CF0EB} diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj new file mode 100644 index 000000000..edac24e37 --- /dev/null +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj @@ -0,0 +1,20 @@ + + + + + + Amazon Lambda .NET Core support - AWS AppSync package. + netstandard2.0;net8.0 + Amazon.Lambda.AppSyncEvents + 0.0.1 + Amazon.Lambda.AppSyncEvents + Amazon.Lambda.AppSyncEvents + AWS;Amazon;Lambda;AppSync + + + + IL2026,IL2067,IL2075 + true + true + + diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs new file mode 100644 index 000000000..50cc6afd6 --- /dev/null +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs @@ -0,0 +1,92 @@ +namespace Amazon.Lambda.AppSyncEvents +{ + using System.Collections.Generic; + + /// + /// Represents the event payload received from AWS AppSync. + /// + public class AppSyncEvent + { + /// + /// Gets or sets the input arguments for the GraphQL operation. + /// + public Dictionary Arguments { get; set; } + + /// + /// Gets or sets information about the identity that triggered the event. + /// + public object Identity { get; set; } + + /// + /// Gets or sets information about the data source that originated the event. + /// + public object Source { get; set; } + + /// + /// Gets or sets information about the HTTP request that triggered the event. + /// + public RequestContext Request { get; set; } + + /// + /// Gets or sets information about the previous state of the data before the operation was executed. + /// + public object Prev { get; set; } + + /// + /// Gets or sets information about the GraphQL operation being executed. + /// + public Information Info { get; set; } + + /// + /// Gets or sets additional information that can be passed between Lambda functions during an AppSync pipeline. + /// + public Dictionary Stash { get; set; } + + /// + /// Represents information about the HTTP request that triggered the event. + /// + public class RequestContext + { + /// + /// Gets or sets the headers of the HTTP request. + /// + public Dictionary Headers { get; set; } + + /// + /// Gets or sets the domain name associated with the request. + /// + public object DomainName { get; set; } + } + + /// + /// Represents information about the GraphQL operation being executed. + /// + public class Information + { + /// + /// Gets or sets the name of the GraphQL field being executed. + /// + public string FieldName { get; set; } + + /// + /// Gets or sets a list of fields being selected in the GraphQL operation. + /// + public List SelectionSetList { get; set; } + + /// + /// Gets or sets the GraphQL selection set for the operation. + /// + public string SelectionSetGraphQL { get; set; } + + /// + /// Gets or sets the variables passed to the GraphQL operation. + /// + public Dictionary Variables { get; set; } + + /// + /// Gets or sets the parent type name for the GraphQL operation. + /// + public string ParentTypeName { get; set; } + } + } +} \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md new file mode 100644 index 000000000..3502cccfa --- /dev/null +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md @@ -0,0 +1,18 @@ +# Amazon.Lambda.AppSyncEvents + +This package contains classes that can be used as input types for Lambda functions that process AppSync events. + +# Sample Function + +The following is a sample class and Lambda function that receives AppSync event record data as an input and logs some of the incoming event data. (Note that by default anything written to Console will be logged as CloudWatch Logs events.) + +```csharp +public class Function +{ + public string Handler(AppSyncEvent appSyncEvent) + { + var input = JsonSerializer.Serialize(appSyncEvent.Arguments); + Console.WriteLine($"AppSync request payload {input}."); + } +} +``` diff --git a/Libraries/test/EventsTests.NET6/EventsTests.NET6.csproj b/Libraries/test/EventsTests.NET6/EventsTests.NET6.csproj index af60ce665..9fe6c957d 100644 --- a/Libraries/test/EventsTests.NET6/EventsTests.NET6.csproj +++ b/Libraries/test/EventsTests.NET6/EventsTests.NET6.csproj @@ -27,6 +27,7 @@ + diff --git a/Libraries/test/EventsTests.NETCore31/EventsTests.NETCore31.csproj b/Libraries/test/EventsTests.NETCore31/EventsTests.NETCore31.csproj index 1c5812340..fbea03df8 100644 --- a/Libraries/test/EventsTests.NETCore31/EventsTests.NETCore31.csproj +++ b/Libraries/test/EventsTests.NETCore31/EventsTests.NETCore31.csproj @@ -27,6 +27,7 @@ + diff --git a/Libraries/test/EventsTests.Shared/EventTests.cs b/Libraries/test/EventsTests.Shared/EventTests.cs index fa2cf6e04..bb5e2ed09 100644 --- a/Libraries/test/EventsTests.Shared/EventTests.cs +++ b/Libraries/test/EventsTests.Shared/EventTests.cs @@ -3,6 +3,7 @@ namespace Amazon.Lambda.Tests { using Amazon.Lambda.APIGatewayEvents; using Amazon.Lambda.ApplicationLoadBalancerEvents; + using Amazon.Lambda.AppSyncEvents; using Amazon.Lambda.CloudWatchEvents.BatchEvents; using Amazon.Lambda.CloudWatchEvents.ECSEvents; using Amazon.Lambda.CloudWatchEvents.S3Events; @@ -3907,6 +3908,40 @@ public void TestJsonIncludeNullValueSerializer() Assert.Equal(123, serialized["SomeValue"]); Assert.Equal(JTokenType.Null, serialized["SomeOtherValue"].Type); // System.NullReferenceException is thrown if value is missing. } + + [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 AppSyncTest(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event.json")) + { + var appSyncEvent = serializer.Deserialize(fileStream); + Assert.NotNull(appSyncEvent); + Assert.NotNull(appSyncEvent.Arguments); + Assert.NotNull(appSyncEvent.Arguments["input"]); + + Assert.NotNull(appSyncEvent.Request); + Assert.NotNull(appSyncEvent.Request.Headers); + var headers = appSyncEvent.Request.Headers; + Assert.Equal("value1", headers["key1"]); + Assert.Equal("value2", headers["key2"]); + + Assert.NotNull(appSyncEvent.Info); + Assert.Equal("createTodo", appSyncEvent.Info.FieldName); + Assert.Equal("Mutation", appSyncEvent.Info.ParentTypeName); + + Assert.NotNull(appSyncEvent.Info.SelectionSetList); + Assert.Equal(3, appSyncEvent.Info.SelectionSetList.Count); + Assert.Contains("id", appSyncEvent.Info.SelectionSetList); + Assert.Contains("description", appSyncEvent.Info.SelectionSetList); + Assert.Contains("completed", appSyncEvent.Info.SelectionSetList); + } + } class ClassUsingPascalCase { diff --git a/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems b/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems index 4fdc41123..47adfd48b 100644 --- a/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems +++ b/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems @@ -12,6 +12,7 @@ + diff --git a/Libraries/test/EventsTests.Shared/appsync-event.json b/Libraries/test/EventsTests.Shared/appsync-event.json new file mode 100644 index 000000000..5540487d5 --- /dev/null +++ b/Libraries/test/EventsTests.Shared/appsync-event.json @@ -0,0 +1,61 @@ +{ + "arguments": { + "input": { + "title": "test title", + "description": "test description" + } + }, + "identity": null, + "source": null, + "request": { + "headers": { + "key1": "value1", + "key2": "value2", + "x-forwarded-for": "223.190.85.124, 64.252.163.140", + "cloudfront-viewer-country": "IN", + "cloudfront-is-tablet-viewer": "false", + "x-amzn-requestid": "80abe633-c35f-4eef-911a-45582a0ff63d", + "via": "2.0 ba7cbe9cb489c2d3f36cb36e8ab2d0ba.cloudfront.net (CloudFront)", + "cloudfront-forwarded-proto": "https", + "origin": "https://us-east-1.console.aws.amazon.com", + "content-length": "227", + "x-forwarded-proto": "https", + "accept-language": "en-US,en;q=0.5", + "host": "hbmek2mkajdjxix7recvfrvls4.appsync-api.us-east-1.amazonaws.com", + "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0", + "cloudfront-is-mobile-viewer": "false", + "accept": "application/json, text/plain, */*", + "priority": "u=0", + "cloudfront-viewer-asn": "24560", + "cloudfront-is-smarttv-viewer": "false", + "x-amzn-appsync-is-vpce-request": "false", + "accept-encoding": "gzip, deflate, br, zstd", + "referer": "https://us-east-1.console.aws.amazon.com/", + "x-amzn-remote-ip": "223.190.85.124", + "x-api-key": "da2-2mz5t3o4zvb67iledrusv5fwne", + "content-type": "application/json", + "sec-fetch-mode": "cors", + "x-amzn-trace-id": "Root=1-676188b0-24a54b414e5efff525f844ed", + "x-amz-cf-id": "fWAr7rhMkSOcLcrEqGNU4n7uOpcm-VFHERrnYTO16O1at35i3RyyPw==", + "sec-fetch-dest": "empty", + "x-amz-user-agent": "AWS-Console-AppSync/", + "cloudfront-is-desktop-viewer": "true", + "sec-fetch-site": "cross-site", + "x-forwarded-port": "443" + }, + "domainName": null + }, + "prev": null, + "info": { + "fieldName": "createTodo", + "selectionSetList": [ + "id", + "description", + "completed" + ], + "selectionSetGraphQL": "{\n id\n description\n completed\n}", + "variables": {}, + "parentTypeName": "Mutation" + }, + "stash": {} +} \ No newline at end of file From 43359144f1f12ff5133fe5f0cbcbfd450f6bb7d3 Mon Sep 17 00:00:00 2001 From: Ankush Jain Date: Tue, 21 Jan 2025 18:33:03 +0530 Subject: [PATCH 02/27] Added AppSyncEvent class, and respective test cases --- .../Amazon.Lambda.AppSyncEvents.csproj | 6 +- .../AppSyncEvent.cs | 19 ++- .../AppSyncIdentityCognito.cs | 46 ++++++ .../AppSyncIdentityIAM.cs | 50 ++++++ .../test/EventsTests.Shared/EventTests.cs | 147 +++++++++++++++--- .../EventsTests.Shared.projitems | 1 + .../appsync-event-cognito-authorizer.json | 68 ++++++++ .../appsync-event-iam-authorizer.json | 48 ++++++ .../EventsTests.Shared/appsync-event.json | 83 ++++------ 9 files changed, 389 insertions(+), 79 deletions(-) create mode 100644 Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIdentityCognito.cs create mode 100644 Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIdentityIAM.cs create mode 100644 Libraries/test/EventsTests.Shared/appsync-event-cognito-authorizer.json create mode 100644 Libraries/test/EventsTests.Shared/appsync-event-iam-authorizer.json diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj index edac24e37..54553244b 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj @@ -4,12 +4,12 @@ Amazon Lambda .NET Core support - AWS AppSync package. - netstandard2.0;net8.0 + netstandard2.0;netcoreapp3.1;net8.0 Amazon.Lambda.AppSyncEvents - 0.0.1 + 1.0.0 Amazon.Lambda.AppSyncEvents Amazon.Lambda.AppSyncEvents - AWS;Amazon;Lambda;AppSync + AWS;Amazon;Lambda diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs index 50cc6afd6..80153094d 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs @@ -1,7 +1,7 @@ -namespace Amazon.Lambda.AppSyncEvents +using System.Collections.Generic; + +namespace Amazon.Lambda.AppSyncEvents { - using System.Collections.Generic; - /// /// Represents the event payload received from AWS AppSync. /// @@ -13,8 +13,19 @@ public class AppSyncEvent public Dictionary Arguments { get; set; } /// - /// Gets or sets information about the identity that triggered the event. + /// An object that contains information about the caller. + /// Returns null for API_KEY authorization. + /// Returns AppSyncIdentityIAM for AWS_IAM authorization. + /// Returns AppSyncIdentityCognito for AMAZON_COGNITO_USER_POOLS authorization. + /// For AWS_LAMBDA authorization, returns the object returned by your Lambda authorizer function. /// + /// + /// The Identity object type depends on the authorization mode: + /// - For API_KEY: null + /// - For AWS_IAM: + /// - For AMAZON_COGNITO_USER_POOLS: + /// - For AWS_LAMBDA: Dynamic object returned by Lambda authorizer + /// public object Identity { get; set; } /// diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIdentityCognito.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIdentityCognito.cs new file mode 100644 index 000000000..b02011086 --- /dev/null +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIdentityCognito.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; + +namespace Amazon.Lambda.AppSyncEvents +{ + /// + /// Represents Amazon Cognito User Pools authorization identity for AppSync + /// + public class AppSyncIdentityCognito + { + /// + /// The source IP address of the caller received by AWS AppSync + /// + public List SourceIp { get; set; } + + /// + /// The username of the authenticated user + /// + public string Username { get; set; } + + /// + /// The UUID of the authenticated user + /// + public string Sub { get; set; } + + /// + /// The claims that the user has + /// + public Dictionary Claims { get; set; } + + /// + /// The default authorization strategy for this caller (ALLOW or DENY) + /// + public string DefaultAuthStrategy { get; set; } + + /// + /// List of OIDC groups + /// + public List Groups { get; set; } + + /// + /// The token issuer + /// + public string Issuer { get; set; } + } + +} \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIdentityIAM.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIdentityIAM.cs new file mode 100644 index 000000000..962edff9f --- /dev/null +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIdentityIAM.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; + +namespace Amazon.Lambda.AppSyncEvents +{ + /// + /// Represents AWS IAM authorization identity for AppSync + /// + public class AppSyncIdentityIAM + { + /// + /// The source IP address of the caller received by AWS AppSync + /// + public List SourceIp { get; set; } + + /// + /// The username of the authenticated user (IAM user principal) + /// + public string Username { get; set; } + + /// + /// The AWS account ID of the caller + /// + public string AccountId { get; set; } + + /// + /// The Amazon Cognito identity pool ID associated with the caller + /// + public string CognitoIdentityPoolId { get; set; } + + /// + /// The Amazon Cognito identity ID of the caller + /// + public string CognitoIdentityId { get; set; } + + /// + /// The ARN of the IAM user + /// + public string UserArn { get; set; } + + /// + /// Either authenticated or unauthenticated based on the identity type + /// + public string CognitoIdentityAuthType { get; set; } + + /// + /// A comma separated list of external identity provider information used in obtaining the credentials used to sign the request + /// + public string CognitoIdentityAuthProvider { get; set; } + } +} \ No newline at end of file diff --git a/Libraries/test/EventsTests.Shared/EventTests.cs b/Libraries/test/EventsTests.Shared/EventTests.cs index bb5e2ed09..5fa06ff58 100644 --- a/Libraries/test/EventsTests.Shared/EventTests.cs +++ b/Libraries/test/EventsTests.Shared/EventTests.cs @@ -952,7 +952,7 @@ public void CognitoDefineAuthChallengeEventTest(Type serializerType) Assert.True(session0.ChallengeResult); Assert.Equal("challenge_metadata1", session0.ChallengeMetadata); - + var session1 = cognitoDefineAuthChallengeEvent.Request.Session[1]; Assert.Equal("challenge2", session1.ChallengeName); Assert.False(session1.ChallengeResult); @@ -1110,7 +1110,7 @@ public void CognitoVerifyAuthChallengeEventTest(Type serializerType) Assert.Equal("private_value_2", cognitoVerifyAuthChallengeEvent.Request.PrivateChallengeParameters.ToArray()[1].Value); Assert.True(cognitoVerifyAuthChallengeEvent.Request.UserNotFound); - + Assert.True(cognitoVerifyAuthChallengeEvent.Response.AnswerCorrect); MemoryStream ms = new MemoryStream(); @@ -1254,11 +1254,11 @@ public void CognitoPreTokenGenerationV2EventTest(Type serializerType) 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]); - + // Value comparison would vary across different serializers. Skip it for now and validate the complete JSON later. Assert.Equal(5, cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.IdTokenGeneration.ClaimsToAddOrOverride.Count); Assert.Equal("id_claim_1", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.IdTokenGeneration.ClaimsToAddOrOverride.ToArray()[0].Key); @@ -1266,7 +1266,7 @@ public void CognitoPreTokenGenerationV2EventTest(Type serializerType) Assert.Equal("id_claim_3", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.IdTokenGeneration.ClaimsToAddOrOverride.ToArray()[2].Key); Assert.Equal("id_claim_4", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.IdTokenGeneration.ClaimsToAddOrOverride.ToArray()[3].Key); Assert.Equal("id_claim_5", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.IdTokenGeneration.ClaimsToAddOrOverride.ToArray()[4].Key); - + 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]); @@ -1278,7 +1278,7 @@ public void CognitoPreTokenGenerationV2EventTest(Type serializerType) Assert.Equal("access_claim_3", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ClaimsToAddOrOverride.ToArray()[2].Key); Assert.Equal("access_claim_4", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ClaimsToAddOrOverride.ToArray()[3].Key); Assert.Equal("access_claim_5", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ClaimsToAddOrOverride.ToArray()[4].Key); - + 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]); @@ -1288,7 +1288,7 @@ public void CognitoPreTokenGenerationV2EventTest(Type serializerType) 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]); @@ -1309,7 +1309,7 @@ public void CognitoPreTokenGenerationV2EventTest(Type serializerType) 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 @@ -2050,7 +2050,7 @@ public void APIGatewayAuthorizerWithSimpleIAMConditionResponseTest(Type serializ Condition = new Dictionary>() { { "StringEquals", new Dictionary() - { + { { "aws:PrincipalTag/job-category", "iamuser-admin" } } } @@ -2113,16 +2113,16 @@ public void APIGatewayAuthorizerWithMultiValueIAMConditionResponseTest(Type seri Resource = new HashSet{ "*" }, Condition = new Dictionary>() { - { - "StringEquals", + { + "StringEquals", new Dictionary() { { "aws:PrincipalTag/department", new List{ "finance", "hr", "legal" } }, { "aws:PrincipalTag/role", new List{ "audit", "security" } } } }, - { - "ArnLike", + { + "ArnLike", new Dictionary() { { "aws:PrincipalArn", new List{ "arn:aws:iam::XXXXXXXXXXXX:user/User1", "arn:aws:iam::XXXXXXXXXXXX:user/User2" } } @@ -3908,7 +3908,7 @@ public void TestJsonIncludeNullValueSerializer() Assert.Equal(123, serialized["SomeValue"]); Assert.Equal(JTokenType.Null, serialized["SomeOtherValue"].Type); // System.NullReferenceException is thrown if value is missing. } - + [Theory] [InlineData(typeof(JsonSerializer))] #if NETCOREAPP3_1_OR_GREATER @@ -3932,17 +3932,126 @@ public void AppSyncTest(Type serializerType) Assert.Equal("value2", headers["key2"]); Assert.NotNull(appSyncEvent.Info); - Assert.Equal("createTodo", appSyncEvent.Info.FieldName); + Assert.Equal("openSupportTicket", appSyncEvent.Info.FieldName); Assert.Equal("Mutation", appSyncEvent.Info.ParentTypeName); - + Assert.NotNull(appSyncEvent.Info.SelectionSetList); - Assert.Equal(3, appSyncEvent.Info.SelectionSetList.Count); - Assert.Contains("id", appSyncEvent.Info.SelectionSetList); + Assert.Equal(6, appSyncEvent.Info.SelectionSetList.Count); + Assert.Contains("ticketId", appSyncEvent.Info.SelectionSetList); + Assert.Contains("status", appSyncEvent.Info.SelectionSetList); + Assert.Contains("title", appSyncEvent.Info.SelectionSetList); Assert.Contains("description", appSyncEvent.Info.SelectionSetList); - Assert.Contains("completed", appSyncEvent.Info.SelectionSetList); + Assert.Contains("createdAt", appSyncEvent.Info.SelectionSetList); + Assert.Contains("updatedAt", appSyncEvent.Info.SelectionSetList); + + Assert.NotNull(appSyncEvent.Info.SelectionSetGraphQL); + Assert.NotNull(appSyncEvent.Info.Variables); + Assert.NotNull(appSyncEvent.Info.Variables["input"]); + + Assert.NotNull(appSyncEvent.Stash); + Assert.Empty(appSyncEvent.Stash); } } + [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 AppSyncTestCognitoAuthorizer(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-cognito-authorizer.json")) + { + var request = serializer.Deserialize(fileStream); + + Assert.NotNull(request.Identity); + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) + { + var identity = serializer.Deserialize(stream); + Assert.NotNull(identity); + + // Claims + Assert.NotNull(identity.Claims); + Assert.True(identity.Claims.ContainsKey("client_id")); + Assert.True(identity.Claims.ContainsKey("scope")); + Assert.True(identity.Claims.ContainsKey("sub")); + Assert.True(identity.Claims.ContainsKey("token_use")); + + // DefaultAuthStrategy + Assert.NotEmpty(identity.DefaultAuthStrategy); + + // Groups + Assert.NotNull(identity.Groups); + Assert.NotEmpty(identity.Groups); + + // Issuer + Assert.NotEmpty(identity.Issuer); + + // SourceIp + Assert.NotNull(identity.SourceIp); + Assert.NotEmpty(identity.SourceIp); + + // Sub + Assert.NotEmpty(identity.Sub); + + // Username + Assert.NotEmpty(identity.Username); + } + } + } + + [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 AppSyncTestIAMAuthorizer(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-iam-authorizer.json")) + { + var request = serializer.Deserialize(fileStream); + + Assert.NotNull(request.Identity); + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) + { + var identity = serializer.Deserialize(stream); + Assert.NotNull(identity); + + // AccountId + Assert.NotEmpty(identity.AccountId); + + // CognitoIdentityAuthProvider + Assert.NotEmpty(identity.CognitoIdentityAuthProvider); + + // CognitoIdentityAuthType + Assert.NotEmpty(identity.CognitoIdentityAuthType); + + // CognitoIdentityId + Assert.NotEmpty(identity.CognitoIdentityId); + + // CognitoIdentityPoolId + Assert.NotEmpty(identity.CognitoIdentityPoolId); + + // SourceIp + Assert.NotNull(identity.SourceIp); + Assert.NotEmpty(identity.SourceIp); + + // UserArn + Assert.NotEmpty(identity.UserArn); + + // Username + Assert.NotEmpty(identity.Username); + } + } + } + + class ClassUsingPascalCase { public int SomeValue { get; set; } diff --git a/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems b/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems index 47adfd48b..7186ba827 100644 --- a/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems +++ b/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems @@ -12,6 +12,7 @@ + diff --git a/Libraries/test/EventsTests.Shared/appsync-event-cognito-authorizer.json b/Libraries/test/EventsTests.Shared/appsync-event-cognito-authorizer.json new file mode 100644 index 000000000..0c4805d02 --- /dev/null +++ b/Libraries/test/EventsTests.Shared/appsync-event-cognito-authorizer.json @@ -0,0 +1,68 @@ +{ + "arguments": { + "input": { + "title": "Support Ticket Test", + "description": "Support Ticket Test" + } + }, + "identity": { + "claims": { + "sub": "b662d2e4-d0a1-7098-4973-20a5d6ff5a12", + "cognito:groups": [ + "admin" + ], + "iss": "https://cognito-idp.eu-west-2.amazonaws.com/eu-west-2_xxxxxx", + "version": 2, + "client_id": "458vq6091kg88r4qurfnxxxxx", + "origin_jti": "6102131f-89b2-4909-80bc-200ccf675892", + "event_id": "373cdbc2-5460-4dff-bebb-3cba1de69777", + "token_use": "access", + "scope": "aws.cognito.signin.user.admin openid profile email", + "auth_time": 1737358577, + "exp": 1737362177, + "iat": 1737358577, + "jti": "821f10f1-9a6c-46bd-b1d6-62e266d6639b", + "username": "b662d2e4-d0a1-7098-4973-20a5d6ff5a12" + }, + "defaultAuthStrategy": "ALLOW", + "groups": [ + "admin" + ], + "issuer": "https://cognito-idp.eu-west-2.amazonaws.com/eu-west-2_xxxxxx", + "sourceIp": [ + "192.168.234.157" + ], + "sub": "b662d2e4-d0a1-7098-4973-20a5d6ff5a12", + "username": "b662d2e4-d0a1-7098-4973-20a5d6ff5a12" + }, + "source": null, + "request": { + "headers": { + "key1": "value1", + "key2": "value2" + }, + "domainName": null + }, + "prev": null, + "info": { + "fieldName": "openSupportTicket", + "selectionSetList": [ + "ticketId", + "status", + "title", + "description", + "createdAt", + "updatedAt", + "__typename" + ], + "selectionSetGraphQL": "{\n ticketId\n status\n title\n description\n createdAt\n updatedAt\n __typename\n}", + "variables": { + "input": { + "title": "Support Ticket Test", + "description": "Support Ticket Test" + } + }, + "parentTypeName": "Mutation" + }, + "stash": {} +} \ No newline at end of file diff --git a/Libraries/test/EventsTests.Shared/appsync-event-iam-authorizer.json b/Libraries/test/EventsTests.Shared/appsync-event-iam-authorizer.json new file mode 100644 index 000000000..f26e60b7c --- /dev/null +++ b/Libraries/test/EventsTests.Shared/appsync-event-iam-authorizer.json @@ -0,0 +1,48 @@ +{ + "arguments": { + "input": { + "title": "Support Ticket Test", + "description": "Support Ticket Test" + } + }, + "identity": { + "accountId": "123456789012", + "cognitoIdentityPoolId": "us-east-1:1234abcd-1234-5678-abcd-1234567890ab", + "cognitoIdentityId": "us-east-1:1234abcd-1234-5678-abcd-1234567890ab", + "sourceIp": [ "192.0.2.1" ], + "username": "IAMUser", + "userArn": "arn:aws:iam::123456789012:user/IAMUser", + "cognitoIdentityAuthType": "authenticated", + "cognitoIdentityAuthProvider": "cognito-identity.amazonaws.com" + }, + "source": null, + "request": { + "headers": { + "key1": "value1", + "key2": "value2" + }, + "domainName": null + }, + "prev": null, + "info": { + "fieldName": "openSupportTicket", + "selectionSetList": [ + "ticketId", + "status", + "title", + "description", + "createdAt", + "updatedAt", + "__typename" + ], + "selectionSetGraphQL": "{\n ticketId\n status\n title\n description\n createdAt\n updatedAt\n __typename\n}", + "variables": { + "input": { + "title": "Support Ticket Test", + "description": "Support Ticket Test" + } + }, + "parentTypeName": "Mutation" + }, + "stash": {} +} \ No newline at end of file diff --git a/Libraries/test/EventsTests.Shared/appsync-event.json b/Libraries/test/EventsTests.Shared/appsync-event.json index 5540487d5..224f5cb05 100644 --- a/Libraries/test/EventsTests.Shared/appsync-event.json +++ b/Libraries/test/EventsTests.Shared/appsync-event.json @@ -1,61 +1,38 @@ { "arguments": { "input": { - "title": "test title", - "description": "test description" + "title": "Support Ticket Test", + "description": "Support Ticket Test" } }, - "identity": null, - "source": null, - "request": { - "headers": { - "key1": "value1", - "key2": "value2", - "x-forwarded-for": "223.190.85.124, 64.252.163.140", - "cloudfront-viewer-country": "IN", - "cloudfront-is-tablet-viewer": "false", - "x-amzn-requestid": "80abe633-c35f-4eef-911a-45582a0ff63d", - "via": "2.0 ba7cbe9cb489c2d3f36cb36e8ab2d0ba.cloudfront.net (CloudFront)", - "cloudfront-forwarded-proto": "https", - "origin": "https://us-east-1.console.aws.amazon.com", - "content-length": "227", - "x-forwarded-proto": "https", - "accept-language": "en-US,en;q=0.5", - "host": "hbmek2mkajdjxix7recvfrvls4.appsync-api.us-east-1.amazonaws.com", - "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0", - "cloudfront-is-mobile-viewer": "false", - "accept": "application/json, text/plain, */*", - "priority": "u=0", - "cloudfront-viewer-asn": "24560", - "cloudfront-is-smarttv-viewer": "false", - "x-amzn-appsync-is-vpce-request": "false", - "accept-encoding": "gzip, deflate, br, zstd", - "referer": "https://us-east-1.console.aws.amazon.com/", - "x-amzn-remote-ip": "223.190.85.124", - "x-api-key": "da2-2mz5t3o4zvb67iledrusv5fwne", - "content-type": "application/json", - "sec-fetch-mode": "cors", - "x-amzn-trace-id": "Root=1-676188b0-24a54b414e5efff525f844ed", - "x-amz-cf-id": "fWAr7rhMkSOcLcrEqGNU4n7uOpcm-VFHERrnYTO16O1at35i3RyyPw==", - "sec-fetch-dest": "empty", - "x-amz-user-agent": "AWS-Console-AppSync/", - "cloudfront-is-desktop-viewer": "true", - "sec-fetch-site": "cross-site", - "x-forwarded-port": "443" - }, - "domainName": null + "identity": null, + "source": null, + "request": { + "headers": { + "key1": "value1", + "key2": "value2" }, - "prev": null, - "info": { - "fieldName": "createTodo", - "selectionSetList": [ - "id", - "description", - "completed" - ], - "selectionSetGraphQL": "{\n id\n description\n completed\n}", - "variables": {}, - "parentTypeName": "Mutation" + "domainName": null + }, + "prev": null, + "info": { + "fieldName": "openSupportTicket", + "selectionSetList": [ + "ticketId", + "status", + "title", + "description", + "createdAt", + "updatedAt" + ], + "selectionSetGraphQL": "{\n ticketId\n status\n title\n description\n createdAt\n updatedAt\n }", + "variables": { + "input": { + "title": "Support Ticket Test", + "description": "Support Ticket Test" + } }, - "stash": {} + "parentTypeName": "Mutation" + }, + "stash": {} } \ No newline at end of file From f28756241c1d79b2d9af8684e3b5a5b892da4869 Mon Sep 17 00:00:00 2001 From: Ankush Jain Date: Wed, 22 Jan 2025 14:42:21 +0530 Subject: [PATCH 03/27] Updated README --- .../src/Amazon.Lambda.AppSyncEvents/README.md | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md index 3502cccfa..9a25fe7ed 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md @@ -4,15 +4,26 @@ This package contains classes that can be used as input types for Lambda functio # Sample Function -The following is a sample class and Lambda function that receives AppSync event record data as an input and logs some of the incoming event data. (Note that by default anything written to Console will be logged as CloudWatch Logs events.) +The following is a sample class and Lambda function that receives AppSync event record data as an `appSyncEvent` and logs some of the incoming event data. (Note that by default anything written to Console will be logged as CloudWatch Logs events.) ```csharp -public class Function +public void FunctionHandler(AppSyncEvent appSyncEvent, ILambdaContext context) { - public string Handler(AppSyncEvent appSyncEvent) + var input = JsonSerializer.Serialize(appSyncEvent.Arguments); + Console.WriteLine($"AppSync request payload {input}."); + + if (appSyncEvent.Identity != null) { - var input = JsonSerializer.Serialize(appSyncEvent.Arguments); - Console.WriteLine($"AppSync request payload {input}."); + var lambdaSerializer = new DefaultLambdaJsonSerializer(); + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(appSyncEvent.Identity.ToString()!))) + { + // When using AMAZON_COGNITO_USER_POOLS authorization + var cognitoIdentity = lambdaSerializer.Deserialize(stream); + + // When using AWS_IAM authorization + var iamIdentity = lambdaSerializer.Deserialize(stream); + } } } ``` From 1bb2045a098db0cb2918d8b3e385ba49da8daab1 Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Thu, 23 Jan 2025 19:53:01 +0530 Subject: [PATCH 04/27] Update readme --- Libraries/src/Amazon.Lambda.AppSyncEvents/README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md index 9a25fe7ed..c10bff60e 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md @@ -7,13 +7,16 @@ This package contains classes that can be used as input types for Lambda functio The following is a sample class and Lambda function that receives AppSync event record data as an `appSyncEvent` and logs some of the incoming event data. (Note that by default anything written to Console will be logged as CloudWatch Logs events.) ```csharp -public void FunctionHandler(AppSyncEvent appSyncEvent, ILambdaContext context) +public void Handler(AppSyncEvent appSyncEvent, ILambdaContext context) { - var input = JsonSerializer.Serialize(appSyncEvent.Arguments); - Console.WriteLine($"AppSync request payload {input}."); + foreach (var item in appSyncEvent.Arguments) + { + Console.WriteLine($"AppSync request key - {item.Key}."); + } if (appSyncEvent.Identity != null) { + // Create an instance of the serializer var lambdaSerializer = new DefaultLambdaJsonSerializer(); using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(appSyncEvent.Identity.ToString()!))) From 033f1e87a8b1778ac7aa37eefd404308bb3e07f5 Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Thu, 30 Jan 2025 18:46:57 +0530 Subject: [PATCH 05/27] Update Arguments type in event --- Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs | 4 ++-- Libraries/src/Amazon.Lambda.AppSyncEvents/README.md | 2 +- Libraries/test/EventsTests.Shared/EventTests.cs | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs index 80153094d..f86164657 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs @@ -5,12 +5,12 @@ namespace Amazon.Lambda.AppSyncEvents /// /// Represents the event payload received from AWS AppSync. /// - public class AppSyncEvent + public class AppSyncEvent { /// /// Gets or sets the input arguments for the GraphQL operation. /// - public Dictionary Arguments { get; set; } + public TArguments Arguments { get; set; } /// /// An object that contains information about the caller. diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md index c10bff60e..c6c28e9b2 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md @@ -7,7 +7,7 @@ This package contains classes that can be used as input types for Lambda functio The following is a sample class and Lambda function that receives AppSync event record data as an `appSyncEvent` and logs some of the incoming event data. (Note that by default anything written to Console will be logged as CloudWatch Logs events.) ```csharp -public void Handler(AppSyncEvent appSyncEvent, ILambdaContext context) +public void Handler(AppSyncEvent> appSyncEvent, ILambdaContext context) { foreach (var item in appSyncEvent.Arguments) { diff --git a/Libraries/test/EventsTests.Shared/EventTests.cs b/Libraries/test/EventsTests.Shared/EventTests.cs index 5fa06ff58..6b00362c6 100644 --- a/Libraries/test/EventsTests.Shared/EventTests.cs +++ b/Libraries/test/EventsTests.Shared/EventTests.cs @@ -3920,7 +3920,7 @@ public void AppSyncTest(Type serializerType) var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; using (var fileStream = LoadJsonTestFile("appsync-event.json")) { - var appSyncEvent = serializer.Deserialize(fileStream); + var appSyncEvent = serializer.Deserialize>>(fileStream); Assert.NotNull(appSyncEvent); Assert.NotNull(appSyncEvent.Arguments); Assert.NotNull(appSyncEvent.Arguments["input"]); @@ -3964,7 +3964,7 @@ public void AppSyncTestCognitoAuthorizer(Type serializerType) var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; using (var fileStream = LoadJsonTestFile("appsync-event-cognito-authorizer.json")) { - var request = serializer.Deserialize(fileStream); + var request = serializer.Deserialize>>(fileStream); Assert.NotNull(request.Identity); @@ -4014,7 +4014,7 @@ public void AppSyncTestIAMAuthorizer(Type serializerType) var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; using (var fileStream = LoadJsonTestFile("appsync-event-iam-authorizer.json")) { - var request = serializer.Deserialize(fileStream); + var request = serializer.Deserialize>>(fileStream); Assert.NotNull(request.Identity); From 204e17ab213bb3174c44a0a95a6fecf345cd85f4 Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Wed, 5 Feb 2025 18:52:45 +0530 Subject: [PATCH 06/27] Update schema --- ...ppSyncIdentityCognito.cs => AppSyncCognitoIdentity.cs} | 2 +- Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs | 8 ++++---- .../{AppSyncIdentityIAM.cs => AppSyncIamIdentity.cs} | 2 +- Libraries/src/Amazon.Lambda.AppSyncEvents/README.md | 4 ++-- Libraries/test/EventsTests.Shared/EventTests.cs | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) rename Libraries/src/Amazon.Lambda.AppSyncEvents/{AppSyncIdentityCognito.cs => AppSyncCognitoIdentity.cs} (96%) rename Libraries/src/Amazon.Lambda.AppSyncEvents/{AppSyncIdentityIAM.cs => AppSyncIamIdentity.cs} (97%) diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIdentityCognito.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncCognitoIdentity.cs similarity index 96% rename from Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIdentityCognito.cs rename to Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncCognitoIdentity.cs index b02011086..2cb90bc0d 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIdentityCognito.cs +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncCognitoIdentity.cs @@ -5,7 +5,7 @@ namespace Amazon.Lambda.AppSyncEvents /// /// Represents Amazon Cognito User Pools authorization identity for AppSync /// - public class AppSyncIdentityCognito + public class AppSyncCognitoIdentity { /// /// The source IP address of the caller received by AWS AppSync diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs index f86164657..cb8277e0a 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs @@ -15,15 +15,15 @@ public class AppSyncEvent /// /// An object that contains information about the caller. /// Returns null for API_KEY authorization. - /// Returns AppSyncIdentityIAM for AWS_IAM authorization. - /// Returns AppSyncIdentityCognito for AMAZON_COGNITO_USER_POOLS authorization. + /// Returns AppSyncIamIdentity for AWS_IAM authorization. + /// Returns AppSyncCognitoIdentity for AMAZON_COGNITO_USER_POOLS authorization. /// For AWS_LAMBDA authorization, returns the object returned by your Lambda authorizer function. /// /// /// The Identity object type depends on the authorization mode: /// - For API_KEY: null - /// - For AWS_IAM: - /// - For AMAZON_COGNITO_USER_POOLS: + /// - For AWS_IAM: + /// - For AMAZON_COGNITO_USER_POOLS: /// - For AWS_LAMBDA: Dynamic object returned by Lambda authorizer /// public object Identity { get; set; } diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIdentityIAM.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIamIdentity.cs similarity index 97% rename from Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIdentityIAM.cs rename to Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIamIdentity.cs index 962edff9f..e37455bb5 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIdentityIAM.cs +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIamIdentity.cs @@ -5,7 +5,7 @@ namespace Amazon.Lambda.AppSyncEvents /// /// Represents AWS IAM authorization identity for AppSync /// - public class AppSyncIdentityIAM + public class AppSyncIamIdentity { /// /// The source IP address of the caller received by AWS AppSync diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md index c6c28e9b2..10039ce60 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md @@ -22,10 +22,10 @@ public void Handler(AppSyncEvent> appSyncEvent, ILamb using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(appSyncEvent.Identity.ToString()!))) { // When using AMAZON_COGNITO_USER_POOLS authorization - var cognitoIdentity = lambdaSerializer.Deserialize(stream); + var cognitoIdentity = lambdaSerializer.Deserialize(stream); // When using AWS_IAM authorization - var iamIdentity = lambdaSerializer.Deserialize(stream); + var iamIdentity = lambdaSerializer.Deserialize(stream); } } } diff --git a/Libraries/test/EventsTests.Shared/EventTests.cs b/Libraries/test/EventsTests.Shared/EventTests.cs index 6b00362c6..91e285e73 100644 --- a/Libraries/test/EventsTests.Shared/EventTests.cs +++ b/Libraries/test/EventsTests.Shared/EventTests.cs @@ -3970,7 +3970,7 @@ public void AppSyncTestCognitoAuthorizer(Type serializerType) using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) { - var identity = serializer.Deserialize(stream); + var identity = serializer.Deserialize(stream); Assert.NotNull(identity); // Claims @@ -4020,7 +4020,7 @@ public void AppSyncTestIAMAuthorizer(Type serializerType) using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) { - var identity = serializer.Deserialize(stream); + var identity = serializer.Deserialize(stream); Assert.NotNull(identity); // AccountId From 87f899a874a7d16ff308899ca97f2006c4ea95f1 Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Mon, 17 Feb 2025 14:24:31 +0530 Subject: [PATCH 07/27] fix review comment --- .../{AppSyncEvent.cs => AppSyncResolverEvent.cs} | 4 ++-- Libraries/src/Amazon.Lambda.AppSyncEvents/README.md | 10 +++++----- Libraries/test/EventsTests.Shared/EventTests.cs | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) rename Libraries/src/Amazon.Lambda.AppSyncEvents/{AppSyncEvent.cs => AppSyncResolverEvent.cs} (97%) diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncResolverEvent.cs similarity index 97% rename from Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs rename to Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncResolverEvent.cs index cb8277e0a..01ca648fc 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncEvent.cs +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncResolverEvent.cs @@ -5,7 +5,7 @@ namespace Amazon.Lambda.AppSyncEvents /// /// Represents the event payload received from AWS AppSync. /// - public class AppSyncEvent + public class AppSyncResolverEvent { /// /// Gets or sets the input arguments for the GraphQL operation. @@ -66,7 +66,7 @@ public class RequestContext /// /// Gets or sets the domain name associated with the request. /// - public object DomainName { get; set; } + public string DomainName { get; set; } } /// diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md index 10039ce60..d642c002b 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md @@ -4,22 +4,22 @@ This package contains classes that can be used as input types for Lambda functio # Sample Function -The following is a sample class and Lambda function that receives AppSync event record data as an `appSyncEvent` and logs some of the incoming event data. (Note that by default anything written to Console will be logged as CloudWatch Logs events.) +The following is a sample class and Lambda function that receives AppSync event record data as an `appSyncResolverEvent` and logs some of the incoming event data. (Note that by default anything written to Console will be logged as CloudWatch Logs events.) ```csharp -public void Handler(AppSyncEvent> appSyncEvent, ILambdaContext context) +public void Handler(AppSyncResolverEvent> appSyncResolverEvent, ILambdaContext context) { - foreach (var item in appSyncEvent.Arguments) + foreach (var item in appSyncResolverEvent.Arguments) { Console.WriteLine($"AppSync request key - {item.Key}."); } - if (appSyncEvent.Identity != null) + if (appSyncResolverEvent.Identity != null) { // Create an instance of the serializer var lambdaSerializer = new DefaultLambdaJsonSerializer(); - using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(appSyncEvent.Identity.ToString()!))) + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(appSyncResolverEvent.Identity.ToString()!))) { // When using AMAZON_COGNITO_USER_POOLS authorization var cognitoIdentity = lambdaSerializer.Deserialize(stream); diff --git a/Libraries/test/EventsTests.Shared/EventTests.cs b/Libraries/test/EventsTests.Shared/EventTests.cs index 91e285e73..4a7ac56a7 100644 --- a/Libraries/test/EventsTests.Shared/EventTests.cs +++ b/Libraries/test/EventsTests.Shared/EventTests.cs @@ -3920,7 +3920,7 @@ public void AppSyncTest(Type serializerType) var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; using (var fileStream = LoadJsonTestFile("appsync-event.json")) { - var appSyncEvent = serializer.Deserialize>>(fileStream); + var appSyncEvent = serializer.Deserialize>>(fileStream); Assert.NotNull(appSyncEvent); Assert.NotNull(appSyncEvent.Arguments); Assert.NotNull(appSyncEvent.Arguments["input"]); @@ -3964,7 +3964,7 @@ public void AppSyncTestCognitoAuthorizer(Type serializerType) var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; using (var fileStream = LoadJsonTestFile("appsync-event-cognito-authorizer.json")) { - var request = serializer.Deserialize>>(fileStream); + var request = serializer.Deserialize>>(fileStream); Assert.NotNull(request.Identity); @@ -4014,7 +4014,7 @@ public void AppSyncTestIAMAuthorizer(Type serializerType) var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; using (var fileStream = LoadJsonTestFile("appsync-event-iam-authorizer.json")) { - var request = serializer.Deserialize>>(fileStream); + var request = serializer.Deserialize>>(fileStream); Assert.NotNull(request.Identity); From 8ebea503851f2a581ae80c00d925c89b29ae16cc Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Fri, 7 Mar 2025 18:05:47 +0530 Subject: [PATCH 08/27] Added Lambda and oidc auth type --- .../AppSyncLambdaIdentity.cs | 16 +++++ .../AppSyncOidcIdentity.cs | 25 ++++++++ .../src/Amazon.Lambda.AppSyncEvents/README.md | 6 ++ .../test/EventsTests.Shared/EventTests.cs | 58 +++++++++++++++++++ .../EventsTests.Shared.projitems | 2 + .../appsync-event-lambda-authorizer.json | 45 ++++++++++++++ .../appsync-event-oidc-authorizer.json | 51 ++++++++++++++++ 7 files changed, 203 insertions(+) create mode 100644 Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncLambdaIdentity.cs create mode 100644 Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncOidcIdentity.cs create mode 100644 Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer.json create mode 100644 Libraries/test/EventsTests.Shared/appsync-event-oidc-authorizer.json diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncLambdaIdentity.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncLambdaIdentity.cs new file mode 100644 index 000000000..844650355 --- /dev/null +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncLambdaIdentity.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace Amazon.Lambda.AppSyncEvents +{ + /// + /// Represents AWS LAMBDA authorization identity for AppSync + /// + public class AppSyncLambdaIdentity + { + /// + /// Optional context information that will be passed to subsequent resolvers + /// Can contain user information, claims, or any other contextual data + /// + public Dictionary ResolverContext { get; set; } + } +} \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncOidcIdentity.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncOidcIdentity.cs new file mode 100644 index 000000000..dd489acc9 --- /dev/null +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncOidcIdentity.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; + +namespace Amazon.Lambda.AppSyncEvents +{ + /// + /// Represents OPENID CONNECT authorization identity for AppSync + /// + public class AppSyncOidcIdentity + { + /// + /// Claims from the OIDC token as key-value pairs + /// + public Dictionary Claims { get; set; } + + /// + /// The issuer of the OIDC token + /// + public string Issuer { get; set; } + + /// + /// The UUID of the authenticated user + /// + public string Sub { get; set; } + } +} \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md index d642c002b..fd28ec564 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md @@ -26,6 +26,12 @@ public void Handler(AppSyncResolverEvent> appSyncReso // When using AWS_IAM authorization var iamIdentity = lambdaSerializer.Deserialize(stream); + + // When using AWS_LAMBDA authorization + var lambdaIdentity = lambdaSerializer.Deserialize(stream); + + // When using OPENID_CONNECT authorization + var oidcIdentity = lambdaSerializer.Deserialize(stream); } } } diff --git a/Libraries/test/EventsTests.Shared/EventTests.cs b/Libraries/test/EventsTests.Shared/EventTests.cs index 4a7ac56a7..99f65f11c 100644 --- a/Libraries/test/EventsTests.Shared/EventTests.cs +++ b/Libraries/test/EventsTests.Shared/EventTests.cs @@ -4051,6 +4051,64 @@ public void AppSyncTestIAMAuthorizer(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 AppSyncTestLambdaAuthorizer(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-lambda-authorizer.json")) + { + var request = serializer.Deserialize>>(fileStream); + + Assert.NotNull(request.Identity); + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) + { + var identity = serializer.Deserialize(stream); + Assert.NotNull(identity); + + // ResolverContext + Assert.NotNull(identity.ResolverContext); + } + } + } + + [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 AppSyncTestOidcAuthorizer(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-oidc-authorizer.json")) + { + var request = serializer.Deserialize>>(fileStream); + + Assert.NotNull(request.Identity); + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) + { + var identity = serializer.Deserialize(stream); + Assert.NotNull(identity); + + // Claims + Assert.NotNull(identity.Claims); + Assert.True(identity.Claims.ContainsKey("client_id")); + + // Issuer + Assert.NotEmpty(identity.Issuer); + + // Sub + Assert.NotEmpty(identity.Sub); + } + } + } class ClassUsingPascalCase { diff --git a/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems b/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems index 7186ba827..a7dc07656 100644 --- a/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems +++ b/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems @@ -12,6 +12,8 @@ + + diff --git a/Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer.json b/Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer.json new file mode 100644 index 000000000..d6fcf6a0c --- /dev/null +++ b/Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer.json @@ -0,0 +1,45 @@ +{ + "arguments": { + "input": { + "title": "Support Ticket Test", + "description": "Support Ticket Test" + } + }, + "identity": { + "resolverContext": { + "userid": "test-user-id", + "info": "contextual information A", + "more_info": "contextual information B" + } + }, + "source": null, + "request": { + "headers": { + "key1": "value1", + "key2": "value2" + }, + "domainName": null + }, + "prev": null, + "info": { + "fieldName": "openSupportTicket", + "selectionSetList": [ + "ticketId", + "status", + "title", + "description", + "createdAt", + "updatedAt", + "__typename" + ], + "selectionSetGraphQL": "{\n ticketId\n status\n title\n description\n createdAt\n updatedAt\n __typename\n}", + "variables": { + "input": { + "title": "Support Ticket Test", + "description": "Support Ticket Test" + } + }, + "parentTypeName": "Mutation" + }, + "stash": {} +} \ No newline at end of file diff --git a/Libraries/test/EventsTests.Shared/appsync-event-oidc-authorizer.json b/Libraries/test/EventsTests.Shared/appsync-event-oidc-authorizer.json new file mode 100644 index 000000000..c4d50868e --- /dev/null +++ b/Libraries/test/EventsTests.Shared/appsync-event-oidc-authorizer.json @@ -0,0 +1,51 @@ +{ + "arguments": { + "input": { + "title": "Support Ticket Test", + "description": "Support Ticket Test" + } + }, + "identity": { + "claims": { + "client_id": "458vq6091kg88r4qurfnxxxxx", + "event_id": "373cdbc2-5460-4dff-bebb-3cba1de69777", + "username": "b662d2e4-d0a1-7098-4973-20a5d6ff5a12" + }, + "defaultAuthStrategy": "ALLOW", + "groups": [ + "admin" + ], + "issuer": "https://cognito-idp.eu-west-2.amazonaws.com/eu-west-2_xxxxxx", + "sub": "b662d2e4-d0a1-7098-4973-20a5d6ff5a12" + }, + "source": null, + "request": { + "headers": { + "key1": "value1", + "key2": "value2" + }, + "domainName": null + }, + "prev": null, + "info": { + "fieldName": "openSupportTicket", + "selectionSetList": [ + "ticketId", + "status", + "title", + "description", + "createdAt", + "updatedAt", + "__typename" + ], + "selectionSetGraphQL": "{\n ticketId\n status\n title\n description\n createdAt\n updatedAt\n __typename\n}", + "variables": { + "input": { + "title": "Support Ticket Test", + "description": "Support Ticket Test" + } + }, + "parentTypeName": "Mutation" + }, + "stash": {} +} \ No newline at end of file From 24aafb03c34598cebf991d71a766f5c4232115f4 Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Fri, 7 Mar 2025 18:13:21 +0530 Subject: [PATCH 09/27] Update readme --- Libraries/src/Amazon.Lambda.AppSyncEvents/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md index fd28ec564..3e84a3237 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md @@ -4,7 +4,7 @@ This package contains classes that can be used as input types for Lambda functio # Sample Function -The following is a sample class and Lambda function that receives AppSync event record data as an `appSyncResolverEvent` and logs some of the incoming event data. (Note that by default anything written to Console will be logged as CloudWatch Logs events.) +The following is a sample class and Lambda function that receives AppSync resolver event record data as an `appSyncResolverEvent` and logs some of the incoming event data. (Note that by default anything written to Console will be logged as CloudWatch Logs events.) ```csharp public void Handler(AppSyncResolverEvent> appSyncResolverEvent, ILambdaContext context) From 634f4a486c6729cf6988760f22d8d8a04be8021a Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Fri, 7 Mar 2025 19:15:24 +0530 Subject: [PATCH 10/27] Added changefile --- .autover/autover.json | 4 ++++ .../changes/b188d010-090a-4ead-b9cf-8f82d7c236ed.json | 11 +++++++++++ README.md | 1 + 3 files changed, 16 insertions(+) create mode 100644 .autover/changes/b188d010-090a-4ead-b9cf-8f82d7c236ed.json diff --git a/.autover/autover.json b/.autover/autover.json index a5257a79d..5d48abad7 100644 --- a/.autover/autover.json +++ b/.autover/autover.json @@ -135,6 +135,10 @@ { "Name": "SnapshotRestore.Registry", "Path": "Libraries/src/SnapshotRestore.Registry/SnapshotRestore.Registry.csproj" + }, + { + "Name": "Amazon.Lambda.AppSyncEvents", + "Path": "Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj" } ], "UseCommitsForChangelog": false, diff --git a/.autover/changes/b188d010-090a-4ead-b9cf-8f82d7c236ed.json b/.autover/changes/b188d010-090a-4ead-b9cf-8f82d7c236ed.json new file mode 100644 index 000000000..bb7d99698 --- /dev/null +++ b/.autover/changes/b188d010-090a-4ead-b9cf-8f82d7c236ed.json @@ -0,0 +1,11 @@ +{ + "Projects": [ + { + "Name": "Amazon.Lambda.AppSyncEvents", + "Type": "Patch", + "ChangelogMessages": [ + "Added AppSyncResolverEvent to support direct lambda resolver" + ] + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index f5ce22798..37871d167 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ These are the packages and their README.md files: * [Amazon.Lambda.SNSEvents](Libraries/src/Amazon.Lambda.SNSEvents) - [README.md](Libraries/src/Amazon.Lambda.SNSEvents/README.md) * [Amazon.Lambda.SQSEvents](Libraries/src/Amazon.Lambda.SQSEvents) - [README.md](Libraries/src/Amazon.Lambda.SQSEvents/README.md) * [Amazon.Lambda.KafkaEvents](Libraries/src/Amazon.Lambda.KafkaEvents) - [README.md](Libraries/src/Amazon.Lambda.KafkaEvents/README.md) +* [Amazon.Lambda.AppSyncEvents](Libraries/src/Amazon.Lambda.AppSyncEvents) - [README.md](Libraries/src/Amazon.Lambda.AppSyncEvents/README.md) ### Amazon.Lambda.Tools From 0ad9cd6d20fdcbb60e6b728cb549216a70f123b5 Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Tue, 11 Mar 2025 12:56:40 +0530 Subject: [PATCH 11/27] Added AuthorizerEvent and Result --- .../Amazon.Lambda.AppSyncEvents.csproj | 2 +- .../AppSyncAuthorizerEvent.cs | 40 +++++++++++++++++++ .../AppSyncAuthorizerResult.cs | 16 ++++++++ .../AppSyncLambdaIdentity.cs | 6 +-- .../AppSyncResolverEvent.cs | 7 ++-- 5 files changed, 64 insertions(+), 7 deletions(-) create mode 100644 Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerEvent.cs create mode 100644 Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerResult.cs diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj index 54553244b..76bd7291f 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj @@ -6,7 +6,7 @@ Amazon Lambda .NET Core support - AWS AppSync package. netstandard2.0;netcoreapp3.1;net8.0 Amazon.Lambda.AppSyncEvents - 1.0.0 + 0.0.1 Amazon.Lambda.AppSyncEvents Amazon.Lambda.AppSyncEvents AWS;Amazon;Lambda diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerEvent.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerEvent.cs new file mode 100644 index 000000000..3ed017c1f --- /dev/null +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerEvent.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; + +namespace Amazon.Lambda.AppSyncEvents +{ + // Represents an AppSync authorization event + public class AppSyncAuthorizerEvent + { + // The authorization token from the request + public string AuthorizationToken { get; set; } + + // Headers from the request + public Dictionary RequestHeaders { get; set; } + + // Context information about the request + public RequestContext RequestContext { get; set; } + } + + // Request context for AppSync authorization + + public class RequestContext + { + // The ID of the AppSync API + public string ApiId { get; set; } + + // The AWS account ID + public string AccountId { get; set; } + + // Unique identifier for the request + public string RequestId { get; set; } + + // The GraphQL query string + public string QueryString { get; set; } + + // Name of the GraphQL operation + public string OperationName { get; set; } + + /// Variables passed to the GraphQL operation. + public Dictionary Variables { get; set; } + } +} diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerResult.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerResult.cs new file mode 100644 index 000000000..b2cce7e4c --- /dev/null +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerResult.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace Amazon.Lambda.AppSyncEvents +{ + public class AppSyncAuthorizerResult + { + // Indicates if the request is authorized + public bool IsAuthorized { get; set; } + // Custom context to pass to resolvers, only supports key-value pairs. + public Dictionary ResolverContext { get; set; } + // List of fields that are denied access + public IEnumerable DeniedFields { get; set; } + // The number of seconds that the response should be cached for + public int? TtlOverride { get; set; } + } +} diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncLambdaIdentity.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncLambdaIdentity.cs index 844650355..66770933f 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncLambdaIdentity.cs +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncLambdaIdentity.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace Amazon.Lambda.AppSyncEvents { @@ -11,6 +11,6 @@ public class AppSyncLambdaIdentity /// Optional context information that will be passed to subsequent resolvers /// Can contain user information, claims, or any other contextual data /// - public Dictionary ResolverContext { get; set; } + public Dictionary ResolverContext { get; set; } } -} \ No newline at end of file +} diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncResolverEvent.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncResolverEvent.cs index 01ca648fc..d357f0411 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncResolverEvent.cs +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncResolverEvent.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace Amazon.Lambda.AppSyncEvents { @@ -24,7 +24,8 @@ public class AppSyncResolverEvent /// - For API_KEY: null /// - For AWS_IAM: /// - For AMAZON_COGNITO_USER_POOLS: - /// - For AWS_LAMBDA: Dynamic object returned by Lambda authorizer + /// - For AWS_LAMBDA: + /// - For OPENID_CONNECT: /// public object Identity { get; set; } @@ -100,4 +101,4 @@ public class Information public string ParentTypeName { get; set; } } } -} \ No newline at end of file +} From f2af59d70cabedf50bb7c39b577a291642087b75 Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Wed, 12 Mar 2025 10:37:03 +0530 Subject: [PATCH 12/27] update changefile and readme --- ...2d7c236ed.json => 78ee1265-f50d-434a-b25c-fcb8e9e7a26a.json} | 2 +- CONTRIBUTING.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) rename .autover/changes/{b188d010-090a-4ead-b9cf-8f82d7c236ed.json => 78ee1265-f50d-434a-b25c-fcb8e9e7a26a.json} (89%) diff --git a/.autover/changes/b188d010-090a-4ead-b9cf-8f82d7c236ed.json b/.autover/changes/78ee1265-f50d-434a-b25c-fcb8e9e7a26a.json similarity index 89% rename from .autover/changes/b188d010-090a-4ead-b9cf-8f82d7c236ed.json rename to .autover/changes/78ee1265-f50d-434a-b25c-fcb8e9e7a26a.json index bb7d99698..320fd3ada 100644 --- a/.autover/changes/b188d010-090a-4ead-b9cf-8f82d7c236ed.json +++ b/.autover/changes/78ee1265-f50d-434a-b25c-fcb8e9e7a26a.json @@ -2,7 +2,7 @@ "Projects": [ { "Name": "Amazon.Lambda.AppSyncEvents", - "Type": "Patch", + "Type": "Major", "ChangelogMessages": [ "Added AppSyncResolverEvent to support direct lambda resolver" ] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5492e1dfb..dbd28736e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -104,6 +104,7 @@ The available projects are: * Amazon.Lambda.SQSEvents * Amazon.Lambda.TestUtilities * Amazon.Lambda.TestTool.BlazorTester +* Amazon.Lambda.AppSyncEvents The possible increment types are: * Patch From 247a2be8bea8ba0f779733d3c6c02686bfb4ff4b Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Wed, 12 Mar 2025 15:40:50 +0530 Subject: [PATCH 13/27] Update JsonProperty attribute --- .../Amazon.Lambda.AppSyncEvents.csproj | 27 +++++++++++++----- .../AppSyncAuthorizerResult.cs | 28 +++++++++++++++++++ 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj index 76bd7291f..0a6fcb507 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj @@ -4,17 +4,30 @@ Amazon Lambda .NET Core support - AWS AppSync package. - netstandard2.0;netcoreapp3.1;net8.0 + netstandard2.0;netcoreapp3.1;net8.0 Amazon.Lambda.AppSyncEvents 0.0.1 Amazon.Lambda.AppSyncEvents Amazon.Lambda.AppSyncEvents - AWS;Amazon;Lambda + AWS;Amazon;Lambda - - IL2026,IL2067,IL2075 - true + + + NETSTANDARD_2_0 + IL2026,IL2067,IL2075 + true true - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerResult.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerResult.cs index b2cce7e4c..fd46e3d9d 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerResult.cs +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerResult.cs @@ -1,16 +1,44 @@ using System.Collections.Generic; +#if NETSTANDARD_2_0 +using Newtonsoft.Json; +#else +using System.Text.Json.Serialization; +#endif namespace Amazon.Lambda.AppSyncEvents { public class AppSyncAuthorizerResult { // Indicates if the request is authorized +#if NETSTANDARD_2_0 + [JsonProperty("isAuthorized")] +#else + [JsonPropertyName("isAuthorized")] +#endif public bool IsAuthorized { get; set; } + // Custom context to pass to resolvers, only supports key-value pairs. +#if NETSTANDARD_2_0 + [JsonProperty("resolverContext")] +#else + [JsonPropertyName("resolverContext")] +#endif public Dictionary ResolverContext { get; set; } + // List of fields that are denied access +#if NETSTANDARD_2_0 + [JsonProperty("deniedFields")] +#else + [JsonPropertyName("deniedFields")] +#endif public IEnumerable DeniedFields { get; set; } + // The number of seconds that the response should be cached for +#if NETSTANDARD_2_0 + [JsonProperty("ttlOverride")] +#else + [JsonPropertyName("ttlOverride")] +#endif public int? TtlOverride { get; set; } } } From 4356b85de1bfe49ac5a1a6a1a066f6ec3afc67e9 Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Wed, 12 Mar 2025 15:48:53 +0530 Subject: [PATCH 14/27] Test case updated --- Libraries/test/EventsTests.Shared/EventTests.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Libraries/test/EventsTests.Shared/EventTests.cs b/Libraries/test/EventsTests.Shared/EventTests.cs index 99f65f11c..59fc0fc9a 100644 --- a/Libraries/test/EventsTests.Shared/EventTests.cs +++ b/Libraries/test/EventsTests.Shared/EventTests.cs @@ -4073,6 +4073,9 @@ public void AppSyncTestLambdaAuthorizer(Type serializerType) // ResolverContext Assert.NotNull(identity.ResolverContext); + Assert.NotEmpty(identity.ResolverContext["userid"]); + Assert.NotEmpty(identity.ResolverContext["info"]); + Assert.NotEmpty(identity.ResolverContext["more_info"]); } } } @@ -4117,4 +4120,4 @@ class ClassUsingPascalCase } } } -#pragma warning restore 618 \ No newline at end of file +#pragma warning restore 618 From 9b8f7aec184c7671d937a139314d4992d6410a53 Mon Sep 17 00:00:00 2001 From: Ankush Jain Date: Sun, 23 Mar 2025 13:55:42 +0530 Subject: [PATCH 15/27] Added new tests, updated readme and incorporated review comments --- .../Amazon.Lambda.AppSyncEvents.csproj | 23 ++----- .../AppSyncAuthorizerEvent.cs | 53 ++++++++++---- .../AppSyncAuthorizerResult.cs | 69 ++++++++++--------- .../src/Amazon.Lambda.AppSyncEvents/README.md | 35 +++++++++- .../test/EventsTests.Shared/EventTests.cs | 67 ++++++++++++++++++ ...psync-event-lambda-authorizer-request.json | 35 ++++++++++ ...sync-event-lambda-authorizer-response.json | 13 ++++ 7 files changed, 231 insertions(+), 64 deletions(-) create mode 100644 Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer-request.json create mode 100644 Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer-response.json diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj index 0a6fcb507..0507bb52a 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj @@ -12,22 +12,9 @@ AWS;Amazon;Lambda - - - NETSTANDARD_2_0 - IL2026,IL2067,IL2075 - true + + IL2026,IL2067,IL2075 + true true - - - - - - - - - - - - - \ No newline at end of file + + diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerEvent.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerEvent.cs index 3ed017c1f..cbfa5d3b0 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerEvent.cs +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerEvent.cs @@ -1,40 +1,67 @@ using System.Collections.Generic; - namespace Amazon.Lambda.AppSyncEvents { - // Represents an AppSync authorization event + /// + /// Represents an AWS AppSync authorization event that is sent to a Lambda authorizer + /// for evaluating access permissions to the GraphQL API. + /// public class AppSyncAuthorizerEvent { - // The authorization token from the request + /// + /// Gets or sets the authorization token received from the client request. + /// This token is used to make authorization decisions. + /// public string AuthorizationToken { get; set; } - // Headers from the request + /// + /// Gets or sets the headers from the client request. + /// Contains key-value pairs of HTTP header names and their values. + /// public Dictionary RequestHeaders { get; set; } - // Context information about the request + /// + /// Gets or sets the context information about the AppSync request. + /// Contains metadata about the API and the GraphQL operation being executed. + /// public RequestContext RequestContext { get; set; } } - // Request context for AppSync authorization - + /// + /// Contains contextual information about the AppSync request being authorized. + /// This class provides details about the API, account, and GraphQL operation. + /// public class RequestContext { - // The ID of the AppSync API + /// + /// Gets or sets the unique identifier of the AppSync API. + /// public string ApiId { get; set; } - // The AWS account ID + /// + /// Gets or sets the AWS account ID where the AppSync API is deployed. + /// public string AccountId { get; set; } - // Unique identifier for the request + /// + /// Gets or sets the unique identifier for this specific request. + /// public string RequestId { get; set; } - // The GraphQL query string + /// + /// Gets or sets the GraphQL query string containing the operation to be executed. + /// public string QueryString { get; set; } - // Name of the GraphQL operation + /// + /// Gets or sets the name of the GraphQL operation to be executed. + /// This corresponds to the operation name in the GraphQL query. + /// public string OperationName { get; set; } - /// Variables passed to the GraphQL operation. + /// + /// Gets or sets the variables passed to the GraphQL operation. + /// Contains key-value pairs of variable names and their values. + /// public Dictionary Variables { get; set; } } } diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerResult.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerResult.cs index fd46e3d9d..89d9243c8 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerResult.cs +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerResult.cs @@ -1,44 +1,49 @@ using System.Collections.Generic; -#if NETSTANDARD_2_0 -using Newtonsoft.Json; -#else -using System.Text.Json.Serialization; -#endif +using System.Runtime.Serialization; + namespace Amazon.Lambda.AppSyncEvents { - public class AppSyncAuthorizerResult - { - // Indicates if the request is authorized -#if NETSTANDARD_2_0 - [JsonProperty("isAuthorized")] -#else - [JsonPropertyName("isAuthorized")] + /// + /// Represents the result returned by an AWS AppSync Lambda authorizer. + /// + [DataContract] + public class AppSyncAuthorizerResult + { + /// + /// Indicates if the request is authorized + /// + [DataMember(Name = "isAuthorized")] +#if NETCOREAPP3_1_OR_GREATER + [System.Text.Json.Serialization.JsonPropertyName("isAuthorized")] #endif - public bool IsAuthorized { get; set; } + public bool IsAuthorized { get; set; } - // Custom context to pass to resolvers, only supports key-value pairs. -#if NETSTANDARD_2_0 - [JsonProperty("resolverContext")] -#else - [JsonPropertyName("resolverContext")] + /// + /// Custom context to pass to resolvers, only supports key-value pairs. + /// + [DataMember(Name = "resolverContext")] +#if NETCOREAPP3_1_OR_GREATER + [System.Text.Json.Serialization.JsonPropertyName("resolverContext")] #endif - public Dictionary ResolverContext { get; set; } + public Dictionary ResolverContext { get; set; } - // List of fields that are denied access -#if NETSTANDARD_2_0 - [JsonProperty("deniedFields")] -#else - [JsonPropertyName("deniedFields")] + /// + /// List of fields that are denied access + /// + [DataMember(Name = "deniedFields")] +#if NETCOREAPP3_1_OR_GREATER + [System.Text.Json.Serialization.JsonPropertyName("deniedFields")] #endif - public IEnumerable DeniedFields { get; set; } + public IEnumerable DeniedFields { get; set; } - // The number of seconds that the response should be cached for -#if NETSTANDARD_2_0 - [JsonProperty("ttlOverride")] -#else - [JsonPropertyName("ttlOverride")] + /// + /// The number of seconds that the response should be cached for + /// + [DataMember(Name = "ttlOverride")] +#if NETCOREAPP3_1_OR_GREATER + [System.Text.Json.Serialization.JsonPropertyName("ttlOverride")] #endif - public int? TtlOverride { get; set; } - } + public int? TtlOverride { get; set; } + } } diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md index 3e84a3237..0c88a31c0 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md @@ -2,7 +2,7 @@ This package contains classes that can be used as input types for Lambda functions that process AppSync events. -# Sample Function +## Sample Function The following is a sample class and Lambda function that receives AppSync resolver event record data as an `appSyncResolverEvent` and logs some of the incoming event data. (Note that by default anything written to Console will be logged as CloudWatch Logs events.) @@ -36,3 +36,36 @@ public void Handler(AppSyncResolverEvent> appSyncReso } } ``` + +## Example of Custom Lambda Authorizer +This example demonstrates how to implement a custom Lambda authorizer for AppSync using the AppSync Events package. The authorizer function receives an `AppSyncAuthorizerEvent` containing the authorization token and request context. It returns an `AppSyncAuthorizerResult` that determines whether the request is authorized and includes additional context. + +The function also provides some data in the `resolverContext` object. This information is available in the AppSync resolver’s context `identity` object. + +``` +public async Task CustomLambdaAuthorizerHandler(AppSyncAuthorizerEvent appSyncAuthorizerEvent) +{ + var authorizationToken = appSyncAuthorizerEvent.AuthorizationToken; + var apiId = appSyncAuthorizerEvent.RequestContext.ApiId; + var accountId = appSyncAuthorizerEvent.RequestContext.AccountId; + + var response = new AppSyncAuthorizerResult + { + IsAuthorized = authorizationToken == "custom-authorized", + ResolverContext = new Dictionary + { + { "userid", "test-user-id" }, + { "info", "contextual information A" }, + { "more_info", "contextual information B" } + }, + DeniedFields = new List + { + $"arn:aws:appsync:{Environment.GetEnvironmentVariable("AWS_REGION")}:{accountId}:apis/{apiId}/types/Event/fields/comments", + "Mutation.createEvent" + }, + TtlOverride = 10 + }; + + return response; +} +``` \ No newline at end of file diff --git a/Libraries/test/EventsTests.Shared/EventTests.cs b/Libraries/test/EventsTests.Shared/EventTests.cs index 59fc0fc9a..ed35964ef 100644 --- a/Libraries/test/EventsTests.Shared/EventTests.cs +++ b/Libraries/test/EventsTests.Shared/EventTests.cs @@ -4113,6 +4113,73 @@ public void AppSyncTestOidcAuthorizer(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 AppSyncTestLambdaAuthorizerRequestEvent(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-lambda-authorizer-request.json")) + { + var request = serializer.Deserialize(fileStream); + + // Assert Authorization Token + Assert.Equal("custom-token", request.AuthorizationToken); + + // Assert Request Context + Assert.NotNull(request.RequestContext); + Assert.Equal("xxxxxxxx", request.RequestContext.ApiId); + Assert.Equal("112233445566", request.RequestContext.AccountId); + Assert.Equal("36307622-97fe-4dfa-bd71-b15b1d03ce97", request.RequestContext.RequestId); + Assert.Equal("MyQuery", request.RequestContext.OperationName); + Assert.NotNull(request.RequestContext.Variables); + Assert.Empty(request.RequestContext.Variables); + Assert.Contains("listTodos", request.RequestContext.QueryString); + + // Assert Request Headers + Assert.NotNull(request.RequestHeaders); + Assert.Equal("This is test token", request.RequestHeaders["authorization"]); + Assert.Equal("application/json", request.RequestHeaders["content-type"]); + Assert.Equal("https://ap-south-1.console.aws.amazon.com", request.RequestHeaders["origin"]); + } + } + + [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 AppSyncTestLambdaAuthorizerResponseEvent(Type serializerType) + { + var response = new AppSyncAuthorizerResult + { + IsAuthorized = true, + ResolverContext = new Dictionary + { + { "userid", "test-user-id" }, + { "info", "contextual information A" }, + { "more_info", "contextual information B" } + }, + DeniedFields = new List + { + "arn:aws:appsync:us-east-1:1234567890:apis/xxxxxx/types/Event/fields/comments", + "Mutation.createEvent" + }, + TtlOverride = 10 + }; + + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + var json = SerializeJson(serializer, response); + var actualObject = JObject.Parse(json); + var expectedJObject = JObject.Parse(File.ReadAllText("appsync-event-lambda-authorizer-response.json")); + + Assert.True(JToken.DeepEquals(actualObject, expectedJObject)); + } + class ClassUsingPascalCase { public int SomeValue { get; set; } diff --git a/Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer-request.json b/Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer-request.json new file mode 100644 index 000000000..47648175f --- /dev/null +++ b/Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer-request.json @@ -0,0 +1,35 @@ +{ + "authorizationToken": "custom-token", + "requestContext": { + "apiId": "xxxxxxxx", + "accountId": "112233445566", + "requestId": "36307622-97fe-4dfa-bd71-b15b1d03ce97", + "queryString": "query MyQuery {\n listTodos {\n completed\n createdAt\n description\n id\n title\n updatedAt\n }\n}\n", + "operationName": "MyQuery", + "variables": {} + }, + "requestHeaders": { + "x-forwarded-for": "182.70.233.9, 15.158.25.215", + "accept-encoding": "gzip, deflate, br, zstd", + "sec-ch-ua-mobile": "?0", + "referer": "https://ap-south-1.console.aws.amazon.com/", + "via": "2.0 30c122bd8d8efabc1fd1b3b11bfb53ea.cloudfront.net (CloudFront)", + "content-type": "application/json", + "origin": "https://ap-south-1.console.aws.amazon.com", + "sec-fetch-mode": "cors", + "authorization": "This is test token", + "sec-fetch-dest": "empty", + "content-length": "159", + "x-amz-user-agent": "AWS-Console-AppSync/", + "sec-ch-ua-platform": "\"macOS\"", + "x-forwarded-proto": "https", + "accept-language": "en-US,en;q=0.9", + "host": "cndjdbaxrfhzppcdhvfvx3a7zq.appsync-api.ap-south-1.amazonaws.com", + "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36", + "sec-fetch-site": "cross-site", + "accept": "application/json, text/plain, */*", + "priority": "u=1, i", + "sec-ch-ua": "\"Chromium\";v=\"134\", \"Not:A-Brand\";v=\"24\", \"Google Chrome\";v=\"134\"", + "x-forwarded-port": "443" + } + } \ No newline at end of file diff --git a/Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer-response.json b/Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer-response.json new file mode 100644 index 000000000..6f406ad5f --- /dev/null +++ b/Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer-response.json @@ -0,0 +1,13 @@ +{ + "isAuthorized": true, + "resolverContext": { + "userid": "test-user-id", + "info": "contextual information A", + "more_info": "contextual information B" + }, + "deniedFields": [ + "arn:aws:appsync:us-east-1:1234567890:apis/xxxxxx/types/Event/fields/comments", + "Mutation.createEvent" + ], + "ttlOverride": 10 + } \ No newline at end of file From f94d5883780fd0a47c81b8bedf10fa583571d5d7 Mon Sep 17 00:00:00 2001 From: Ankush Jain Date: Sun, 23 Mar 2025 14:30:00 +0530 Subject: [PATCH 16/27] Updated README --- Libraries/src/Amazon.Lambda.AppSyncEvents/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md index 0c88a31c0..bd61ebbd0 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md @@ -42,7 +42,7 @@ This example demonstrates how to implement a custom Lambda authorizer for AppSyn The function also provides some data in the `resolverContext` object. This information is available in the AppSync resolver’s context `identity` object. -``` +```csharp public async Task CustomLambdaAuthorizerHandler(AppSyncAuthorizerEvent appSyncAuthorizerEvent) { var authorizationToken = appSyncAuthorizerEvent.AuthorizationToken; From 51807353ef3cbd1a4d23f27b1b90e602c9cbe89a Mon Sep 17 00:00:00 2001 From: Ankush Jain Date: Tue, 25 Mar 2025 01:32:44 +0530 Subject: [PATCH 17/27] Updated README --- Libraries/src/Amazon.Lambda.AppSyncEvents/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md index bd61ebbd0..c883e32cd 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md @@ -40,7 +40,8 @@ public void Handler(AppSyncResolverEvent> appSyncReso ## Example of Custom Lambda Authorizer This example demonstrates how to implement a custom Lambda authorizer for AppSync using the AppSync Events package. The authorizer function receives an `AppSyncAuthorizerEvent` containing the authorization token and request context. It returns an `AppSyncAuthorizerResult` that determines whether the request is authorized and includes additional context. -The function also provides some data in the `resolverContext` object. This information is available in the AppSync resolver’s context `identity` object. +The function provides contextual data through the `ResolverContext` property of the `AppSyncAuthorizerResult` instance. This information can be accessed via the `Identity` property of the `AppSyncResolverEvent` instance. Since the `Identity` property is of type `object`, you can deserialize it to `AppSyncLambdaIdentity` (as shown above) to get strong typing support. + ```csharp public async Task CustomLambdaAuthorizerHandler(AppSyncAuthorizerEvent appSyncAuthorizerEvent) From 0708f459ed7c75b4c251308b64234955abeabe80 Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Fri, 28 Mar 2025 13:36:00 +0530 Subject: [PATCH 18/27] fixed code review comments --- .../Amazon.Lambda.AppSyncEvents.csproj | 12 +- .../AppSyncAuthorizerEvent.cs | 104 ++++++----- .../AppSyncAuthorizerResult.cs | 70 +++----- .../AppSyncCognitoIdentity.cs | 68 ++++--- .../AppSyncIamIdentity.cs | 91 +++++----- .../AppSyncLambdaIdentity.cs | 19 +- .../AppSyncOidcIdentity.cs | 35 ++-- .../AppSyncResolverEvent.cs | 169 +++++++++--------- .../EventsTests.NETCore31.csproj | 1 - .../test/EventsTests.Shared/EventTests.cs | 22 --- 10 files changed, 265 insertions(+), 326 deletions(-) diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj index 0507bb52a..835b602d2 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj @@ -3,18 +3,14 @@ - Amazon Lambda .NET Core support - AWS AppSync package. - netstandard2.0;netcoreapp3.1;net8.0 + Amazon Lambda .NET support - AWS AppSync package. + net6.0;net8.0 Amazon.Lambda.AppSyncEvents 0.0.1 Amazon.Lambda.AppSyncEvents Amazon.Lambda.AppSyncEvents AWS;Amazon;Lambda + enable - - - IL2026,IL2067,IL2075 - true - true - + diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerEvent.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerEvent.cs index cbfa5d3b0..cfb36d85d 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerEvent.cs +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerEvent.cs @@ -1,67 +1,65 @@ -using System.Collections.Generic; -namespace Amazon.Lambda.AppSyncEvents +namespace Amazon.Lambda.AppSyncEvents; + +/// +/// Represents an AWS AppSync authorization event that is sent to a Lambda authorizer +/// for evaluating access permissions to the GraphQL API. +/// +public class AppSyncAuthorizerEvent { /// - /// Represents an AWS AppSync authorization event that is sent to a Lambda authorizer - /// for evaluating access permissions to the GraphQL API. + /// Gets or sets the authorization token received from the client request. + /// This token is used to make authorization decisions. /// - public class AppSyncAuthorizerEvent - { - /// - /// Gets or sets the authorization token received from the client request. - /// This token is used to make authorization decisions. - /// - public string AuthorizationToken { get; set; } + public string AuthorizationToken { get; set; } - /// - /// Gets or sets the headers from the client request. - /// Contains key-value pairs of HTTP header names and their values. - /// - public Dictionary RequestHeaders { get; set; } + /// + /// Gets or sets the headers from the client request. + /// Contains key-value pairs of HTTP header names and their values. + /// + public Dictionary RequestHeaders { get; set; } - /// - /// Gets or sets the context information about the AppSync request. - /// Contains metadata about the API and the GraphQL operation being executed. - /// - public RequestContext RequestContext { get; set; } - } + /// + /// Gets or sets the context information about the AppSync request. + /// Contains metadata about the API and the GraphQL operation being executed. + /// + public AppSyncRequestContext RequestContext { get; set; } +} +/// +/// Contains contextual information about the AppSync request being authorized. +/// This class provides details about the API, account, and GraphQL operation. +/// +public class AppSyncRequestContext +{ /// - /// Contains contextual information about the AppSync request being authorized. - /// This class provides details about the API, account, and GraphQL operation. + /// Gets or sets the unique identifier of the AppSync API. /// - public class RequestContext - { - /// - /// Gets or sets the unique identifier of the AppSync API. - /// - public string ApiId { get; set; } + public string ApiId { get; set; } - /// - /// Gets or sets the AWS account ID where the AppSync API is deployed. - /// - public string AccountId { get; set; } + /// + /// Gets or sets the AWS account ID where the AppSync API is deployed. + /// + public string AccountId { get; set; } - /// - /// Gets or sets the unique identifier for this specific request. - /// - public string RequestId { get; set; } + /// + /// Gets or sets the unique identifier for this specific request. + /// + public string RequestId { get; set; } - /// - /// Gets or sets the GraphQL query string containing the operation to be executed. - /// - public string QueryString { get; set; } + /// + /// Gets or sets the GraphQL query string containing the operation to be executed. + /// + public string QueryString { get; set; } - /// - /// Gets or sets the name of the GraphQL operation to be executed. - /// This corresponds to the operation name in the GraphQL query. - /// - public string OperationName { get; set; } + /// + /// Gets or sets the name of the GraphQL operation to be executed. + /// This corresponds to the operation name in the GraphQL query. + /// + public string OperationName { get; set; } - /// - /// Gets or sets the variables passed to the GraphQL operation. - /// Contains key-value pairs of variable names and their values. - /// - public Dictionary Variables { get; set; } - } + /// + /// Gets or sets the variables passed to the GraphQL operation. + /// Contains key-value pairs of variable names and their values. + /// + public Dictionary Variables { get; set; } } diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerResult.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerResult.cs index 89d9243c8..356bc1895 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerResult.cs +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerResult.cs @@ -1,49 +1,33 @@ -using System.Collections.Generic; -using System.Runtime.Serialization; +using System.Text.Json.Serialization; +namespace Amazon.Lambda.AppSyncEvents; - -namespace Amazon.Lambda.AppSyncEvents +/// +/// Represents the authorization result returned by a Lambda authorizer to AWS AppSync +/// containing authorization decisions and optional context for the GraphQL API. +/// +public class AppSyncAuthorizerResult { - /// - /// Represents the result returned by an AWS AppSync Lambda authorizer. - /// - [DataContract] - public class AppSyncAuthorizerResult - { - /// - /// Indicates if the request is authorized - /// - [DataMember(Name = "isAuthorized")] -#if NETCOREAPP3_1_OR_GREATER - [System.Text.Json.Serialization.JsonPropertyName("isAuthorized")] -#endif - public bool IsAuthorized { get; set; } + /// + /// Indicates if the request is authorized + /// + [JsonPropertyName("isAuthorized")] + public bool IsAuthorized { get; set; } - /// - /// Custom context to pass to resolvers, only supports key-value pairs. - /// - [DataMember(Name = "resolverContext")] -#if NETCOREAPP3_1_OR_GREATER - [System.Text.Json.Serialization.JsonPropertyName("resolverContext")] -#endif - public Dictionary ResolverContext { get; set; } + /// + /// Custom context to pass to resolvers, only supports key-value pairs. + /// + [JsonPropertyName("resolverContext")] + public Dictionary ResolverContext { get; set; } - /// - /// List of fields that are denied access - /// - [DataMember(Name = "deniedFields")] -#if NETCOREAPP3_1_OR_GREATER - [System.Text.Json.Serialization.JsonPropertyName("deniedFields")] -#endif - public IEnumerable DeniedFields { get; set; } + /// + /// List of fields that are denied access + /// + [JsonPropertyName("deniedFields")] + public IEnumerable DeniedFields { get; set; } - /// - /// The number of seconds that the response should be cached for - /// - [DataMember(Name = "ttlOverride")] -#if NETCOREAPP3_1_OR_GREATER - [System.Text.Json.Serialization.JsonPropertyName("ttlOverride")] -#endif - public int? TtlOverride { get; set; } - } + /// + /// The number of seconds that the response should be cached for + /// + [JsonPropertyName("ttlOverride")] + public int? TtlOverride { get; set; } } diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncCognitoIdentity.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncCognitoIdentity.cs index 2cb90bc0d..2b048cc81 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncCognitoIdentity.cs +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncCognitoIdentity.cs @@ -1,46 +1,42 @@ -using System.Collections.Generic; +namespace Amazon.Lambda.AppSyncEvents; -namespace Amazon.Lambda.AppSyncEvents +/// +/// Represents Amazon Cognito User Pools authorization identity for AppSync +/// +public class AppSyncCognitoIdentity { /// - /// Represents Amazon Cognito User Pools authorization identity for AppSync + /// The source IP address of the caller received by AWS AppSync /// - public class AppSyncCognitoIdentity - { - /// - /// The source IP address of the caller received by AWS AppSync - /// - public List SourceIp { get; set; } + public List SourceIp { get; set; } - /// - /// The username of the authenticated user - /// - public string Username { get; set; } - - /// - /// The UUID of the authenticated user - /// - public string Sub { get; set; } + /// + /// The username of the authenticated user + /// + public string Username { get; set; } - /// - /// The claims that the user has - /// - public Dictionary Claims { get; set; } + /// + /// The UUID of the authenticated user + /// + public string Sub { get; set; } - /// - /// The default authorization strategy for this caller (ALLOW or DENY) - /// - public string DefaultAuthStrategy { get; set; } + /// + /// The claims that the user has + /// + public Dictionary Claims { get; set; } - /// - /// List of OIDC groups - /// - public List Groups { get; set; } + /// + /// The default authorization strategy for this caller (ALLOW or DENY) + /// + public string DefaultAuthStrategy { get; set; } - /// - /// The token issuer - /// - public string Issuer { get; set; } - } + /// + /// List of OIDC groups + /// + public List Groups { get; set; } -} \ No newline at end of file + /// + /// The token issuer + /// + public string Issuer { get; set; } +} diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIamIdentity.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIamIdentity.cs index e37455bb5..a22e82430 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIamIdentity.cs +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIamIdentity.cs @@ -1,50 +1,47 @@ -using System.Collections.Generic; +namespace Amazon.Lambda.AppSyncEvents; -namespace Amazon.Lambda.AppSyncEvents +/// +/// Represents AWS IAM authorization identity for AppSync +/// +public class AppSyncIamIdentity { /// - /// Represents AWS IAM authorization identity for AppSync - /// - public class AppSyncIamIdentity - { - /// - /// The source IP address of the caller received by AWS AppSync - /// - public List SourceIp { get; set; } - - /// - /// The username of the authenticated user (IAM user principal) - /// - public string Username { get; set; } - - /// - /// The AWS account ID of the caller - /// - public string AccountId { get; set; } - - /// - /// The Amazon Cognito identity pool ID associated with the caller - /// - public string CognitoIdentityPoolId { get; set; } - - /// - /// The Amazon Cognito identity ID of the caller - /// - public string CognitoIdentityId { get; set; } - - /// - /// The ARN of the IAM user - /// - public string UserArn { get; set; } - - /// - /// Either authenticated or unauthenticated based on the identity type - /// - public string CognitoIdentityAuthType { get; set; } - - /// - /// A comma separated list of external identity provider information used in obtaining the credentials used to sign the request - /// - public string CognitoIdentityAuthProvider { get; set; } - } -} \ No newline at end of file + /// The source IP address of the caller received by AWS AppSync + /// + public List SourceIp { get; set; } + + /// + /// The username of the authenticated user (IAM user principal) + /// + public string Username { get; set; } + + /// + /// The AWS account ID of the caller + /// + public string AccountId { get; set; } + + /// + /// The Amazon Cognito identity pool ID associated with the caller + /// + public string CognitoIdentityPoolId { get; set; } + + /// + /// The Amazon Cognito identity ID of the caller + /// + public string CognitoIdentityId { get; set; } + + /// + /// The ARN of the IAM user + /// + public string UserArn { get; set; } + + /// + /// Either authenticated or unauthenticated based on the identity type + /// + public string CognitoIdentityAuthType { get; set; } + + /// + /// A comma separated list of external identity provider information used in obtaining the credentials used to sign the request + /// + public string CognitoIdentityAuthProvider { get; set; } +} diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncLambdaIdentity.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncLambdaIdentity.cs index 66770933f..b55a8645b 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncLambdaIdentity.cs +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncLambdaIdentity.cs @@ -1,16 +1,13 @@ -using System.Collections.Generic; +namespace Amazon.Lambda.AppSyncEvents; -namespace Amazon.Lambda.AppSyncEvents +/// +/// Represents AWS Lambda authorization identity for AppSync +/// +public class AppSyncLambdaIdentity { /// - /// Represents AWS LAMBDA authorization identity for AppSync + /// Optional context information that will be passed to subsequent resolvers + /// Can contain user information, claims, or any other contextual data /// - public class AppSyncLambdaIdentity - { - /// - /// Optional context information that will be passed to subsequent resolvers - /// Can contain user information, claims, or any other contextual data - /// - public Dictionary ResolverContext { get; set; } - } + public Dictionary ResolverContext { get; set; } } diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncOidcIdentity.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncOidcIdentity.cs index dd489acc9..f1023c286 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncOidcIdentity.cs +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncOidcIdentity.cs @@ -1,25 +1,22 @@ -using System.Collections.Generic; +namespace Amazon.Lambda.AppSyncEvents; -namespace Amazon.Lambda.AppSyncEvents +/// +/// Represents OpenID Connect authorization identity for AppSync +/// +public class AppSyncOidcIdentity { /// - /// Represents OPENID CONNECT authorization identity for AppSync + /// Claims from the OIDC token as key-value pairs /// - public class AppSyncOidcIdentity - { - /// - /// Claims from the OIDC token as key-value pairs - /// - public Dictionary Claims { get; set; } + public Dictionary Claims { get; set; } - /// - /// The issuer of the OIDC token - /// - public string Issuer { get; set; } + /// + /// The issuer of the OIDC token + /// + public string Issuer { get; set; } - /// - /// The UUID of the authenticated user - /// - public string Sub { get; set; } - } -} \ No newline at end of file + /// + /// The UUID of the authenticated user + /// + public string Sub { get; set; } +} diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncResolverEvent.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncResolverEvent.cs index d357f0411..c650be02d 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncResolverEvent.cs +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncResolverEvent.cs @@ -1,104 +1,101 @@ -using System.Collections.Generic; +namespace Amazon.Lambda.AppSyncEvents; -namespace Amazon.Lambda.AppSyncEvents +/// +/// Represents the event payload received from AWS AppSync. +/// +public class AppSyncResolverEvent { /// - /// Represents the event payload received from AWS AppSync. + /// Gets or sets the input arguments for the GraphQL operation. /// - public class AppSyncResolverEvent - { - /// - /// Gets or sets the input arguments for the GraphQL operation. - /// - public TArguments Arguments { get; set; } + public TArguments Arguments { get; set; } - /// - /// An object that contains information about the caller. - /// Returns null for API_KEY authorization. - /// Returns AppSyncIamIdentity for AWS_IAM authorization. - /// Returns AppSyncCognitoIdentity for AMAZON_COGNITO_USER_POOLS authorization. - /// For AWS_LAMBDA authorization, returns the object returned by your Lambda authorizer function. - /// - /// - /// The Identity object type depends on the authorization mode: - /// - For API_KEY: null - /// - For AWS_IAM: - /// - For AMAZON_COGNITO_USER_POOLS: - /// - For AWS_LAMBDA: - /// - For OPENID_CONNECT: - /// - public object Identity { get; set; } + /// + /// An object that contains information about the caller. + /// Returns null for API_KEY authorization. + /// Returns AppSyncIamIdentity for AWS_IAM authorization. + /// Returns AppSyncCognitoIdentity for AMAZON_COGNITO_USER_POOLS authorization. + /// For AWS_LAMBDA authorization, returns the object returned by your Lambda authorizer function. + /// + /// + /// The Identity object type depends on the authorization mode: + /// - For API_KEY: null + /// - For AWS_IAM: + /// - For AMAZON_COGNITO_USER_POOLS: + /// - For AWS_LAMBDA: + /// - For OPENID_CONNECT: + /// + public object Identity { get; set; } - /// - /// Gets or sets information about the data source that originated the event. - /// - public object Source { get; set; } + /// + /// Gets or sets information about the data source that originated the event. + /// + public object Source { get; set; } - /// - /// Gets or sets information about the HTTP request that triggered the event. - /// - public RequestContext Request { get; set; } + /// + /// Gets or sets information about the HTTP request that triggered the event. + /// + public RequestContext Request { get; set; } - /// - /// Gets or sets information about the previous state of the data before the operation was executed. - /// - public object Prev { get; set; } + /// + /// Gets or sets information about the previous state of the data before the operation was executed. + /// + public object Prev { get; set; } - /// - /// Gets or sets information about the GraphQL operation being executed. - /// - public Information Info { get; set; } + /// + /// Gets or sets information about the GraphQL operation being executed. + /// + public Information Info { get; set; } - /// - /// Gets or sets additional information that can be passed between Lambda functions during an AppSync pipeline. - /// - public Dictionary Stash { get; set; } + /// + /// Gets or sets additional information that can be passed between Lambda functions during an AppSync pipeline. + /// + public Dictionary Stash { get; set; } +} - /// - /// Represents information about the HTTP request that triggered the event. - /// - public class RequestContext - { - /// - /// Gets or sets the headers of the HTTP request. - /// - public Dictionary Headers { get; set; } +/// +/// Represents information about the HTTP request that triggered the event. +/// +public class RequestContext +{ + /// + /// Gets or sets the headers of the HTTP request. + /// + public Dictionary Headers { get; set; } - /// - /// Gets or sets the domain name associated with the request. - /// - public string DomainName { get; set; } - } + /// + /// Gets or sets the domain name associated with the request. + /// + public string DomainName { get; set; } +} - /// - /// Represents information about the GraphQL operation being executed. - /// - public class Information - { - /// - /// Gets or sets the name of the GraphQL field being executed. - /// - public string FieldName { get; set; } +/// +/// Represents information about the GraphQL operation being executed. +/// +public class Information +{ + /// + /// Gets or sets the name of the GraphQL field being executed. + /// + public string FieldName { get; set; } - /// - /// Gets or sets a list of fields being selected in the GraphQL operation. - /// - public List SelectionSetList { get; set; } + /// + /// Gets or sets a list of fields being selected in the GraphQL operation. + /// + public List SelectionSetList { get; set; } - /// - /// Gets or sets the GraphQL selection set for the operation. - /// - public string SelectionSetGraphQL { get; set; } + /// + /// Gets or sets the GraphQL selection set for the operation. + /// + public string SelectionSetGraphQL { get; set; } - /// - /// Gets or sets the variables passed to the GraphQL operation. - /// - public Dictionary Variables { get; set; } + /// + /// Gets or sets the variables passed to the GraphQL operation. + /// + public Dictionary Variables { get; set; } - /// - /// Gets or sets the parent type name for the GraphQL operation. - /// - public string ParentTypeName { get; set; } - } - } + /// + /// Gets or sets the parent type name for the GraphQL operation. + /// + public string ParentTypeName { get; set; } } diff --git a/Libraries/test/EventsTests.NETCore31/EventsTests.NETCore31.csproj b/Libraries/test/EventsTests.NETCore31/EventsTests.NETCore31.csproj index fbea03df8..1c5812340 100644 --- a/Libraries/test/EventsTests.NETCore31/EventsTests.NETCore31.csproj +++ b/Libraries/test/EventsTests.NETCore31/EventsTests.NETCore31.csproj @@ -27,7 +27,6 @@ - diff --git a/Libraries/test/EventsTests.Shared/EventTests.cs b/Libraries/test/EventsTests.Shared/EventTests.cs index ed35964ef..b046d26a1 100644 --- a/Libraries/test/EventsTests.Shared/EventTests.cs +++ b/Libraries/test/EventsTests.Shared/EventTests.cs @@ -3910,11 +3910,8 @@ public void TestJsonIncludeNullValueSerializer() } [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 AppSyncTest(Type serializerType) { var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; @@ -3954,11 +3951,8 @@ public void AppSyncTest(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 AppSyncTestCognitoAuthorizer(Type serializerType) { var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; @@ -4005,10 +3999,6 @@ public void AppSyncTestCognitoAuthorizer(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 AppSyncTestIAMAuthorizer(Type serializerType) { var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; @@ -4052,11 +4042,8 @@ public void AppSyncTestIAMAuthorizer(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 AppSyncTestLambdaAuthorizer(Type serializerType) { var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; @@ -4081,11 +4068,8 @@ public void AppSyncTestLambdaAuthorizer(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 AppSyncTestOidcAuthorizer(Type serializerType) { var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; @@ -4114,11 +4098,8 @@ public void AppSyncTestOidcAuthorizer(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 AppSyncTestLambdaAuthorizerRequestEvent(Type serializerType) { var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; @@ -4148,11 +4129,8 @@ public void AppSyncTestLambdaAuthorizerRequestEvent(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 AppSyncTestLambdaAuthorizerResponseEvent(Type serializerType) { var response = new AppSyncAuthorizerResult From d7cd825a7fc86ba217082e70f79929af3639794f Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Fri, 28 Mar 2025 13:58:42 +0530 Subject: [PATCH 19/27] fixed formatting --- .autover/autover.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.autover/autover.json b/.autover/autover.json index 9b5d3c977..a814d33be 100644 --- a/.autover/autover.json +++ b/.autover/autover.json @@ -140,7 +140,7 @@ "Name": "Amazon.Lambda.TestTool", "Path": "Tools/LambdaTestTool-v2/src/Amazon.Lambda.TestTool/Amazon.Lambda.TestTool.csproj" }, - { + { "Name": "Amazon.Lambda.AppSyncEvents", "Path": "Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj" } From 1c34513a3b5e617a94de17b94a88d52cbd1579f4 Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Fri, 28 Mar 2025 14:08:25 +0530 Subject: [PATCH 20/27] Revert warning and remove condition --- .../Amazon.Lambda.AppSyncEvents.csproj | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj index 835b602d2..6bdea9775 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj @@ -12,5 +12,11 @@ AWS;Amazon;Lambda enable - + + + IL2026,IL2067,IL2075,IL3050 + true + true + + From 06fe27092027d5e977db3073565b3c18730f0c95 Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Fri, 28 Mar 2025 14:44:24 +0530 Subject: [PATCH 21/27] Added .net8 directive --- Libraries/test/EventsTests.Shared/EventTests.cs | 13 +++++++++---- .../EventsTests.Shared/EventsTests.Shared.projitems | 3 +++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Libraries/test/EventsTests.Shared/EventTests.cs b/Libraries/test/EventsTests.Shared/EventTests.cs index b046d26a1..7d66bd660 100644 --- a/Libraries/test/EventsTests.Shared/EventTests.cs +++ b/Libraries/test/EventsTests.Shared/EventTests.cs @@ -3,7 +3,9 @@ namespace Amazon.Lambda.Tests { using Amazon.Lambda.APIGatewayEvents; using Amazon.Lambda.ApplicationLoadBalancerEvents; +#if NET8_0_OR_GREATER using Amazon.Lambda.AppSyncEvents; +#endif using Amazon.Lambda.CloudWatchEvents.BatchEvents; using Amazon.Lambda.CloudWatchEvents.ECSEvents; using Amazon.Lambda.CloudWatchEvents.S3Events; @@ -202,7 +204,7 @@ public void SetHeadersToHttpApiV2Response() [Theory] [InlineData(typeof(JsonSerializer))] -#if NETCOREAPP3_1_OR_GREATER +#if NETCOREAPP3_1_OR_GREATER [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] #endif @@ -246,7 +248,7 @@ public void S3ObjectLambdaEventTest(Type serializerType) [Theory] [InlineData(typeof(JsonSerializer))] -#if NETCOREAPP3_1_OR_GREATER +#if NETCOREAPP3_1_OR_GREATER [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] #endif @@ -292,7 +294,7 @@ private void Handle(S3Event s3Event) [Theory] [InlineData(typeof(JsonSerializer))] -#if NETCOREAPP3_1_OR_GREATER +#if NETCOREAPP3_1_OR_GREATER [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] #endif @@ -3909,6 +3911,7 @@ public void TestJsonIncludeNullValueSerializer() Assert.Equal(JTokenType.Null, serialized["SomeOtherValue"].Type); // System.NullReferenceException is thrown if value is missing. } +#if NET8_0_OR_GREATER [Theory] [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] @@ -3998,7 +4001,8 @@ public void AppSyncTestCognitoAuthorizer(Type serializerType) } [Theory] - [InlineData(typeof(JsonSerializer))] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] public void AppSyncTestIAMAuthorizer(Type serializerType) { var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; @@ -4157,6 +4161,7 @@ public void AppSyncTestLambdaAuthorizerResponseEvent(Type serializerType) Assert.True(JToken.DeepEquals(actualObject, expectedJObject)); } +#endif class ClassUsingPascalCase { diff --git a/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems b/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems index a7dc07656..b424aa506 100644 --- a/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems +++ b/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems @@ -12,6 +12,9 @@ + + + From 308156c99a881a021d287f694f6f48f08076754d Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Thu, 3 Apr 2025 15:01:51 +0530 Subject: [PATCH 22/27] Remove warning --- .../Amazon.Lambda.AppSyncEvents.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj index 6bdea9775..74270c5c3 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj @@ -14,7 +14,7 @@ - IL2026,IL2067,IL2075,IL3050 + IL2026,IL2067,IL2075 true true From e37ad36fbf50617d44bd8402f53dd4fd63364e1e Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Thu, 3 Apr 2025 15:45:25 +0530 Subject: [PATCH 23/27] fixed review comments --- Libraries/Libraries.sln | 7 + .../Amazon.Lambda.AppSyncEvents.csproj | 2 +- .../EventsTests.NET6/EventsTests.NET6.csproj | 1 - .../test/EventsTests.NET8/AppSyncTests.cs | 281 ++++++++++++++++++ .../EventsTests.NET8/EventsTests.NET8.csproj | 35 +++ .../test/EventsTests.Shared/EventTests.cs | 255 ---------------- 6 files changed, 324 insertions(+), 257 deletions(-) create mode 100644 Libraries/test/EventsTests.NET8/AppSyncTests.cs create mode 100644 Libraries/test/EventsTests.NET8/EventsTests.NET8.csproj diff --git a/Libraries/Libraries.sln b/Libraries/Libraries.sln index b63125e33..b3666cbb1 100644 --- a/Libraries/Libraries.sln +++ b/Libraries/Libraries.sln @@ -137,6 +137,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SnapshotRestore.Registry.Te EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Amazon.Lambda.AppSyncEvents", "src\Amazon.Lambda.AppSyncEvents\Amazon.Lambda.AppSyncEvents.csproj", "{99F39E49-1FD0-4EF5-BF4B-8F2473FB8198}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EventsTests.NET8", "test\EventsTests.NET8\EventsTests.NET8.csproj", "{1FB22337-5D88-4CE7-ADFF-FFD89204F0E9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -375,6 +377,10 @@ Global {99F39E49-1FD0-4EF5-BF4B-8F2473FB8198}.Debug|Any CPU.Build.0 = Debug|Any CPU {99F39E49-1FD0-4EF5-BF4B-8F2473FB8198}.Release|Any CPU.ActiveCfg = Release|Any CPU {99F39E49-1FD0-4EF5-BF4B-8F2473FB8198}.Release|Any CPU.Build.0 = Release|Any CPU + {1FB22337-5D88-4CE7-ADFF-FFD89204F0E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1FB22337-5D88-4CE7-ADFF-FFD89204F0E9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1FB22337-5D88-4CE7-ADFF-FFD89204F0E9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1FB22337-5D88-4CE7-ADFF-FFD89204F0E9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -442,6 +448,7 @@ Global {7261A438-8C1D-47AD-98B0-7678F72E4382} = {AAB54E74-20B1-42ED-BC3D-CE9F7BC7FD12} {A699E183-D0D4-4F26-A0A7-88DA5607F455} = {1DE4EE60-45BA-4EF7-BE00-B9EB861E4C69} {99F39E49-1FD0-4EF5-BF4B-8F2473FB8198} = {AAB54E74-20B1-42ED-BC3D-CE9F7BC7FD12} + {1FB22337-5D88-4CE7-ADFF-FFD89204F0E9} = {1DE4EE60-45BA-4EF7-BE00-B9EB861E4C69} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {503678A4-B8D1-4486-8915-405A3E9CF0EB} diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj index 74270c5c3..7b3352894 100644 --- a/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj +++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj @@ -4,7 +4,7 @@ Amazon Lambda .NET support - AWS AppSync package. - net6.0;net8.0 + net8.0 Amazon.Lambda.AppSyncEvents 0.0.1 Amazon.Lambda.AppSyncEvents diff --git a/Libraries/test/EventsTests.NET6/EventsTests.NET6.csproj b/Libraries/test/EventsTests.NET6/EventsTests.NET6.csproj index 9fe6c957d..af60ce665 100644 --- a/Libraries/test/EventsTests.NET6/EventsTests.NET6.csproj +++ b/Libraries/test/EventsTests.NET6/EventsTests.NET6.csproj @@ -27,7 +27,6 @@ - diff --git a/Libraries/test/EventsTests.NET8/AppSyncTests.cs b/Libraries/test/EventsTests.NET8/AppSyncTests.cs new file mode 100644 index 000000000..5e7b2cb7a --- /dev/null +++ b/Libraries/test/EventsTests.NET8/AppSyncTests.cs @@ -0,0 +1,281 @@ +using Amazon.Lambda.AppSyncEvents; +using System.Text; +using Amazon.Lambda.Core; +using System.Text.Json; + +namespace EventsTests.NET8 +{ + public class AppSyncTests + { + // This utility method takes care of removing the BOM that System.Text.Json doesn't like. + public MemoryStream LoadJsonTestFile(string filename) + { + var json = File.ReadAllText(filename); + return new MemoryStream(UTF8Encoding.UTF8.GetBytes(json)); + } + public string SerializeJson(ILambdaSerializer serializer, T response) + { + string serializedJson; + using (MemoryStream stream = new MemoryStream()) + { + serializer.Serialize(response, stream); + + stream.Position = 0; + serializedJson = Encoding.UTF8.GetString(stream.ToArray()); + } + return serializedJson; + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTest(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event.json")) + { + var appSyncEvent = serializer.Deserialize>>(fileStream); + Assert.NotNull(appSyncEvent); + Assert.NotNull(appSyncEvent.Arguments); + Assert.NotNull(appSyncEvent.Arguments["input"]); + + Assert.NotNull(appSyncEvent.Request); + Assert.NotNull(appSyncEvent.Request.Headers); + var headers = appSyncEvent.Request.Headers; + Assert.Equal("value1", headers["key1"]); + Assert.Equal("value2", headers["key2"]); + + Assert.NotNull(appSyncEvent.Info); + Assert.Equal("openSupportTicket", appSyncEvent.Info.FieldName); + Assert.Equal("Mutation", appSyncEvent.Info.ParentTypeName); + + Assert.NotNull(appSyncEvent.Info.SelectionSetList); + Assert.Equal(6, appSyncEvent.Info.SelectionSetList.Count); + Assert.Contains("ticketId", appSyncEvent.Info.SelectionSetList); + Assert.Contains("status", appSyncEvent.Info.SelectionSetList); + Assert.Contains("title", appSyncEvent.Info.SelectionSetList); + Assert.Contains("description", appSyncEvent.Info.SelectionSetList); + Assert.Contains("createdAt", appSyncEvent.Info.SelectionSetList); + Assert.Contains("updatedAt", appSyncEvent.Info.SelectionSetList); + + Assert.NotNull(appSyncEvent.Info.SelectionSetGraphQL); + Assert.NotNull(appSyncEvent.Info.Variables); + Assert.NotNull(appSyncEvent.Info.Variables["input"]); + + Assert.NotNull(appSyncEvent.Stash); + Assert.Empty(appSyncEvent.Stash); + } + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTestCognitoAuthorizer(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-cognito-authorizer.json")) + { + var request = serializer.Deserialize>>(fileStream); + + Assert.NotNull(request.Identity); + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) + { + var identity = serializer.Deserialize(stream); + Assert.NotNull(identity); + + // Claims + Assert.NotNull(identity.Claims); + Assert.True(identity.Claims.ContainsKey("client_id")); + Assert.True(identity.Claims.ContainsKey("scope")); + Assert.True(identity.Claims.ContainsKey("sub")); + Assert.True(identity.Claims.ContainsKey("token_use")); + + // DefaultAuthStrategy + Assert.NotEmpty(identity.DefaultAuthStrategy); + + // Groups + Assert.NotNull(identity.Groups); + Assert.NotEmpty(identity.Groups); + + // Issuer + Assert.NotEmpty(identity.Issuer); + + // SourceIp + Assert.NotNull(identity.SourceIp); + Assert.NotEmpty(identity.SourceIp); + + // Sub + Assert.NotEmpty(identity.Sub); + + // Username + Assert.NotEmpty(identity.Username); + } + } + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTestIAMAuthorizer(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-iam-authorizer.json")) + { + var request = serializer.Deserialize>>(fileStream); + + Assert.NotNull(request.Identity); + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) + { + var identity = serializer.Deserialize(stream); + Assert.NotNull(identity); + + // AccountId + Assert.NotEmpty(identity.AccountId); + + // CognitoIdentityAuthProvider + Assert.NotEmpty(identity.CognitoIdentityAuthProvider); + + // CognitoIdentityAuthType + Assert.NotEmpty(identity.CognitoIdentityAuthType); + + // CognitoIdentityId + Assert.NotEmpty(identity.CognitoIdentityId); + + // CognitoIdentityPoolId + Assert.NotEmpty(identity.CognitoIdentityPoolId); + + // SourceIp + Assert.NotNull(identity.SourceIp); + Assert.NotEmpty(identity.SourceIp); + + // UserArn + Assert.NotEmpty(identity.UserArn); + + // Username + Assert.NotEmpty(identity.Username); + } + } + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTestLambdaAuthorizer(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-lambda-authorizer.json")) + { + var request = serializer.Deserialize>>(fileStream); + + Assert.NotNull(request.Identity); + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) + { + var identity = serializer.Deserialize(stream); + Assert.NotNull(identity); + + // ResolverContext + Assert.NotNull(identity.ResolverContext); + Assert.NotEmpty(identity.ResolverContext["userid"]); + Assert.NotEmpty(identity.ResolverContext["info"]); + Assert.NotEmpty(identity.ResolverContext["more_info"]); + } + } + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTestOidcAuthorizer(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-oidc-authorizer.json")) + { + var request = serializer.Deserialize>>(fileStream); + + Assert.NotNull(request.Identity); + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) + { + var identity = serializer.Deserialize(stream); + Assert.NotNull(identity); + + // Claims + Assert.NotNull(identity.Claims); + Assert.True(identity.Claims.ContainsKey("client_id")); + + // Issuer + Assert.NotEmpty(identity.Issuer); + + // Sub + Assert.NotEmpty(identity.Sub); + } + } + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTestLambdaAuthorizerRequestEvent(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-lambda-authorizer-request.json")) + { + var request = serializer.Deserialize(fileStream); + + // Assert Authorization Token + Assert.Equal("custom-token", request.AuthorizationToken); + + // Assert Request Context + Assert.NotNull(request.RequestContext); + Assert.Equal("xxxxxxxx", request.RequestContext.ApiId); + Assert.Equal("112233445566", request.RequestContext.AccountId); + Assert.Equal("36307622-97fe-4dfa-bd71-b15b1d03ce97", request.RequestContext.RequestId); + Assert.Equal("MyQuery", request.RequestContext.OperationName); + Assert.NotNull(request.RequestContext.Variables); + Assert.Empty(request.RequestContext.Variables); + Assert.Contains("listTodos", request.RequestContext.QueryString); + + // Assert Request Headers + Assert.NotNull(request.RequestHeaders); + Assert.Equal("This is test token", request.RequestHeaders["authorization"]); + Assert.Equal("application/json", request.RequestHeaders["content-type"]); + Assert.Equal("https://ap-south-1.console.aws.amazon.com", request.RequestHeaders["origin"]); + } + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTestLambdaAuthorizerResponseEvent(Type serializerType) + { + var response = new AppSyncAuthorizerResult + { + IsAuthorized = true, + ResolverContext = new Dictionary + { + { "userid", "test-user-id" }, + { "info", "contextual information A" }, + { "more_info", "contextual information B" } + }, + DeniedFields = new List + { + "arn:aws:appsync:us-east-1:1234567890:apis/xxxxxx/types/Event/fields/comments", + "Mutation.createEvent" + }, + TtlOverride = 10 + }; + + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + var json = SerializeJson(serializer, response); + + // Deserialize both the actual and expected JSON for comparison + var actualObject = JsonSerializer.Deserialize(json); + var expectedJson = File.ReadAllText("appsync-event-lambda-authorizer-response.json"); + var expectedObject = JsonSerializer.Deserialize(expectedJson); + + // Assert: Compare the deserialized objects + Assert.Equal(expectedObject.IsAuthorized, actualObject.IsAuthorized); + Assert.Equal(expectedObject.TtlOverride, actualObject.TtlOverride); + Assert.Equal(expectedObject.ResolverContext["userid"], actualObject.ResolverContext["userid"]); + Assert.Equal(expectedObject.ResolverContext["info"], actualObject.ResolverContext["info"]); + Assert.Equal(expectedObject.ResolverContext["more_info"], actualObject.ResolverContext["more_info"]); + Assert.Equal(expectedObject.DeniedFields.Count(), actualObject.DeniedFields.Count()); + } + } +} diff --git a/Libraries/test/EventsTests.NET8/EventsTests.NET8.csproj b/Libraries/test/EventsTests.NET8/EventsTests.NET8.csproj new file mode 100644 index 000000000..6c596a21c --- /dev/null +++ b/Libraries/test/EventsTests.NET8/EventsTests.NET8.csproj @@ -0,0 +1,35 @@ + + + + net8.0 + enable + + false + true + + + + + PreserveNewest + + + + + + + + + + + + + + + + + + + + + + diff --git a/Libraries/test/EventsTests.Shared/EventTests.cs b/Libraries/test/EventsTests.Shared/EventTests.cs index 7d66bd660..c9fb82c83 100644 --- a/Libraries/test/EventsTests.Shared/EventTests.cs +++ b/Libraries/test/EventsTests.Shared/EventTests.cs @@ -3,9 +3,6 @@ namespace Amazon.Lambda.Tests { using Amazon.Lambda.APIGatewayEvents; using Amazon.Lambda.ApplicationLoadBalancerEvents; -#if NET8_0_OR_GREATER - using Amazon.Lambda.AppSyncEvents; -#endif using Amazon.Lambda.CloudWatchEvents.BatchEvents; using Amazon.Lambda.CloudWatchEvents.ECSEvents; using Amazon.Lambda.CloudWatchEvents.S3Events; @@ -3911,258 +3908,6 @@ public void TestJsonIncludeNullValueSerializer() Assert.Equal(JTokenType.Null, serialized["SomeOtherValue"].Type); // System.NullReferenceException is thrown if value is missing. } -#if NET8_0_OR_GREATER - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTest(Type serializerType) - { - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - using (var fileStream = LoadJsonTestFile("appsync-event.json")) - { - var appSyncEvent = serializer.Deserialize>>(fileStream); - Assert.NotNull(appSyncEvent); - Assert.NotNull(appSyncEvent.Arguments); - Assert.NotNull(appSyncEvent.Arguments["input"]); - - Assert.NotNull(appSyncEvent.Request); - Assert.NotNull(appSyncEvent.Request.Headers); - var headers = appSyncEvent.Request.Headers; - Assert.Equal("value1", headers["key1"]); - Assert.Equal("value2", headers["key2"]); - - Assert.NotNull(appSyncEvent.Info); - Assert.Equal("openSupportTicket", appSyncEvent.Info.FieldName); - Assert.Equal("Mutation", appSyncEvent.Info.ParentTypeName); - - Assert.NotNull(appSyncEvent.Info.SelectionSetList); - Assert.Equal(6, appSyncEvent.Info.SelectionSetList.Count); - Assert.Contains("ticketId", appSyncEvent.Info.SelectionSetList); - Assert.Contains("status", appSyncEvent.Info.SelectionSetList); - Assert.Contains("title", appSyncEvent.Info.SelectionSetList); - Assert.Contains("description", appSyncEvent.Info.SelectionSetList); - Assert.Contains("createdAt", appSyncEvent.Info.SelectionSetList); - Assert.Contains("updatedAt", appSyncEvent.Info.SelectionSetList); - - Assert.NotNull(appSyncEvent.Info.SelectionSetGraphQL); - Assert.NotNull(appSyncEvent.Info.Variables); - Assert.NotNull(appSyncEvent.Info.Variables["input"]); - - Assert.NotNull(appSyncEvent.Stash); - Assert.Empty(appSyncEvent.Stash); - } - } - - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTestCognitoAuthorizer(Type serializerType) - { - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - using (var fileStream = LoadJsonTestFile("appsync-event-cognito-authorizer.json")) - { - var request = serializer.Deserialize>>(fileStream); - - Assert.NotNull(request.Identity); - - using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) - { - var identity = serializer.Deserialize(stream); - Assert.NotNull(identity); - - // Claims - Assert.NotNull(identity.Claims); - Assert.True(identity.Claims.ContainsKey("client_id")); - Assert.True(identity.Claims.ContainsKey("scope")); - Assert.True(identity.Claims.ContainsKey("sub")); - Assert.True(identity.Claims.ContainsKey("token_use")); - - // DefaultAuthStrategy - Assert.NotEmpty(identity.DefaultAuthStrategy); - - // Groups - Assert.NotNull(identity.Groups); - Assert.NotEmpty(identity.Groups); - - // Issuer - Assert.NotEmpty(identity.Issuer); - - // SourceIp - Assert.NotNull(identity.SourceIp); - Assert.NotEmpty(identity.SourceIp); - - // Sub - Assert.NotEmpty(identity.Sub); - - // Username - Assert.NotEmpty(identity.Username); - } - } - } - - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTestIAMAuthorizer(Type serializerType) - { - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - using (var fileStream = LoadJsonTestFile("appsync-event-iam-authorizer.json")) - { - var request = serializer.Deserialize>>(fileStream); - - Assert.NotNull(request.Identity); - - using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) - { - var identity = serializer.Deserialize(stream); - Assert.NotNull(identity); - - // AccountId - Assert.NotEmpty(identity.AccountId); - - // CognitoIdentityAuthProvider - Assert.NotEmpty(identity.CognitoIdentityAuthProvider); - - // CognitoIdentityAuthType - Assert.NotEmpty(identity.CognitoIdentityAuthType); - - // CognitoIdentityId - Assert.NotEmpty(identity.CognitoIdentityId); - - // CognitoIdentityPoolId - Assert.NotEmpty(identity.CognitoIdentityPoolId); - - // SourceIp - Assert.NotNull(identity.SourceIp); - Assert.NotEmpty(identity.SourceIp); - - // UserArn - Assert.NotEmpty(identity.UserArn); - - // Username - Assert.NotEmpty(identity.Username); - } - } - } - - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTestLambdaAuthorizer(Type serializerType) - { - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - using (var fileStream = LoadJsonTestFile("appsync-event-lambda-authorizer.json")) - { - var request = serializer.Deserialize>>(fileStream); - - Assert.NotNull(request.Identity); - - using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) - { - var identity = serializer.Deserialize(stream); - Assert.NotNull(identity); - - // ResolverContext - Assert.NotNull(identity.ResolverContext); - Assert.NotEmpty(identity.ResolverContext["userid"]); - Assert.NotEmpty(identity.ResolverContext["info"]); - Assert.NotEmpty(identity.ResolverContext["more_info"]); - } - } - } - - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTestOidcAuthorizer(Type serializerType) - { - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - using (var fileStream = LoadJsonTestFile("appsync-event-oidc-authorizer.json")) - { - var request = serializer.Deserialize>>(fileStream); - - Assert.NotNull(request.Identity); - - using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) - { - var identity = serializer.Deserialize(stream); - Assert.NotNull(identity); - - // Claims - Assert.NotNull(identity.Claims); - Assert.True(identity.Claims.ContainsKey("client_id")); - - // Issuer - Assert.NotEmpty(identity.Issuer); - - // Sub - Assert.NotEmpty(identity.Sub); - } - } - } - - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTestLambdaAuthorizerRequestEvent(Type serializerType) - { - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - using (var fileStream = LoadJsonTestFile("appsync-event-lambda-authorizer-request.json")) - { - var request = serializer.Deserialize(fileStream); - - // Assert Authorization Token - Assert.Equal("custom-token", request.AuthorizationToken); - - // Assert Request Context - Assert.NotNull(request.RequestContext); - Assert.Equal("xxxxxxxx", request.RequestContext.ApiId); - Assert.Equal("112233445566", request.RequestContext.AccountId); - Assert.Equal("36307622-97fe-4dfa-bd71-b15b1d03ce97", request.RequestContext.RequestId); - Assert.Equal("MyQuery", request.RequestContext.OperationName); - Assert.NotNull(request.RequestContext.Variables); - Assert.Empty(request.RequestContext.Variables); - Assert.Contains("listTodos", request.RequestContext.QueryString); - - // Assert Request Headers - Assert.NotNull(request.RequestHeaders); - Assert.Equal("This is test token", request.RequestHeaders["authorization"]); - Assert.Equal("application/json", request.RequestHeaders["content-type"]); - Assert.Equal("https://ap-south-1.console.aws.amazon.com", request.RequestHeaders["origin"]); - } - } - - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTestLambdaAuthorizerResponseEvent(Type serializerType) - { - var response = new AppSyncAuthorizerResult - { - IsAuthorized = true, - ResolverContext = new Dictionary - { - { "userid", "test-user-id" }, - { "info", "contextual information A" }, - { "more_info", "contextual information B" } - }, - DeniedFields = new List - { - "arn:aws:appsync:us-east-1:1234567890:apis/xxxxxx/types/Event/fields/comments", - "Mutation.createEvent" - }, - TtlOverride = 10 - }; - - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - var json = SerializeJson(serializer, response); - var actualObject = JObject.Parse(json); - var expectedJObject = JObject.Parse(File.ReadAllText("appsync-event-lambda-authorizer-response.json")); - - Assert.True(JToken.DeepEquals(actualObject, expectedJObject)); - } -#endif - class ClassUsingPascalCase { public int SomeValue { get; set; } From 399007844a1ba752afc9489364927fefad5c2975 Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Thu, 3 Apr 2025 15:53:42 +0530 Subject: [PATCH 24/27] fix formatting --- Libraries/test/EventsTests.Shared/EventTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Libraries/test/EventsTests.Shared/EventTests.cs b/Libraries/test/EventsTests.Shared/EventTests.cs index c9fb82c83..f4cd6d902 100644 --- a/Libraries/test/EventsTests.Shared/EventTests.cs +++ b/Libraries/test/EventsTests.Shared/EventTests.cs @@ -201,7 +201,7 @@ public void SetHeadersToHttpApiV2Response() [Theory] [InlineData(typeof(JsonSerializer))] -#if NETCOREAPP3_1_OR_GREATER +#if NETCOREAPP3_1_OR_GREATER [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] #endif @@ -245,7 +245,7 @@ public void S3ObjectLambdaEventTest(Type serializerType) [Theory] [InlineData(typeof(JsonSerializer))] -#if NETCOREAPP3_1_OR_GREATER +#if NETCOREAPP3_1_OR_GREATER [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] #endif @@ -291,7 +291,7 @@ private void Handle(S3Event s3Event) [Theory] [InlineData(typeof(JsonSerializer))] -#if NETCOREAPP3_1_OR_GREATER +#if NETCOREAPP3_1_OR_GREATER [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] #endif From 25190dad40f03de08ceaa606d3a87f58c8341b63 Mon Sep 17 00:00:00 2001 From: Pankaj Rawat Date: Thu, 3 Apr 2025 18:36:52 +0530 Subject: [PATCH 25/27] Refactor .NET8 and 6 test --- Libraries/Libraries.sln | 1 + .../EventsTests.NET6/EventsTests.NET6.csproj | 2 +- .../test/EventsTests.NET8/AppSyncTests.cs | 281 ------------------ .../EventsTests.NET8/EventsTests.NET8.csproj | 60 +++- .../test/EventsTests.Shared/EventTests.cs | 255 ++++++++++++++++ 5 files changed, 302 insertions(+), 297 deletions(-) delete mode 100644 Libraries/test/EventsTests.NET8/AppSyncTests.cs diff --git a/Libraries/Libraries.sln b/Libraries/Libraries.sln index b3666cbb1..f44ca9ab3 100644 --- a/Libraries/Libraries.sln +++ b/Libraries/Libraries.sln @@ -454,6 +454,7 @@ Global SolutionGuid = {503678A4-B8D1-4486-8915-405A3E9CF0EB} EndGlobalSection GlobalSection(SharedMSBuildProjectFiles) = preSolution + test\EventsTests.Shared\EventsTests.Shared.projitems*{1fb22337-5d88-4ce7-adff-ffd89204f0e9}*SharedItemsImports = 5 test\EventsTests.Shared\EventsTests.Shared.projitems*{44e9d925-b61d-4234-97b7-61424c963ba6}*SharedItemsImports = 5 test\EventsTests.Shared\EventsTests.Shared.projitems*{a2cb78bb-e54f-48ca-bbfb-9553d27ef23d}*SharedItemsImports = 13 test\EventsTests.Shared\EventsTests.Shared.projitems*{c1bb30d2-3237-4cfc-ba93-627471148ec2}*SharedItemsImports = 5 diff --git a/Libraries/test/EventsTests.NET6/EventsTests.NET6.csproj b/Libraries/test/EventsTests.NET6/EventsTests.NET6.csproj index af60ce665..5e64d7c09 100644 --- a/Libraries/test/EventsTests.NET6/EventsTests.NET6.csproj +++ b/Libraries/test/EventsTests.NET6/EventsTests.NET6.csproj @@ -1,7 +1,7 @@  - net6.0;net8.0 + net6.0 EventsTests31 true EventsTests.NET6 diff --git a/Libraries/test/EventsTests.NET8/AppSyncTests.cs b/Libraries/test/EventsTests.NET8/AppSyncTests.cs deleted file mode 100644 index 5e7b2cb7a..000000000 --- a/Libraries/test/EventsTests.NET8/AppSyncTests.cs +++ /dev/null @@ -1,281 +0,0 @@ -using Amazon.Lambda.AppSyncEvents; -using System.Text; -using Amazon.Lambda.Core; -using System.Text.Json; - -namespace EventsTests.NET8 -{ - public class AppSyncTests - { - // This utility method takes care of removing the BOM that System.Text.Json doesn't like. - public MemoryStream LoadJsonTestFile(string filename) - { - var json = File.ReadAllText(filename); - return new MemoryStream(UTF8Encoding.UTF8.GetBytes(json)); - } - public string SerializeJson(ILambdaSerializer serializer, T response) - { - string serializedJson; - using (MemoryStream stream = new MemoryStream()) - { - serializer.Serialize(response, stream); - - stream.Position = 0; - serializedJson = Encoding.UTF8.GetString(stream.ToArray()); - } - return serializedJson; - } - - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTest(Type serializerType) - { - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - using (var fileStream = LoadJsonTestFile("appsync-event.json")) - { - var appSyncEvent = serializer.Deserialize>>(fileStream); - Assert.NotNull(appSyncEvent); - Assert.NotNull(appSyncEvent.Arguments); - Assert.NotNull(appSyncEvent.Arguments["input"]); - - Assert.NotNull(appSyncEvent.Request); - Assert.NotNull(appSyncEvent.Request.Headers); - var headers = appSyncEvent.Request.Headers; - Assert.Equal("value1", headers["key1"]); - Assert.Equal("value2", headers["key2"]); - - Assert.NotNull(appSyncEvent.Info); - Assert.Equal("openSupportTicket", appSyncEvent.Info.FieldName); - Assert.Equal("Mutation", appSyncEvent.Info.ParentTypeName); - - Assert.NotNull(appSyncEvent.Info.SelectionSetList); - Assert.Equal(6, appSyncEvent.Info.SelectionSetList.Count); - Assert.Contains("ticketId", appSyncEvent.Info.SelectionSetList); - Assert.Contains("status", appSyncEvent.Info.SelectionSetList); - Assert.Contains("title", appSyncEvent.Info.SelectionSetList); - Assert.Contains("description", appSyncEvent.Info.SelectionSetList); - Assert.Contains("createdAt", appSyncEvent.Info.SelectionSetList); - Assert.Contains("updatedAt", appSyncEvent.Info.SelectionSetList); - - Assert.NotNull(appSyncEvent.Info.SelectionSetGraphQL); - Assert.NotNull(appSyncEvent.Info.Variables); - Assert.NotNull(appSyncEvent.Info.Variables["input"]); - - Assert.NotNull(appSyncEvent.Stash); - Assert.Empty(appSyncEvent.Stash); - } - } - - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTestCognitoAuthorizer(Type serializerType) - { - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - using (var fileStream = LoadJsonTestFile("appsync-event-cognito-authorizer.json")) - { - var request = serializer.Deserialize>>(fileStream); - - Assert.NotNull(request.Identity); - - using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) - { - var identity = serializer.Deserialize(stream); - Assert.NotNull(identity); - - // Claims - Assert.NotNull(identity.Claims); - Assert.True(identity.Claims.ContainsKey("client_id")); - Assert.True(identity.Claims.ContainsKey("scope")); - Assert.True(identity.Claims.ContainsKey("sub")); - Assert.True(identity.Claims.ContainsKey("token_use")); - - // DefaultAuthStrategy - Assert.NotEmpty(identity.DefaultAuthStrategy); - - // Groups - Assert.NotNull(identity.Groups); - Assert.NotEmpty(identity.Groups); - - // Issuer - Assert.NotEmpty(identity.Issuer); - - // SourceIp - Assert.NotNull(identity.SourceIp); - Assert.NotEmpty(identity.SourceIp); - - // Sub - Assert.NotEmpty(identity.Sub); - - // Username - Assert.NotEmpty(identity.Username); - } - } - } - - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTestIAMAuthorizer(Type serializerType) - { - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - using (var fileStream = LoadJsonTestFile("appsync-event-iam-authorizer.json")) - { - var request = serializer.Deserialize>>(fileStream); - - Assert.NotNull(request.Identity); - - using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) - { - var identity = serializer.Deserialize(stream); - Assert.NotNull(identity); - - // AccountId - Assert.NotEmpty(identity.AccountId); - - // CognitoIdentityAuthProvider - Assert.NotEmpty(identity.CognitoIdentityAuthProvider); - - // CognitoIdentityAuthType - Assert.NotEmpty(identity.CognitoIdentityAuthType); - - // CognitoIdentityId - Assert.NotEmpty(identity.CognitoIdentityId); - - // CognitoIdentityPoolId - Assert.NotEmpty(identity.CognitoIdentityPoolId); - - // SourceIp - Assert.NotNull(identity.SourceIp); - Assert.NotEmpty(identity.SourceIp); - - // UserArn - Assert.NotEmpty(identity.UserArn); - - // Username - Assert.NotEmpty(identity.Username); - } - } - } - - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTestLambdaAuthorizer(Type serializerType) - { - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - using (var fileStream = LoadJsonTestFile("appsync-event-lambda-authorizer.json")) - { - var request = serializer.Deserialize>>(fileStream); - - Assert.NotNull(request.Identity); - - using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) - { - var identity = serializer.Deserialize(stream); - Assert.NotNull(identity); - - // ResolverContext - Assert.NotNull(identity.ResolverContext); - Assert.NotEmpty(identity.ResolverContext["userid"]); - Assert.NotEmpty(identity.ResolverContext["info"]); - Assert.NotEmpty(identity.ResolverContext["more_info"]); - } - } - } - - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTestOidcAuthorizer(Type serializerType) - { - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - using (var fileStream = LoadJsonTestFile("appsync-event-oidc-authorizer.json")) - { - var request = serializer.Deserialize>>(fileStream); - - Assert.NotNull(request.Identity); - - using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) - { - var identity = serializer.Deserialize(stream); - Assert.NotNull(identity); - - // Claims - Assert.NotNull(identity.Claims); - Assert.True(identity.Claims.ContainsKey("client_id")); - - // Issuer - Assert.NotEmpty(identity.Issuer); - - // Sub - Assert.NotEmpty(identity.Sub); - } - } - } - - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTestLambdaAuthorizerRequestEvent(Type serializerType) - { - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - using (var fileStream = LoadJsonTestFile("appsync-event-lambda-authorizer-request.json")) - { - var request = serializer.Deserialize(fileStream); - - // Assert Authorization Token - Assert.Equal("custom-token", request.AuthorizationToken); - - // Assert Request Context - Assert.NotNull(request.RequestContext); - Assert.Equal("xxxxxxxx", request.RequestContext.ApiId); - Assert.Equal("112233445566", request.RequestContext.AccountId); - Assert.Equal("36307622-97fe-4dfa-bd71-b15b1d03ce97", request.RequestContext.RequestId); - Assert.Equal("MyQuery", request.RequestContext.OperationName); - Assert.NotNull(request.RequestContext.Variables); - Assert.Empty(request.RequestContext.Variables); - Assert.Contains("listTodos", request.RequestContext.QueryString); - - // Assert Request Headers - Assert.NotNull(request.RequestHeaders); - Assert.Equal("This is test token", request.RequestHeaders["authorization"]); - Assert.Equal("application/json", request.RequestHeaders["content-type"]); - Assert.Equal("https://ap-south-1.console.aws.amazon.com", request.RequestHeaders["origin"]); - } - } - - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTestLambdaAuthorizerResponseEvent(Type serializerType) - { - var response = new AppSyncAuthorizerResult - { - IsAuthorized = true, - ResolverContext = new Dictionary - { - { "userid", "test-user-id" }, - { "info", "contextual information A" }, - { "more_info", "contextual information B" } - }, - DeniedFields = new List - { - "arn:aws:appsync:us-east-1:1234567890:apis/xxxxxx/types/Event/fields/comments", - "Mutation.createEvent" - }, - TtlOverride = 10 - }; - - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - var json = SerializeJson(serializer, response); - - // Deserialize both the actual and expected JSON for comparison - var actualObject = JsonSerializer.Deserialize(json); - var expectedJson = File.ReadAllText("appsync-event-lambda-authorizer-response.json"); - var expectedObject = JsonSerializer.Deserialize(expectedJson); - - // Assert: Compare the deserialized objects - Assert.Equal(expectedObject.IsAuthorized, actualObject.IsAuthorized); - Assert.Equal(expectedObject.TtlOverride, actualObject.TtlOverride); - Assert.Equal(expectedObject.ResolverContext["userid"], actualObject.ResolverContext["userid"]); - Assert.Equal(expectedObject.ResolverContext["info"], actualObject.ResolverContext["info"]); - Assert.Equal(expectedObject.ResolverContext["more_info"], actualObject.ResolverContext["more_info"]); - Assert.Equal(expectedObject.DeniedFields.Count(), actualObject.DeniedFields.Count()); - } - } -} diff --git a/Libraries/test/EventsTests.NET8/EventsTests.NET8.csproj b/Libraries/test/EventsTests.NET8/EventsTests.NET8.csproj index 6c596a21c..54bff1296 100644 --- a/Libraries/test/EventsTests.NET8/EventsTests.NET8.csproj +++ b/Libraries/test/EventsTests.NET8/EventsTests.NET8.csproj @@ -1,35 +1,65 @@ - + - net8.0 - enable - - false - true + net8.0 + EventsTests31 + true + EventsTests.NET8 + latest + + PreserveNewest - + - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/Libraries/test/EventsTests.Shared/EventTests.cs b/Libraries/test/EventsTests.Shared/EventTests.cs index f4cd6d902..f9ef72f46 100644 --- a/Libraries/test/EventsTests.Shared/EventTests.cs +++ b/Libraries/test/EventsTests.Shared/EventTests.cs @@ -3,6 +3,9 @@ namespace Amazon.Lambda.Tests { using Amazon.Lambda.APIGatewayEvents; using Amazon.Lambda.ApplicationLoadBalancerEvents; +#if NET8_0_OR_GREATER + using Amazon.Lambda.AppSyncEvents; +#endif using Amazon.Lambda.CloudWatchEvents.BatchEvents; using Amazon.Lambda.CloudWatchEvents.ECSEvents; using Amazon.Lambda.CloudWatchEvents.S3Events; @@ -3908,6 +3911,258 @@ public void TestJsonIncludeNullValueSerializer() Assert.Equal(JTokenType.Null, serialized["SomeOtherValue"].Type); // System.NullReferenceException is thrown if value is missing. } +#if NET8_0_OR_GREATER + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTest(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event.json")) + { + var appSyncEvent = serializer.Deserialize>>(fileStream); + Assert.NotNull(appSyncEvent); + Assert.NotNull(appSyncEvent.Arguments); + Assert.NotNull(appSyncEvent.Arguments["input"]); + + Assert.NotNull(appSyncEvent.Request); + Assert.NotNull(appSyncEvent.Request.Headers); + var headers = appSyncEvent.Request.Headers; + Assert.Equal("value1", headers["key1"]); + Assert.Equal("value2", headers["key2"]); + + Assert.NotNull(appSyncEvent.Info); + Assert.Equal("openSupportTicket", appSyncEvent.Info.FieldName); + Assert.Equal("Mutation", appSyncEvent.Info.ParentTypeName); + + Assert.NotNull(appSyncEvent.Info.SelectionSetList); + Assert.Equal(6, appSyncEvent.Info.SelectionSetList.Count); + Assert.Contains("ticketId", appSyncEvent.Info.SelectionSetList); + Assert.Contains("status", appSyncEvent.Info.SelectionSetList); + Assert.Contains("title", appSyncEvent.Info.SelectionSetList); + Assert.Contains("description", appSyncEvent.Info.SelectionSetList); + Assert.Contains("createdAt", appSyncEvent.Info.SelectionSetList); + Assert.Contains("updatedAt", appSyncEvent.Info.SelectionSetList); + + Assert.NotNull(appSyncEvent.Info.SelectionSetGraphQL); + Assert.NotNull(appSyncEvent.Info.Variables); + Assert.NotNull(appSyncEvent.Info.Variables["input"]); + + Assert.NotNull(appSyncEvent.Stash); + Assert.Empty(appSyncEvent.Stash); + } + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTestCognitoAuthorizer(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-cognito-authorizer.json")) + { + var request = serializer.Deserialize>>(fileStream); + + Assert.NotNull(request.Identity); + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) + { + var identity = serializer.Deserialize(stream); + Assert.NotNull(identity); + + // Claims + Assert.NotNull(identity.Claims); + Assert.True(identity.Claims.ContainsKey("client_id")); + Assert.True(identity.Claims.ContainsKey("scope")); + Assert.True(identity.Claims.ContainsKey("sub")); + Assert.True(identity.Claims.ContainsKey("token_use")); + + // DefaultAuthStrategy + Assert.NotEmpty(identity.DefaultAuthStrategy); + + // Groups + Assert.NotNull(identity.Groups); + Assert.NotEmpty(identity.Groups); + + // Issuer + Assert.NotEmpty(identity.Issuer); + + // SourceIp + Assert.NotNull(identity.SourceIp); + Assert.NotEmpty(identity.SourceIp); + + // Sub + Assert.NotEmpty(identity.Sub); + + // Username + Assert.NotEmpty(identity.Username); + } + } + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTestIAMAuthorizer(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-iam-authorizer.json")) + { + var request = serializer.Deserialize>>(fileStream); + + Assert.NotNull(request.Identity); + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) + { + var identity = serializer.Deserialize(stream); + Assert.NotNull(identity); + + // AccountId + Assert.NotEmpty(identity.AccountId); + + // CognitoIdentityAuthProvider + Assert.NotEmpty(identity.CognitoIdentityAuthProvider); + + // CognitoIdentityAuthType + Assert.NotEmpty(identity.CognitoIdentityAuthType); + + // CognitoIdentityId + Assert.NotEmpty(identity.CognitoIdentityId); + + // CognitoIdentityPoolId + Assert.NotEmpty(identity.CognitoIdentityPoolId); + + // SourceIp + Assert.NotNull(identity.SourceIp); + Assert.NotEmpty(identity.SourceIp); + + // UserArn + Assert.NotEmpty(identity.UserArn); + + // Username + Assert.NotEmpty(identity.Username); + } + } + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTestLambdaAuthorizer(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-lambda-authorizer.json")) + { + var request = serializer.Deserialize>>(fileStream); + + Assert.NotNull(request.Identity); + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) + { + var identity = serializer.Deserialize(stream); + Assert.NotNull(identity); + + // ResolverContext + Assert.NotNull(identity.ResolverContext); + Assert.NotEmpty(identity.ResolverContext["userid"]); + Assert.NotEmpty(identity.ResolverContext["info"]); + Assert.NotEmpty(identity.ResolverContext["more_info"]); + } + } + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTestOidcAuthorizer(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-oidc-authorizer.json")) + { + var request = serializer.Deserialize>>(fileStream); + + Assert.NotNull(request.Identity); + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) + { + var identity = serializer.Deserialize(stream); + Assert.NotNull(identity); + + // Claims + Assert.NotNull(identity.Claims); + Assert.True(identity.Claims.ContainsKey("client_id")); + + // Issuer + Assert.NotEmpty(identity.Issuer); + + // Sub + Assert.NotEmpty(identity.Sub); + } + } + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTestLambdaAuthorizerRequestEvent(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-lambda-authorizer-request.json")) + { + var request = serializer.Deserialize(fileStream); + + // Assert Authorization Token + Assert.Equal("custom-token", request.AuthorizationToken); + + // Assert Request Context + Assert.NotNull(request.RequestContext); + Assert.Equal("xxxxxxxx", request.RequestContext.ApiId); + Assert.Equal("112233445566", request.RequestContext.AccountId); + Assert.Equal("36307622-97fe-4dfa-bd71-b15b1d03ce97", request.RequestContext.RequestId); + Assert.Equal("MyQuery", request.RequestContext.OperationName); + Assert.NotNull(request.RequestContext.Variables); + Assert.Empty(request.RequestContext.Variables); + Assert.Contains("listTodos", request.RequestContext.QueryString); + + // Assert Request Headers + Assert.NotNull(request.RequestHeaders); + Assert.Equal("This is test token", request.RequestHeaders["authorization"]); + Assert.Equal("application/json", request.RequestHeaders["content-type"]); + Assert.Equal("https://ap-south-1.console.aws.amazon.com", request.RequestHeaders["origin"]); + } + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTestLambdaAuthorizerResponseEvent(Type serializerType) + { + var response = new AppSyncAuthorizerResult + { + IsAuthorized = true, + ResolverContext = new Dictionary + { + { "userid", "test-user-id" }, + { "info", "contextual information A" }, + { "more_info", "contextual information B" } + }, + DeniedFields = new List + { + "arn:aws:appsync:us-east-1:1234567890:apis/xxxxxx/types/Event/fields/comments", + "Mutation.createEvent" + }, + TtlOverride = 10 + }; + + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + var json = SerializeJson(serializer, response); + var actualObject = JObject.Parse(json); + var expectedJObject = JObject.Parse(File.ReadAllText("appsync-event-lambda-authorizer-response.json")); + + Assert.True(JToken.DeepEquals(actualObject, expectedJObject)); + } +#endif + class ClassUsingPascalCase { public int SomeValue { get; set; } From d2469ca642e5022cffdf1a98c02269a06e50afd6 Mon Sep 17 00:00:00 2001 From: Ankush Jain Date: Wed, 23 Apr 2025 17:09:39 +0530 Subject: [PATCH 26/27] Moved AppSync tests to a new prpject --- .../EventsTests.NET8/AppSyncEventTests.cs | 287 ++++++++++++++++++ .../EventsTests.NET8/EventsTests.NET8.csproj | 1 + .../test/EventsTests.Shared/EventTests.cs | 255 ---------------- 3 files changed, 288 insertions(+), 255 deletions(-) create mode 100644 Libraries/test/EventsTests.NET8/AppSyncEventTests.cs diff --git a/Libraries/test/EventsTests.NET8/AppSyncEventTests.cs b/Libraries/test/EventsTests.NET8/AppSyncEventTests.cs new file mode 100644 index 000000000..4c927f1fd --- /dev/null +++ b/Libraries/test/EventsTests.NET8/AppSyncEventTests.cs @@ -0,0 +1,287 @@ + +#pragma warning disable 618 +namespace Amazon.Lambda.Tests; + +using Amazon.Lambda.AppSyncEvents; +using Amazon.Lambda.Core; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Xunit; + +public class AppSyncEventTests +{ + // This utility method takes care of removing the BOM that System.Text.Json doesn't like. + public MemoryStream LoadJsonTestFile(string filename) + { + var json = File.ReadAllText(filename); + return new MemoryStream(UTF8Encoding.UTF8.GetBytes(json)); + } + + public string SerializeJson(ILambdaSerializer serializer, T response) + { + string serializedJson; + using (MemoryStream stream = new MemoryStream()) + { + serializer.Serialize(response, stream); + + stream.Position = 0; + serializedJson = Encoding.UTF8.GetString(stream.ToArray()); + } + return serializedJson; + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTest(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event.json")) + { + var appSyncEvent = serializer.Deserialize>>(fileStream); + Assert.NotNull(appSyncEvent); + Assert.NotNull(appSyncEvent.Arguments); + Assert.NotNull(appSyncEvent.Arguments["input"]); + + Assert.NotNull(appSyncEvent.Request); + Assert.NotNull(appSyncEvent.Request.Headers); + var headers = appSyncEvent.Request.Headers; + Assert.Equal("value1", headers["key1"]); + Assert.Equal("value2", headers["key2"]); + + Assert.NotNull(appSyncEvent.Info); + Assert.Equal("openSupportTicket", appSyncEvent.Info.FieldName); + Assert.Equal("Mutation", appSyncEvent.Info.ParentTypeName); + + Assert.NotNull(appSyncEvent.Info.SelectionSetList); + Assert.Equal(6, appSyncEvent.Info.SelectionSetList.Count); + Assert.Contains("ticketId", appSyncEvent.Info.SelectionSetList); + Assert.Contains("status", appSyncEvent.Info.SelectionSetList); + Assert.Contains("title", appSyncEvent.Info.SelectionSetList); + Assert.Contains("description", appSyncEvent.Info.SelectionSetList); + Assert.Contains("createdAt", appSyncEvent.Info.SelectionSetList); + Assert.Contains("updatedAt", appSyncEvent.Info.SelectionSetList); + + Assert.NotNull(appSyncEvent.Info.SelectionSetGraphQL); + Assert.NotNull(appSyncEvent.Info.Variables); + Assert.NotNull(appSyncEvent.Info.Variables["input"]); + + Assert.NotNull(appSyncEvent.Stash); + Assert.Empty(appSyncEvent.Stash); + } + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTestCognitoAuthorizer(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-cognito-authorizer.json")) + { + var request = serializer.Deserialize>>(fileStream); + + Assert.NotNull(request.Identity); + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) + { + var identity = serializer.Deserialize(stream); + Assert.NotNull(identity); + + // Claims + Assert.NotNull(identity.Claims); + Assert.True(identity.Claims.ContainsKey("client_id")); + Assert.True(identity.Claims.ContainsKey("scope")); + Assert.True(identity.Claims.ContainsKey("sub")); + Assert.True(identity.Claims.ContainsKey("token_use")); + + // DefaultAuthStrategy + Assert.NotEmpty(identity.DefaultAuthStrategy); + + // Groups + Assert.NotNull(identity.Groups); + Assert.NotEmpty(identity.Groups); + + // Issuer + Assert.NotEmpty(identity.Issuer); + + // SourceIp + Assert.NotNull(identity.SourceIp); + Assert.NotEmpty(identity.SourceIp); + + // Sub + Assert.NotEmpty(identity.Sub); + + // Username + Assert.NotEmpty(identity.Username); + } + } + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTestIAMAuthorizer(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-iam-authorizer.json")) + { + var request = serializer.Deserialize>>(fileStream); + + Assert.NotNull(request.Identity); + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) + { + var identity = serializer.Deserialize(stream); + Assert.NotNull(identity); + + // AccountId + Assert.NotEmpty(identity.AccountId); + + // CognitoIdentityAuthProvider + Assert.NotEmpty(identity.CognitoIdentityAuthProvider); + + // CognitoIdentityAuthType + Assert.NotEmpty(identity.CognitoIdentityAuthType); + + // CognitoIdentityId + Assert.NotEmpty(identity.CognitoIdentityId); + + // CognitoIdentityPoolId + Assert.NotEmpty(identity.CognitoIdentityPoolId); + + // SourceIp + Assert.NotNull(identity.SourceIp); + Assert.NotEmpty(identity.SourceIp); + + // UserArn + Assert.NotEmpty(identity.UserArn); + + // Username + Assert.NotEmpty(identity.Username); + } + } + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTestLambdaAuthorizer(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-lambda-authorizer.json")) + { + var request = serializer.Deserialize>>(fileStream); + + Assert.NotNull(request.Identity); + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) + { + var identity = serializer.Deserialize(stream); + Assert.NotNull(identity); + + // ResolverContext + Assert.NotNull(identity.ResolverContext); + Assert.NotEmpty(identity.ResolverContext["userid"]); + Assert.NotEmpty(identity.ResolverContext["info"]); + Assert.NotEmpty(identity.ResolverContext["more_info"]); + } + } + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTestOidcAuthorizer(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-oidc-authorizer.json")) + { + var request = serializer.Deserialize>>(fileStream); + + Assert.NotNull(request.Identity); + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) + { + var identity = serializer.Deserialize(stream); + Assert.NotNull(identity); + + // Claims + Assert.NotNull(identity.Claims); + Assert.True(identity.Claims.ContainsKey("client_id")); + + // Issuer + Assert.NotEmpty(identity.Issuer); + + // Sub + Assert.NotEmpty(identity.Sub); + } + } + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTestLambdaAuthorizerRequestEvent(Type serializerType) + { + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + using (var fileStream = LoadJsonTestFile("appsync-event-lambda-authorizer-request.json")) + { + var request = serializer.Deserialize(fileStream); + + // Assert Authorization Token + Assert.Equal("custom-token", request.AuthorizationToken); + + // Assert Request Context + Assert.NotNull(request.RequestContext); + Assert.Equal("xxxxxxxx", request.RequestContext.ApiId); + Assert.Equal("112233445566", request.RequestContext.AccountId); + Assert.Equal("36307622-97fe-4dfa-bd71-b15b1d03ce97", request.RequestContext.RequestId); + Assert.Equal("MyQuery", request.RequestContext.OperationName); + Assert.NotNull(request.RequestContext.Variables); + Assert.Empty(request.RequestContext.Variables); + Assert.Contains("listTodos", request.RequestContext.QueryString); + + // Assert Request Headers + Assert.NotNull(request.RequestHeaders); + Assert.Equal("This is test token", request.RequestHeaders["authorization"]); + Assert.Equal("application/json", request.RequestHeaders["content-type"]); + Assert.Equal("https://ap-south-1.console.aws.amazon.com", request.RequestHeaders["origin"]); + } + } + + [Theory] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] + [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] + public void AppSyncTestLambdaAuthorizerResponseEvent(Type serializerType) + { + var response = new AppSyncAuthorizerResult + { + IsAuthorized = true, + ResolverContext = new Dictionary + { + { "userid", "test-user-id" }, + { "info", "contextual information A" }, + { "more_info", "contextual information B" } + }, + DeniedFields = new List + { + "arn:aws:appsync:us-east-1:1234567890:apis/xxxxxx/types/Event/fields/comments", + "Mutation.createEvent" + }, + TtlOverride = 10 + }; + + var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; + var json = SerializeJson(serializer, response); + var actualObject = JObject.Parse(json); + var expectedJObject = JObject.Parse(File.ReadAllText("appsync-event-lambda-authorizer-response.json")); + + Assert.True(JToken.DeepEquals(actualObject, expectedJObject)); + } +} + +#pragma warning restore 618 diff --git a/Libraries/test/EventsTests.NET8/EventsTests.NET8.csproj b/Libraries/test/EventsTests.NET8/EventsTests.NET8.csproj index 54bff1296..db86179bf 100644 --- a/Libraries/test/EventsTests.NET8/EventsTests.NET8.csproj +++ b/Libraries/test/EventsTests.NET8/EventsTests.NET8.csproj @@ -14,6 +14,7 @@ PreserveNewest + diff --git a/Libraries/test/EventsTests.Shared/EventTests.cs b/Libraries/test/EventsTests.Shared/EventTests.cs index f9ef72f46..f4cd6d902 100644 --- a/Libraries/test/EventsTests.Shared/EventTests.cs +++ b/Libraries/test/EventsTests.Shared/EventTests.cs @@ -3,9 +3,6 @@ namespace Amazon.Lambda.Tests { using Amazon.Lambda.APIGatewayEvents; using Amazon.Lambda.ApplicationLoadBalancerEvents; -#if NET8_0_OR_GREATER - using Amazon.Lambda.AppSyncEvents; -#endif using Amazon.Lambda.CloudWatchEvents.BatchEvents; using Amazon.Lambda.CloudWatchEvents.ECSEvents; using Amazon.Lambda.CloudWatchEvents.S3Events; @@ -3911,258 +3908,6 @@ public void TestJsonIncludeNullValueSerializer() Assert.Equal(JTokenType.Null, serialized["SomeOtherValue"].Type); // System.NullReferenceException is thrown if value is missing. } -#if NET8_0_OR_GREATER - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTest(Type serializerType) - { - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - using (var fileStream = LoadJsonTestFile("appsync-event.json")) - { - var appSyncEvent = serializer.Deserialize>>(fileStream); - Assert.NotNull(appSyncEvent); - Assert.NotNull(appSyncEvent.Arguments); - Assert.NotNull(appSyncEvent.Arguments["input"]); - - Assert.NotNull(appSyncEvent.Request); - Assert.NotNull(appSyncEvent.Request.Headers); - var headers = appSyncEvent.Request.Headers; - Assert.Equal("value1", headers["key1"]); - Assert.Equal("value2", headers["key2"]); - - Assert.NotNull(appSyncEvent.Info); - Assert.Equal("openSupportTicket", appSyncEvent.Info.FieldName); - Assert.Equal("Mutation", appSyncEvent.Info.ParentTypeName); - - Assert.NotNull(appSyncEvent.Info.SelectionSetList); - Assert.Equal(6, appSyncEvent.Info.SelectionSetList.Count); - Assert.Contains("ticketId", appSyncEvent.Info.SelectionSetList); - Assert.Contains("status", appSyncEvent.Info.SelectionSetList); - Assert.Contains("title", appSyncEvent.Info.SelectionSetList); - Assert.Contains("description", appSyncEvent.Info.SelectionSetList); - Assert.Contains("createdAt", appSyncEvent.Info.SelectionSetList); - Assert.Contains("updatedAt", appSyncEvent.Info.SelectionSetList); - - Assert.NotNull(appSyncEvent.Info.SelectionSetGraphQL); - Assert.NotNull(appSyncEvent.Info.Variables); - Assert.NotNull(appSyncEvent.Info.Variables["input"]); - - Assert.NotNull(appSyncEvent.Stash); - Assert.Empty(appSyncEvent.Stash); - } - } - - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTestCognitoAuthorizer(Type serializerType) - { - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - using (var fileStream = LoadJsonTestFile("appsync-event-cognito-authorizer.json")) - { - var request = serializer.Deserialize>>(fileStream); - - Assert.NotNull(request.Identity); - - using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) - { - var identity = serializer.Deserialize(stream); - Assert.NotNull(identity); - - // Claims - Assert.NotNull(identity.Claims); - Assert.True(identity.Claims.ContainsKey("client_id")); - Assert.True(identity.Claims.ContainsKey("scope")); - Assert.True(identity.Claims.ContainsKey("sub")); - Assert.True(identity.Claims.ContainsKey("token_use")); - - // DefaultAuthStrategy - Assert.NotEmpty(identity.DefaultAuthStrategy); - - // Groups - Assert.NotNull(identity.Groups); - Assert.NotEmpty(identity.Groups); - - // Issuer - Assert.NotEmpty(identity.Issuer); - - // SourceIp - Assert.NotNull(identity.SourceIp); - Assert.NotEmpty(identity.SourceIp); - - // Sub - Assert.NotEmpty(identity.Sub); - - // Username - Assert.NotEmpty(identity.Username); - } - } - } - - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTestIAMAuthorizer(Type serializerType) - { - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - using (var fileStream = LoadJsonTestFile("appsync-event-iam-authorizer.json")) - { - var request = serializer.Deserialize>>(fileStream); - - Assert.NotNull(request.Identity); - - using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) - { - var identity = serializer.Deserialize(stream); - Assert.NotNull(identity); - - // AccountId - Assert.NotEmpty(identity.AccountId); - - // CognitoIdentityAuthProvider - Assert.NotEmpty(identity.CognitoIdentityAuthProvider); - - // CognitoIdentityAuthType - Assert.NotEmpty(identity.CognitoIdentityAuthType); - - // CognitoIdentityId - Assert.NotEmpty(identity.CognitoIdentityId); - - // CognitoIdentityPoolId - Assert.NotEmpty(identity.CognitoIdentityPoolId); - - // SourceIp - Assert.NotNull(identity.SourceIp); - Assert.NotEmpty(identity.SourceIp); - - // UserArn - Assert.NotEmpty(identity.UserArn); - - // Username - Assert.NotEmpty(identity.Username); - } - } - } - - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTestLambdaAuthorizer(Type serializerType) - { - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - using (var fileStream = LoadJsonTestFile("appsync-event-lambda-authorizer.json")) - { - var request = serializer.Deserialize>>(fileStream); - - Assert.NotNull(request.Identity); - - using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) - { - var identity = serializer.Deserialize(stream); - Assert.NotNull(identity); - - // ResolverContext - Assert.NotNull(identity.ResolverContext); - Assert.NotEmpty(identity.ResolverContext["userid"]); - Assert.NotEmpty(identity.ResolverContext["info"]); - Assert.NotEmpty(identity.ResolverContext["more_info"]); - } - } - } - - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTestOidcAuthorizer(Type serializerType) - { - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - using (var fileStream = LoadJsonTestFile("appsync-event-oidc-authorizer.json")) - { - var request = serializer.Deserialize>>(fileStream); - - Assert.NotNull(request.Identity); - - using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString()))) - { - var identity = serializer.Deserialize(stream); - Assert.NotNull(identity); - - // Claims - Assert.NotNull(identity.Claims); - Assert.True(identity.Claims.ContainsKey("client_id")); - - // Issuer - Assert.NotEmpty(identity.Issuer); - - // Sub - Assert.NotEmpty(identity.Sub); - } - } - } - - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTestLambdaAuthorizerRequestEvent(Type serializerType) - { - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - using (var fileStream = LoadJsonTestFile("appsync-event-lambda-authorizer-request.json")) - { - var request = serializer.Deserialize(fileStream); - - // Assert Authorization Token - Assert.Equal("custom-token", request.AuthorizationToken); - - // Assert Request Context - Assert.NotNull(request.RequestContext); - Assert.Equal("xxxxxxxx", request.RequestContext.ApiId); - Assert.Equal("112233445566", request.RequestContext.AccountId); - Assert.Equal("36307622-97fe-4dfa-bd71-b15b1d03ce97", request.RequestContext.RequestId); - Assert.Equal("MyQuery", request.RequestContext.OperationName); - Assert.NotNull(request.RequestContext.Variables); - Assert.Empty(request.RequestContext.Variables); - Assert.Contains("listTodos", request.RequestContext.QueryString); - - // Assert Request Headers - Assert.NotNull(request.RequestHeaders); - Assert.Equal("This is test token", request.RequestHeaders["authorization"]); - Assert.Equal("application/json", request.RequestHeaders["content-type"]); - Assert.Equal("https://ap-south-1.console.aws.amazon.com", request.RequestHeaders["origin"]); - } - } - - [Theory] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))] - [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] - public void AppSyncTestLambdaAuthorizerResponseEvent(Type serializerType) - { - var response = new AppSyncAuthorizerResult - { - IsAuthorized = true, - ResolverContext = new Dictionary - { - { "userid", "test-user-id" }, - { "info", "contextual information A" }, - { "more_info", "contextual information B" } - }, - DeniedFields = new List - { - "arn:aws:appsync:us-east-1:1234567890:apis/xxxxxx/types/Event/fields/comments", - "Mutation.createEvent" - }, - TtlOverride = 10 - }; - - var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer; - var json = SerializeJson(serializer, response); - var actualObject = JObject.Parse(json); - var expectedJObject = JObject.Parse(File.ReadAllText("appsync-event-lambda-authorizer-response.json")); - - Assert.True(JToken.DeepEquals(actualObject, expectedJObject)); - } -#endif - class ClassUsingPascalCase { public int SomeValue { get; set; } From 089f4115aff972027b88e7375c608377794815b3 Mon Sep 17 00:00:00 2001 From: Ankush Jain Date: Wed, 23 Apr 2025 17:29:54 +0530 Subject: [PATCH 27/27] Reverted EventTests file --- .../test/EventsTests.Shared/EventTests.cs | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Libraries/test/EventsTests.Shared/EventTests.cs b/Libraries/test/EventsTests.Shared/EventTests.cs index f4cd6d902..fa2cf6e04 100644 --- a/Libraries/test/EventsTests.Shared/EventTests.cs +++ b/Libraries/test/EventsTests.Shared/EventTests.cs @@ -951,7 +951,7 @@ public void CognitoDefineAuthChallengeEventTest(Type serializerType) Assert.True(session0.ChallengeResult); Assert.Equal("challenge_metadata1", session0.ChallengeMetadata); - + var session1 = cognitoDefineAuthChallengeEvent.Request.Session[1]; Assert.Equal("challenge2", session1.ChallengeName); Assert.False(session1.ChallengeResult); @@ -1109,7 +1109,7 @@ public void CognitoVerifyAuthChallengeEventTest(Type serializerType) Assert.Equal("private_value_2", cognitoVerifyAuthChallengeEvent.Request.PrivateChallengeParameters.ToArray()[1].Value); Assert.True(cognitoVerifyAuthChallengeEvent.Request.UserNotFound); - + Assert.True(cognitoVerifyAuthChallengeEvent.Response.AnswerCorrect); MemoryStream ms = new MemoryStream(); @@ -1253,11 +1253,11 @@ public void CognitoPreTokenGenerationV2EventTest(Type serializerType) 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]); - + // Value comparison would vary across different serializers. Skip it for now and validate the complete JSON later. Assert.Equal(5, cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.IdTokenGeneration.ClaimsToAddOrOverride.Count); Assert.Equal("id_claim_1", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.IdTokenGeneration.ClaimsToAddOrOverride.ToArray()[0].Key); @@ -1265,7 +1265,7 @@ public void CognitoPreTokenGenerationV2EventTest(Type serializerType) Assert.Equal("id_claim_3", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.IdTokenGeneration.ClaimsToAddOrOverride.ToArray()[2].Key); Assert.Equal("id_claim_4", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.IdTokenGeneration.ClaimsToAddOrOverride.ToArray()[3].Key); Assert.Equal("id_claim_5", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.IdTokenGeneration.ClaimsToAddOrOverride.ToArray()[4].Key); - + 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]); @@ -1277,7 +1277,7 @@ public void CognitoPreTokenGenerationV2EventTest(Type serializerType) Assert.Equal("access_claim_3", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ClaimsToAddOrOverride.ToArray()[2].Key); Assert.Equal("access_claim_4", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ClaimsToAddOrOverride.ToArray()[3].Key); Assert.Equal("access_claim_5", cognitoPreTokenGenerationV2Event.Response.ClaimsAndScopeOverrideDetails.AccessTokenGeneration.ClaimsToAddOrOverride.ToArray()[4].Key); - + 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]); @@ -1287,7 +1287,7 @@ public void CognitoPreTokenGenerationV2EventTest(Type serializerType) 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]); @@ -1308,7 +1308,7 @@ public void CognitoPreTokenGenerationV2EventTest(Type serializerType) 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 @@ -2049,7 +2049,7 @@ public void APIGatewayAuthorizerWithSimpleIAMConditionResponseTest(Type serializ Condition = new Dictionary>() { { "StringEquals", new Dictionary() - { + { { "aws:PrincipalTag/job-category", "iamuser-admin" } } } @@ -2112,16 +2112,16 @@ public void APIGatewayAuthorizerWithMultiValueIAMConditionResponseTest(Type seri Resource = new HashSet{ "*" }, Condition = new Dictionary>() { - { - "StringEquals", + { + "StringEquals", new Dictionary() { { "aws:PrincipalTag/department", new List{ "finance", "hr", "legal" } }, { "aws:PrincipalTag/role", new List{ "audit", "security" } } } }, - { - "ArnLike", + { + "ArnLike", new Dictionary() { { "aws:PrincipalArn", new List{ "arn:aws:iam::XXXXXXXXXXXX:user/User1", "arn:aws:iam::XXXXXXXXXXXX:user/User2" } } @@ -3915,4 +3915,4 @@ class ClassUsingPascalCase } } } -#pragma warning restore 618 +#pragma warning restore 618 \ No newline at end of file