Skip to content

Commit be33916

Browse files
committed
fromx support for authorizers
source gen tests add IT tests fix serialization update generator for rest in progress
1 parent 5495eeb commit be33916

42 files changed

Lines changed: 3810 additions & 722 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Amazon.Lambda.Annotations.SourceGenerator.csproj

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,14 @@
103103
<Generator>TextTemplatingFilePreprocessor</Generator>
104104
<LastGenOutput>ExecutableAssembly.cs</LastGenOutput>
105105
</None>
106+
<None Update="Templates\AuthorizerSetupParameters.tt">
107+
<Generator>TextTemplatingFilePreprocessor</Generator>
108+
<LastGenOutput>AuthorizerSetupParameters.cs</LastGenOutput>
109+
</None>
110+
<None Update="Templates\AuthorizerInvoke.tt">
111+
<Generator>TextTemplatingFilePreprocessor</Generator>
112+
<LastGenOutput>AuthorizerInvoke.cs</LastGenOutput>
113+
</None>
106114
</ItemGroup>
107115

108116
<ItemGroup>
@@ -136,6 +144,16 @@
136144
<AutoGen>True</AutoGen>
137145
<DependentUpon>ExecutableAssembly.tt</DependentUpon>
138146
</Compile>
147+
<Compile Update="Templates\AuthorizerSetupParameters.cs">
148+
<DesignTime>True</DesignTime>
149+
<AutoGen>True</AutoGen>
150+
<DependentUpon>AuthorizerSetupParameters.tt</DependentUpon>
151+
</Compile>
152+
<Compile Update="Templates\AuthorizerInvoke.cs">
153+
<DesignTime>True</DesignTime>
154+
<AutoGen>True</AutoGen>
155+
<DependentUpon>AuthorizerInvoke.tt</DependentUpon>
156+
</Compile>
139157
</ItemGroup>
140158

141159
<ItemGroup>

Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/AttributeModelBuilder.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,24 @@ public static AttributeModel Build(AttributeData att, GeneratorExecutionContext
9090
Type = TypeModelBuilder.Build(att.AttributeClass, context)
9191
};
9292
}
93+
else if (att.AttributeClass.Equals(context.Compilation.GetTypeByMetadataName(TypeFullNames.HttpApiAuthorizerAttribute), SymbolEqualityComparer.Default))
94+
{
95+
var data = HttpApiAuthorizerAttributeBuilder.Build(att);
96+
model = new AttributeModel<HttpApiAuthorizerAttribute>
97+
{
98+
Data = data,
99+
Type = TypeModelBuilder.Build(att.AttributeClass, context)
100+
};
101+
}
102+
else if (att.AttributeClass.Equals(context.Compilation.GetTypeByMetadataName(TypeFullNames.RestApiAuthorizerAttribute), SymbolEqualityComparer.Default))
103+
{
104+
var data = RestApiAuthorizerAttributeBuilder.Build(att);
105+
model = new AttributeModel<RestApiAuthorizerAttribute>
106+
{
107+
Data = data,
108+
Type = TypeModelBuilder.Build(att.AttributeClass, context)
109+
};
110+
}
93111
else
94112
{
95113
model = new AttributeModel

Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/EventType.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public enum EventType
1010
S3,
1111
SQS,
1212
DynamoDB,
13-
Schedule
13+
Schedule,
14+
Authorizer
1415
}
1516
}

Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/EventTypeBuilder.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ public static HashSet<EventType> Build(IMethodSymbol lambdaMethodSymbol,
2626
{
2727
events.Add(EventType.SQS);
2828
}
29+
else if (attribute.AttributeClass.ToDisplayString() == TypeFullNames.HttpApiAuthorizerAttribute
30+
|| attribute.AttributeClass.ToDisplayString() == TypeFullNames.RestApiAuthorizerAttribute)
31+
{
32+
events.Add(EventType.Authorizer);
33+
}
2934
}
3035

3136
return events;

Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/GeneratedMethodModelBuilder.cs

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ private static IList<string> BuildUsings(LambdaMethodModel lambdaMethodModel,
5555

5656
namespaces.Add("Amazon.Lambda.Core");
5757

58-
if(lambdaMethodModel.ReturnsIHttpResults)
58+
if(lambdaMethodModel.ReturnsIHttpResults || lambdaMethodModel.ReturnsIAuthorizerResult)
5959
{
6060
namespaces.Add("Amazon.Lambda.Annotations.APIGateway");
6161
}
@@ -79,6 +79,26 @@ private static TypeModel BuildResponseType(IMethodSymbol lambdaMethodSymbol,
7979
return TypeModelBuilder.Build(typeStream, context);
8080
}
8181

82+
// For authorizer functions returning IAuthorizerResult, the generated handler returns Stream
83+
// (the IAuthorizerResult.Serialize method produces the JSON stream)
84+
if (lambdaMethodModel.ReturnsIAuthorizerResult)
85+
{
86+
var typeStream = context.Compilation.GetTypeByMetadataName(TypeFullNames.Stream);
87+
if (lambdaMethodModel.ReturnsGenericTask)
88+
{
89+
var genericTask = task.Construct(typeStream);
90+
return TypeModelBuilder.Build(genericTask, context);
91+
}
92+
return TypeModelBuilder.Build(typeStream, context);
93+
}
94+
95+
// For authorizer functions that return raw API Gateway types (backwards compatibility),
96+
// pass through the return type as-is
97+
if (lambdaMethodSymbol.HasAttribute(context, TypeFullNames.HttpApiAuthorizerAttribute) ||
98+
lambdaMethodSymbol.HasAttribute(context, TypeFullNames.RestApiAuthorizerAttribute))
99+
{
100+
return lambdaMethodModel.ReturnType;
101+
}
82102

83103
if (lambdaMethodSymbol.HasAttribute(context, TypeFullNames.RestApiAttribute))
84104
{
@@ -143,6 +163,20 @@ private static HttpApiVersion GetHttpApiVersion(IMethodSymbol lambdaMethodSymbol
143163
return (HttpApiVersion)versionArgument.Value;
144164
}
145165

166+
private static AuthorizerPayloadFormatVersion GetAuthorizerPayloadFormatVersion(AttributeData authorizerAttribute)
167+
{
168+
var versionArg = authorizerAttribute.NamedArguments
169+
.FirstOrDefault(arg => arg.Key == "AuthorizerPayloadFormatVersion").Value;
170+
171+
if (versionArg.Type == null || versionArg.Value == null)
172+
{
173+
// Default is V2
174+
return AuthorizerPayloadFormatVersion.V2;
175+
}
176+
177+
return (AuthorizerPayloadFormatVersion)(int)versionArg.Value;
178+
}
179+
146180
private static IList<ParameterModel> BuildParameters(IMethodSymbol lambdaMethodSymbol,
147181
LambdaMethodModel lambdaMethodModel, GeneratorExecutionContext context)
148182
{
@@ -158,7 +192,48 @@ private static IList<ParameterModel> BuildParameters(IMethodSymbol lambdaMethodS
158192
Documentation = "The ILambdaContext that provides methods for logging and describing the Lambda environment."
159193
};
160194

161-
if (lambdaMethodSymbol.HasAttribute(context, TypeFullNames.RestApiAttribute))
195+
if (lambdaMethodSymbol.HasAttribute(context, TypeFullNames.HttpApiAuthorizerAttribute))
196+
{
197+
// For HTTP API authorizer functions, the generated handler accepts the authorizer request type
198+
var authorizerAttribute = lambdaMethodSymbol.GetAttributeData(context, TypeFullNames.HttpApiAuthorizerAttribute);
199+
var payloadVersion = GetAuthorizerPayloadFormatVersion(authorizerAttribute);
200+
201+
string requestTypeName;
202+
if (payloadVersion == AuthorizerPayloadFormatVersion.V2)
203+
{
204+
requestTypeName = TypeFullNames.APIGatewayCustomAuthorizerV2Request;
205+
}
206+
else
207+
{
208+
requestTypeName = TypeFullNames.APIGatewayCustomAuthorizerRequest;
209+
}
210+
211+
var symbol = context.Compilation.GetTypeByMetadataName(requestTypeName);
212+
var type = TypeModelBuilder.Build(symbol, context);
213+
var requestParameter = new ParameterModel
214+
{
215+
Name = "__request__",
216+
Type = type,
217+
Documentation = "The API Gateway authorizer request object that will be processed by the Lambda function handler."
218+
};
219+
parameters.Add(requestParameter);
220+
parameters.Add(contextParameter);
221+
}
222+
else if (lambdaMethodSymbol.HasAttribute(context, TypeFullNames.RestApiAuthorizerAttribute))
223+
{
224+
// For REST API authorizer functions, always use APIGatewayCustomAuthorizerRequest
225+
var symbol = context.Compilation.GetTypeByMetadataName(TypeFullNames.APIGatewayCustomAuthorizerRequest);
226+
var type = TypeModelBuilder.Build(symbol, context);
227+
var requestParameter = new ParameterModel
228+
{
229+
Name = "__request__",
230+
Type = type,
231+
Documentation = "The API Gateway authorizer request object that will be processed by the Lambda function handler."
232+
};
233+
parameters.Add(requestParameter);
234+
parameters.Add(contextParameter);
235+
}
236+
else if (lambdaMethodSymbol.HasAttribute(context, TypeFullNames.RestApiAttribute))
162237
{
163238
var symbol = context.Compilation.GetTypeByMetadataName(TypeFullNames.APIGatewayProxyRequest);
164239
var type = TypeModelBuilder.Build(symbol, context);

Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaMethodModel.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,31 @@ public bool ReturnsIHttpResults
6464
}
6565
}
6666

67+
/// <summary>
68+
/// Returns true if the Lambda function returns either IAuthorizerResult or Task&lt;IAuthorizerResult&gt;
69+
/// </summary>
70+
public bool ReturnsIAuthorizerResult
71+
{
72+
get
73+
{
74+
if (ReturnsVoid)
75+
{
76+
return false;
77+
}
78+
79+
if (ReturnType.FullName == TypeFullNames.IAuthorizerResult)
80+
{
81+
return true;
82+
}
83+
if (ReturnsGenericTask && ReturnType.TypeArguments.Count == 1 && ReturnType.TypeArguments[0].FullName == TypeFullNames.IAuthorizerResult)
84+
{
85+
return true;
86+
}
87+
88+
return false;
89+
}
90+
}
91+
6792
/// <summary>
6893
/// Returns true if the Lambda function returns either void, Task, SQSBatchResponse or Task<SQSBatchResponse>
6994
/// </summary>

0 commit comments

Comments
 (0)