Merge remote-tracking branch 'origin/v9/dev' into v9/bugfix/Refractor_UmbracoContextAccessor
This commit is contained in:
@@ -1,22 +1,21 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Web.Common.ApplicationBuilder
|
||||
{
|
||||
public interface IUmbracoApplicationBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Called to include umbraco middleware
|
||||
/// EXPERT call to replace the middlewares that Umbraco installs by default with a completely custom pipeline.
|
||||
/// </summary>
|
||||
/// <param name="configureUmbraco"></param>
|
||||
/// <param name="configureUmbracoMiddleware"></param>
|
||||
/// <returns></returns>
|
||||
IUmbracoApplicationBuilder WithMiddleware(Action<IUmbracoMiddlewareBuilder> configureUmbraco);
|
||||
IUmbracoEndpointBuilder WithCustomMiddleware(Action<IUmbracoApplicationBuilderContext> configureUmbracoMiddleware);
|
||||
|
||||
/// <summary>
|
||||
/// Final call during app building to configure endpoints
|
||||
/// Called to include default middleware to run umbraco.
|
||||
/// </summary>
|
||||
/// <param name="configureUmbraco"></param>
|
||||
void WithEndpoints(Action<IUmbracoEndpointBuilder> configureUmbraco);
|
||||
/// <param name="configureUmbracoMiddleware"></param>
|
||||
/// <returns></returns>
|
||||
IUmbracoEndpointBuilder WithMiddleware(Action<IUmbracoApplicationBuilderContext> configureUmbracoMiddleware);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Cms.Web.Common.ApplicationBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// The context object used during
|
||||
/// </summary>
|
||||
public interface IUmbracoApplicationBuilderContext : IUmbracoApplicationBuilderServices
|
||||
{
|
||||
/// <summary>
|
||||
/// Called to include the core umbraco middleware.
|
||||
/// </summary>
|
||||
void UseUmbracoCoreMiddleware();
|
||||
|
||||
/// <summary>
|
||||
/// Manually runs the <see cref="IUmbracoPipelineFilter"/> pre pipeline filters
|
||||
/// </summary>
|
||||
void RunPrePipeline();
|
||||
|
||||
/// <summary>
|
||||
/// Manually runs the <see cref="IUmbracoPipelineFilter "/> post pipeline filters
|
||||
/// </summary>
|
||||
void RunPostPipeline();
|
||||
|
||||
/// <summary>
|
||||
/// Called to include all of the default umbraco required middleware.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If using this method, there is no need to use <see cref="UseUmbracoCoreMiddleware"/>
|
||||
/// </remarks>
|
||||
void RegisterDefaultRequiredMiddleware();
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,16 @@
|
||||
using System;
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Web.Common.ApplicationBuilder
|
||||
{
|
||||
public interface IUmbracoMiddlewareBuilder
|
||||
/// <summary>
|
||||
/// Services used during the Umbraco building phase.
|
||||
/// </summary>
|
||||
public interface IUmbracoApplicationBuilderServices
|
||||
{
|
||||
IRuntimeState RuntimeState { get; }
|
||||
IServiceProvider ApplicationServices { get; }
|
||||
IApplicationBuilder AppBuilder { get; }
|
||||
IServiceProvider ApplicationServices { get; }
|
||||
IRuntimeState RuntimeState { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Cms.Web.Common.ApplicationBuilder
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// A builder to allow encapsulating the enabled routing features in Umbraco
|
||||
/// </summary>
|
||||
public interface IUmbracoEndpointBuilder : IUmbracoMiddlewareBuilder
|
||||
{
|
||||
IEndpointRouteBuilder EndpointRouteBuilder { get; }
|
||||
public interface IUmbracoEndpointBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Final call during app building to configure endpoints
|
||||
/// </summary>
|
||||
/// <param name="configureUmbraco"></param>
|
||||
void WithEndpoints(Action<IUmbracoEndpointBuilderContext> configureUmbraco);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
|
||||
namespace Umbraco.Cms.Web.Common.ApplicationBuilder
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// A builder to allow encapsulating the enabled routing features in Umbraco
|
||||
/// </summary>
|
||||
public interface IUmbracoEndpointBuilderContext : IUmbracoApplicationBuilderServices
|
||||
{
|
||||
IEndpointRouteBuilder EndpointRouteBuilder { get; }
|
||||
}
|
||||
}
|
||||
@@ -2,61 +2,144 @@ using System;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using SixLabors.ImageSharp.Web.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Web.Common.ApplicationBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// A builder to allow encapsulating the enabled endpoints in Umbraco
|
||||
/// A builder used to enable middleware and endpoints required for Umbraco to operate.
|
||||
/// </summary>
|
||||
internal class UmbracoApplicationBuilder : IUmbracoApplicationBuilder, IUmbracoMiddlewareBuilder
|
||||
/// <remarks>
|
||||
/// This helps to ensure that everything is registered in the correct order.
|
||||
/// </remarks>
|
||||
public class UmbracoApplicationBuilder : IUmbracoApplicationBuilder, IUmbracoEndpointBuilder, IUmbracoApplicationBuilderContext
|
||||
{
|
||||
public UmbracoApplicationBuilder(IServiceProvider services, IRuntimeState runtimeState, IApplicationBuilder appBuilder)
|
||||
private readonly IOptions<UmbracoPipelineOptions> _umbracoPipelineStartupOptions;
|
||||
|
||||
public UmbracoApplicationBuilder(IApplicationBuilder appBuilder)
|
||||
{
|
||||
ApplicationServices = services;
|
||||
RuntimeState = runtimeState;
|
||||
AppBuilder = appBuilder;
|
||||
AppBuilder = appBuilder ?? throw new ArgumentNullException(nameof(appBuilder));
|
||||
ApplicationServices = appBuilder.ApplicationServices;
|
||||
RuntimeState = appBuilder.ApplicationServices.GetRequiredService<IRuntimeState>();
|
||||
_umbracoPipelineStartupOptions = ApplicationServices.GetRequiredService<IOptions<UmbracoPipelineOptions>>();
|
||||
}
|
||||
|
||||
public IServiceProvider ApplicationServices { get; }
|
||||
public IRuntimeState RuntimeState { get; }
|
||||
public IApplicationBuilder AppBuilder { get; }
|
||||
|
||||
public IUmbracoApplicationBuilder WithMiddleware(Action<IUmbracoMiddlewareBuilder> configureUmbraco)
|
||||
/// <inheritdoc />
|
||||
public IUmbracoEndpointBuilder WithCustomMiddleware(Action<IUmbracoApplicationBuilderContext> configureUmbracoMiddleware)
|
||||
{
|
||||
IOptions<UmbracoPipelineOptions> startupOptions = ApplicationServices.GetRequiredService<IOptions<UmbracoPipelineOptions>>();
|
||||
RunPostPipeline(startupOptions.Value);
|
||||
if (configureUmbracoMiddleware is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(configureUmbracoMiddleware));
|
||||
}
|
||||
|
||||
configureUmbraco(this);
|
||||
configureUmbracoMiddleware(this);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void WithEndpoints(Action<IUmbracoEndpointBuilder> configureUmbraco)
|
||||
/// <inheritdoc />
|
||||
public IUmbracoEndpointBuilder WithMiddleware(Action<IUmbracoApplicationBuilderContext> configureUmbracoMiddleware)
|
||||
{
|
||||
if (configureUmbracoMiddleware is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(configureUmbracoMiddleware));
|
||||
}
|
||||
|
||||
RunPrePipeline();
|
||||
|
||||
RegisterDefaultRequiredMiddleware();
|
||||
|
||||
RunPostPipeline();
|
||||
|
||||
configureUmbracoMiddleware(this);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void WithEndpoints(Action<IUmbracoEndpointBuilderContext> configureUmbraco)
|
||||
{
|
||||
IOptions<UmbracoPipelineOptions> startupOptions = ApplicationServices.GetRequiredService<IOptions<UmbracoPipelineOptions>>();
|
||||
RunPreEndpointsPipeline(startupOptions.Value);
|
||||
RunPreEndpointsPipeline();
|
||||
|
||||
AppBuilder.UseEndpoints(endpoints =>
|
||||
{
|
||||
var umbAppBuilder = (IUmbracoEndpointBuilder)ActivatorUtilities.CreateInstance<UmbracoEndpointBuilder>(
|
||||
var umbAppBuilder = (IUmbracoEndpointBuilderContext)ActivatorUtilities.CreateInstance<UmbracoEndpointBuilder>(
|
||||
ApplicationServices,
|
||||
new object[] { AppBuilder, endpoints });
|
||||
configureUmbraco(umbAppBuilder);
|
||||
});
|
||||
}
|
||||
|
||||
private void RunPostPipeline(UmbracoPipelineOptions startupOptions)
|
||||
/// <summary>
|
||||
/// Registers the default required middleware to run Umbraco
|
||||
/// </summary>
|
||||
/// <param name="umbracoApplicationBuilderContext"></param>
|
||||
public void RegisterDefaultRequiredMiddleware()
|
||||
{
|
||||
foreach (IUmbracoPipelineFilter filter in startupOptions.PipelineFilters)
|
||||
UseUmbracoCoreMiddleware();
|
||||
|
||||
AppBuilder.UseStatusCodePages();
|
||||
|
||||
// Important we handle image manipulations before the static files, otherwise the querystring is just ignored.
|
||||
AppBuilder.UseImageSharp();
|
||||
AppBuilder.UseStaticFiles();
|
||||
AppBuilder.UseUmbracoPluginsStaticFiles();
|
||||
|
||||
// UseRouting adds endpoint routing middleware, this means that middlewares registered after this one
|
||||
// will execute after endpoint routing. The ordering of everything is quite important here, see
|
||||
// https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-5.0
|
||||
// where we need to have UseAuthentication and UseAuthorization proceeding this call but before
|
||||
// endpoints are defined.
|
||||
AppBuilder.UseRouting();
|
||||
AppBuilder.UseAuthentication();
|
||||
AppBuilder.UseAuthorization();
|
||||
|
||||
// This must come after auth because the culture is based on the auth'd user
|
||||
AppBuilder.UseRequestLocalization();
|
||||
|
||||
// Must be called after UseRouting and before UseEndpoints
|
||||
AppBuilder.UseSession();
|
||||
|
||||
// DO NOT PUT ANY UseEndpoints declarations here!! Those must all come very last in the pipeline,
|
||||
// endpoints are terminating middleware. All of our endpoints are declared in ext of IUmbracoApplicationBuilder
|
||||
}
|
||||
|
||||
public void UseUmbracoCoreMiddleware()
|
||||
{
|
||||
AppBuilder.UseUmbracoCore();
|
||||
AppBuilder.UseUmbracoRequestLogging();
|
||||
|
||||
// We need to add this before UseRouting so that the UmbracoContext and other middlewares are executed
|
||||
// before endpoint routing middleware.
|
||||
AppBuilder.UseUmbracoRouting();
|
||||
}
|
||||
|
||||
public void RunPrePipeline()
|
||||
{
|
||||
foreach (IUmbracoPipelineFilter filter in _umbracoPipelineStartupOptions.Value.PipelineFilters)
|
||||
{
|
||||
filter.OnPrePipeline(AppBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
public void RunPostPipeline()
|
||||
{
|
||||
foreach (IUmbracoPipelineFilter filter in _umbracoPipelineStartupOptions.Value.PipelineFilters)
|
||||
{
|
||||
filter.OnPostPipeline(AppBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
private void RunPreEndpointsPipeline(UmbracoPipelineOptions startupOptions)
|
||||
private void RunPreEndpointsPipeline()
|
||||
{
|
||||
foreach (IUmbracoPipelineFilter filter in startupOptions.PipelineFilters)
|
||||
foreach (IUmbracoPipelineFilter filter in _umbracoPipelineStartupOptions.Value.PipelineFilters)
|
||||
{
|
||||
filter.OnEndpoints(AppBuilder);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Umbraco.Cms.Web.Common.ApplicationBuilder
|
||||
/// <summary>
|
||||
/// A builder to allow encapsulating the enabled endpoints in Umbraco
|
||||
/// </summary>
|
||||
internal class UmbracoEndpointBuilder : IUmbracoEndpointBuilder
|
||||
internal class UmbracoEndpointBuilder : IUmbracoEndpointBuilderContext
|
||||
{
|
||||
public UmbracoEndpointBuilder(IServiceProvider services, IRuntimeState runtimeState, IApplicationBuilder appBuilder, IEndpointRouteBuilder endpointRouteBuilder)
|
||||
{
|
||||
|
||||
@@ -4,7 +4,6 @@ using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Serilog.Context;
|
||||
using SixLabors.ImageSharp.Web.DependencyInjection;
|
||||
using StackExchange.Profiling;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
@@ -26,63 +25,7 @@ namespace Umbraco.Extensions
|
||||
/// Configures and use services required for using Umbraco
|
||||
/// </summary>
|
||||
public static IUmbracoApplicationBuilder UseUmbraco(this IApplicationBuilder app)
|
||||
{
|
||||
// TODO: Should we do some checks like this to verify that the corresponding "Add" methods have been called for the
|
||||
// corresponding "Use" methods?
|
||||
// https://github.com/dotnet/aspnetcore/blob/b795ac3546eb3e2f47a01a64feb3020794ca33bb/src/Mvc/Mvc.Core/src/Builder/MvcApplicationBuilderExtensions.cs#L132
|
||||
if (app == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(app));
|
||||
}
|
||||
|
||||
IOptions<UmbracoPipelineOptions> startupOptions = app.ApplicationServices.GetRequiredService<IOptions<UmbracoPipelineOptions>>();
|
||||
app.RunPrePipeline(startupOptions.Value);
|
||||
|
||||
app.UseUmbracoCore();
|
||||
app.UseUmbracoRequestLogging();
|
||||
|
||||
// We need to add this before UseRouting so that the UmbracoContext and other middlewares are executed
|
||||
// before endpoint routing middleware.
|
||||
app.UseUmbracoRouting();
|
||||
|
||||
app.UseStatusCodePages();
|
||||
|
||||
// Important we handle image manipulations before the static files, otherwise the querystring is just ignored.
|
||||
// TODO: Since we are dependent on these we need to register them but what happens when we call this multiple times since we are dependent on this for UseUmbracoBackOffice too?
|
||||
app.UseImageSharp();
|
||||
app.UseStaticFiles();
|
||||
app.UseUmbracoPlugins();
|
||||
|
||||
// UseRouting adds endpoint routing middleware, this means that middlewares registered after this one
|
||||
// will execute after endpoint routing. The ordering of everything is quite important here, see
|
||||
// https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-5.0
|
||||
// where we need to have UseAuthentication and UseAuthorization proceeding this call but before
|
||||
// endpoints are defined.
|
||||
app.UseRouting();
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
// This must come after auth because the culture is based on the auth'd user
|
||||
app.UseRequestLocalization();
|
||||
|
||||
// Must be called after UseRouting and before UseEndpoints
|
||||
app.UseSession();
|
||||
|
||||
// DO NOT PUT ANY UseEndpoints declarations here!! Those must all come very last in the pipeline,
|
||||
// endpoints are terminating middleware. All of our endpoints are declared in ext of IUmbracoApplicationBuilder
|
||||
|
||||
return ActivatorUtilities.CreateInstance<UmbracoApplicationBuilder>(
|
||||
app.ApplicationServices,
|
||||
new object[] { app });
|
||||
}
|
||||
|
||||
private static void RunPrePipeline(this IApplicationBuilder app, UmbracoPipelineOptions startupOptions)
|
||||
{
|
||||
foreach (IUmbracoPipelineFilter filter in startupOptions.PipelineFilters)
|
||||
{
|
||||
filter.OnPrePipeline(app);
|
||||
}
|
||||
}
|
||||
=> new UmbracoApplicationBuilder(app);
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if Umbraco <see cref="IRuntimeState"/> is greater than <see cref="RuntimeLevel.BootFailed"/>
|
||||
@@ -158,7 +101,12 @@ namespace Umbraco.Extensions
|
||||
return app;
|
||||
}
|
||||
|
||||
public static IApplicationBuilder UseUmbracoPlugins(this IApplicationBuilder app)
|
||||
/// <summary>
|
||||
/// Allow static file access for App_Plugins folders
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseUmbracoPluginsStaticFiles(this IApplicationBuilder app)
|
||||
{
|
||||
var hostingEnvironment = app.ApplicationServices.GetRequiredService<IHostingEnvironment>();
|
||||
var umbracoPluginSettings = app.ApplicationServices.GetRequiredService<IOptions<UmbracoPluginSettings>>();
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Umbraco.Cms.Web.Common.Extensions
|
||||
/// <summary>
|
||||
/// Enables runtime minification for Umbraco
|
||||
/// </summary>
|
||||
public static IUmbracoEndpointBuilder UseUmbracoRuntimeMinificationEndpoints(this IUmbracoEndpointBuilder app)
|
||||
public static IUmbracoEndpointBuilderContext UseUmbracoRuntimeMinificationEndpoints(this IUmbracoEndpointBuilderContext app)
|
||||
{
|
||||
if (app == null)
|
||||
{
|
||||
|
||||
@@ -198,6 +198,9 @@ namespace Umbraco.Cms.Web.Common.Security
|
||||
// code taken from aspnetcore: https://github.com/dotnet/aspnetcore/blob/master/src/Identity/Core/src/SignInManager.cs
|
||||
// we also override to set the current HttpContext principal since this isn't done by default
|
||||
|
||||
// we also need to call our handle login to ensure all date/events are set
|
||||
await HandleSignIn(user, user.UserName, SignInResult.Success);
|
||||
|
||||
var userPrincipal = await CreateUserPrincipalAsync(user);
|
||||
foreach (var claim in additionalClaims)
|
||||
{
|
||||
@@ -363,7 +366,7 @@ namespace Umbraco.Cms.Web.Common.Security
|
||||
await Context.SignOutAsync(ExternalAuthenticationType);
|
||||
}
|
||||
if (loginProvider == null)
|
||||
{
|
||||
{
|
||||
await SignInWithClaimsAsync(user, isPersistent, new Claim[] { new Claim("amr", "pwd") });
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user