Skip to content

Commit 7c977a4

Browse files
committed
update IT tests
1 parent f57feca commit 7c977a4

12 files changed

Lines changed: 2097 additions & 40 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// <auto-generated/>
2+
3+
using System;
4+
using System.Linq;
5+
using System.Collections.Generic;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
using System.IO;
9+
using Amazon.Lambda.Core;
10+
11+
namespace TestCustomAuthorizerApp
12+
{
13+
public class AuthorizerFunction_HttpApiAuthorizeV1_Generated
14+
{
15+
private readonly AuthorizerFunction authorizerFunction;
16+
private readonly Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer serializer;
17+
18+
/// <summary>
19+
/// Default constructor. This constructor is used by Lambda to construct the instance. When invoked in a Lambda environment
20+
/// the AWS credentials will come from the IAM role associated with the function and the AWS region will be set to the
21+
/// region the Lambda function is executed in.
22+
/// </summary>
23+
public AuthorizerFunction_HttpApiAuthorizeV1_Generated()
24+
{
25+
SetExecutionEnvironment();
26+
authorizerFunction = new AuthorizerFunction();
27+
serializer = new Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer();
28+
}
29+
30+
/// <summary>
31+
/// The generated Lambda function handler for <see cref="HttpApiAuthorizeV1(Amazon.Lambda.APIGatewayEvents.APIGatewayCustomAuthorizerRequest, Amazon.Lambda.Core.ILambdaContext)"/>
32+
/// </summary>
33+
/// <param name="__request__">The request object that will be processed by the Lambda function handler.</param>
34+
/// <param name="__context__">The ILambdaContext that provides methods for logging and describing the Lambda environment.</param>
35+
/// <returns>Result of the Lambda function execution</returns>
36+
public Amazon.Lambda.APIGatewayEvents.APIGatewayCustomAuthorizerResponse HttpApiAuthorizeV1(Amazon.Lambda.APIGatewayEvents.APIGatewayCustomAuthorizerRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__)
37+
{
38+
return authorizerFunction.HttpApiAuthorizeV1(__request__, __context__);
39+
}
40+
41+
private static void SetExecutionEnvironment()
42+
{
43+
const string envName = "AWS_EXECUTION_ENV";
44+
45+
var envValue = new StringBuilder();
46+
47+
// If there is an existing execution environment variable add the annotations package as a suffix.
48+
if(!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(envName)))
49+
{
50+
envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_");
51+
}
52+
53+
envValue.Append("lib/amazon-lambda-annotations#{ANNOTATIONS_ASSEMBLY_VERSION}");
54+
55+
Environment.SetEnvironmentVariable(envName, envValue.ToString());
56+
}
57+
}
58+
}

Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/customAuthorizerApp.template

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,23 @@
2727
},
2828
"EnableFunctionDefaultPermissions": true,
2929
"AuthorizerResultTtlInSeconds": 0
30+
},
31+
"HttpApiLambdaAuthorizerV1": {
32+
"FunctionArn": {
33+
"Fn::GetAtt": [
34+
"CustomAuthorizerV1",
35+
"Arn"
36+
]
37+
},
38+
"AuthorizerPayloadFormatVersion": "1.0",
39+
"EnableSimpleResponses": false,
40+
"Identity": {
41+
"Headers": [
42+
"authorization"
43+
]
44+
},
45+
"EnableFunctionDefaultPermissions": true,
46+
"AuthorizerResultTtlInSeconds": 0
3047
}
3148
}
3249
}
@@ -74,6 +91,23 @@
7491
"Handler": "TestProject::TestCustomAuthorizerApp.AuthorizerFunction_HttpApiAuthorize_Generated::HttpApiAuthorize"
7592
}
7693
},
94+
"CustomAuthorizerV1": {
95+
"Type": "AWS::Serverless::Function",
96+
"Metadata": {
97+
"Tool": "Amazon.Lambda.Annotations"
98+
},
99+
"Properties": {
100+
"Runtime": "dotnet6",
101+
"CodeUri": ".",
102+
"MemorySize": 512,
103+
"Timeout": 30,
104+
"Policies": [
105+
"AWSLambdaBasicExecutionRole"
106+
],
107+
"PackageType": "Zip",
108+
"Handler": "TestProject::TestCustomAuthorizerApp.AuthorizerFunction_HttpApiAuthorizeV1_Generated::HttpApiAuthorizeV1"
109+
}
110+
},
77111
"RestApiAuthorizer": {
78112
"Type": "AWS::Serverless::Function",
79113
"Metadata": {
@@ -187,7 +221,8 @@
187221
"SyncedEventProperties": {
188222
"RootGet": [
189223
"Path",
190-
"Method"
224+
"Method",
225+
"ApiId.Ref"
191226
]
192227
}
193228
},
@@ -206,7 +241,10 @@
206241
"Type": "HttpApi",
207242
"Properties": {
208243
"Path": "/api/health",
209-
"Method": "GET"
244+
"Method": "GET",
245+
"ApiId": {
246+
"Ref": "AnnotationsHttpApi"
247+
}
210248
}
211249
}
212250
}
@@ -290,7 +328,7 @@
290328
"Method": "GET",
291329
"PayloadFormatVersion": "1.0",
292330
"Auth": {
293-
"Authorizer": "HttpApiLambdaAuthorizer"
331+
"Authorizer": "HttpApiLambdaAuthorizerV1"
294332
},
295333
"ApiId": {
296334
"Ref": "AnnotationsHttpApi"

Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1654,6 +1654,7 @@ public async Task CustomAuthorizerAppAuthorizerDefinitionsTest()
16541654
{
16551655
var expectedTemplateContent = await ReadSnapshotContent(Path.Combine("Snapshots", "ServerlessTemplates", "customAuthorizerApp.template"));
16561656
var expectedHttpApiAuthorizeGenerated = await ReadSnapshotContent(Path.Combine("Snapshots", "AuthorizerFunction_HttpApiAuthorize_Generated.g.cs"));
1657+
var expectedHttpApiAuthorizeV1Generated = await ReadSnapshotContent(Path.Combine("Snapshots", "AuthorizerFunction_HttpApiAuthorizeV1_Generated.g.cs"));
16571658
var expectedRestApiAuthorizeGenerated = await ReadSnapshotContent(Path.Combine("Snapshots", "AuthorizerFunction_RestApiAuthorize_Generated.g.cs"));
16581659
var expectedGetProtectedDataGenerated = await ReadSnapshotContent(Path.Combine("Snapshots", "ProtectedFunction_GetProtectedData_Generated.g.cs"));
16591660
var expectedGetUserInfoGenerated = await ReadSnapshotContent(Path.Combine("Snapshots", "ProtectedFunction_GetUserInfo_Generated.g.cs"));
@@ -1676,6 +1677,7 @@ public async Task CustomAuthorizerAppAuthorizerDefinitionsTest()
16761677
(Path.Combine("Amazon.Lambda.Annotations", "APIGateway", "HttpApiAttribute.cs"), File.ReadAllText(Path.Combine("Amazon.Lambda.Annotations", "APIGateway", "HttpApiAttribute.cs"))),
16771678
(Path.Combine("Amazon.Lambda.Annotations", "APIGateway", "RestApiAttribute.cs"), File.ReadAllText(Path.Combine("Amazon.Lambda.Annotations", "APIGateway", "RestApiAttribute.cs"))),
16781679
(Path.Combine("Amazon.Lambda.Annotations", "APIGateway", "HttpApiAuthorizerAttribute.cs"), File.ReadAllText(Path.Combine("Amazon.Lambda.Annotations", "APIGateway", "HttpApiAuthorizerAttribute.cs"))),
1680+
(Path.Combine("Amazon.Lambda.Annotations", "APIGateway", "AuthorizerPayloadFormatVersion.cs"), File.ReadAllText(Path.Combine("Amazon.Lambda.Annotations", "APIGateway", "AuthorizerPayloadFormatVersion.cs"))),
16791681
(Path.Combine("Amazon.Lambda.Annotations", "APIGateway", "RestApiAuthorizerAttribute.cs"), File.ReadAllText(Path.Combine("Amazon.Lambda.Annotations", "APIGateway", "RestApiAuthorizerAttribute.cs"))),
16801682
(Path.Combine("Amazon.Lambda.Annotations", "APIGateway", "FromCustomAuthorizerAttribute.cs"), File.ReadAllText(Path.Combine("Amazon.Lambda.Annotations", "APIGateway", "FromCustomAuthorizerAttribute.cs"))),
16811683
},
@@ -1686,6 +1688,11 @@ public async Task CustomAuthorizerAppAuthorizerDefinitionsTest()
16861688
"AuthorizerFunction_HttpApiAuthorize_Generated.g.cs",
16871689
SourceText.From(expectedHttpApiAuthorizeGenerated, Encoding.UTF8, SourceHashAlgorithm.Sha256)
16881690
),
1691+
(
1692+
typeof(SourceGenerator.Generator),
1693+
"AuthorizerFunction_HttpApiAuthorizeV1_Generated.g.cs",
1694+
SourceText.From(expectedHttpApiAuthorizeV1Generated, Encoding.UTF8, SourceHashAlgorithm.Sha256)
1695+
),
16891696
(
16901697
typeof(SourceGenerator.Generator),
16911698
"AuthorizerFunction_RestApiAuthorize_Generated.g.cs",
@@ -1729,6 +1736,7 @@ public async Task CustomAuthorizerAppAuthorizerDefinitionsTest()
17291736
},
17301737
ExpectedDiagnostics =
17311738
{
1739+
new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info).WithArguments("AuthorizerFunction_HttpApiAuthorizeV1_Generated.g.cs", expectedHttpApiAuthorizeV1Generated),
17321740
new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info).WithArguments("AuthorizerFunction_HttpApiAuthorize_Generated.g.cs", expectedHttpApiAuthorizeGenerated),
17331741
new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info).WithArguments("AuthorizerFunction_RestApiAuthorize_Generated.g.cs", expectedRestApiAuthorizeGenerated),
17341742
new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info).WithArguments("ProtectedFunction_GetProtectedData_Generated.g.cs", expectedGetProtectedDataGenerated),

Libraries/test/TestCustomAuthorizerApp.IntegrationTests/HealthCheckTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public HealthCheckTests(IntegrationTestContextFixture fixture)
2020
public async Task HealthCheck_ReturnsOk_WithoutAuthorization()
2121
{
2222
// Arrange & Act
23-
var response = await _fixture.HttpClient.GetAsync($"{_fixture.ImplicitHttpApiUrl}/api/health");
23+
var response = await _fixture.HttpClient.GetAsync($"{_fixture.HttpApiUrl}/api/health");
2424

2525
// Assert
2626
Assert.Equal(HttpStatusCode.OK, response.StatusCode);

Libraries/test/TestCustomAuthorizerApp.IntegrationTests/IntegrationTestContextFixture.cs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,10 @@ public class IntegrationTestContextFixture : IAsyncLifetime
2323
public readonly HttpClient HttpClient;
2424

2525
/// <summary>
26-
/// HTTP API base URL for endpoints explicitly attached to AnnotationsHttpApi (no trailing slash)
26+
/// HTTP API base URL for endpoints attached to AnnotationsHttpApi (no trailing slash)
2727
/// </summary>
2828
public string HttpApiUrl = string.Empty;
2929

30-
/// <summary>
31-
/// HTTP API base URL for endpoints using the implicit SAM-generated ServerlessHttpApi (no trailing slash).
32-
/// Functions without an explicit ApiId (e.g. HealthCheck) are placed on this API.
33-
/// </summary>
34-
public string ImplicitHttpApiUrl = string.Empty;
35-
3630
/// <summary>
3731
/// REST API base URL (no trailing slash)
3832
/// </summary>
@@ -76,24 +70,21 @@ public async Task InitializeAsync()
7670
var region = "us-west-2";
7771
Console.WriteLine($"[IntegrationTest] Querying stack resources for '{_stackName}'...");
7872
var httpApiId = await _cloudFormationHelper.GetResourcePhysicalIdAsync(_stackName, "AnnotationsHttpApi");
79-
var implicitHttpApiId = await _cloudFormationHelper.GetResourcePhysicalIdAsync(_stackName, "ServerlessHttpApi");
8073
var restApiId = await _cloudFormationHelper.GetResourcePhysicalIdAsync(_stackName, "AnnotationsRestApi");
81-
Console.WriteLine($"[IntegrationTest] AnnotationsHttpApi: {httpApiId}, ServerlessHttpApi: {implicitHttpApiId}, AnnotationsRestApi: {restApiId}");
74+
Console.WriteLine($"[IntegrationTest] AnnotationsHttpApi: {httpApiId}, AnnotationsRestApi: {restApiId}");
8275
Assert.False(string.IsNullOrEmpty(httpApiId), $"CloudFormation resource 'AnnotationsHttpApi' was not found in stack '{_stackName}'.");
83-
Assert.False(string.IsNullOrEmpty(implicitHttpApiId), $"CloudFormation resource 'ServerlessHttpApi' was not found in stack '{_stackName}'.");
8476
Assert.False(string.IsNullOrEmpty(restApiId), $"CloudFormation resource 'AnnotationsRestApi' was not found in stack '{_stackName}'.");
8577
HttpApiUrl = $"https://{httpApiId}.execute-api.{region}.amazonaws.com";
86-
ImplicitHttpApiUrl = $"https://{implicitHttpApiId}.execute-api.{region}.amazonaws.com";
8778
RestApiUrl = $"https://{restApiId}.execute-api.{region}.amazonaws.com/Prod";
8879

8980
LambdaFunctions = await LambdaHelper.FilterByCloudFormationStackAsync(_stackName);
9081
Console.WriteLine($"[IntegrationTest] Found {LambdaFunctions.Count} Lambda functions: {string.Join(", ", LambdaFunctions.Select(f => f.Name ?? "(null)"))}");
9182

9283
Assert.True(await _s3Helper.BucketExistsAsync(_bucketName), $"S3 bucket {_bucketName} should exist");
9384

94-
// There are 9 Lambda functions in TestCustomAuthorizerApp:
95-
// CustomAuthorizer, RestApiAuthorizer, ProtectedEndpoint, GetUserInfo, HealthCheck, RestUserInfo, HttpApiV1UserInfo, IHttpResultUserInfo, NonStringUserInfo
96-
Assert.Equal(9, LambdaFunctions.Count);
85+
// There are 10 Lambda functions in TestCustomAuthorizerApp:
86+
// CustomAuthorizer, CustomAuthorizerV1, RestApiAuthorizer, ProtectedEndpoint, GetUserInfo, HealthCheck, RestUserInfo, HttpApiV1UserInfo, IHttpResultUserInfo, NonStringUserInfo
87+
Assert.Equal(10, LambdaFunctions.Count);
9788

9889
await LambdaHelper.WaitTillNotPending(LambdaFunctions.Where(x => x.Name != null).Select(x => x.Name!).ToList());
9990

Libraries/test/TestCustomAuthorizerApp/AuthorizerFunction.cs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,89 @@ public APIGatewayCustomAuthorizerV2SimpleResponse HttpApiAuthorize(
116116
};
117117
}
118118

119+
/// <summary>
120+
/// HTTP API Lambda Authorizer (Payload format 1.0)
121+
/// Used by HTTP API V1 endpoints that need payload format 1.0
122+
/// </summary>
123+
[LambdaFunction(ResourceName = "CustomAuthorizerV1")]
124+
[HttpApiAuthorizer(
125+
Name = "HttpApiLambdaAuthorizerV1",
126+
IdentityHeader = "authorization",
127+
EnableSimpleResponses = false,
128+
AuthorizerPayloadFormatVersion = AuthorizerPayloadFormatVersion.V1)]
129+
public APIGatewayCustomAuthorizerResponse HttpApiAuthorizeV1(
130+
APIGatewayCustomAuthorizerRequest request,
131+
ILambdaContext context)
132+
{
133+
context.Logger.LogLine($"V1 Authorizer invoked");
134+
context.Logger.LogLine($"Authorization token: {request.AuthorizationToken}");
135+
136+
var authToken = request.AuthorizationToken ?? "";
137+
138+
// Deny if not a valid or partial-context token
139+
if (!ValidTokens.Contains(authToken) && !PartialContextTokens.Contains(authToken))
140+
{
141+
context.Logger.LogLine("V1 Authorizer: Denying request");
142+
return GenerateDenyPolicy("anonymous", request.MethodArn);
143+
}
144+
145+
// Check for partial-context tokens - authorize but return incomplete context
146+
if (PartialContextTokens.Contains(authToken))
147+
{
148+
context.Logger.LogLine("V1 Authorizer: Authorizing with partial context (missing expected keys)");
149+
150+
return new APIGatewayCustomAuthorizerResponse
151+
{
152+
PrincipalID = "partial-user",
153+
PolicyDocument = new APIGatewayCustomAuthorizerPolicy
154+
{
155+
Version = "2012-10-17",
156+
Statement = new List<APIGatewayCustomAuthorizerPolicy.IAMPolicyStatement>
157+
{
158+
new APIGatewayCustomAuthorizerPolicy.IAMPolicyStatement
159+
{
160+
Action = new HashSet<string> { "execute-api:Invoke" },
161+
Effect = "Allow",
162+
Resource = new HashSet<string> { request.MethodArn }
163+
}
164+
}
165+
},
166+
Context = new APIGatewayCustomAuthorizerContextOutput
167+
{
168+
// Intentionally return only unexpected keys, omitting userId, tenantId, email
169+
["unexpectedKey"] = "some-value"
170+
}
171+
};
172+
}
173+
174+
context.Logger.LogLine("V1 Authorizer: Authorizing request with valid token");
175+
176+
return new APIGatewayCustomAuthorizerResponse
177+
{
178+
PrincipalID = "user-12345",
179+
PolicyDocument = new APIGatewayCustomAuthorizerPolicy
180+
{
181+
Version = "2012-10-17",
182+
Statement = new List<APIGatewayCustomAuthorizerPolicy.IAMPolicyStatement>
183+
{
184+
new APIGatewayCustomAuthorizerPolicy.IAMPolicyStatement
185+
{
186+
Action = new HashSet<string> { "execute-api:Invoke" },
187+
Effect = "Allow",
188+
Resource = new HashSet<string> { request.MethodArn }
189+
}
190+
}
191+
},
192+
Context = new APIGatewayCustomAuthorizerContextOutput
193+
{
194+
["userId"] = "user-12345",
195+
["tenantId"] = "42",
196+
["userRole"] = "admin",
197+
["email"] = "test@example.com"
198+
}
199+
};
200+
}
201+
119202
/// <summary>
120203
/// REST API Lambda Authorizer (Token-based authorizer)
121204
/// Returns an IAM policy document along with custom context values

Libraries/test/TestCustomAuthorizerApp/ProtectedFunction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ public object GetRestUserInfo(
149149
/// where RequestContext.Authorizer is a dictionary, not RequestContext.Authorizer.Lambda.
150150
/// </summary>
151151
[LambdaFunction(ResourceName = "HttpApiV1UserInfo")]
152-
[HttpApi(LambdaHttpMethod.Get, "/api/http-v1-user-info", Version = HttpApiVersion.V1, Authorizer = "HttpApiLambdaAuthorizer")]
152+
[HttpApi(LambdaHttpMethod.Get, "/api/http-v1-user-info", Version = HttpApiVersion.V1, Authorizer = "HttpApiLambdaAuthorizerV1")]
153153
public object GetHttpApiV1UserInfo(
154154
[FromCustomAuthorizer(Name = "userId")] string userId,
155155
[FromCustomAuthorizer(Name = "email")] string email,

Libraries/test/TestCustomAuthorizerApp/aws-lambda-tools-defaults.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"configuration": "Release",
99
"template": "serverless.template",
1010
"template-parameters": "",
11-
"s3-bucket": "test-custom-authorizer-app",
11+
"s3-bucket" : "test-custom-authorizer-112e1ec1",
1212
"s3-prefix": "TestCustomAuthorizerApp/",
13-
"stack-name": "test-custom-authorizer",
14-
"function-architecture": "x86_64"
15-
}
13+
"stack-name" : "test-custom-authorizer-112e1ec1",
14+
"function-architecture" : "x86_64"
15+
}

0 commit comments

Comments
 (0)