diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/AttributeModelBuilder.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/AttributeModelBuilder.cs index 21419dcb8..859935d71 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/AttributeModelBuilder.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/AttributeModelBuilder.cs @@ -53,6 +53,15 @@ public static AttributeModel Build(AttributeData att, GeneratorExecutionContext Type = TypeModelBuilder.Build(att.AttributeClass, context) }; } + else if(att.AttributeClass.Equals(context.Compilation.GetTypeByMetadataName(TypeFullNames.FromCustomAuthorizerAttribute), SymbolEqualityComparer.Default)) + { + var data = FromCustomAuthorizerAttributeBuilder.Build(att); + model = new AttributeModel + { + Data = data, + Type = TypeModelBuilder.Build(att.AttributeClass, context) + }; + } else if (att.AttributeClass.Equals(context.Compilation.GetTypeByMetadataName(TypeFullNames.HttpApiAttribute), SymbolEqualityComparer.Default)) { var data = HttpApiAttributeBuilder.Build(att); diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/FromCustomAuthorizerAttributeBuilder.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/FromCustomAuthorizerAttributeBuilder.cs new file mode 100644 index 000000000..687e27446 --- /dev/null +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/FromCustomAuthorizerAttributeBuilder.cs @@ -0,0 +1,22 @@ +using Amazon.Lambda.Annotations.APIGateway; +using Microsoft.CodeAnalysis; + +namespace Amazon.Lambda.Annotations.SourceGenerator.Models.Attributes +{ + public class FromCustomAuthorizerAttributeBuilder + { + public static FromCustomAuthorizerAttribute Build(AttributeData att) + { + var data = new FromCustomAuthorizerAttribute(); + foreach (var pair in att.NamedArguments) + { + if (pair.Key == nameof(data.Name) && pair.Value.Value is string value) + { + data.Name = value; + } + } + + return data; + } + } +} \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/APIGatewaySetupParameters.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/APIGatewaySetupParameters.cs index f00263815..4a8a90b2d 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/APIGatewaySetupParameters.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/APIGatewaySetupParameters.cs @@ -634,6 +634,215 @@ public virtual string TransformText() } } + else if (parameter.Attributes.Any(att => att.Type.FullName == TypeFullNames.FromCustomAuthorizerAttribute)) + { + var fromAuthorizerAttribute = parameter.Attributes?.FirstOrDefault(att => att.Type.FullName == TypeFullNames.FromCustomAuthorizerAttribute) as AttributeModel; + + // Use parameter name as key, if Name has not specified explicitly in the attribute definition. + var authKey = fromAuthorizerAttribute?.Data?.Name ?? parameter.Name; + if(restApiAttribute != null) + { + + + #line default + #line hidden + this.Write(" var "); + + #line 259 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(parameter.Name)); + + #line default + #line hidden + this.Write(" = default("); + + #line 259 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(parameter.Type.FullName)); + + #line default + #line hidden + this.Write(");\r\n if (__request__.RequestContext?.Authorizer == null || __request__" + + ".RequestContext?.Authorizer.ContainsKey(\""); + + #line 260 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(authKey)); + + #line default + #line hidden + this.Write("\") == false)\r\n {\r\n return new "); + + #line 262 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(restApiAttribute != null || httpApiAttribute?.Data.Version == Amazon.Lambda.Annotations.APIGateway.HttpApiVersion.V1 ? "Amazon.Lambda.APIGatewayEvents.APIGatewayProxyResponse" : "Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyResponse")); + + #line default + #line hidden + this.Write(@" + { + Headers = new Dictionary + { + {""Content-Type"", ""application/json""}, + {""x-amzn-ErrorType"", ""AccessDeniedException""} + }, + StatusCode = 401 + }; + } + + try + { + "); + + #line 275 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(parameter.Name)); + + #line default + #line hidden + this.Write(" = ("); + + #line 275 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(parameter.Type.FullName)); + + #line default + #line hidden + this.Write(")Convert.ChangeType(__request__.RequestContext.Authorizer[\""); + + #line 275 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(authKey)); + + #line default + #line hidden + this.Write("\"], typeof("); + + #line 275 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(parameter.Type.FullNameWithoutAnnotations)); + + #line default + #line hidden + this.Write("));\r\n }\r\n catch (Exception e) when (e is InvalidCastExcepti" + + "on || e is FormatException || e is OverflowException || e is ArgumentException)\r" + + "\n {\r\n return new "); + + #line 279 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(restApiAttribute != null || httpApiAttribute?.Data.Version == Amazon.Lambda.Annotations.APIGateway.HttpApiVersion.V1 ? "Amazon.Lambda.APIGatewayEvents.APIGatewayProxyResponse" : "Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyResponse")); + + #line default + #line hidden + this.Write(@" + { + Headers = new Dictionary + { + {""Content-Type"", ""application/json""}, + {""x-amzn-ErrorType"", ""AccessDeniedException""} + }, + StatusCode = 401 + }; + } + +"); + + #line 290 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + + } + else + { + + + #line default + #line hidden + this.Write(" var "); + + #line 295 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(parameter.Name)); + + #line default + #line hidden + this.Write(" = default("); + + #line 295 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(parameter.Type.FullName)); + + #line default + #line hidden + this.Write(");\r\n if (__request__.RequestContext?.Authorizer?.Lambda == null || __r" + + "equest__.RequestContext?.Authorizer?.Lambda.ContainsKey(\""); + + #line 296 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(authKey)); + + #line default + #line hidden + this.Write("\") == false)\r\n {\r\n return new "); + + #line 298 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(restApiAttribute != null || httpApiAttribute?.Data.Version == Amazon.Lambda.Annotations.APIGateway.HttpApiVersion.V1 ? "Amazon.Lambda.APIGatewayEvents.APIGatewayProxyResponse" : "Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyResponse")); + + #line default + #line hidden + this.Write(@" + { + Headers = new Dictionary + { + {""Content-Type"", ""application/json""}, + {""x-amzn-ErrorType"", ""AccessDeniedException""} + }, + StatusCode = 401 + }; + } + + try + { + "); + + #line 311 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(parameter.Name)); + + #line default + #line hidden + this.Write(" = ("); + + #line 311 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(parameter.Type.FullName)); + + #line default + #line hidden + this.Write(")Convert.ChangeType(__request__.RequestContext.Authorizer.Lambda[\""); + + #line 311 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(authKey)); + + #line default + #line hidden + this.Write("\"], typeof("); + + #line 311 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(parameter.Type.FullNameWithoutAnnotations)); + + #line default + #line hidden + this.Write("));\r\n }\r\n catch (Exception e) when (e is InvalidCastExcepti" + + "on || e is FormatException || e is OverflowException || e is ArgumentException)\r" + + "\n {\r\n return new "); + + #line 315 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(restApiAttribute != null || httpApiAttribute?.Data.Version == Amazon.Lambda.Annotations.APIGateway.HttpApiVersion.V1 ? "Amazon.Lambda.APIGatewayEvents.APIGatewayProxyResponse" : "Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyResponse")); + + #line default + #line hidden + this.Write(@" + { + Headers = new Dictionary + { + {""Content-Type"", ""application/json""}, + {""x-amzn-ErrorType"", ""AccessDeniedException""} + }, + StatusCode = 401 + }; + } + +"); + + #line 326 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + + } + } else if (parameter.Attributes.Any(att => att.Type.FullName == TypeFullNames.FromRouteAttribute) || routeParameters.Contains(parameter.Name)) { var fromRouteAttribute = parameter.Attributes?.FirstOrDefault(att => att.Type.FullName == TypeFullNames.FromRouteAttribute) as AttributeModel; @@ -646,21 +855,21 @@ public virtual string TransformText() #line hidden this.Write(" var "); - #line 257 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + #line 336 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" this.Write(this.ToStringHelper.ToStringWithCulture(parameter.Name)); #line default #line hidden this.Write(" = default("); - #line 257 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + #line 336 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" this.Write(this.ToStringHelper.ToStringWithCulture(parameter.Type.FullName)); #line default #line hidden this.Write(");\r\n if (__request__.PathParameters?.ContainsKey(\""); - #line 258 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + #line 337 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" this.Write(this.ToStringHelper.ToStringWithCulture(routeKey)); #line default @@ -668,28 +877,28 @@ public virtual string TransformText() this.Write("\") == true)\r\n {\r\n try\r\n {\r\n " + " "); - #line 262 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + #line 341 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" this.Write(this.ToStringHelper.ToStringWithCulture(parameter.Name)); #line default #line hidden this.Write(" = ("); - #line 262 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + #line 341 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" this.Write(this.ToStringHelper.ToStringWithCulture(parameter.Type.FullName)); #line default #line hidden this.Write(")Convert.ChangeType(__request__.PathParameters[\""); - #line 262 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + #line 341 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" this.Write(this.ToStringHelper.ToStringWithCulture(routeKey)); #line default #line hidden this.Write("\"], typeof("); - #line 262 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + #line 341 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" this.Write(this.ToStringHelper.ToStringWithCulture(parameter.Type.FullNameWithoutAnnotations)); #line default @@ -700,14 +909,14 @@ public virtual string TransformText() { validationErrors.Add($""Value {__request__.PathParameters["""); - #line 266 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + #line 345 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" this.Write(this.ToStringHelper.ToStringWithCulture(routeKey)); #line default #line hidden this.Write("\"]} at \'"); - #line 266 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + #line 345 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" this.Write(this.ToStringHelper.ToStringWithCulture(routeKey)); #line default @@ -715,7 +924,7 @@ public virtual string TransformText() this.Write("\' failed to satisfy constraint: {e.Message}\");\r\n }\r\n }\r" + "\n\r\n"); - #line 270 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + #line 349 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" } else @@ -734,7 +943,7 @@ public virtual string TransformText() " if (validationErrors.Any())\r\n {\r\n var errorResult" + " = new "); - #line 284 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + #line 363 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" this.Write(this.ToStringHelper.ToStringWithCulture(restApiAttribute != null || httpApiAttribute?.Data.Version == Amazon.Lambda.Annotations.APIGateway.HttpApiVersion.V1 ? "Amazon.Lambda.APIGatewayEvents.APIGatewayProxyResponse" : "Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyResponse")); #line default @@ -751,7 +960,7 @@ public virtual string TransformText() }; "); - #line 294 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + #line 373 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" if(_model.LambdaMethod.ReturnsIHttpResults) { @@ -763,7 +972,7 @@ public virtual string TransformText() "System.Text.Json.JsonSerializer.Serialize(errorStream, errorResult);\r\n " + " return errorStream;\r\n"); - #line 301 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + #line 380 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" } else @@ -774,7 +983,7 @@ public virtual string TransformText() #line hidden this.Write(" return errorResult;\r\n"); - #line 307 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + #line 386 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" } @@ -783,7 +992,7 @@ public virtual string TransformText() #line hidden this.Write(" }\r\n\r\n"); - #line 312 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" + #line 391 "C:\codebase\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\APIGatewaySetupParameters.tt" } @@ -815,7 +1024,7 @@ public class APIGatewaySetupParametersBase /// /// The string builder that generation-time code is using to assemble generated output /// - protected System.Text.StringBuilder GenerationEnvironment + public System.Text.StringBuilder GenerationEnvironment { get { diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/APIGatewaySetupParameters.tt b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/APIGatewaySetupParameters.tt index 321a3fc46..d0b2cd101 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/APIGatewaySetupParameters.tt +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/APIGatewaySetupParameters.tt @@ -244,6 +244,85 @@ validationErrors.Add($"Value {__request__.Body} at 'body' failed to satisfy constraint: {e.Message}"); } +<# + } + } + else if (parameter.Attributes.Any(att => att.Type.FullName == TypeFullNames.FromCustomAuthorizerAttribute)) + { + var fromAuthorizerAttribute = parameter.Attributes?.FirstOrDefault(att => att.Type.FullName == TypeFullNames.FromCustomAuthorizerAttribute) as AttributeModel; + + // Use parameter name as key, if Name has not specified explicitly in the attribute definition. + var authKey = fromAuthorizerAttribute?.Data?.Name ?? parameter.Name; + if(restApiAttribute != null) + { +#> + var <#= parameter.Name #> = default(<#= parameter.Type.FullName #>); + if (__request__.RequestContext?.Authorizer == null || __request__.RequestContext?.Authorizer.ContainsKey("<#= authKey #>") == false) + { + return new <#= restApiAttribute != null || httpApiAttribute?.Data.Version == Amazon.Lambda.Annotations.APIGateway.HttpApiVersion.V1 ? "Amazon.Lambda.APIGatewayEvents.APIGatewayProxyResponse" : "Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyResponse" #> + { + Headers = new Dictionary + { + {"Content-Type", "application/json"}, + {"x-amzn-ErrorType", "AccessDeniedException"} + }, + StatusCode = 401 + }; + } + + try + { + <#= parameter.Name #> = (<#= parameter.Type.FullName #>)Convert.ChangeType(__request__.RequestContext.Authorizer["<#= authKey #>"], typeof(<#= parameter.Type.FullNameWithoutAnnotations #>)); + } + catch (Exception e) when (e is InvalidCastException || e is FormatException || e is OverflowException || e is ArgumentException) + { + return new <#= restApiAttribute != null || httpApiAttribute?.Data.Version == Amazon.Lambda.Annotations.APIGateway.HttpApiVersion.V1 ? "Amazon.Lambda.APIGatewayEvents.APIGatewayProxyResponse" : "Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyResponse" #> + { + Headers = new Dictionary + { + {"Content-Type", "application/json"}, + {"x-amzn-ErrorType", "AccessDeniedException"} + }, + StatusCode = 401 + }; + } + +<# + } + else + { +#> + var <#= parameter.Name #> = default(<#= parameter.Type.FullName #>); + if (__request__.RequestContext?.Authorizer?.Lambda == null || __request__.RequestContext?.Authorizer?.Lambda.ContainsKey("<#= authKey #>") == false) + { + return new <#= restApiAttribute != null || httpApiAttribute?.Data.Version == Amazon.Lambda.Annotations.APIGateway.HttpApiVersion.V1 ? "Amazon.Lambda.APIGatewayEvents.APIGatewayProxyResponse" : "Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyResponse" #> + { + Headers = new Dictionary + { + {"Content-Type", "application/json"}, + {"x-amzn-ErrorType", "AccessDeniedException"} + }, + StatusCode = 401 + }; + } + + try + { + <#= parameter.Name #> = (<#= parameter.Type.FullName #>)Convert.ChangeType(__request__.RequestContext.Authorizer.Lambda["<#= authKey #>"], typeof(<#= parameter.Type.FullNameWithoutAnnotations #>)); + } + catch (Exception e) when (e is InvalidCastException || e is FormatException || e is OverflowException || e is ArgumentException) + { + return new <#= restApiAttribute != null || httpApiAttribute?.Data.Version == Amazon.Lambda.Annotations.APIGateway.HttpApiVersion.V1 ? "Amazon.Lambda.APIGatewayEvents.APIGatewayProxyResponse" : "Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyResponse" #> + { + Headers = new Dictionary + { + {"Content-Type", "application/json"}, + {"x-amzn-ErrorType", "AccessDeniedException"} + }, + StatusCode = 401 + }; + } + <# } } diff --git a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/TypeFullNames.cs b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/TypeFullNames.cs index 6026b2969..37e58bc84 100644 --- a/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/TypeFullNames.cs +++ b/Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/TypeFullNames.cs @@ -31,6 +31,7 @@ public static class TypeFullNames public const string FromHeaderAttribute = "Amazon.Lambda.Annotations.APIGateway.FromHeaderAttribute"; public const string FromBodyAttribute = "Amazon.Lambda.Annotations.APIGateway.FromBodyAttribute"; public const string FromRouteAttribute = "Amazon.Lambda.Annotations.APIGateway.FromRouteAttribute"; + public const string FromCustomAuthorizerAttribute = "Amazon.Lambda.Annotations.APIGateway.FromCustomAuthorizerAttribute"; public const string LambdaSerializerAttribute = "Amazon.Lambda.Core.LambdaSerializerAttribute"; diff --git a/Libraries/src/Amazon.Lambda.Annotations/APIGateway/FromCustomAuthorizerAttribute.cs b/Libraries/src/Amazon.Lambda.Annotations/APIGateway/FromCustomAuthorizerAttribute.cs new file mode 100644 index 000000000..4bdc173e6 --- /dev/null +++ b/Libraries/src/Amazon.Lambda.Annotations/APIGateway/FromCustomAuthorizerAttribute.cs @@ -0,0 +1,19 @@ +using System; + +namespace Amazon.Lambda.Annotations.APIGateway +{ + /// + /// Maps this parameter to a custom authorizer item + /// + /// + /// Will try to get the specified key from Custom Authorizer values + /// + [AttributeUsage(AttributeTargets.Parameter)] + public class FromCustomAuthorizerAttribute : Attribute, INamedAttribute + { + /// + /// Key of the value + /// + public string Name { get; set; } + } +} diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Amazon.Lambda.Annotations.SourceGenerators.Tests.csproj b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Amazon.Lambda.Annotations.SourceGenerators.Tests.csproj index adbe62620..cf6c8f4f9 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Amazon.Lambda.Annotations.SourceGenerators.Tests.csproj +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Amazon.Lambda.Annotations.SourceGenerators.Tests.csproj @@ -58,6 +58,8 @@ + + diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomAuthorizerHttpApiExample_HttpApiAuthorizer_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomAuthorizerHttpApiExample_HttpApiAuthorizer_Generated.g.cs new file mode 100644 index 000000000..85d630792 --- /dev/null +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomAuthorizerHttpApiExample_HttpApiAuthorizer_Generated.g.cs @@ -0,0 +1,95 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using System.Text; +using Amazon.Lambda.Core; + +namespace TestServerlessApp +{ + public class CustomAuthorizerHttpApiExample_HttpApiAuthorizer_Generated + { + private readonly CustomAuthorizerHttpApiExample customAuthorizerHttpApiExample; + + public CustomAuthorizerHttpApiExample_HttpApiAuthorizer_Generated() + { + SetExecutionEnvironment(); + customAuthorizerHttpApiExample = new CustomAuthorizerHttpApiExample(); + } + + public async System.Threading.Tasks.Task HttpApiAuthorizer(Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) + { + var validationErrors = new List(); + + var authorizerValue = default(string); + if (__request__.RequestContext?.Authorizer?.Lambda == null || __request__.RequestContext?.Authorizer?.Lambda.ContainsKey("authKey") == false) + { + return new Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyResponse + { + Headers = new Dictionary + { + {"Content-Type", "application/json"}, + {"x-amzn-ErrorType", "AccessDeniedException"} + }, + StatusCode = 401 + }; + } + + try + { + authorizerValue = (string)Convert.ChangeType(__request__.RequestContext.Authorizer.Lambda["authKey"], typeof(string)); + } + catch (Exception e) when (e is InvalidCastException || e is FormatException || e is OverflowException || e is ArgumentException) + { + return new Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyResponse + { + Headers = new Dictionary + { + {"Content-Type", "application/json"}, + {"x-amzn-ErrorType", "AccessDeniedException"} + }, + StatusCode = 401 + }; + } + + // return 400 Bad Request if there exists a validation error + if (validationErrors.Any()) + { + var errorResult = new Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyResponse + { + Body = @$"{{""message"": ""{validationErrors.Count} validation error(s) detected: {string.Join(",", validationErrors)}""}}", + Headers = new Dictionary + { + {"Content-Type", "application/json"}, + {"x-amzn-ErrorType", "ValidationException"} + }, + StatusCode = 400 + }; + return errorResult; + } + + await customAuthorizerHttpApiExample.HttpApiAuthorizer(authorizerValue, __context__); + + return new Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyResponse + { + StatusCode = 200 + }; + } + + private static void SetExecutionEnvironment() + { + const string envName = "AWS_EXECUTION_ENV"; + + var envValue = new StringBuilder(); + + // If there is an existing execution environment variable add the annotations package as a suffix. + if(!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(envName))) + { + envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); + } + + envValue.Append("amazon-lambda-annotations_1.0.0.0"); + + Environment.SetEnvironmentVariable(envName, envValue.ToString()); + } + } +} \ No newline at end of file diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomAuthorizerRestExample_RestAuthorizer_Generated.g.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomAuthorizerRestExample_RestAuthorizer_Generated.g.cs new file mode 100644 index 000000000..230c4b316 --- /dev/null +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/CustomAuthorizerRestExample_RestAuthorizer_Generated.g.cs @@ -0,0 +1,95 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using System.Text; +using Amazon.Lambda.Core; + +namespace TestServerlessApp +{ + public class CustomAuthorizerRestExample_RestAuthorizer_Generated + { + private readonly CustomAuthorizerRestExample customAuthorizerRestExample; + + public CustomAuthorizerRestExample_RestAuthorizer_Generated() + { + SetExecutionEnvironment(); + customAuthorizerRestExample = new CustomAuthorizerRestExample(); + } + + public async System.Threading.Tasks.Task RestAuthorizer(Amazon.Lambda.APIGatewayEvents.APIGatewayProxyRequest __request__, Amazon.Lambda.Core.ILambdaContext __context__) + { + var validationErrors = new List(); + + var authorizerValue = default(string); + if (__request__.RequestContext?.Authorizer == null || __request__.RequestContext?.Authorizer.ContainsKey("theAuthKey") == false) + { + return new Amazon.Lambda.APIGatewayEvents.APIGatewayProxyResponse + { + Headers = new Dictionary + { + {"Content-Type", "application/json"}, + {"x-amzn-ErrorType", "AccessDeniedException"} + }, + StatusCode = 401 + }; + } + + try + { + authorizerValue = (string)Convert.ChangeType(__request__.RequestContext.Authorizer["theAuthKey"], typeof(string)); + } + catch (Exception e) when (e is InvalidCastException || e is FormatException || e is OverflowException || e is ArgumentException) + { + return new Amazon.Lambda.APIGatewayEvents.APIGatewayProxyResponse + { + Headers = new Dictionary + { + {"Content-Type", "application/json"}, + {"x-amzn-ErrorType", "AccessDeniedException"} + }, + StatusCode = 401 + }; + } + + // return 400 Bad Request if there exists a validation error + if (validationErrors.Any()) + { + var errorResult = new Amazon.Lambda.APIGatewayEvents.APIGatewayProxyResponse + { + Body = @$"{{""message"": ""{validationErrors.Count} validation error(s) detected: {string.Join(",", validationErrors)}""}}", + Headers = new Dictionary + { + {"Content-Type", "application/json"}, + {"x-amzn-ErrorType", "ValidationException"} + }, + StatusCode = 400 + }; + return errorResult; + } + + await customAuthorizerRestExample.RestAuthorizer(authorizerValue, __context__); + + return new Amazon.Lambda.APIGatewayEvents.APIGatewayProxyResponse + { + StatusCode = 200 + }; + } + + private static void SetExecutionEnvironment() + { + const string envName = "AWS_EXECUTION_ENV"; + + var envValue = new StringBuilder(); + + // If there is an existing execution environment variable add the annotations package as a suffix. + if(!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(envName))) + { + envValue.Append($"{Environment.GetEnvironmentVariable(envName)}_"); + } + + envValue.Append("amazon-lambda-annotations_1.0.0.0"); + + Environment.SetEnvironmentVariable(envName, envValue.ToString()); + } + } +} \ No newline at end of file diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/authorizerHttpApi.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/authorizerHttpApi.template new file mode 100644 index 000000000..a73441fa6 --- /dev/null +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/authorizerHttpApi.template @@ -0,0 +1,39 @@ +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Transform": "AWS::Serverless-2016-10-31", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.0.0.0).", + "Resources": { + "HttpApiAuthorizerTest": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestProject::TestServerlessApp.CustomAuthorizerHttpApiExample_HttpApiAuthorizer_Generated::HttpApiAuthorizer" + ] + }, + "Events": { + "RootGet": { + "Type": "HttpApi", + "Properties": { + "Path": "/api/authorizer", + "Method": "GET" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/authorizerRest.template b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/authorizerRest.template new file mode 100644 index 000000000..b8db4ef7d --- /dev/null +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/authorizerRest.template @@ -0,0 +1,39 @@ +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Transform": "AWS::Serverless-2016-10-31", + "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.0.0.0).", + "Resources": { + "RestAuthorizerTest": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestProject::TestServerlessApp.CustomAuthorizerRestExample_RestAuthorizer_Generated::RestAuthorizer" + ] + }, + "Events": { + "RootGet": { + "Type": "Api", + "Properties": { + "Path": "/rest/authorizer", + "Method": "GET" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs index 47cd2cc8b..27f93617e 100644 --- a/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs +++ b/Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs @@ -68,7 +68,7 @@ public async Task GeneratorDoesNotRunDueToCompileError() await new VerifyCS.Test { TestState = - { + { Sources = { (Path.Combine("TestServerlessApp", "Greeter.cs"), File.ReadAllText(Path.Combine("TestServerlessApp", "Greeter.cs"))), @@ -485,7 +485,7 @@ public async Task CustomizeResponses() new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info).WithArguments("CustomizeResponseExamples_NotFoundResponseWithHeaderV2_Generated.g.cs", expectedNotFoundResponseWithHeaderV2Generated), new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info).WithArguments("CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated.g.cs", expectedNotFoundResponseWithHeaderV2AsyncGenerated), - + new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info).WithArguments("CustomizeResponseExamples_NotFoundResponseWithHeaderV1_Generated.g.cs", expectedNotFoundResponseWithHeaderV1Generated), new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info).WithArguments("CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated.g.cs", expectedNotFoundResponseWithHeaderV1AsyncGenerated), @@ -493,7 +493,7 @@ public async Task CustomizeResponses() }, ReferenceAssemblies = ReferenceAssemblies.Net.Net60 } - + }.RunAsync(); var actualTemplateContent = File.ReadAllText(Path.Combine("TestServerlessApp", "serverless.template")); @@ -521,7 +521,7 @@ public async Task InvalidReturnTypeIHttpResult() }, ExpectedDiagnostics = { - DiagnosticResult.CompilerError("AWSLambda0105").WithSpan($"TestServerlessApp{Path.DirectorySeparatorChar}CustomizeResponseWithErrors.cs", 14, 9, 21, 10).WithArguments("Error") + DiagnosticResult.CompilerError("AWSLambda0105").WithSpan($"TestServerlessApp{Path.DirectorySeparatorChar}CustomizeResponseWithErrors.cs", 14, 9, 21, 10).WithArguments("Error") }, ReferenceAssemblies = ReferenceAssemblies.Net.Net60 } @@ -557,6 +557,84 @@ public async Task MissingResourePathMapping() }.RunAsync(); } + [Fact] + public async Task CustomAuthorizerRestTest() + { + var expectedTemplateContent = File.ReadAllText(Path.Combine("Snapshots", "ServerlessTemplates", "authorizerRest.template")).ToEnvironmentLineEndings(); + var expectedRestAuthorizerGenerated = File.ReadAllText(Path.Combine("Snapshots", "CustomAuthorizerRestExample_RestAuthorizer_Generated.g.cs")).ToEnvironmentLineEndings(); + + await new VerifyCS.Test + { + TestState = + { + Sources = + { + (Path.Combine("TestServerlessApp", "CustomAuthorizerRestExample.cs"), File.ReadAllText(Path.Combine("TestServerlessApp", "CustomAuthorizerRestExample.cs"))), + (Path.Combine("Amazon.Lambda.Annotations", "LambdaFunctionAttribute.cs"), File.ReadAllText(Path.Combine("Amazon.Lambda.Annotations", "LambdaFunctionAttribute.cs"))), + (Path.Combine("Amazon.Lambda.Annotations", "LambdaStartupAttribute.cs"), File.ReadAllText(Path.Combine("Amazon.Lambda.Annotations", "LambdaStartupAttribute.cs"))), + (Path.Combine("Amazon.Lambda.Annotations", "APIGateway", "RestApiAttribute.cs"), File.ReadAllText(Path.Combine("Amazon.Lambda.Annotations", "APIGateway", "RestApiAttribute.cs"))), + (Path.Combine("TestServerlessApp", "AssemblyAttributes.cs"), File.ReadAllText(Path.Combine("TestServerlessApp", "AssemblyAttributes.cs"))), + }, + GeneratedSources = + { + ( + typeof(SourceGenerator.Generator), + "CustomAuthorizerRestExample_RestAuthorizer_Generated.g.cs", + SourceText.From(expectedRestAuthorizerGenerated, Encoding.UTF8, SourceHashAlgorithm.Sha256) + ) + }, + ExpectedDiagnostics = + { + new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info).WithArguments("CustomAuthorizerRestExample_RestAuthorizer_Generated.g.cs", expectedRestAuthorizerGenerated), + new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info).WithArguments($"TestServerlessApp{Path.DirectorySeparatorChar}serverless.template", expectedTemplateContent) + }, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60 + } + }.RunAsync(); + + var actualTemplateContent = File.ReadAllText(Path.Combine("TestServerlessApp", "serverless.template")); + Assert.Equal(expectedTemplateContent, actualTemplateContent); + } + + [Fact] + public async Task CustomAuthorizerHttpApiTest() + { + var expectedTemplateContent = File.ReadAllText(Path.Combine("Snapshots", "ServerlessTemplates", "authorizerHttpApi.template")).ToEnvironmentLineEndings(); + var expectedRestAuthorizerGenerated = File.ReadAllText(Path.Combine("Snapshots", "CustomAuthorizerHttpApiExample_HttpApiAuthorizer_Generated.g.cs")).ToEnvironmentLineEndings(); + + await new VerifyCS.Test + { + TestState = + { + Sources = + { + (Path.Combine("TestServerlessApp", "CustomAuthorizerHttpApiExample.cs"), File.ReadAllText(Path.Combine("TestServerlessApp", "CustomAuthorizerHttpApiExample.cs"))), + (Path.Combine("Amazon.Lambda.Annotations", "LambdaFunctionAttribute.cs"), File.ReadAllText(Path.Combine("Amazon.Lambda.Annotations", "LambdaFunctionAttribute.cs"))), + (Path.Combine("Amazon.Lambda.Annotations", "LambdaStartupAttribute.cs"), File.ReadAllText(Path.Combine("Amazon.Lambda.Annotations", "LambdaStartupAttribute.cs"))), + (Path.Combine("Amazon.Lambda.Annotations", "APIGateway", "HttpApiAttribute.cs"), File.ReadAllText(Path.Combine("Amazon.Lambda.Annotations", "APIGateway", "HttpApiAttribute.cs"))), + (Path.Combine("TestServerlessApp", "AssemblyAttributes.cs"), File.ReadAllText(Path.Combine("TestServerlessApp", "AssemblyAttributes.cs"))), + }, + GeneratedSources = + { + ( + typeof(SourceGenerator.Generator), + "CustomAuthorizerHttpApiExample_HttpApiAuthorizer_Generated.g.cs", + SourceText.From(expectedRestAuthorizerGenerated, Encoding.UTF8, SourceHashAlgorithm.Sha256) + ) + }, + ExpectedDiagnostics = + { + new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info).WithArguments("CustomAuthorizerHttpApiExample_HttpApiAuthorizer_Generated.g.cs", expectedRestAuthorizerGenerated), + new DiagnosticResult("AWSLambda0103", DiagnosticSeverity.Info).WithArguments($"TestServerlessApp{Path.DirectorySeparatorChar}serverless.template", expectedTemplateContent) + }, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60 + } + }.RunAsync(); + + var actualTemplateContent = File.ReadAllText(Path.Combine("TestServerlessApp", "serverless.template")); + Assert.Equal(expectedTemplateContent, actualTemplateContent); + } + [Fact] public async Task VerifyApiFunctionUsingNullableParameters() { diff --git a/Libraries/test/TestServerlessApp/CustomAuthorizerHttpApiExample.cs b/Libraries/test/TestServerlessApp/CustomAuthorizerHttpApiExample.cs new file mode 100644 index 000000000..7754a189f --- /dev/null +++ b/Libraries/test/TestServerlessApp/CustomAuthorizerHttpApiExample.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Amazon.Lambda.Annotations; +using Amazon.Lambda.Annotations.APIGateway; +using Amazon.Lambda.Core; + +namespace TestServerlessApp +{ + public class CustomAuthorizerHttpApiExample + { + [LambdaFunction(ResourceName = "HttpApiAuthorizerTest", PackageType = LambdaPackageType.Image)] + [HttpApi(LambdaHttpMethod.Get, "/api/authorizer")] + public async Task HttpApiAuthorizer([FromCustomAuthorizer(Name = "authKey")] string authorizerValue, ILambdaContext context) + { + context.Logger.LogLine(authorizerValue); + await Task.CompletedTask; + } + } +} \ No newline at end of file diff --git a/Libraries/test/TestServerlessApp/CustomAuthorizerRestExample.cs b/Libraries/test/TestServerlessApp/CustomAuthorizerRestExample.cs new file mode 100644 index 000000000..8779fa283 --- /dev/null +++ b/Libraries/test/TestServerlessApp/CustomAuthorizerRestExample.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Amazon.Lambda.Annotations; +using Amazon.Lambda.Annotations.APIGateway; +using Amazon.Lambda.Core; + +namespace TestServerlessApp +{ + public class CustomAuthorizerRestExample + { + [LambdaFunction(ResourceName = "RestAuthorizerTest", PackageType = LambdaPackageType.Image)] + [RestApi(LambdaHttpMethod.Get, "/rest/authorizer")] + public async Task RestAuthorizer([FromCustomAuthorizer(Name = "theAuthKey")] string authorizerValue, ILambdaContext context) + { + context.Logger.LogLine(authorizerValue); + await Task.CompletedTask; + } + } +} \ No newline at end of file diff --git a/Libraries/test/TestServerlessApp/serverless.template b/Libraries/test/TestServerlessApp/serverless.template index 2df85836e..f2d6826fd 100644 --- a/Libraries/test/TestServerlessApp/serverless.template +++ b/Libraries/test/TestServerlessApp/serverless.template @@ -1,737 +1,821 @@ -{ - "AWSTemplateFormatVersion": "2010-09-09", - "Transform": "AWS::Serverless-2016-10-31", - "Description": "An AWS Serverless Application. This template is partially managed by Amazon.Lambda.Annotations (v1.0.0.0).", - "Parameters": { - "ArchitectureTypeParameter": { - "Type": "String", - "Default": "x86_64", - "AllowedValues": [ - "x86_64", - "arm64" - ] - } - }, - "Globals": { - "Function": { - "Architectures": [ - { - "Ref": "ArchitectureTypeParameter" - } - ] - } - }, - "Resources": { - "TestServerlessAppComplexCalculatorAddGenerated": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations", - "SyncedEvents": [ - "RootPost" - ] - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.ComplexCalculator_Add_Generated::Add" - ] - }, - "Events": { - "RootPost": { - "Type": "HttpApi", - "Properties": { - "Path": "/ComplexCalculator/Add", - "Method": "POST" - } - } - } - } - }, - "TestServerlessAppComplexCalculatorSubtractGenerated": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations", - "SyncedEvents": [ - "RootPost" - ] - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.ComplexCalculator_Subtract_Generated::Subtract" - ] - }, - "Events": { - "RootPost": { - "Type": "HttpApi", - "Properties": { - "Path": "/ComplexCalculator/Subtract", - "Method": "POST" - } - } - } - } - }, - "TestServerlessAppDynamicExampleDynamicReturnGenerated": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations" - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.DynamicExample_DynamicReturn_Generated::DynamicReturn" - ] - } - } - }, - "TestServerlessAppDynamicExampleDynamicInputGenerated": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations" - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.DynamicExample_DynamicInput_Generated::DynamicInput" - ] - } - } - }, - "TestServerlessAppTaskExampleTaskReturnGenerated": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations" - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.TaskExample_TaskReturn_Generated::TaskReturn" - ] - } - } - }, - "TestServerlessAppVoidExampleVoidReturnGenerated": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations" - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.VoidExample_VoidReturn_Generated::VoidReturn" - ] - } - } - }, - "TestServerlessAppCustomizeResponseExamplesOkResponseWithHeaderGenerated": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations", - "SyncedEvents": [ - "RootGet" - ] - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.CustomizeResponseExamples_OkResponseWithHeader_Generated::OkResponseWithHeader" - ] - }, - "Events": { - "RootGet": { - "Type": "Api", - "Properties": { - "Path": "/okresponsewithheader/{x}", - "Method": "GET" - } - } - } - } - }, - "TestServerlessAppCustomizeResponseExamplesOkResponseWithHeaderAsyncGenerated": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations", - "SyncedEvents": [ - "RootGet" - ] - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.CustomizeResponseExamples_OkResponseWithHeaderAsync_Generated::OkResponseWithHeaderAsync" - ] - }, - "Events": { - "RootGet": { - "Type": "Api", - "Properties": { - "Path": "/okresponsewithheaderasync/{x}", - "Method": "GET" - } - } - } - } - }, - "TestServerlessAppCustomizeResponseExamplesNotFoundResponseWithHeaderV2Generated": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations", - "SyncedEvents": [ - "RootGet" - ] - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.CustomizeResponseExamples_NotFoundResponseWithHeaderV2_Generated::NotFoundResponseWithHeaderV2" - ] - }, - "Events": { - "RootGet": { - "Type": "HttpApi", - "Properties": { - "Path": "/notfoundwithheaderv2/{x}", - "Method": "GET" - } - } - } - } - }, - "TestServerlessAppCustomizeResponseExamplesNotFoundResponseWithHeaderV2AsyncGenerated": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations", - "SyncedEvents": [ - "RootGet" - ] - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated::NotFoundResponseWithHeaderV2Async" - ] - }, - "Events": { - "RootGet": { - "Type": "HttpApi", - "Properties": { - "Path": "/notfoundwithheaderv2async/{x}", - "Method": "GET" - } - } - } - } - }, - "TestServerlessAppCustomizeResponseExamplesNotFoundResponseWithHeaderV1Generated": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations", - "SyncedEvents": [ - "RootGet" - ] - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.CustomizeResponseExamples_NotFoundResponseWithHeaderV1_Generated::NotFoundResponseWithHeaderV1" - ] - }, - "Events": { - "RootGet": { - "Type": "HttpApi", - "Properties": { - "Path": "/notfoundwithheaderv1/{x}", - "Method": "GET", - "PayloadFormatVersion": "1.0" - } - } - } - } - }, - "TestServerlessAppCustomizeResponseExamplesNotFoundResponseWithHeaderV1AsyncGenerated": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations", - "SyncedEvents": [ - "RootGet" - ] - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated::NotFoundResponseWithHeaderV1Async" - ] - }, - "Events": { - "RootGet": { - "Type": "HttpApi", - "Properties": { - "Path": "/notfoundwithheaderv1async/{x}", - "Method": "GET", - "PayloadFormatVersion": "1.0" - } - } - } - } - }, - "GreeterSayHello": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations", - "SyncedEvents": [ - "RootGet" - ] - }, - "Properties": { - "MemorySize": 1024, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.Greeter_SayHello_Generated::SayHello" - ] - }, - "Events": { - "RootGet": { - "Type": "HttpApi", - "Properties": { - "Path": "/Greeter/SayHello", - "Method": "GET", - "PayloadFormatVersion": "1.0" - } - } - } - } - }, - "GreeterSayHelloAsync": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations", - "SyncedEvents": [ - "RootGet" - ] - }, - "Properties": { - "MemorySize": 256, - "Timeout": 50, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.Greeter_SayHelloAsync_Generated::SayHelloAsync" - ] - }, - "Events": { - "RootGet": { - "Type": "HttpApi", - "Properties": { - "Path": "/Greeter/SayHelloAsync", - "Method": "GET", - "PayloadFormatVersion": "1.0" - } - } - } - } - }, - "SimpleCalculatorAdd": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations", - "SyncedEvents": [ - "RootGet" - ] - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.SimpleCalculator_Add_Generated::Add" - ] - }, - "Events": { - "RootGet": { - "Type": "Api", - "Properties": { - "Path": "/SimpleCalculator/Add", - "Method": "GET" - } - } - } - } - }, - "SimpleCalculatorSubtract": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations", - "SyncedEvents": [ - "RootGet" - ] - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.SimpleCalculator_Subtract_Generated::Subtract" - ] - }, - "Events": { - "RootGet": { - "Type": "Api", - "Properties": { - "Path": "/SimpleCalculator/Subtract", - "Method": "GET" - } - } - } - } - }, - "SimpleCalculatorMultiply": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations", - "SyncedEvents": [ - "RootGet" - ] - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.SimpleCalculator_Multiply_Generated::Multiply" - ] - }, - "Events": { - "RootGet": { - "Type": "Api", - "Properties": { - "Path": "/SimpleCalculator/Multiply/{x}/{y}", - "Method": "GET" - } - } - } - } - }, - "SimpleCalculatorDivideAsync": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations", - "SyncedEvents": [ - "RootGet" - ] - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.SimpleCalculator_DivideAsync_Generated::DivideAsync" - ] - }, - "Events": { - "RootGet": { - "Type": "Api", - "Properties": { - "Path": "/SimpleCalculator/DivideAsync/{x}/{y}", - "Method": "GET" - } - } - } - } - }, - "PI": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations" - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.SimpleCalculator_Pi_Generated::Pi" - ] - } - } - }, - "Random": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations" - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.SimpleCalculator_Random_Generated::Random" - ] - } - } - }, - "Randoms": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations" - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.SimpleCalculator_Randoms_Generated::Randoms" - ] - } - } - }, - "ToUpper": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations" - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.Sub1.Functions_ToUpper_Generated::ToUpper" - ] - } - } - }, - "TestServerlessAppNullableReferenceTypeExampleNullableHeaderHttpApiGenerated": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations", - "SyncedEvents": [ - "RootGet" - ] - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.NullableReferenceTypeExample_NullableHeaderHttpApi_Generated::NullableHeaderHttpApi" - ] - }, - "Events": { - "RootGet": { - "Type": "HttpApi", - "Properties": { - "Path": "/nullableheaderhttpapi", - "Method": "GET" - } - } - } - } - }, - "TestServerlessAppFromScratchNoApiGatewayEventsReferenceToUpperGenerated": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations", - "SyncedEvents": [ - "RootGet" - ] - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "Events": { - "RootGet": { - "Type": "HttpApi", - "Properties": { - "Path": "/{text}", - "Method": "GET" - } - } - }, - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.FromScratch.NoApiGatewayEventsReference_ToUpper_Generated::ToUpper" - ] - } - } - }, - "TestServerlessAppFromScratchNoSerializerAttributeReferenceToUpperGenerated": { - "Type": "AWS::Serverless::Function", - "Metadata": { - "Tool": "Amazon.Lambda.Annotations" - }, - "Properties": { - "MemorySize": 256, - "Timeout": 30, - "Policies": [ - "AWSLambdaBasicExecutionRole" - ], - "PackageType": "Image", - "Events": {}, - "ImageUri": ".", - "ImageConfig": { - "Command": [ - "TestServerlessApp::TestServerlessApp.FromScratch.NoSerializerAttributeReference_ToUpper_Generated::ToUpper" - ] - } - } - } - }, - "Outputs": { - "RestApiURL": { - "Description": "Rest API endpoint URL for Prod environment", - "Value": { - "Fn::Sub": "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod" - } - }, - "HttpApiURL": { - "Description": "HTTP API endpoint URL for Prod environment", - "Value": { - "Fn::Sub": "https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com" - } - } - } +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Transform": "AWS::Serverless-2016-10-31", + "Description": "An AWS Serverless Application. This template is partially managed by Amazon.Lambda.Annotations (v0.13.3.0).", + "Parameters": { + "ArchitectureTypeParameter": { + "Type": "String", + "Default": "x86_64", + "AllowedValues": [ + "x86_64", + "arm64" + ] + } + }, + "Globals": { + "Function": { + "Architectures": [ + { + "Ref": "ArchitectureTypeParameter" + } + ] + } + }, + "Resources": { + "TestServerlessAppComplexCalculatorAddGenerated": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootPost" + ] + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.ComplexCalculator_Add_Generated::Add" + ] + }, + "Events": { + "RootPost": { + "Type": "HttpApi", + "Properties": { + "Path": "/ComplexCalculator/Add", + "Method": "POST" + } + } + } + } + }, + "TestServerlessAppComplexCalculatorSubtractGenerated": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootPost" + ] + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.ComplexCalculator_Subtract_Generated::Subtract" + ] + }, + "Events": { + "RootPost": { + "Type": "HttpApi", + "Properties": { + "Path": "/ComplexCalculator/Subtract", + "Method": "POST" + } + } + } + } + }, + "TestServerlessAppDynamicExampleDynamicReturnGenerated": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations" + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.DynamicExample_DynamicReturn_Generated::DynamicReturn" + ] + } + } + }, + "TestServerlessAppDynamicExampleDynamicInputGenerated": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations" + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.DynamicExample_DynamicInput_Generated::DynamicInput" + ] + } + } + }, + "TestServerlessAppTaskExampleTaskReturnGenerated": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations" + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.TaskExample_TaskReturn_Generated::TaskReturn" + ] + } + } + }, + "TestServerlessAppVoidExampleVoidReturnGenerated": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations" + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.VoidExample_VoidReturn_Generated::VoidReturn" + ] + } + } + }, + "TestServerlessAppCustomizeResponseExamplesOkResponseWithHeaderGenerated": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.CustomizeResponseExamples_OkResponseWithHeader_Generated::OkResponseWithHeader" + ] + }, + "Events": { + "RootGet": { + "Type": "Api", + "Properties": { + "Path": "/okresponsewithheader/{x}", + "Method": "GET" + } + } + } + } + }, + "TestServerlessAppCustomizeResponseExamplesOkResponseWithHeaderAsyncGenerated": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.CustomizeResponseExamples_OkResponseWithHeaderAsync_Generated::OkResponseWithHeaderAsync" + ] + }, + "Events": { + "RootGet": { + "Type": "Api", + "Properties": { + "Path": "/okresponsewithheaderasync/{x}", + "Method": "GET" + } + } + } + } + }, + "TestServerlessAppCustomizeResponseExamplesNotFoundResponseWithHeaderV2Generated": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.CustomizeResponseExamples_NotFoundResponseWithHeaderV2_Generated::NotFoundResponseWithHeaderV2" + ] + }, + "Events": { + "RootGet": { + "Type": "HttpApi", + "Properties": { + "Path": "/notfoundwithheaderv2/{x}", + "Method": "GET" + } + } + } + } + }, + "TestServerlessAppCustomizeResponseExamplesNotFoundResponseWithHeaderV2AsyncGenerated": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.CustomizeResponseExamples_NotFoundResponseWithHeaderV2Async_Generated::NotFoundResponseWithHeaderV2Async" + ] + }, + "Events": { + "RootGet": { + "Type": "HttpApi", + "Properties": { + "Path": "/notfoundwithheaderv2async/{x}", + "Method": "GET" + } + } + } + } + }, + "TestServerlessAppCustomizeResponseExamplesNotFoundResponseWithHeaderV1Generated": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.CustomizeResponseExamples_NotFoundResponseWithHeaderV1_Generated::NotFoundResponseWithHeaderV1" + ] + }, + "Events": { + "RootGet": { + "Type": "HttpApi", + "Properties": { + "Path": "/notfoundwithheaderv1/{x}", + "Method": "GET", + "PayloadFormatVersion": "1.0" + } + } + } + } + }, + "TestServerlessAppCustomizeResponseExamplesNotFoundResponseWithHeaderV1AsyncGenerated": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.CustomizeResponseExamples_NotFoundResponseWithHeaderV1Async_Generated::NotFoundResponseWithHeaderV1Async" + ] + }, + "Events": { + "RootGet": { + "Type": "HttpApi", + "Properties": { + "Path": "/notfoundwithheaderv1async/{x}", + "Method": "GET", + "PayloadFormatVersion": "1.0" + } + } + } + } + }, + "GreeterSayHello": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 1024, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.Greeter_SayHello_Generated::SayHello" + ] + }, + "Events": { + "RootGet": { + "Type": "HttpApi", + "Properties": { + "Path": "/Greeter/SayHello", + "Method": "GET", + "PayloadFormatVersion": "1.0" + } + } + } + } + }, + "GreeterSayHelloAsync": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 256, + "Timeout": 50, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.Greeter_SayHelloAsync_Generated::SayHelloAsync" + ] + }, + "Events": { + "RootGet": { + "Type": "HttpApi", + "Properties": { + "Path": "/Greeter/SayHelloAsync", + "Method": "GET", + "PayloadFormatVersion": "1.0" + } + } + } + } + }, + "SimpleCalculatorAdd": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.SimpleCalculator_Add_Generated::Add" + ] + }, + "Events": { + "RootGet": { + "Type": "Api", + "Properties": { + "Path": "/SimpleCalculator/Add", + "Method": "GET" + } + } + } + } + }, + "SimpleCalculatorSubtract": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.SimpleCalculator_Subtract_Generated::Subtract" + ] + }, + "Events": { + "RootGet": { + "Type": "Api", + "Properties": { + "Path": "/SimpleCalculator/Subtract", + "Method": "GET" + } + } + } + } + }, + "SimpleCalculatorMultiply": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.SimpleCalculator_Multiply_Generated::Multiply" + ] + }, + "Events": { + "RootGet": { + "Type": "Api", + "Properties": { + "Path": "/SimpleCalculator/Multiply/{x}/{y}", + "Method": "GET" + } + } + } + } + }, + "SimpleCalculatorDivideAsync": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.SimpleCalculator_DivideAsync_Generated::DivideAsync" + ] + }, + "Events": { + "RootGet": { + "Type": "Api", + "Properties": { + "Path": "/SimpleCalculator/DivideAsync/{x}/{y}", + "Method": "GET" + } + } + } + } + }, + "PI": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations" + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.SimpleCalculator_Pi_Generated::Pi" + ] + } + } + }, + "Random": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations" + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.SimpleCalculator_Random_Generated::Random" + ] + } + } + }, + "Randoms": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations" + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.SimpleCalculator_Randoms_Generated::Randoms" + ] + } + } + }, + "ToUpper": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations" + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.Sub1.Functions_ToUpper_Generated::ToUpper" + ] + } + } + }, + "TestServerlessAppNullableReferenceTypeExampleNullableHeaderHttpApiGenerated": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.NullableReferenceTypeExample_NullableHeaderHttpApi_Generated::NullableHeaderHttpApi" + ] + }, + "Events": { + "RootGet": { + "Type": "HttpApi", + "Properties": { + "Path": "/nullableheaderhttpapi", + "Method": "GET" + } + } + } + } + }, + "TestServerlessAppFromScratchNoApiGatewayEventsReferenceToUpperGenerated": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "Events": { + "RootGet": { + "Type": "HttpApi", + "Properties": { + "Path": "/{text}", + "Method": "GET" + } + } + }, + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.FromScratch.NoApiGatewayEventsReference_ToUpper_Generated::ToUpper" + ] + } + } + }, + "TestServerlessAppFromScratchNoSerializerAttributeReferenceToUpperGenerated": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations" + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "Events": {}, + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.FromScratch.NoSerializerAttributeReference_ToUpper_Generated::ToUpper" + ] + } + } + }, + "RestAuthorizerTest": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.CustomAuthorizerRestExample_RestAuthorizer_Generated::RestAuthorizer" + ] + }, + "Events": { + "RootGet": { + "Type": "Api", + "Properties": { + "Path": "/rest/authorizer", + "Method": "GET" + } + } + } + } + }, + "HttpApiAuthorizerTest": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations", + "SyncedEvents": [ + "RootGet" + ] + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.CustomAuthorizerHttpApiExample_HttpApiAuthorizer_Generated::HttpApiAuthorizer" + ] + }, + "Events": { + "RootGet": { + "Type": "HttpApi", + "Properties": { + "Path": "/api/authorizer", + "Method": "GET" + } + } + } + } + }, + "TestServerlessAppIntrinsicExampleHasIntrinsicGenerated": { + "Type": "AWS::Serverless::Function", + "Metadata": { + "Tool": "Amazon.Lambda.Annotations" + }, + "Properties": { + "MemorySize": 256, + "Timeout": 30, + "Policies": [ + "AWSLambdaBasicExecutionRole" + ], + "PackageType": "Image", + "ImageUri": ".", + "ImageConfig": { + "Command": [ + "TestServerlessApp::TestServerlessApp.IntrinsicExample_HasIntrinsic_Generated::HasIntrinsic" + ] + } + } + } + }, + "Outputs": { + "RestApiURL": { + "Description": "Rest API endpoint URL for Prod environment", + "Value": { + "Fn::Sub": "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod" + } + }, + "HttpApiURL": { + "Description": "HTTP API endpoint URL for Prod environment", + "Value": { + "Fn::Sub": "https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com" + } + } + } } \ No newline at end of file