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);
}
}
}