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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ internal SourceCode GenerateClass() =>
using System;

namespace {{@namespace}};

public sealed class {{ClassName}}

/// <summary>
/// Configuration for the generated web API.
/// </summary>
public sealed class {{ClassName}}
{
/// <summary>
/// The uri to the exposed OpenAPI specification used to generate the API.
Expand Down
18 changes: 14 additions & 4 deletions src/OpenAPI.WebApiGenerator/CodeGeneration/AuthGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ public AuthGenerator(OpenApiDocument openApiDocument)
{
return null;
}
return new SourceCode("SecuritySchemes.g.cs",
return new SourceCode("SecuritySchemes.g.cs",
$$"""
using Microsoft.AspNetCore.Http;
using System.Collections.Immutable;

namespace {{@namespace}};
Expand Down Expand Up @@ -216,7 +217,12 @@ internal static class {{className}}
#nullable enable
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;

namespace {{@namespace}};

Expand Down Expand Up @@ -387,13 +393,15 @@ internal sealed class {{securityRequirementsFilterClassName}}(Operation operatio
protected override SecurityRequirements Requirements { get; } = new()
{{{string.Join(",",
securityRequirementGroups.Select(securityRequirementGroup =>
securityRequirementGroup.AggregateToString(securityRequirement =>
securityRequirementGroup.Any() ? securityRequirementGroup.AggregateToString(securityRequirement =>
$$"""
new SecurityRequirement
{
["{{securityRequirement.Key}}"] = [{{string.Join(", ", securityRequirement.Value.Select(scope => $"\"{scope}\""))}}]
}
""")))}}
""") : """
new SecurityRequirement()
"""))}}
};

private static Request ResolveRequest(HttpContext context) => (Request) context.Items[RequestItemKey]!;
Expand All @@ -409,9 +417,11 @@ internal sealed class {{securityRequirementsFilterClassName}}(Operation operatio
{
return null;
}
return new SourceCode("SecuritySchemeOptions.g.cs",
return new SourceCode("SecuritySchemeOptions.g.cs",
$$"""
#nullable enable
using System;

namespace {{@namespace}};

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,17 @@ internal SourceCode GenerateHttpRequestExtensionsClass() =>
new($"{HttpRequestExtensionsClassName}.g.cs",
$$$""""
#nullable enable
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Corvus.Json;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Primitives;
using Microsoft.Net.Http.Headers;
using OpenAPI.ParameterStyleParsers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ internal SourceCode GenerateHttpResponseExtensionsClass() =>
new($"{HttpResponseExtensionsClassName}.g.cs",
$$$""""
#nullable enable
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Nodes;
using Corvus.Json;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ internal SourceCode GenerateJsonValidationExceptionClass() =>
#nullable enable
using Corvus.Json;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Text;

namespace {{@namespace}};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,14 @@ internal SourceCode Generate(string @namespace,
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;

namespace {{@namespace}};
{{ new[]
Expand Down Expand Up @@ -72,7 +77,7 @@ internal partial class Operation
/// Create a request validation error response.
/// <exception cref="JsonValidationException"></exception>
/// <param name="request">The invalid request</param>
/// <param name="ValidationContext">The validation context describing the validation errors</param>
/// <param name="validationContext">The validation context describing the validation errors</param>
/// </summary>
private Response CreateRequestValidationErrorResponse(Request request, ValidationContext validationContext)
{
Expand Down Expand Up @@ -272,6 +277,10 @@ private static Diagnostic CreateMissingHandlersDiagnosticMessage(string @namespa

private static string GenerateMissingHandler(string @namespace) =>
$$"""
using System;
using System.Threading;
using System.Threading.Tasks;

namespace {{@namespace}}
{
internal partial class Operation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ internal SourceCode ForMinimalApi(List<(string Namespace, KeyValuePair<HttpMetho
$$"""
#nullable enable
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

namespace {{@namespace}};

/// <summary>
/// Configure routes for OpenAPI operations
/// Configure routes for OpenAPI operations
/// </summary>
internal static class OperationRouter
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ internal SourceCode GenerateRequestClass(string @namespace, string path)
$$"""
#nullable enable
using Corvus.Json;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace {{@namespace}};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,13 @@ public SourceCode GenerateResponseClass(string @namespace, string path)
$$"""
#nullable enable
using Corvus.Json;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Net.Http.Headers;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text.Json;
using {{httpResponseExtensionsGenerator.Namespace}};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ private List<TypeDeclaration> GenerateCode(SourceGeneratorHelpers.TypesToGenerat
optionalAsNullable: typesToGenerate.OptionalAsNullable,
disabledNamingHeuristics: [.. typesToGenerate.DisabledNamingHeuristics],
fileExtension: ".g.cs",
addExplicitUsings: true,
defaultAccessibility: typesToGenerate.DefaultAccessibility);

var languageProvider = CSharpLanguageProvider.DefaultWithOptions(options);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ internal string GetFullyQualifiedTypeName(
using Microsoft.AspNetCore.Authorization;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipelines;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;

namespace {{@namespace}};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ internal sealed class ValidationExtensionsGenerator(string @namespace)
$$"""
#nullable enable
using Corvus.Json;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Text.Json;

namespace {{@namespace}};
Expand Down
1 change: 1 addition & 0 deletions tests/Example.OpenApi20/Example.OpenApi20.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>Example.OpenApi20</RootNamespace>
<GenerateDocumentationFile>true</GenerateDocumentationFile>

<ApiCompatValidateAssemblies>true</ApiCompatValidateAssemblies>
<ApiCompatContractAssembly>LastMajorVersionBinary/$(AssemblyName).dll</ApiCompatContractAssembly>
Expand Down
3 changes: 3 additions & 0 deletions tests/Example.OpenApi20/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,7 @@
app.MapOperations();
app.Run();

/// <summary>
/// Application entry point.
/// </summary>
public abstract partial class Program;
1 change: 1 addition & 0 deletions tests/Example.OpenApi30/Example.OpenApi30.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>Example.OpenApi30</RootNamespace>
<GenerateDocumentationFile>true</GenerateDocumentationFile>

<ApiCompatValidateAssemblies>true</ApiCompatValidateAssemblies>
<ApiCompatContractAssembly>LastMajorVersionBinary/$(AssemblyName).dll</ApiCompatContractAssembly>
Expand Down
3 changes: 3 additions & 0 deletions tests/Example.OpenApi30/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,7 @@
app.MapOperations();
app.Run();

/// <summary>
/// Application entry point.
/// </summary>
public abstract partial class Program;
1 change: 1 addition & 0 deletions tests/Example.OpenApi31/Example.OpenApi31.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>Example.OpenApi31</RootNamespace>
<GenerateDocumentationFile>true</GenerateDocumentationFile>

<ApiCompatValidateAssemblies>true</ApiCompatValidateAssemblies>
<ApiCompatContractAssembly>LastMajorVersionBinary/$(AssemblyName).dll</ApiCompatContractAssembly>
Expand Down
3 changes: 3 additions & 0 deletions tests/Example.OpenApi31/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,7 @@
app.MapOperations();
app.Run();

/// <summary>
/// Application entry point.
/// </summary>
public abstract partial class Program;
2 changes: 1 addition & 1 deletion tests/Example.OpenApi32/Example.OpenApi32.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>Example.OpenApi32</RootNamespace>
<GenerateDocumentationFile>true</GenerateDocumentationFile>

<ApiCompatValidateAssemblies>true</ApiCompatValidateAssemblies>
<ApiCompatContractAssembly>LastMajorVersionBinary/$(AssemblyName).dll</ApiCompatContractAssembly>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
using System.Threading;
using System.Threading.Tasks;

namespace Example.OpenApi32.Paths.FooFooId.Delete;

internal partial class Operation
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Corvus.Json;

namespace Example.OpenApi32.Paths.FooFooId.Put;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Example.OpenApi32.Components.Schemas;

namespace Example.OpenApi32.Paths.FooFooIdEvents.Get;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using Example.OpenApi32.Components.Schemas;
using System;
using System.Threading;
using System.Threading.Tasks;
using Example.OpenApi32.Components.Schemas;

namespace Example.OpenApi32.Paths.FooFooIdEvents.Post;

Expand Down
7 changes: 7 additions & 0 deletions tests/Example.OpenApi32/Program.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
using System;
using Corvus.Json;
using Example.OpenApi.Auth;
using Example.OpenApi32;
using Microsoft.AspNetCore.Authentication.Certificate;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;

var builder = WebApplication.CreateBuilder(args);
Expand Down Expand Up @@ -49,4 +53,7 @@
app.MapOperations();
app.Run();

/// <summary>
/// Application entry point.
/// </summary>
public abstract partial class Program;
6 changes: 5 additions & 1 deletion tests/Example.OpenApi32/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,11 @@
"200": {
"description": "Successfully deleted"
}
}
},
"security": [
{},
{"openIdConnect": []}
]
},
"parameters": [
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.IO;
using System.Linq;
using AwesomeAssertions;
using Xunit;

namespace OpenAPI.WebApiGenerator.Tests;

public partial class ApiGeneratorTests
{
[Theory]
[MemberData(nameof(AnonymousSecurityRequirementSpecs))]
public void GivenAnonymousSecurityRequirement_WhenGenerating_SecurityRequirementsFilterRepresentsEachRequirementObject(
string _, string openApiSpec)
{
var sourceCode = GetOperationSourceCode(openApiSpec);

sourceCode.Should().Contain("class SecurityRequirementsFilter");
sourceCode.Should().Contain("new SecurityRequirement", Exactly.Twice());
sourceCode.Should().Contain("[\"secret_key\"] = []", Exactly.Once());
}

private string GetOperationSourceCode(string openApiSpec)
{
var compilation = SetupGenerator(openApiSpec, out var diagnostics);
HasOnlyMissingHandler(diagnostics);

var operationSyntaxTree = compilation.SyntaxTrees
.FirstOrDefault(t => Path.GetFileName(t.FilePath).EndsWith("Operation.g.cs"));
operationSyntaxTree.Should().NotBeNull();

return operationSyntaxTree.ToString();
}
}
Loading
Loading