Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .autover/changes/b0df0353-6e47-4548-94a7-45b42f67b910.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"Projects": [
{
"Name": "Amazon.Lambda.APIGatewayEvents",
"Type": "Patch",
"ChangelogMessages": [
"Added NotResource field to APIGatewayCustomAuthorizerPolicy.IAMPolicyStatement"
]
}
]
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Amazon.Lambda.APIGatewayEvents
namespace Amazon.Lambda.APIGatewayEvents
{
using System.Collections.Generic;

Expand Down Expand Up @@ -52,6 +52,14 @@ public class IAMPolicyStatement
#endif
public HashSet<string> Resource { get; set; }

/// <summary>
/// Gets or sets the resources the statement does not apply to.
/// </summary>
#if NETCOREAPP3_1_OR_GREATER
[System.Text.Json.Serialization.JsonPropertyName("NotResource")]
#endif
public HashSet<string> NotResource { get; set; }

/// <summary>
/// Gets or sets the conditions for when a policy is in effect.
/// https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
Expand Down Expand Up @@ -221,10 +221,11 @@ public void TestCustomAuthorizerSerialization()

var json = JsonSerializer.Serialize(response, new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull
});
Assert.NotNull(json);
var expected = "{\"principalId\":\"com.amazon.someuser\",\"policyDocument\":{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":[\"execute-api:Invoke\"],\"Resource\":[\"arn:aws:execute-api:us-west-2:1234567890:apit123d45/Prod/GET/*\"],\"Condition\":null}]},\"context\":{\"stringKey\":\"Hey I'm a string\",\"boolKey\":true,\"numKey\":9},\"usageIdentifierKey\":null}";
var expected = "{\"principalId\":\"com.amazon.someuser\",\"policyDocument\":{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":[\"execute-api:Invoke\"],\"Resource\":[\"arn:aws:execute-api:us-west-2:1234567890:apit123d45/Prod/GET/*\"]}]},\"context\":{\"stringKey\":\"Hey I'm a string\",\"boolKey\":true,\"numKey\":9}}";
Assert.Equal(expected, json);
}

Expand Down
66 changes: 66 additions & 0 deletions Libraries/test/EventsTests.Shared/EventTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2165,6 +2165,72 @@ public void APIGatewayAuthorizerWithMultiValueIAMConditionResponseTest(Type seri
Assert.Equal("arn:aws:iam::XXXXXXXXXXXX:user/User2", root["policyDocument"]["Statement"][0]["Condition"]["ArnLike"]["aws:PrincipalArn"][1]);
}

[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 APIGatewayAuthorizerResponseNotResourceTest(Type serializerType)
{
var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer;
var context = new APIGatewayCustomAuthorizerContextOutput();
context["field1"] = "value1";
context["field2"] = "value2";

var response = new APIGatewayCustomAuthorizerResponse
{
PrincipalID = "prin1",
UsageIdentifierKey = "usageKey",
Context = context,
PolicyDocument = new APIGatewayCustomAuthorizerPolicy
{
Version = "2012-10-17",
Statement = new List<APIGatewayCustomAuthorizerPolicy.IAMPolicyStatement>
{
new APIGatewayCustomAuthorizerPolicy.IAMPolicyStatement
{
Action = new HashSet<string>{ "execute-api:Invoke" },
Effect = "Deny",
NotResource = new HashSet<string>
{
"arn:aws:execute-api:us-east-1:1234567890:abcdef1234/Prod/GET/resource1",
"arn:aws:execute-api:us-east-1:1234567890:abcdef1234/Prod/GET/resource2"
}
}
}
}
};

string serializedJson;
using (MemoryStream stream = new MemoryStream())
{
serializer.Serialize(response, stream);

stream.Position = 0;
serializedJson = Encoding.UTF8.GetString(stream.ToArray());
}

JObject root = Newtonsoft.Json.JsonConvert.DeserializeObject(serializedJson) as JObject;

Assert.Equal("prin1", root["principalId"]);
Assert.Equal("usageKey", root["usageIdentifierKey"]);
Assert.Equal("value1", root["context"]["field1"]);
Assert.Equal("value2", root["context"]["field2"]);

Assert.Equal("2012-10-17", root["policyDocument"]["Version"]);
Assert.Equal("execute-api:Invoke", root["policyDocument"]["Statement"][0]["Action"][0]);
Assert.Equal("Deny", root["policyDocument"]["Statement"][0]["Effect"]);

var allowedResources = root["policyDocument"]["Statement"][0]["NotResource"];
Assert.Equal(2, allowedResources.Count());
Assert.Contains("arn:aws:execute-api:us-east-1:1234567890:abcdef1234/Prod/GET/resource1", allowedResources);
Assert.Contains("arn:aws:execute-api:us-east-1:1234567890:abcdef1234/Prod/GET/resource2", allowedResources);

Assert.Null(root["policyDocument"]["Statement"][0]["Condition"]);
Assert.Null(root["policyDocument"]["Statement"][0]["Resource"]);
}

[Theory]
[InlineData(typeof(JsonSerializer))]
#if NETCOREAPP3_1_OR_GREATER
Expand Down