Create matcher policy to pick the correct item endpoint (#14987)

This commit is contained in:
Kenn Jacobsen
2023-10-17 08:55:09 +02:00
committed by GitHub
parent 13913cd9fb
commit ea4f07bd08
2 changed files with 60 additions and 0 deletions

View File

@@ -1,5 +1,6 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Api.Common.DependencyInjection;
using Umbraco.Cms.Api.Delivery.Accessors;
@@ -7,6 +8,7 @@ using Umbraco.Cms.Api.Delivery.Configuration;
using Umbraco.Cms.Api.Delivery.Handlers;
using Umbraco.Cms.Api.Delivery.Json;
using Umbraco.Cms.Api.Delivery.Rendering;
using Umbraco.Cms.Api.Delivery.Routing;
using Umbraco.Cms.Api.Delivery.Security;
using Umbraco.Cms.Api.Delivery.Services;
using Umbraco.Cms.Core;
@@ -57,6 +59,9 @@ public static class UmbracoBuilderExtensions
builder.AddNotificationAsyncHandler<MemberDeletedNotification, RevokeMemberAuthenticationTokensNotificationHandler>();
builder.AddNotificationAsyncHandler<AssignedMemberRolesNotification, RevokeMemberAuthenticationTokensNotificationHandler>();
builder.AddNotificationAsyncHandler<RemovedMemberRolesNotification, RevokeMemberAuthenticationTokensNotificationHandler>();
// FIXME: remove this when Delivery API V1 is removed
builder.Services.AddSingleton<MatcherPolicy, DeliveryApiItemsEndpointsMatcherPolicy>();
return builder;
}
}

View File

@@ -0,0 +1,55 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Routing.Matching;
using Umbraco.Cms.Api.Delivery.Controllers;
namespace Umbraco.Cms.Api.Delivery.Routing;
// FIXME: remove this when Delivery API V1 is removed
internal sealed class DeliveryApiItemsEndpointsMatcherPolicy : MatcherPolicy, IEndpointSelectorPolicy
{
public override int Order => 100;
public bool AppliesToEndpoints(IReadOnlyList<Endpoint> endpoints)
{
for (var i = 0; i < endpoints.Count; i++)
{
ControllerActionDescriptor? controllerActionDescriptor = endpoints[i].Metadata.GetMetadata<ControllerActionDescriptor>();
if (IsByIdsController(controllerActionDescriptor) || IsByRouteController(controllerActionDescriptor))
{
return true;
}
}
return false;
}
public Task ApplyAsync(HttpContext httpContext, CandidateSet candidates)
{
var hasIdQueryParameter = httpContext.Request.Query.ContainsKey("id");
for (var i = 0; i < candidates.Count; i++)
{
ControllerActionDescriptor? controllerActionDescriptor = candidates[i].Endpoint?.Metadata.GetMetadata<ControllerActionDescriptor>();
if (IsByIdsController(controllerActionDescriptor))
{
candidates.SetValidity(i, hasIdQueryParameter);
}
else if (IsByRouteController(controllerActionDescriptor))
{
candidates.SetValidity(i, hasIdQueryParameter is false);
}
}
return Task.CompletedTask;
}
private static bool IsByIdsController(ControllerActionDescriptor? controllerActionDescriptor)
=> IsControllerType<ByIdsContentApiController>(controllerActionDescriptor) || IsControllerType<ByIdsMediaApiController>(controllerActionDescriptor);
private static bool IsByRouteController(ControllerActionDescriptor? controllerActionDescriptor)
=> IsControllerType<ByRouteContentApiController>(controllerActionDescriptor) || IsControllerType<ByPathMediaApiController>(controllerActionDescriptor);
private static bool IsControllerType<T>(ControllerActionDescriptor? controllerActionDescriptor)
=> controllerActionDescriptor?.MethodInfo.DeclaringType == typeof(T);
}