Skip to content

Commit

Permalink
Add PreRouting and PostRouting pipeline filters (#14503)
Browse files Browse the repository at this point in the history
  • Loading branch information
ronaldbarendse authored Jul 20, 2023
1 parent a49a985 commit 57852f5
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -1,30 +1,47 @@
namespace Umbraco.Cms.Web.Common.ApplicationBuilder;

/// <summary>
/// The context object used during
/// The context object used when building the Umbraco application.
/// </summary>
/// <seealso cref="Umbraco.Cms.Web.Common.ApplicationBuilder.IUmbracoApplicationBuilderServices" />
public interface IUmbracoApplicationBuilderContext : IUmbracoApplicationBuilderServices
{
/// <summary>
/// Called to include the core umbraco middleware.
/// Called to include the core Umbraco middlewares.
/// </summary>
void UseUmbracoCoreMiddleware();

/// <summary>
/// Manually runs the <see cref="IUmbracoPipelineFilter" /> pre pipeline filters
/// Manually runs the <see cref="IUmbracoPipelineFilter" /> pre pipeline filters.
/// </summary>
void RunPrePipeline();

/// <summary>
/// Manually runs the <see cref="IUmbracoPipelineFilter " /> post pipeline filters
/// Manually runs the <see cref="IUmbracoPipelineFilter" /> pre routing filters.
/// </summary>
void RunPreRouting()
{
// TODO: Remove default implementation in Umbraco 13
}

/// <summary>
/// Manually runs the <see cref="IUmbracoPipelineFilter" /> post routing filters.
/// </summary>
void RunPostRouting()
{
// TODO: Remove default implementation in Umbraco 13
}

/// <summary>
/// Manually runs the <see cref="IUmbracoPipelineFilter" /> post pipeline filters.
/// </summary>
void RunPostPipeline();

/// <summary>
/// Called to include all of the default umbraco required middleware.
/// 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" />
/// If using this method, there is no need to use <see cref="UseUmbracoCoreMiddleware" />.
/// </remarks>
void RegisterDefaultRequiredMiddleware();
}
42 changes: 31 additions & 11 deletions src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoPipelineFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,57 @@
namespace Umbraco.Cms.Web.Common.ApplicationBuilder;

/// <summary>
/// Used to modify the <see cref="IApplicationBuilder" /> pipeline before and after Umbraco registers it's core
/// middlewares.
/// Used to modify the <see cref="IApplicationBuilder" /> pipeline before and after Umbraco registers its middlewares.
/// </summary>
/// <remarks>
/// Mainly used for package developers.
/// Mainly used for package developers.
/// </remarks>
public interface IUmbracoPipelineFilter
{
/// <summary>
/// The name of the filter
/// The name of the filter.
/// </summary>
/// <value>
/// The name.
/// </value>
/// <remarks>
/// This can be used by developers to see what is registered and if anything should be re-ordered, removed, etc...
/// This can be used by developers to see what is registered and if anything should be re-ordered, removed, etc...
/// </remarks>
string Name { get; }

/// <summary>
/// Executes before Umbraco middlewares are registered
/// Executes before any default Umbraco middlewares are registered.
/// </summary>
/// <param name="app"></param>
/// <param name="app">The application.</param>
void OnPrePipeline(IApplicationBuilder app);

/// <summary>
/// Executes after core Umbraco middlewares are registered and before any Endpoints are declared
/// Executes after static files middlewares are registered and just before the routing middleware is registered.
/// </summary>
/// <param name="app"></param>
/// <param name="app">The application.</param>
void OnPreRouting(IApplicationBuilder app)
{
// TODO: Remove default implementation in Umbraco 13
}

/// <summary>
/// Executes after the routing middleware is registered and just before the authentication and authorization middlewares are registered. This can be used to add CORS policies.
/// </summary>
/// <param name="app">The application.</param>
void OnPostRouting(IApplicationBuilder app)
{
// TODO: Remove default implementation in Umbraco 13
}

/// <summary>
/// Executes after core Umbraco middlewares are registered and before any endpoints are declared.
/// </summary>
/// <param name="app">The application.</param>
void OnPostPipeline(IApplicationBuilder app);

/// <summary>
/// Executes after <see cref="OnPostPipeline(IApplicationBuilder)" /> just before any Umbraco endpoints are declared.
/// Executes after the middlewares are registered and just before any Umbraco endpoints are declared.
/// </summary>
/// <param name="app"></param>
/// <param name="app">The application.</param>
void OnEndpoints(IApplicationBuilder app);
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ public void RegisterDefaultRequiredMiddleware()
// 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.
RunPreRouting();
AppBuilder.UseRouting();
RunPostRouting();

AppBuilder.UseAuthentication();
AppBuilder.UseAuthorization();

Expand Down Expand Up @@ -114,6 +117,22 @@ public void RunPrePipeline()
}
}

public void RunPreRouting()
{
foreach (IUmbracoPipelineFilter filter in _umbracoPipelineStartupOptions.Value.PipelineFilters)
{
filter.OnPreRouting(AppBuilder);
}
}

public void RunPostRouting()
{
foreach (IUmbracoPipelineFilter filter in _umbracoPipelineStartupOptions.Value.PipelineFilters)
{
filter.OnPostRouting(AppBuilder);
}
}

public void RunPostPipeline()
{
foreach (IUmbracoPipelineFilter filter in _umbracoPipelineStartupOptions.Value.PipelineFilters)
Expand Down
92 changes: 81 additions & 11 deletions src/Umbraco.Web.Common/ApplicationBuilder/UmbracoPipelineFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,113 @@

namespace Umbraco.Cms.Web.Common.ApplicationBuilder;

/// <summary>
/// Used to modify the <see cref="IApplicationBuilder" /> pipeline before and after Umbraco registers it's core
/// middlewares.
/// </summary>
/// <remarks>
/// Mainly used for package developers.
/// </remarks>
/// <inheritdoc />
public class UmbracoPipelineFilter : IUmbracoPipelineFilter
{
/// <summary>
/// Initializes a new instance of the <see cref="UmbracoPipelineFilter" /> class.
/// </summary>
/// <param name="name">The name.</param>
public UmbracoPipelineFilter(string name)
: this(name, null, null, null)
{
}
: this(name, null, null, null, null, null)
{ }

/// <summary>
/// Initializes a new instance of the <see cref="UmbracoPipelineFilter" /> class.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="prePipeline">The pre pipeline callback.</param>
/// <param name="postPipeline">The post pipeline callback.</param>
/// <param name="endpointCallback">The endpoint callback.</param>
[Obsolete("Use the constructor with named parameters or set the callback properties instead. This constructor will be removed in Umbraco 13.")]
public UmbracoPipelineFilter(
string name,
Action<IApplicationBuilder>? prePipeline,
Action<IApplicationBuilder>? postPipeline,
Action<IApplicationBuilder>? endpointCallback)
: this(name, prePipeline, null, null, postPipeline, endpointCallback)
{ }

/// <summary>
/// Initializes a new instance of the <see cref="UmbracoPipelineFilter" /> class.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="prePipeline">The pre pipeline callback.</param>
/// <param name="preRouting">The pre routing callback.</param>
/// <param name="postRouting">The post routing callback.</param>
/// <param name="postPipeline">The post pipeline callback.</param>
/// <param name="endpoints">The endpoints callback.</param>
public UmbracoPipelineFilter(
string name,
Action<IApplicationBuilder>? prePipeline = null,
Action<IApplicationBuilder>? preRouting = null,
Action<IApplicationBuilder>? postRouting = null,
Action<IApplicationBuilder>? postPipeline = null,
Action<IApplicationBuilder>? endpoints = null)
{
Name = name ?? throw new ArgumentNullException(nameof(name));
PrePipeline = prePipeline;
PreRouting = preRouting;
PostRouting = postRouting;
PostPipeline = postPipeline;
Endpoints = endpointCallback;
Endpoints = endpoints;
}

/// <summary>
/// Gets or sets the pre pipeline callback.
/// </summary>
/// <value>
/// The pre pipeline callback.
/// </value>
public Action<IApplicationBuilder>? PrePipeline { get; set; }

/// <summary>
/// Gets or sets the pre routing.
/// </summary>
/// <value>
/// The pre routing.
/// </value>
public Action<IApplicationBuilder>? PreRouting { get; set; }

/// <summary>
/// Gets or sets the post routing callback.
/// </summary>
/// <value>
/// The post routing callback.
/// </value>
public Action<IApplicationBuilder>? PostRouting { get; set; }

/// <summary>
/// Gets or sets the post pipeline callback.
/// </summary>
/// <value>
/// The post pipeline callback.
/// </value>
public Action<IApplicationBuilder>? PostPipeline { get; set; }

/// <summary>
/// Gets or sets the endpoints callback.
/// </summary>
/// <value>
/// The endpoints callback.
/// </value>
public Action<IApplicationBuilder>? Endpoints { get; set; }

/// <inheritdoc />
public string Name { get; }

/// <inheritdoc />
public void OnPrePipeline(IApplicationBuilder app) => PrePipeline?.Invoke(app);

/// <inheritdoc />
public void OnPreRouting(IApplicationBuilder app) => PreRouting?.Invoke(app);

/// <inheritdoc />
public void OnPostRouting(IApplicationBuilder app) => PostRouting?.Invoke(app);

/// <inheritdoc />
public void OnPostPipeline(IApplicationBuilder app) => PostPipeline?.Invoke(app);

/// <inheritdoc />
public void OnEndpoints(IApplicationBuilder app) => Endpoints?.Invoke(app);
}

0 comments on commit 57852f5

Please sign in to comment.