using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Mvc.Controllers; using Umbraco.Cms.Core.Features; namespace Umbraco.Cms.Web.Common.Authorization { /// /// Ensures that the controller is an authorized feature. /// public class FeatureAuthorizeHandler : AuthorizationHandler { private readonly UmbracoFeatures _umbracoFeatures; public FeatureAuthorizeHandler(UmbracoFeatures umbracoFeatures) { _umbracoFeatures = umbracoFeatures; } protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, FeatureAuthorizeRequirement requirement) { var allowed = IsAllowed(context); if (!allowed.HasValue || allowed.Value) { context.Succeed(requirement); } else { context.Fail(); } return Task.CompletedTask; } private bool? IsAllowed(AuthorizationHandlerContext context) { Endpoint? endpoint = null; switch (context.Resource) { case DefaultHttpContext defaultHttpContext: { IEndpointFeature endpointFeature = defaultHttpContext.Features.Get(); endpoint = endpointFeature.Endpoint; break; } case Endpoint resourceEndpoint: { endpoint = resourceEndpoint; break; } } if (endpoint is null) { throw new InvalidOperationException("This authorization handler can only be applied to controllers routed with endpoint routing"); } var actionDescriptor = endpoint.Metadata.GetMetadata(); var controllerType = actionDescriptor.ControllerTypeInfo.AsType(); return _umbracoFeatures.IsControllerEnabled(controllerType); } } }