Fix #6764 EndpointConventionBuilder API review

This commit is contained in:
Ryan Nowak 2019-05-07 15:17:06 -07:00 committed by Ryan Nowak
parent d37b2ca70a
commit 0b590ff46f
9 changed files with 94 additions and 42 deletions

View File

@ -5,7 +5,7 @@ namespace Microsoft.AspNetCore.Builder
{
public static partial class ComponentEndpointConventionBuilderExtensions
{
public static TBuilder AddComponent<TBuilder>(this TBuilder builder, System.Type componentType, string selector) where TBuilder : Microsoft.AspNetCore.SignalR.IHubEndpointConventionBuilder { throw null; }
public static Microsoft.AspNetCore.Components.Server.ComponentEndpointConventionBuilder AddComponent(this Microsoft.AspNetCore.Components.Server.ComponentEndpointConventionBuilder builder, System.Type componentType, string selector) { throw null; }
}
public static partial class ComponentEndpointRouteBuilderExtensions
{

View File

@ -9,19 +9,18 @@ using Microsoft.AspNetCore.SignalR;
namespace Microsoft.AspNetCore.Builder
{
/// <summary>
/// Extensions for <see cref="HubEndpointConventionBuilder"/>.
/// Extensions for <see cref="ComponentEndpointConventionBuilder"/>.
/// </summary>
public static class ComponentEndpointConventionBuilderExtensions
{
/// <summary>
/// Adds <paramref name="componentType"/> to the list of components registered with this <see cref="ComponentHub"/> instance.
/// The selector will default to the component name in lowercase.
/// Adds <paramref name="componentType"/> to the list of components registered with this hub instance.
/// </summary>
/// <param name="builder">The <see cref="IHubEndpointConventionBuilder"/>.</param>
/// <param name="builder">The <see cref="ComponentEndpointConventionBuilder"/>.</param>
/// <param name="componentType">The component type.</param>
/// <param name="selector">The component selector in the DOM for the <paramref name="componentType"/>.</param>
/// <returns>The <paramref name="builder"/>.</returns>
public static TBuilder AddComponent<TBuilder>(this TBuilder builder, Type componentType, string selector) where TBuilder : IHubEndpointConventionBuilder
public static ComponentEndpointConventionBuilder AddComponent(this ComponentEndpointConventionBuilder builder, Type componentType, string selector)
{
if (builder == null)
{

View File

@ -5,8 +5,8 @@ namespace Microsoft.AspNetCore.Builder
{
public static partial class CorsEndpointConventionBuilderExtensions
{
public static TBuilder WithCorsPolicy<TBuilder>(this TBuilder builder, System.Action<Microsoft.AspNetCore.Cors.Infrastructure.CorsPolicyBuilder> configurePolicy) where TBuilder : Microsoft.AspNetCore.Builder.IEndpointConventionBuilder { throw null; }
public static TBuilder WithCorsPolicy<TBuilder>(this TBuilder builder, string policyName) where TBuilder : Microsoft.AspNetCore.Builder.IEndpointConventionBuilder { throw null; }
public static TBuilder RequireCors<TBuilder>(this TBuilder builder, System.Action<Microsoft.AspNetCore.Cors.Infrastructure.CorsPolicyBuilder> configurePolicy) where TBuilder : Microsoft.AspNetCore.Builder.IEndpointConventionBuilder { throw null; }
public static TBuilder RequireCors<TBuilder>(this TBuilder builder, string policyName) where TBuilder : Microsoft.AspNetCore.Builder.IEndpointConventionBuilder { throw null; }
}
public static partial class CorsMiddlewareExtensions
{

View File

@ -63,11 +63,11 @@ namespace SampleDestination
app.UseEndpoints(endpoints =>
{
endpoints.Map("/allow-origin", HandleRequest).WithCorsPolicy("AllowOrigin");
endpoints.Map("/allow-header-method", HandleRequest).WithCorsPolicy("AllowHeaderMethod");
endpoints.Map("/allow-credentials", HandleRequest).WithCorsPolicy("AllowCredentials");
endpoints.Map("/exposed-header", HandleRequest).WithCorsPolicy("ExposedHeader");
endpoints.Map("/allow-all", HandleRequest).WithCorsPolicy("AllowAll");
endpoints.Map("/allow-origin", HandleRequest).RequireCors("AllowOrigin");
endpoints.Map("/allow-header-method", HandleRequest).RequireCors("AllowHeaderMethod");
endpoints.Map("/allow-credentials", HandleRequest).RequireCors("AllowCredentials");
endpoints.Map("/exposed-header", HandleRequest).RequireCors("ExposedHeader");
endpoints.Map("/allow-all", HandleRequest).RequireCors("AllowAll");
});
app.Run(async (context) =>

View File

@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Builder
/// <param name="builder">The endpoint convention builder.</param>
/// <param name="policyName">The CORS policy name.</param>
/// <returns>The original convention builder parameter.</returns>
public static TBuilder WithCorsPolicy<TBuilder>(this TBuilder builder, string policyName) where TBuilder : IEndpointConventionBuilder
public static TBuilder RequireCors<TBuilder>(this TBuilder builder, string policyName) where TBuilder : IEndpointConventionBuilder
{
if (builder == null)
{
@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.Builder
/// <param name="builder">The endpoint convention builder.</param>
/// <param name="configurePolicy">A delegate which can use a policy builder to build a policy.</param>
/// <returns>The original convention builder parameter.</returns>
public static TBuilder WithCorsPolicy<TBuilder>(this TBuilder builder, Action<CorsPolicyBuilder> configurePolicy) where TBuilder : IEndpointConventionBuilder
public static TBuilder RequireCors<TBuilder>(this TBuilder builder, Action<CorsPolicyBuilder> configurePolicy) where TBuilder : IEndpointConventionBuilder
{
if (builder == null)
{

View File

@ -13,13 +13,13 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure
public class CorsEndpointConventionBuilderExtensionsTests
{
[Fact]
public void WithCorsPolicy_Name_MetadataAdded()
public void RequireCors_Name_MetadataAdded()
{
// Arrange
var testConventionBuilder = new TestEndpointConventionBuilder();
// Act
testConventionBuilder.WithCorsPolicy("TestPolicyName");
testConventionBuilder.RequireCors("TestPolicyName");
// Assert
var addCorsPolicy = Assert.Single(testConventionBuilder.Conventions);
@ -34,13 +34,13 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure
}
[Fact]
public void WithCorsPolicy_Policy_MetadataAdded()
public void RequireCors_Policy_MetadataAdded()
{
// Arrange
var testConventionBuilder = new TestEndpointConventionBuilder();
// Act
testConventionBuilder.WithCorsPolicy(builder => builder.AllowAnyOrigin());
testConventionBuilder.RequireCors(builder => builder.AllowAnyOrigin());
// Assert
var addCorsPolicy = Assert.Single(testConventionBuilder.Conventions);
@ -56,13 +56,13 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure
}
[Fact]
public void WithCorsPolicy_ChainedCall_ReturnedBuilderIsDerivedType()
public void RequireCors_ChainedCall_ReturnedBuilderIsDerivedType()
{
// Arrange
var testConventionBuilder = new TestEndpointConventionBuilder();
// Act
var builder = testConventionBuilder.WithCorsPolicy("TestPolicyName");
var builder = testConventionBuilder.RequireCors("TestPolicyName");
// Assert
Assert.True(builder.TestProperty);

View File

@ -717,7 +717,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure
}
[Fact]
public async Task Invoke_HasEndpointWithCorsPolicyMetadata_MiddlewareHasPolicy_RunsCorsWithPolicyName()
public async Task Invoke_HasEndpointRequireCorsMetadata_MiddlewareHasPolicy_RunsCorsWithPolicyName()
{
// Arrange
var defaultPolicy = new CorsPolicyBuilder().Build();

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Authorization;
@ -13,38 +14,25 @@ namespace Microsoft.AspNetCore.Builder
public static class AuthorizationEndpointConventionBuilderExtensions
{
/// <summary>
/// Adds authorization policies with the specified <see cref="IAuthorizeData"/> to the endpoint(s).
/// Adds the default authorization policy to the endpoint(s).
/// </summary>
/// <param name="builder">The endpoint convention builder.</param>
/// <param name="authorizeData">A collection of <see cref="IAuthorizeData"/>.</param>
/// <returns>The original convention builder parameter.</returns>
public static TBuilder RequireAuthorization<TBuilder>(this TBuilder builder, params IAuthorizeData[] authorizeData) where TBuilder : IEndpointConventionBuilder
public static TBuilder RequireAuthorization<TBuilder>(this TBuilder builder) where TBuilder : IEndpointConventionBuilder
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (authorizeData == null)
{
throw new ArgumentNullException(nameof(authorizeData));
}
builder.Add(endpointBuilder =>
{
foreach (var data in authorizeData)
{
endpointBuilder.Metadata.Add(data);
}
});
return builder;
return builder.RequireAuthorization(new AuthorizeAttribute());
}
/// <summary>
/// Adds authorization policies with the specified names to the endpoint(s).
/// </summary>
/// <param name="builder">The endpoint convention builder.</param>
/// <param name="policyNames">A collection of policy names.</param>
/// <param name="policyNames">A collection of policy names. If empty, the default authorization policy will be used.</param>
/// <returns>The original convention builder parameter.</returns>
public static TBuilder RequireAuthorization<TBuilder>(this TBuilder builder, params string[] policyNames) where TBuilder : IEndpointConventionBuilder
{
@ -62,18 +50,45 @@ namespace Microsoft.AspNetCore.Builder
}
/// <summary>
/// Adds the default authorization policy to the endpoint(s).
/// Adds authorization policies with the specified <see cref="IAuthorizeData"/> to the endpoint(s).
/// </summary>
/// <param name="builder">The endpoint convention builder.</param>
/// <param name="authorizeData">
/// A collection of <paramref name="authorizeData"/>. If empty, the default authorization policy will be used.
/// </param>
/// <returns>The original convention builder parameter.</returns>
public static TBuilder RequireAuthorization<TBuilder>(this TBuilder builder) where TBuilder : IEndpointConventionBuilder
public static TBuilder RequireAuthorization<TBuilder>(this TBuilder builder, params IAuthorizeData[] authorizeData)
where TBuilder : IEndpointConventionBuilder
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
return builder.RequireAuthorization(new AuthorizeAttribute());
if (authorizeData == null)
{
throw new ArgumentNullException(nameof(authorizeData));
}
if (authorizeData.Length == 0)
{
authorizeData = new IAuthorizeData[] { new AuthorizeAttribute(), };
}
RequireAuthorizationCore(builder, authorizeData);
return builder;
}
private static void RequireAuthorizationCore<TBuilder>(TBuilder builder, IEnumerable<IAuthorizeData> authorizeData)
where TBuilder : IEndpointConventionBuilder
{
builder.Add(endpointBuilder =>
{
foreach (var data in authorizeData)
{
endpointBuilder.Metadata.Add(data);
}
});
}
}
}

View File

@ -32,6 +32,25 @@ namespace Microsoft.AspNetCore.Authorization.Test
Assert.Equal(metadata, Assert.Single(endpointModel.Metadata));
}
[Fact]
public void RequireAuthorization_IAuthorizeData_Empty()
{
// Arrange
var builder = new TestEndpointConventionBuilder();
// Act
builder.RequireAuthorization(Array.Empty<IAuthorizeData>());
// Assert
var convention = Assert.Single(builder.Conventions);
var endpointModel = new RouteEndpointBuilder((context) => Task.CompletedTask, RoutePatternFactory.Parse("/"), 0);
convention(endpointModel);
var authMetadata = Assert.IsAssignableFrom<IAuthorizeData>(Assert.Single(endpointModel.Metadata));
Assert.Null(authMetadata.Policy);
}
[Fact]
public void RequireAuthorization_PolicyName()
{
@ -51,6 +70,25 @@ namespace Microsoft.AspNetCore.Authorization.Test
Assert.Equal("policy", authMetadata.Policy);
}
[Fact]
public void RequireAuthorization_PolicyName_Empty()
{
// Arrange
var builder = new TestEndpointConventionBuilder();
// Act
builder.RequireAuthorization(Array.Empty<string>());
// Assert
var convention = Assert.Single(builder.Conventions);
var endpointModel = new RouteEndpointBuilder((context) => Task.CompletedTask, RoutePatternFactory.Parse("/"), 0);
convention(endpointModel);
var authMetadata = Assert.IsAssignableFrom<IAuthorizeData>(Assert.Single(endpointModel.Metadata));
Assert.Null(authMetadata.Policy);
}
[Fact]
public void RequireAuthorization_Default()
{