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
45 changes: 30 additions & 15 deletions src/GeneratedEndpoints/MinimalApiGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -710,18 +710,20 @@ private static (
cancellationToken.ThrowIfCancellationRequested();

EquatableImmutableArray<string>? tags = null;
var requireAuthorization = false;
bool? requireAuthorization = null;
EquatableImmutableArray<string>? authorizationPolicies = null;
var disableAntiforgery = false;
var allowAnonymous = false;
var excludeFromDescription = false;
bool? disableAntiforgery = null;
bool? allowAnonymous = null;
bool? excludeFromDescription = null;

List<AcceptsMetadata>? accepts = null;
List<ProducesMetadata>? produces = null;
List<ProducesProblemMetadata>? producesProblem = null;
List<ProducesValidationProblemMetadata>? producesValidationProblem = null;

var classAttributes = classSymbol.GetAttributes();
var classHasAllowAnonymousAttribute = false;
var classHasRequireAuthorizationAttribute = false;
GetAdditionalRequestHandlerAttributeValues(
classAttributes,
ref tags,
Expand All @@ -733,10 +735,14 @@ private static (
ref accepts,
ref produces,
ref producesProblem,
ref producesValidationProblem
ref producesValidationProblem,
ref classHasAllowAnonymousAttribute,
ref classHasRequireAuthorizationAttribute
);

var methodAttributes = methodSymbol.GetAttributes();
var methodHasAllowAnonymousAttribute = false;
var methodHasRequireAuthorizationAttribute = false;
GetAdditionalRequestHandlerAttributeValues(
methodAttributes,
ref tags,
Expand All @@ -748,16 +754,21 @@ ref producesValidationProblem
ref accepts,
ref produces,
ref producesProblem,
ref producesValidationProblem
ref producesValidationProblem,
ref methodHasAllowAnonymousAttribute,
ref methodHasRequireAuthorizationAttribute
);

if (methodHasRequireAuthorizationAttribute && !methodHasAllowAnonymousAttribute)
allowAnonymous = false;

return (
tags,
requireAuthorization,
requireAuthorization ?? false,
authorizationPolicies,
disableAntiforgery,
allowAnonymous,
excludeFromDescription,
disableAntiforgery ?? false,
allowAnonymous ?? false,
excludeFromDescription ?? false,
ToEquatableOrNull(accepts),
ToEquatableOrNull(produces),
ToEquatableOrNull(producesProblem),
Expand All @@ -768,15 +779,17 @@ ref producesValidationProblem
private static void GetAdditionalRequestHandlerAttributeValues(
ImmutableArray<AttributeData> attributes,
ref EquatableImmutableArray<string>? tags,
ref bool requireAuthorization,
ref bool? requireAuthorization,
ref EquatableImmutableArray<string>? authorizationPolicies,
ref bool disableAntiforgery,
ref bool allowAnonymous,
ref bool excludeFromDescription,
ref bool? disableAntiforgery,
ref bool? allowAnonymous,
ref bool? excludeFromDescription,
ref List<AcceptsMetadata>? accepts,
ref List<ProducesMetadata>? produces,
ref List<ProducesProblemMetadata>? producesProblem,
ref List<ProducesValidationProblemMetadata>? producesValidationProblem
ref List<ProducesValidationProblemMetadata>? producesValidationProblem,
ref bool hasAllowAnonymousAttribute,
ref bool hasRequireAuthorizationAttribute
)
{
foreach (var attribute in attributes)
Expand Down Expand Up @@ -818,6 +831,7 @@ ref List<ProducesValidationProblemMetadata>? producesValidationProblem
break;
case $"global::{RequireAuthorizationAttributeFullyQualifiedName}":
requireAuthorization = true;
hasRequireAuthorizationAttribute = true;
if (attribute.ConstructorArguments.Length == 1)
{
var arg = attribute.ConstructorArguments[0];
Expand All @@ -837,6 +851,7 @@ ref List<ProducesValidationProblemMetadata>? producesValidationProblem
break;
case $"global::{AllowAnonymousAttributeFullyQualifiedName}":
allowAnonymous = true;
hasAllowAnonymousAttribute = true;
break;
case "global::Microsoft.AspNetCore.Routing.ExcludeFromDescriptionAttribute":
excludeFromDescription = true;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//-----------------------------------------------------------------------------
// <auto-generated>
// This code was generated by MinimalApiGenerator which can be found
// in the GeneratedEndpoints namespace.
//
// Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated.
// </auto-generated>
//-----------------------------------------------------------------------------

#nullable enable

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;

namespace Microsoft.AspNetCore.Generated.Routing;

internal static class EndpointRouteBuilderExtensions
{
internal static IEndpointRouteBuilder MapEndpointHandlers(this IEndpointRouteBuilder builder)
{
builder.MapGet("/allow-anon", global::GeneratedEndpointsTests.AllowAnonymousClass.Handle)
.WithName("Handle")
.RequireAuthorization();

return builder;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//-----------------------------------------------------------------------------
// <auto-generated>
// This code was generated by MinimalApiGenerator which can be found
// in the GeneratedEndpoints namespace.
//
// Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated.
// </auto-generated>
//-----------------------------------------------------------------------------

#nullable enable

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;

namespace Microsoft.AspNetCore.Generated.Routing;

internal static class EndpointRouteBuilderExtensions
{
internal static IEndpointRouteBuilder MapEndpointHandlers(this IEndpointRouteBuilder builder)
{
builder.MapGet("/allow-anon", global::AllowAnonymousClass.Handle)
.WithName("Handle")
.RequireAuthorization();

return builder;
}
}
23 changes: 23 additions & 0 deletions tests/GeneratedEndpoints.Tests/GeneratedEndpointsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,29 @@ await result.VerifyAsync("MapEndpointHandlers.g.cs")
.UseMethodName($"{nameof(MapGetWithConfigureServiceProvider)}_MapEndpointHandlers_With{(withNamespace ? "" : "out")}Namespace");
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public async Task ClassAllowAnonymousMethodRequireAuthorization(bool withNamespace)
{
var sources = TestHelpers.GetSources("""
[AllowAnonymous]
internal sealed class AllowAnonymousClass
{
[MapGet("/allow-anon")]
[RequireAuthorization]
public static Ok Handle()
=> TypedResults.Ok();
}
""", withNamespace
);

var result = TestHelpers.RunGenerator(sources);

await result.VerifyAsync("MapEndpointHandlers.g.cs")
.UseMethodName($"{nameof(ClassAllowAnonymousMethodRequireAuthorization)}_MapEndpointHandlers_With{(withNamespace ? "" : "out")}Namespace");
}

[Theory]
[InlineData(true)]
[InlineData(false)]
Expand Down
Loading