2019-01-22 17:23:30 +01:00
|
|
|
|
using System.Collections.Generic;
|
2013-11-20 14:18:03 +11:00
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Net.Http;
|
|
|
|
|
|
using System.Threading;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using System.Web.Http;
|
|
|
|
|
|
using System.Web.Http.Controllers;
|
|
|
|
|
|
using System.Web.Http.Filters;
|
|
|
|
|
|
using Umbraco.Web.WebApi.Filters;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Umbraco.Web.WebApi
|
|
|
|
|
|
{
|
|
|
|
|
|
internal static class HttpControllerContextExtensions
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
2019-01-22 17:23:30 +01:00
|
|
|
|
/// Invokes the authorization filters for the controller action.
|
2013-11-20 14:18:03 +11:00
|
|
|
|
/// </summary>
|
2019-01-22 17:23:30 +01:00
|
|
|
|
/// <returns>The response of the first filter returning a result, if any, otherwise null (authorized).</returns>
|
2013-11-20 14:18:03 +11:00
|
|
|
|
internal static async Task<HttpResponseMessage> InvokeAuthorizationFiltersForRequest(this HttpControllerContext controllerContext)
|
|
|
|
|
|
{
|
|
|
|
|
|
var controllerDescriptor = controllerContext.ControllerDescriptor;
|
|
|
|
|
|
var controllerServices = controllerDescriptor.Configuration.Services;
|
|
|
|
|
|
var actionDescriptor = controllerServices.GetActionSelector().SelectAction(controllerContext);
|
2019-01-22 17:23:30 +01:00
|
|
|
|
|
2013-11-20 14:18:03 +11:00
|
|
|
|
var filters = actionDescriptor.GetFilterPipeline();
|
|
|
|
|
|
var filterGrouping = new FilterGrouping(filters);
|
2019-01-22 17:23:30 +01:00
|
|
|
|
|
|
|
|
|
|
// because the continuation gets built from the inside out we need to reverse the filter list
|
2013-11-20 14:18:03 +11:00
|
|
|
|
// so that least specific filters (Global) get run first and the most specific filters (Action) get run last.
|
2019-01-22 17:23:30 +01:00
|
|
|
|
var authorizationFilters = filterGrouping.AuthorizationFilters.Reverse().ToList();
|
|
|
|
|
|
|
|
|
|
|
|
if (authorizationFilters.Count == 0)
|
|
|
|
|
|
return null;
|
2013-11-20 14:18:03 +11:00
|
|
|
|
|
2019-01-22 17:23:30 +01:00
|
|
|
|
// if the authorization filter returns a result, it means it failed to authorize
|
|
|
|
|
|
var actionContext = new HttpActionContext(controllerContext, actionDescriptor);
|
|
|
|
|
|
return await ExecuteAuthorizationFiltersAsync(actionContext, CancellationToken.None, authorizationFilters);
|
2013-11-20 14:18:03 +11:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-22 17:23:30 +01:00
|
|
|
|
/// Executes a chain of filters.
|
2013-11-20 14:18:03 +11:00
|
|
|
|
/// </summary>
|
2019-01-22 17:23:30 +01:00
|
|
|
|
/// <remarks>
|
|
|
|
|
|
/// Recursively calls in to itself as its continuation for the next filter in the chain.
|
|
|
|
|
|
/// </remarks>
|
|
|
|
|
|
private static async Task<HttpResponseMessage> ExecuteAuthorizationFiltersAsync(HttpActionContext actionContext, CancellationToken token, IList<IAuthorizationFilter> filters, int index = 0)
|
2013-11-20 14:18:03 +11:00
|
|
|
|
{
|
2014-05-09 15:50:07 +10:00
|
|
|
|
return await filters[index].ExecuteAuthorizationFilterAsync(actionContext, token,
|
2019-01-22 17:23:30 +01:00
|
|
|
|
() => ++index == filters.Count
|
2014-05-09 15:50:07 +10:00
|
|
|
|
? Task.FromResult<HttpResponseMessage>(null)
|
2019-01-22 17:23:30 +01:00
|
|
|
|
: ExecuteAuthorizationFiltersAsync(actionContext, token, filters, index));
|
2013-11-20 14:18:03 +11:00
|
|
|
|
}
|
2013-12-06 15:01:58 +11:00
|
|
|
|
}
|
2017-07-20 11:21:28 +02:00
|
|
|
|
}
|