2020-03-24 18:18:25 +01:00
using System ;
2020-12-16 16:31:23 +11:00
using System.IO ;
2020-03-24 18:18:25 +01:00
using Microsoft.AspNetCore.Builder ;
2020-05-08 17:30:30 +10:00
using Microsoft.Extensions.DependencyInjection ;
2020-12-16 16:31:23 +11:00
using Microsoft.Extensions.Options ;
2020-05-12 15:18:55 +10:00
using Serilog.Context ;
2020-12-08 16:33:50 +11:00
using SixLabors.ImageSharp.Web.DependencyInjection ;
2020-03-29 22:35:52 +02:00
using StackExchange.Profiling ;
2021-02-09 10:22:42 +01:00
using Umbraco.Cms.Core ;
using Umbraco.Cms.Core.Configuration.Models ;
using Umbraco.Cms.Core.Hosting ;
2021-02-12 11:38:50 +01:00
using Umbraco.Cms.Core.Logging.Serilog.Enrichers ;
2021-02-09 10:22:42 +01:00
using Umbraco.Cms.Core.Services ;
Implements Public Access in netcore (#10137)
* Getting new netcore PublicAccessChecker in place
* Adds full test coverage for PublicAccessChecker
* remove PublicAccessComposer
* adjust namespaces, ensure RoleManager works, separate public access controller, reduce content controller
* Implements the required methods on IMemberManager, removes old migrated code
* Updates routing to be able to re-route, Fixes middleware ordering ensuring endpoints are last, refactors pipeline options, adds public access middleware, ensures public access follows all hops
* adds note
* adds note
* Cleans up ext methods, ensures that members identity is added on both front-end and back ends. updates how UmbracoApplicationBuilder works in that it explicitly starts endpoints at the time of calling.
* Changes name to IUmbracoEndpointBuilder
* adds note
* Fixing tests, fixing error describers so there's 2x one for back office, one for members, fixes TryConvertTo, fixes login redirect
* fixing build
* Fixes keepalive, fixes PublicAccessMiddleware to not throw, updates startup code to be more clear and removes magic that registers middleware.
* adds note
* removes unused filter, fixes build
* fixes WebPath and tests
* Looks up entities in one query
* remove usings
* Fix test, remove stylesheet
* Set status code before we write to response to avoid error
* Ensures that users and members are validated when logging in. Shares more code between users and members.
* Fixes RepositoryCacheKeys to ensure the keys are normalized
* oops didn't mean to commit this
* Fix casing issues with caching, stop boxing value types for all cache operations, stop re-creating string keys in DefaultRepositoryCachePolicy
* bah, far out this keeps getting recommitted. sorry
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2021-04-20 15:11:45 +10:00
using Umbraco.Cms.Web.Common.ApplicationBuilder ;
2021-02-10 11:42:04 +01:00
using Umbraco.Cms.Web.Common.Middleware ;
using Umbraco.Cms.Web.Common.Plugins ;
2020-03-24 18:18:25 +01:00
2020-05-07 10:08:23 +02:00
namespace Umbraco.Extensions
2020-03-24 18:18:25 +01:00
{
2020-12-08 16:33:50 +11:00
/// <summary>
/// <see cref="IApplicationBuilder"/> extensions for Umbraco
/// </summary>
2020-05-12 10:21:40 +10:00
public static class ApplicationBuilderExtensions
2020-03-24 18:18:25 +01:00
{
2020-12-08 16:33:50 +11:00
/// <summary>
/// Configures and use services required for using Umbraco
/// </summary>
Implements Public Access in netcore (#10137)
* Getting new netcore PublicAccessChecker in place
* Adds full test coverage for PublicAccessChecker
* remove PublicAccessComposer
* adjust namespaces, ensure RoleManager works, separate public access controller, reduce content controller
* Implements the required methods on IMemberManager, removes old migrated code
* Updates routing to be able to re-route, Fixes middleware ordering ensuring endpoints are last, refactors pipeline options, adds public access middleware, ensures public access follows all hops
* adds note
* adds note
* Cleans up ext methods, ensures that members identity is added on both front-end and back ends. updates how UmbracoApplicationBuilder works in that it explicitly starts endpoints at the time of calling.
* Changes name to IUmbracoEndpointBuilder
* adds note
* Fixing tests, fixing error describers so there's 2x one for back office, one for members, fixes TryConvertTo, fixes login redirect
* fixing build
* Fixes keepalive, fixes PublicAccessMiddleware to not throw, updates startup code to be more clear and removes magic that registers middleware.
* adds note
* removes unused filter, fixes build
* fixes WebPath and tests
* Looks up entities in one query
* remove usings
* Fix test, remove stylesheet
* Set status code before we write to response to avoid error
* Ensures that users and members are validated when logging in. Shares more code between users and members.
* Fixes RepositoryCacheKeys to ensure the keys are normalized
* oops didn't mean to commit this
* Fix casing issues with caching, stop boxing value types for all cache operations, stop re-creating string keys in DefaultRepositoryCachePolicy
* bah, far out this keeps getting recommitted. sorry
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2021-04-20 15:11:45 +10:00
public static IUmbracoApplicationBuilder UseUmbraco ( this IApplicationBuilder app )
2020-12-08 16:33:50 +11:00
{
Implements Public Access in netcore (#10137)
* Getting new netcore PublicAccessChecker in place
* Adds full test coverage for PublicAccessChecker
* remove PublicAccessComposer
* adjust namespaces, ensure RoleManager works, separate public access controller, reduce content controller
* Implements the required methods on IMemberManager, removes old migrated code
* Updates routing to be able to re-route, Fixes middleware ordering ensuring endpoints are last, refactors pipeline options, adds public access middleware, ensures public access follows all hops
* adds note
* adds note
* Cleans up ext methods, ensures that members identity is added on both front-end and back ends. updates how UmbracoApplicationBuilder works in that it explicitly starts endpoints at the time of calling.
* Changes name to IUmbracoEndpointBuilder
* adds note
* Fixing tests, fixing error describers so there's 2x one for back office, one for members, fixes TryConvertTo, fixes login redirect
* fixing build
* Fixes keepalive, fixes PublicAccessMiddleware to not throw, updates startup code to be more clear and removes magic that registers middleware.
* adds note
* removes unused filter, fixes build
* fixes WebPath and tests
* Looks up entities in one query
* remove usings
* Fix test, remove stylesheet
* Set status code before we write to response to avoid error
* Ensures that users and members are validated when logging in. Shares more code between users and members.
* Fixes RepositoryCacheKeys to ensure the keys are normalized
* oops didn't mean to commit this
* Fix casing issues with caching, stop boxing value types for all cache operations, stop re-creating string keys in DefaultRepositoryCachePolicy
* bah, far out this keeps getting recommitted. sorry
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2021-04-20 15:11:45 +10:00
IOptions < UmbracoPipelineOptions > startupOptions = app . ApplicationServices . GetRequiredService < IOptions < UmbracoPipelineOptions > > ( ) ;
app . RunPrePipeline ( startupOptions . Value ) ;
2021-01-04 12:01:52 +11:00
// 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
2020-12-08 16:33:50 +11:00
if ( app = = null )
{
throw new ArgumentNullException ( nameof ( app ) ) ;
}
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 ( ) ;
2020-12-16 16:31:23 +11:00
app . UseUmbracoPlugins ( ) ;
2020-12-08 16:33:50 +11:00
// 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 ( ) ;
2021-01-18 15:40:22 +01:00
2021-01-08 11:29:07 +11:00
// This must come after auth because the culture is based on the auth'd user
app . UseRequestLocalization ( ) ;
2020-12-08 16:33:50 +11:00
// Must be called after UseRouting and before UseEndpoints
app . UseSession ( ) ;
Implements Public Access in netcore (#10137)
* Getting new netcore PublicAccessChecker in place
* Adds full test coverage for PublicAccessChecker
* remove PublicAccessComposer
* adjust namespaces, ensure RoleManager works, separate public access controller, reduce content controller
* Implements the required methods on IMemberManager, removes old migrated code
* Updates routing to be able to re-route, Fixes middleware ordering ensuring endpoints are last, refactors pipeline options, adds public access middleware, ensures public access follows all hops
* adds note
* adds note
* Cleans up ext methods, ensures that members identity is added on both front-end and back ends. updates how UmbracoApplicationBuilder works in that it explicitly starts endpoints at the time of calling.
* Changes name to IUmbracoEndpointBuilder
* adds note
* Fixing tests, fixing error describers so there's 2x one for back office, one for members, fixes TryConvertTo, fixes login redirect
* fixing build
* Fixes keepalive, fixes PublicAccessMiddleware to not throw, updates startup code to be more clear and removes magic that registers middleware.
* adds note
* removes unused filter, fixes build
* fixes WebPath and tests
* Looks up entities in one query
* remove usings
* Fix test, remove stylesheet
* Set status code before we write to response to avoid error
* Ensures that users and members are validated when logging in. Shares more code between users and members.
* Fixes RepositoryCacheKeys to ensure the keys are normalized
* oops didn't mean to commit this
* Fix casing issues with caching, stop boxing value types for all cache operations, stop re-creating string keys in DefaultRepositoryCachePolicy
* bah, far out this keeps getting recommitted. sorry
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2021-04-20 15:11:45 +10:00
// 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
2020-12-08 16:33:50 +11:00
Implements Public Access in netcore (#10137)
* Getting new netcore PublicAccessChecker in place
* Adds full test coverage for PublicAccessChecker
* remove PublicAccessComposer
* adjust namespaces, ensure RoleManager works, separate public access controller, reduce content controller
* Implements the required methods on IMemberManager, removes old migrated code
* Updates routing to be able to re-route, Fixes middleware ordering ensuring endpoints are last, refactors pipeline options, adds public access middleware, ensures public access follows all hops
* adds note
* adds note
* Cleans up ext methods, ensures that members identity is added on both front-end and back ends. updates how UmbracoApplicationBuilder works in that it explicitly starts endpoints at the time of calling.
* Changes name to IUmbracoEndpointBuilder
* adds note
* Fixing tests, fixing error describers so there's 2x one for back office, one for members, fixes TryConvertTo, fixes login redirect
* fixing build
* Fixes keepalive, fixes PublicAccessMiddleware to not throw, updates startup code to be more clear and removes magic that registers middleware.
* adds note
* removes unused filter, fixes build
* fixes WebPath and tests
* Looks up entities in one query
* remove usings
* Fix test, remove stylesheet
* Set status code before we write to response to avoid error
* Ensures that users and members are validated when logging in. Shares more code between users and members.
* Fixes RepositoryCacheKeys to ensure the keys are normalized
* oops didn't mean to commit this
* Fix casing issues with caching, stop boxing value types for all cache operations, stop re-creating string keys in DefaultRepositoryCachePolicy
* bah, far out this keeps getting recommitted. sorry
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2021-04-20 15:11:45 +10:00
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 ) ;
}
}
2020-05-12 10:21:40 +10:00
/// <summary>
/// Returns true if Umbraco <see cref="IRuntimeState"/> is greater than <see cref="RuntimeLevel.BootFailed"/>
/// </summary>
2020-05-08 17:36:59 +10:00
public static bool UmbracoCanBoot ( this IApplicationBuilder app )
Implements Public Access in netcore (#10137)
* Getting new netcore PublicAccessChecker in place
* Adds full test coverage for PublicAccessChecker
* remove PublicAccessComposer
* adjust namespaces, ensure RoleManager works, separate public access controller, reduce content controller
* Implements the required methods on IMemberManager, removes old migrated code
* Updates routing to be able to re-route, Fixes middleware ordering ensuring endpoints are last, refactors pipeline options, adds public access middleware, ensures public access follows all hops
* adds note
* adds note
* Cleans up ext methods, ensures that members identity is added on both front-end and back ends. updates how UmbracoApplicationBuilder works in that it explicitly starts endpoints at the time of calling.
* Changes name to IUmbracoEndpointBuilder
* adds note
* Fixing tests, fixing error describers so there's 2x one for back office, one for members, fixes TryConvertTo, fixes login redirect
* fixing build
* Fixes keepalive, fixes PublicAccessMiddleware to not throw, updates startup code to be more clear and removes magic that registers middleware.
* adds note
* removes unused filter, fixes build
* fixes WebPath and tests
* Looks up entities in one query
* remove usings
* Fix test, remove stylesheet
* Set status code before we write to response to avoid error
* Ensures that users and members are validated when logging in. Shares more code between users and members.
* Fixes RepositoryCacheKeys to ensure the keys are normalized
* oops didn't mean to commit this
* Fix casing issues with caching, stop boxing value types for all cache operations, stop re-creating string keys in DefaultRepositoryCachePolicy
* bah, far out this keeps getting recommitted. sorry
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2021-04-20 15:11:45 +10:00
= > app . ApplicationServices . GetRequiredService < IRuntimeState > ( ) . UmbracoCanBoot ( ) ;
2020-05-08 17:36:59 +10:00
2020-05-12 15:18:55 +10:00
/// <summary>
2020-12-21 16:44:50 +11:00
/// Enables core Umbraco functionality
2020-05-12 15:18:55 +10:00
/// </summary>
public static IApplicationBuilder UseUmbracoCore ( this IApplicationBuilder app )
{
2020-12-08 16:33:50 +11:00
if ( app = = null )
{
throw new ArgumentNullException ( nameof ( app ) ) ;
}
2020-05-12 15:18:55 +10:00
2020-12-08 16:33:50 +11:00
if ( ! app . UmbracoCanBoot ( ) )
{
return app ;
}
2020-05-12 15:18:55 +10:00
2020-05-14 22:50:27 +10:00
// Register our global threadabort enricher for logging
2020-12-08 16:33:50 +11:00
ThreadAbortExceptionEnricher threadAbortEnricher = app . ApplicationServices . GetRequiredService < ThreadAbortExceptionEnricher > ( ) ;
2020-05-14 22:50:27 +10:00
LogContext . Push ( threadAbortEnricher ) ; // NOTE: We are not in a using clause because we are not removing it, it is on the global context
2020-11-10 08:50:47 +00:00
2020-05-12 15:18:55 +10:00
return app ;
}
2020-05-12 10:21:40 +10:00
/// <summary>
/// Enables middlewares required to run Umbraco
/// </summary>
2020-12-08 16:33:50 +11:00
/// <remarks>
/// Must occur before UseRouting
/// </remarks>
2020-05-12 10:21:40 +10:00
public static IApplicationBuilder UseUmbracoRouting ( this IApplicationBuilder app )
2020-03-24 18:18:25 +01:00
{
2020-12-08 16:33:50 +11:00
// TODO: This method could be internal or part of another call - this is a required system so should't be 'opt-in'
if ( app = = null )
{
throw new ArgumentNullException ( nameof ( app ) ) ;
}
2020-03-24 18:18:25 +01:00
2020-05-14 22:50:27 +10:00
if ( ! app . UmbracoCanBoot ( ) )
{
2021-03-08 10:03:36 +01:00
app . UseStaticFiles ( ) ; // We need static files to show the nice error page.
2020-05-19 14:51:05 +10:00
app . UseMiddleware < BootFailedMiddleware > ( ) ;
2020-05-14 22:50:27 +10:00
}
else
{
2021-02-19 11:45:58 +01:00
app . UseMiddleware < PreviewAuthenticationMiddleware > ( ) ;
2020-05-14 22:50:27 +10:00
app . UseMiddleware < UmbracoRequestMiddleware > ( ) ;
app . UseMiddleware < MiniProfilerMiddleware > ( ) ;
}
2020-05-19 14:51:05 +10:00
2020-03-24 18:18:25 +01:00
return app ;
}
2020-05-12 15:18:55 +10:00
2020-05-14 22:50:27 +10:00
/// <summary>
/// Adds request based serilog enrichers to the LogContext for each request
/// </summary>
2020-05-12 15:18:55 +10:00
public static IApplicationBuilder UseUmbracoRequestLogging ( this IApplicationBuilder app )
{
2020-12-08 16:33:50 +11:00
if ( app = = null )
{
throw new ArgumentNullException ( nameof ( app ) ) ;
}
2020-05-12 15:18:55 +10:00
if ( ! app . UmbracoCanBoot ( ) ) return app ;
app . UseMiddleware < UmbracoRequestLoggingMiddleware > ( ) ;
return app ;
}
2020-12-16 16:31:23 +11:00
public static IApplicationBuilder UseUmbracoPlugins ( this IApplicationBuilder app )
{
var hostingEnvironment = app . ApplicationServices . GetRequiredService < IHostingEnvironment > ( ) ;
var umbracoPluginSettings = app . ApplicationServices . GetRequiredService < IOptions < UmbracoPluginSettings > > ( ) ;
var pluginFolder = hostingEnvironment . MapPathContentRoot ( Constants . SystemDirectories . AppPlugins ) ;
// Ensure the plugin folder exists
Directory . CreateDirectory ( pluginFolder ) ;
var fileProvider = new UmbracoPluginPhysicalFileProvider (
pluginFolder ,
umbracoPluginSettings ) ;
app . UseStaticFiles ( new StaticFileOptions
{
FileProvider = fileProvider ,
RequestPath = Constants . SystemDirectories . AppPlugins
} ) ;
return app ;
}
2020-03-24 18:18:25 +01:00
}
2020-03-29 22:35:52 +02:00
2020-03-24 18:18:25 +01:00
}