2019-04-30 20:13:59 +01:00
using System ;
2016-10-11 18:52:01 +02:00
using System.Globalization ;
using System.IO ;
2021-01-06 17:04:35 +11:00
using System.Linq ;
2021-01-08 00:25:09 +11:00
using System.Threading.Tasks ;
2020-09-21 09:27:54 +02:00
using Microsoft.Extensions.Logging ;
2021-01-06 17:04:35 +11:00
using Microsoft.Extensions.Options ;
2021-02-18 11:06:02 +01:00
using Umbraco.Cms.Core.Configuration.Models ;
using Umbraco.Cms.Core.Events ;
using Umbraco.Cms.Core.Logging ;
using Umbraco.Cms.Core.Models ;
using Umbraco.Cms.Core.Models.PublishedContent ;
2021-05-11 14:33:49 +02:00
using Umbraco.Cms.Core.Notifications ;
2021-02-18 11:06:02 +01:00
using Umbraco.Cms.Core.PublishedCache ;
using Umbraco.Cms.Core.Services ;
using Umbraco.Cms.Core.Web ;
using Umbraco.Extensions ;
2016-10-11 18:52:01 +02:00
2021-02-18 11:06:02 +01:00
namespace Umbraco.Cms.Core.Routing
2016-10-11 18:52:01 +02:00
{
2021-01-08 00:25:09 +11:00
2019-01-31 09:08:51 +01:00
/// <summary>
/// Provides the default <see cref="IPublishedRouter"/> implementation.
/// </summary>
public class PublishedRouter : IPublishedRouter
2017-07-20 11:21:28 +02:00
{
2020-08-21 14:52:47 +01:00
private readonly WebRoutingSettings _webRoutingSettings ;
2016-10-13 21:08:07 +02:00
private readonly ContentFinderCollection _contentFinders ;
2017-07-20 11:21:28 +02:00
private readonly IContentLastChanceFinder _contentLastChanceFinder ;
2018-11-27 13:46:43 +01:00
private readonly IProfilingLogger _profilingLogger ;
2018-06-03 17:21:15 +02:00
private readonly IVariationContextAccessor _variationContextAccessor ;
2020-09-28 08:26:21 +02:00
private readonly ILogger < PublishedRouter > _logger ;
2020-02-14 13:04:49 +01:00
private readonly IPublishedUrlProvider _publishedUrlProvider ;
2020-02-28 11:15:25 +01:00
private readonly IRequestAccessor _requestAccessor ;
private readonly IPublishedValueFallback _publishedValueFallback ;
private readonly IFileService _fileService ;
private readonly IContentTypeService _contentTypeService ;
2021-01-06 17:04:35 +11:00
private readonly IUmbracoContextAccessor _umbracoContextAccessor ;
2021-01-08 00:25:09 +11:00
private readonly IEventAggregator _eventAggregator ;
2016-10-11 18:52:01 +02:00
/// <summary>
2017-10-31 12:48:24 +01:00
/// Initializes a new instance of the <see cref="PublishedRouter"/> class.
2016-10-11 18:52:01 +02:00
/// </summary>
2017-10-31 12:48:24 +01:00
public PublishedRouter (
2020-08-23 23:36:48 +02:00
IOptions < WebRoutingSettings > webRoutingSettings ,
2016-10-13 21:08:07 +02:00
ContentFinderCollection contentFinders ,
2016-10-11 18:52:01 +02:00
IContentLastChanceFinder contentLastChanceFinder ,
2018-06-03 17:21:15 +02:00
IVariationContextAccessor variationContextAccessor ,
2020-01-21 17:03:46 -08:00
IProfilingLogger proflog ,
2020-09-28 08:26:21 +02:00
ILogger < PublishedRouter > logger ,
2020-02-28 11:15:25 +01:00
IPublishedUrlProvider publishedUrlProvider ,
IRequestAccessor requestAccessor ,
IPublishedValueFallback publishedValueFallback ,
IFileService fileService ,
IContentTypeService contentTypeService ,
2021-01-08 00:25:09 +11:00
IUmbracoContextAccessor umbracoContextAccessor ,
IEventAggregator eventAggregator )
2017-07-20 11:21:28 +02:00
{
2020-08-21 14:52:47 +01:00
_webRoutingSettings = webRoutingSettings . Value ? ? throw new ArgumentNullException ( nameof ( webRoutingSettings ) ) ;
2017-05-12 14:49:44 +02:00
_contentFinders = contentFinders ? ? throw new ArgumentNullException ( nameof ( contentFinders ) ) ;
_contentLastChanceFinder = contentLastChanceFinder ? ? throw new ArgumentNullException ( nameof ( contentLastChanceFinder ) ) ;
_profilingLogger = proflog ? ? throw new ArgumentNullException ( nameof ( proflog ) ) ;
2018-06-03 17:21:15 +02:00
_variationContextAccessor = variationContextAccessor ? ? throw new ArgumentNullException ( nameof ( variationContextAccessor ) ) ;
2020-09-15 09:00:14 +02:00
_logger = logger ;
2020-02-14 13:04:49 +01:00
_publishedUrlProvider = publishedUrlProvider ;
2020-02-28 11:15:25 +01:00
_requestAccessor = requestAccessor ;
_publishedValueFallback = publishedValueFallback ;
_fileService = fileService ;
_contentTypeService = contentTypeService ;
2021-01-06 17:04:35 +11:00
_umbracoContextAccessor = umbracoContextAccessor ;
2021-01-08 00:25:09 +11:00
_eventAggregator = eventAggregator ;
2017-07-20 11:21:28 +02:00
}
2016-10-11 18:52:01 +02:00
2019-01-31 09:08:51 +01:00
/// <inheritdoc />
2021-01-08 00:25:09 +11:00
public async Task < IPublishedRequestBuilder > CreateRequestAsync ( Uri uri )
{
// trigger the Creating event - at that point the URL can be changed
// this is based on this old task here: https://issues.umbraco.org/issue/U4-7914 which was fulfiled by
// this PR https://github.com/umbraco/Umbraco-CMS/pull/1137
// It's to do with proxies, quote:
/ *
"Thinking about another solution.
We already have an event , PublishedContentRequest . Prepared , which triggers once the request has been prepared and domain , content , template have been figured out - - but before it renders - - so ppl can change things before rendering .
Wondering whether we could have a event , PublishedContentRequest . Preparing , which would trigger before the request is prepared , and would let ppl change the value of the request ' s URI ( which by default derives from the HttpContext request ) .
That way , if an in - between equipement changes the URI , you could replace it with the original , public - facing URI before we process the request , meaning you could register your HTTPS domain and it would work . And you would have to supply code for each equipment . Less magic in Core . "
* /
// but now we'll just have one event for creating so if people wish to change the URL here they can but nothing else
var creatingRequest = new CreatingRequestNotification ( uri ) ;
await _eventAggregator . PublishAsync ( creatingRequest ) ;
var publishedRequestBuilder = new PublishedRequestBuilder ( creatingRequest . Url , _fileService ) ;
return publishedRequestBuilder ;
}
2016-10-11 18:52:01 +02:00
2021-01-08 10:42:57 +11:00
private IPublishedRequest TryRouteRequest ( IPublishedRequestBuilder request )
2017-07-20 11:21:28 +02:00
{
FindDomain ( request ) ;
2017-05-12 14:49:44 +02:00
2021-01-06 17:04:35 +11:00
if ( request . IsRedirect ( ) )
{
2021-01-08 10:42:57 +11:00
return request . Build ( ) ;
2021-01-06 17:04:35 +11:00
}
2017-05-12 14:49:44 +02:00
2021-01-06 17:04:35 +11:00
if ( request . HasPublishedContent ( ) )
{
2021-01-08 10:42:57 +11:00
return request . Build ( ) ;
2021-01-06 17:04:35 +11:00
}
2017-05-12 14:49:44 +02:00
2021-01-06 17:04:35 +11:00
FindPublishedContent ( request ) ;
2021-01-08 10:42:57 +11:00
return request . Build ( ) ;
2017-07-20 11:21:28 +02:00
}
2017-05-30 10:50:09 +02:00
2021-01-11 13:39:09 +11:00
private void SetVariationContext ( string culture )
2018-06-03 17:21:15 +02:00
{
2021-01-07 20:37:36 +11:00
VariationContext variationContext = _variationContextAccessor . VariationContext ;
2021-01-11 13:39:09 +11:00
if ( variationContext ! = null & & variationContext . Culture = = culture )
2021-01-07 20:37:36 +11:00
{
return ;
}
2021-01-11 13:39:09 +11:00
_variationContextAccessor . VariationContext = new VariationContext ( culture ) ;
2018-06-03 17:21:15 +02:00
}
2019-01-31 09:08:51 +01:00
/// <inheritdoc />
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 async Task < IPublishedRequest > RouteRequestAsync ( IPublishedRequestBuilder builder , RouteRequestOptions options )
2017-07-20 11:21:28 +02:00
{
2021-01-08 10:42:57 +11:00
// outbound routing performs different/simpler logic
if ( options . RouteDirection = = RouteDirection . Outbound )
{
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 TryRouteRequest ( builder ) ;
2021-01-08 10:42:57 +11:00
}
2021-01-06 17:04:35 +11:00
// find domain
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
if ( builder . Domain = = null )
{
FindDomain ( builder ) ;
}
await RouteRequestInternalAsync ( builder ) ;
// complete the PCR and assign the remaining values
return BuildRequest ( builder ) ;
}
2016-10-11 18:52:01 +02: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
private async Task RouteRequestInternalAsync ( IPublishedRequestBuilder builder )
{
// if request builder was already flagged to redirect then return
2017-07-20 11:21:28 +02:00
// whoever called us is in charge of actually redirecting
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
if ( builder . IsRedirect ( ) )
2017-07-20 11:21:28 +02: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 ;
2017-07-20 11:21:28 +02:00
}
2016-10-11 18:52:01 +02:00
2021-01-07 22:05:23 +11:00
// set the culture
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
SetVariationContext ( builder . Culture ) ;
var foundContentByFinders = false ;
2016-10-11 18:52:01 +02: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
// Find the published content if it's not assigned.
// This could be manually assigned with a custom route handler, etc...
// which in turn could call this method
2016-10-11 18:52:01 +02:00
// to setup the rest of the pipeline but we don't want to run the finders since there's one assigned.
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
if ( ! builder . HasPublishedContent ( ) )
2017-07-20 11:21:28 +02: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
_logger . LogDebug ( "FindPublishedContentAndTemplate: Path={UriAbsolutePath}" , builder . Uri . AbsolutePath ) ;
// run the document finders
foundContentByFinders = FindPublishedContent ( builder ) ;
2017-07-20 11:21:28 +02:00
}
2016-10-11 18:52:01 +02: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
// if we are not a redirect
if ( ! builder . IsRedirect ( ) )
{
// handle not-found, redirects, access...
HandlePublishedContent ( builder ) ;
// find a template
FindTemplate ( builder , foundContentByFinders ) ;
// handle umbracoRedirect
FollowExternalRedirect ( builder ) ;
2016-10-11 18:52:01 +02: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
// handle wildcard domains
HandleWildcardDomains ( builder ) ;
// set the culture -- again, 'cos it might have changed due to a finder or wildcard domain
SetVariationContext ( builder . Culture ) ;
}
2016-10-11 18:52:01 +02:00
2021-01-08 00:25:09 +11:00
// trigger the routing request (used to be called Prepared) event - at that point it is still possible to change about anything
// even though the request might be flagged for redirection - we'll redirect _after_ the event
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
var routingRequest = new RoutingRequestNotification ( builder ) ;
2021-01-08 00:25:09 +11:00
await _eventAggregator . PublishAsync ( routingRequest ) ;
2016-10-11 18:52:01 +02:00
// we don't take care of anything so if the content has changed, it's up to the user
// to find out the appropriate template
2017-07-20 11:21:28 +02:00
}
2016-10-11 18:52:01 +02:00
/// <summary>
2021-01-08 02:10:13 +11:00
/// This method finalizes/builds the PCR with the values assigned.
2016-10-11 18:52:01 +02:00
/// </summary>
/// <returns>
/// Returns false if the request was not successfully configured
/// </returns>
/// <remarks>
/// This method logic has been put into it's own method in case developers have created a custom PCR or are assigning their own values
/// but need to finalize it themselves.
/// </remarks>
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
internal IPublishedRequest BuildRequest ( IPublishedRequestBuilder builder )
2016-10-11 18:52:01 +02: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
IPublishedRequest result = builder . Build ( ) ;
2021-01-08 02:10:13 +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
if ( ! builder . HasPublishedContent ( ) )
2016-10-11 18:52:01 +02:00
{
2021-01-08 02:10:13 +11:00
return result ;
2016-10-11 18:52:01 +02:00
}
2021-01-07 22:05:23 +11:00
// set the culture -- again, 'cos it might have changed in the event handler
2021-01-07 20:37:36 +11:00
SetVariationContext ( result . Culture ) ;
2016-10-11 18:52:01 +02:00
2021-01-07 20:37:36 +11:00
return result ;
2016-10-11 18:52:01 +02:00
}
2021-01-08 02:36:55 +11:00
/// <inheritdoc />
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 async Task < IPublishedRequest > UpdateRequestAsync ( IPublishedRequest request , IPublishedContent publishedContent )
2021-01-08 02:36:55 +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
// store the original (if any)
2021-01-08 02:36:55 +11:00
IPublishedContent content = request . PublishedContent ;
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
IPublishedRequestBuilder builder = new PublishedRequestBuilder ( request . Uri , _fileService ) ;
2021-01-08 02:36:55 +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
// set to the new content (or null if specified)
builder . SetPublishedContent ( publishedContent ) ;
// re-route
await RouteRequestInternalAsync ( builder ) ;
// return if we are redirect
if ( builder . IsRedirect ( ) )
2021-01-08 02:36:55 +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 BuildRequest ( builder ) ;
2021-01-08 02:36:55 +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
// this will occur if publishedContent is null and the last chance finders also don't assign content
2021-01-08 02:36:55 +11:00
if ( ! builder . HasPublishedContent ( ) )
{
// means the engine could not find a proper document to handle 404
// restore the saved content so we know it exists
builder . SetPublishedContent ( content ) ;
}
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 BuildRequest ( builder ) ;
2021-01-08 02:36:55 +11:00
}
2016-10-11 18:52:01 +02:00
2017-07-20 11:21:28 +02:00
/// <summary>
2019-04-30 20:13:59 +01:00
/// Finds the site root (if any) matching the http request, and updates the PublishedRequest accordingly.
2017-07-20 11:21:28 +02:00
/// </summary>
/// <returns>A value indicating whether a domain was found.</returns>
2021-01-06 17:04:35 +11:00
internal bool FindDomain ( IPublishedRequestBuilder request )
2017-07-20 11:21:28 +02:00
{
const string tracePrefix = "FindDomain: " ;
2016-10-11 18:52:01 +02:00
2017-07-20 11:21:28 +02:00
// note - we are not handling schemes nor ports here.
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "{TracePrefix}Uri={RequestUri}" , tracePrefix , request . Uri ) ;
2021-08-16 12:36:50 +02:00
var umbracoContext = _umbracoContextAccessor . GetRequiredUmbracoContext ( ) ;
2021-08-11 11:33:46 +02:00
IDomainCache domainsCache = umbracoContext . PublishedSnapshot . Domains ;
2018-05-08 11:21:14 +10:00
var domains = domainsCache . GetAll ( includeWildcards : false ) . ToList ( ) ;
2018-05-08 11:06:07 +02:00
// determines whether a domain corresponds to a published document, since some
// domains may exist but on a document that has been unpublished - as a whole - or
// that is not published for the domain's culture - in which case the domain does
// not apply
bool IsPublishedContentDomain ( Domain domain )
2018-05-08 11:21:14 +10:00
{
2018-05-08 11:06:07 +02:00
// just get it from content cache - optimize there, not here
2021-08-11 11:33:46 +02:00
IPublishedContent domainDocument = umbracoContext . PublishedSnapshot . Content . GetById ( domain . ContentId ) ;
2018-05-08 11:06:07 +02:00
// not published - at all
if ( domainDocument = = null )
2021-01-06 17:04:35 +11:00
{
2018-05-08 11:21:14 +10:00
return false ;
2021-01-06 17:04:35 +11:00
}
2018-05-08 11:06:07 +02:00
// invariant - always published
2018-06-20 14:18:57 +02:00
if ( ! domainDocument . ContentType . VariesByCulture ( ) )
2021-01-06 17:04:35 +11:00
{
2018-05-08 11:21:14 +10:00
return true ;
2021-01-06 17:04:35 +11:00
}
2018-05-08 11:06:07 +02:00
// variant, ensure that the culture corresponding to the domain's language is published
2021-01-11 13:39:09 +11:00
return domainDocument . Cultures . ContainsKey ( domain . Culture ) ;
2018-05-08 11:06:07 +02:00
}
domains = domains . Where ( IsPublishedContentDomain ) . ToList ( ) ;
2018-05-02 14:52:00 +10:00
2018-04-26 16:03:08 +02:00
var defaultCulture = domainsCache . DefaultCulture ;
2017-07-20 11:21:28 +02:00
// try to find a domain matching the current request
2021-01-06 17:04:35 +11:00
DomainAndUri domainAndUri = DomainUtilities . SelectDomain ( domains , request . Uri , defaultCulture : defaultCulture ) ;
2016-10-11 18:52:01 +02:00
2017-07-20 11:21:28 +02:00
// handle domain - always has a contentId and a culture
if ( domainAndUri ! = null )
{
2016-10-11 18:52:01 +02:00
// matching an existing domain
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "{TracePrefix}Matches domain={Domain}, rootId={RootContentId}, culture={Culture}" , tracePrefix , domainAndUri . Name , domainAndUri . ContentId , domainAndUri . Culture ) ;
2016-10-11 18:52:01 +02:00
2021-01-07 23:14:26 +11:00
request . SetDomain ( domainAndUri ) ;
2016-10-11 18:52:01 +02:00
// canonical? not implemented at the moment
// if (...)
// {
// _pcr.RedirectUrl = "...";
// return true;
// }
}
else
2017-07-20 11:21:28 +02:00
{
// not matching any existing domain
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "{TracePrefix}Matches no domain" , tracePrefix ) ;
2016-10-11 18:52:01 +02:00
2021-01-11 13:39:09 +11:00
request . SetCulture ( defaultCulture ? ? CultureInfo . CurrentUICulture . Name ) ;
2017-07-20 11:21:28 +02:00
}
2016-10-11 18:52:01 +02:00
2021-01-11 13:39:09 +11:00
_logger . LogDebug ( "{TracePrefix}Culture={CultureName}" , tracePrefix , request . Culture ) ;
2016-10-11 18:52:01 +02:00
2017-07-20 11:21:28 +02:00
return request . Domain ! = null ;
}
2016-10-11 18:52:01 +02:00
2017-07-20 11:21:28 +02:00
/// <summary>
/// Looks for wildcard domains in the path and updates <c>Culture</c> accordingly.
/// </summary>
2021-01-06 17:04:35 +11:00
internal void HandleWildcardDomains ( IPublishedRequestBuilder request )
2017-07-20 11:21:28 +02:00
{
const string tracePrefix = "HandleWildcardDomains: " ;
2016-10-11 18:52:01 +02:00
2021-01-06 17:04:35 +11:00
if ( request . PublishedContent = = null )
{
2017-07-20 11:21:28 +02:00
return ;
2021-01-06 17:04:35 +11:00
}
2016-10-11 18:52:01 +02:00
2017-07-20 11:21:28 +02:00
var nodePath = request . PublishedContent . Path ;
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "{TracePrefix}Path={NodePath}" , tracePrefix , nodePath ) ;
2021-01-06 17:04:35 +11:00
var rootNodeId = request . Domain ! = null ? request . Domain . ContentId : ( int? ) null ;
2021-08-16 12:36:50 +02:00
var umbracoContext = _umbracoContextAccessor . GetRequiredUmbracoContext ( ) ;
2021-08-11 11:33:46 +02:00
Domain domain = DomainUtilities . FindWildcardDomainInPath ( umbracoContext . PublishedSnapshot . Domains . GetAll ( true ) , nodePath , rootNodeId ) ;
2016-10-11 18:52:01 +02:00
// always has a contentId and a culture
2017-07-20 11:21:28 +02:00
if ( domain ! = null )
{
2021-01-06 17:04:35 +11:00
request . SetCulture ( domain . Culture ) ;
2021-01-11 13:39:09 +11:00
_logger . LogDebug ( "{TracePrefix}Got domain on node {DomainContentId}, set culture to {CultureName}" , tracePrefix , domain . ContentId , request . Culture ) ;
2016-10-11 18:52:01 +02:00
}
2017-07-20 11:21:28 +02:00
else
{
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "{TracePrefix}No match." , tracePrefix ) ;
2017-07-20 11:21:28 +02:00
}
}
2016-10-11 18:52:01 +02:00
internal bool FindTemplateRenderingEngineInDirectory ( DirectoryInfo directory , string alias , string [ ] extensions )
{
if ( directory = = null | | directory . Exists = = false )
2021-01-06 17:31:46 +11:00
{
2016-10-11 18:52:01 +02:00
return false ;
2021-01-06 17:31:46 +11:00
}
2016-10-11 18:52:01 +02:00
var pos = alias . IndexOf ( '/' ) ;
if ( pos > 0 )
{
// recurse
2021-01-06 17:31:46 +11:00
DirectoryInfo subdir = directory . GetDirectories ( alias . Substring ( 0 , pos ) ) . FirstOrDefault ( ) ;
2016-10-11 18:52:01 +02:00
alias = alias . Substring ( pos + 1 ) ;
return subdir ! = null & & FindTemplateRenderingEngineInDirectory ( subdir , alias , extensions ) ;
}
// look here
return directory . GetFiles ( ) . Any ( f = > extensions . Any ( e = > f . Name . InvariantEquals ( alias + e ) ) ) ;
}
2017-07-20 11:21:28 +02:00
/// <summary>
/// Tries to find the document matching the request, by running the IPublishedContentFinder instances.
/// </summary>
2016-10-11 18:52:01 +02:00
/// <exception cref="InvalidOperationException">There is no finder collection.</exception>
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
internal bool FindPublishedContent ( IPublishedRequestBuilder request )
2017-07-20 11:21:28 +02:00
{
const string tracePrefix = "FindPublishedContent: " ;
2016-10-11 18:52:01 +02:00
2017-07-20 11:21:28 +02:00
// look for the document
// the first successful finder, if any, will set this.PublishedContent, and may also set this.Template
// some finders may implement caching
2017-10-31 12:48:24 +01:00
using ( _profilingLogger . DebugDuration < PublishedRouter > (
2016-10-11 18:52:01 +02:00
$"{tracePrefix}Begin finders" ,
2021-01-06 17:04:35 +11:00
$"{tracePrefix}End finders" ) )
2017-07-20 11:21:28 +02:00
{
2021-01-06 17:04:35 +11:00
// iterate but return on first one that finds it
2017-07-20 11:21:28 +02:00
var found = _contentFinders . Any ( finder = >
{
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "Finder {ContentFinderType}" , finder . GetType ( ) . FullName ) ;
2017-07-20 11:21:28 +02:00
return finder . TryFindContent ( request ) ;
} ) ;
2021-03-05 15:36:27 +01:00
2021-03-10 12:08:20 +11:00
_logger . LogDebug (
"Found? {Found}, Content: {PublishedContentId}, Template: {TemplateAlias}, Domain: {Domain}, Culture: {Culture}, StatusCode: {StatusCode}" ,
2021-03-05 15:36:27 +01:00
found ,
request . HasPublishedContent ( ) ? request . PublishedContent . Id : "NULL" ,
request . HasTemplate ( ) ? request . Template ? . Alias : "NULL" ,
request . HasDomain ( ) ? request . Domain . ToString ( ) : "NULL" ,
request . Culture ? ? "NULL" ,
2021-03-10 12:08:20 +11:00
request . ResponseStatusCode ) ;
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 found ;
2017-07-20 11:21:28 +02:00
}
}
/// <summary>
/// Handles the published content (if any).
/// </summary>
2021-01-07 23:14:26 +11:00
/// <param name="request">The request builder.</param>
2017-07-20 11:21:28 +02:00
/// <remarks>
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
/// Handles "not found", internal redirects ...
2017-07-20 11:21:28 +02:00
/// things that must be handled in one place because they can create loops
/// </remarks>
2021-01-08 02:10:13 +11:00
private void HandlePublishedContent ( IPublishedRequestBuilder request )
2017-07-20 11:21:28 +02:00
{
// because these might loop, we have to have some sort of infinite loop detection
int i = 0 , j = 0 ;
const int maxLoop = 8 ;
do
{
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "HandlePublishedContent: Loop {LoopCounter}" , i ) ;
2017-07-20 11:21:28 +02:00
// handle not found
2021-01-06 17:04:35 +11:00
if ( request . PublishedContent = = null )
2017-07-20 11:21:28 +02:00
{
2021-01-06 20:03:49 +11:00
request . SetIs404 ( ) ;
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "HandlePublishedContent: No document, try last chance lookup" ) ;
2017-07-20 11:21:28 +02:00
// if it fails then give up, there isn't much more that we can do
if ( _contentLastChanceFinder . TryFindContent ( request ) = = false )
{
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "HandlePublishedContent: Failed to find a document, give up" ) ;
2017-07-20 11:21:28 +02:00
break ;
}
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "HandlePublishedContent: Found a document" ) ;
2017-07-20 11:21:28 +02:00
}
// follow internal redirects as long as it's not running out of control ie infinite loop of some sort
j = 0 ;
2021-01-08 02:10:13 +11:00
while ( FollowInternalRedirects ( request ) & & j + + < maxLoop )
2017-07-20 11:21:28 +02:00
{ }
2021-01-06 17:04:35 +11:00
// we're running out of control
if ( j = = maxLoop )
{
2017-07-20 11:21:28 +02:00
break ;
2021-01-06 17:04:35 +11:00
}
2017-07-20 11:21:28 +02:00
// loop while we don't have page, ie the redirect or access
// got us to nowhere and now we need to run the notFoundLookup again
// as long as it's not running out of control ie infinite loop of some sort
2021-01-06 17:04:35 +11:00
} while ( request . PublishedContent = = null & & i + + < maxLoop ) ;
2017-07-20 11:21:28 +02:00
if ( i = = maxLoop | | j = = maxLoop )
{
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "HandlePublishedContent: Looks like we are running into an infinite loop, abort" ) ;
2021-01-06 17:04:35 +11:00
request . SetPublishedContent ( null ) ;
2017-07-20 11:21:28 +02:00
}
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "HandlePublishedContent: End" ) ;
2017-07-20 11:21:28 +02:00
}
/// <summary>
/// Follows internal redirections through the <c>umbracoInternalRedirectId</c> document property.
/// </summary>
2021-01-07 23:14:26 +11:00
/// <param name="request">The request builder.</param>
2017-07-20 11:21:28 +02:00
/// <returns>A value indicating whether redirection took place and led to a new published document.</returns>
/// <remarks>
/// <para>Redirecting to a different site root and/or culture will not pick the new site root nor the new culture.</para>
/// <para>As per legacy, if the redirect does not work, we just ignore it.</para>
/// </remarks>
2021-01-08 02:10:13 +11:00
private bool FollowInternalRedirects ( IPublishedRequestBuilder request )
2017-07-20 11:21:28 +02:00
{
if ( request . PublishedContent = = null )
2021-01-06 17:04:35 +11:00
{
2017-07-20 11:21:28 +02:00
throw new InvalidOperationException ( "There is no PublishedContent." ) ;
2021-01-06 17:04:35 +11:00
}
2017-07-20 11:21:28 +02:00
// don't try to find a redirect if the property doesn't exist
if ( request . PublishedContent . HasProperty ( Constants . Conventions . Content . InternalRedirectId ) = = false )
2021-01-06 17:04:35 +11:00
{
2017-07-20 11:21:28 +02:00
return false ;
2021-01-06 17:04:35 +11:00
}
2016-10-11 18:52:01 +02:00
2017-05-30 10:50:09 +02:00
var redirect = false ;
2017-07-20 11:21:28 +02:00
var valid = false ;
IPublishedContent internalRedirectNode = null ;
2020-02-28 11:15:25 +01:00
var internalRedirectId = request . PublishedContent . Value ( _publishedValueFallback , Constants . Conventions . Content . InternalRedirectId , defaultValue : - 1 ) ;
2021-08-16 12:36:50 +02:00
var umbracoContext = _umbracoContextAccessor . GetRequiredUmbracoContext ( ) ;
2016-10-11 18:52:01 +02:00
2017-07-20 11:21:28 +02:00
if ( internalRedirectId > 0 )
{
// try and get the redirect node from a legacy integer ID
valid = true ;
2021-08-11 11:33:46 +02:00
internalRedirectNode = umbracoContext . Content . GetById ( internalRedirectId ) ;
2017-07-20 11:21:28 +02:00
}
else
{
2021-01-06 17:04:35 +11:00
GuidUdi udiInternalRedirectId = request . PublishedContent . Value < GuidUdi > ( _publishedValueFallback , Constants . Conventions . Content . InternalRedirectId ) ;
2017-07-20 11:21:28 +02:00
if ( udiInternalRedirectId ! = null )
{
// try and get the redirect node from a UDI Guid
valid = true ;
2021-08-11 11:33:46 +02:00
internalRedirectNode = umbracoContext . Content . GetById ( udiInternalRedirectId . Guid ) ;
2017-07-20 11:21:28 +02:00
}
}
if ( valid = = false )
{
// bad redirect - log and display the current page (legacy behavior)
2021-01-06 17:04:35 +11:00
_logger . LogDebug (
"FollowInternalRedirects: Failed to redirect to id={InternalRedirectId}: value is not an int nor a GuidUdi." ,
2018-08-14 22:36:47 +01:00
request . PublishedContent . GetProperty ( Constants . Conventions . Content . InternalRedirectId ) . GetSourceValue ( ) ) ;
2017-05-30 10:50:09 +02:00
}
if ( internalRedirectNode = = null )
{
2021-01-06 17:04:35 +11:00
_logger . LogDebug (
"FollowInternalRedirects: Failed to redirect to id={InternalRedirectId}: no such published document." ,
2018-08-14 22:36:47 +01:00
request . PublishedContent . GetProperty ( Constants . Conventions . Content . InternalRedirectId ) . GetSourceValue ( ) ) ;
2017-05-30 10:50:09 +02:00
}
2017-07-20 11:21:28 +02:00
else if ( internalRedirectId = = request . PublishedContent . Id )
{
// redirect to self
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "FollowInternalRedirects: Redirecting to self, ignore" ) ;
2017-07-20 11:21:28 +02:00
}
else
{
2021-01-07 23:14:26 +11:00
// save since it will be cleared
ITemplate template = request . Template ;
request . SetInternalRedirect ( internalRedirectNode ) ; // don't use .PublishedContent here
// must restore the template if it's an internal redirect & the config option is set
if ( request . IsInternalRedirect & & _webRoutingSettings . InternalRedirectPreservesTemplate )
{
// restore
request . SetTemplate ( template ) ;
}
2017-07-20 11:21:28 +02:00
redirect = true ;
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "FollowInternalRedirects: Redirecting to id={InternalRedirectId}" , internalRedirectId ) ;
2017-07-20 11:21:28 +02:00
}
2016-10-11 18:52:01 +02:00
2017-07-20 11:21:28 +02:00
return redirect ;
}
2016-10-11 18:52:01 +02:00
2017-07-20 11:21:28 +02:00
/// <summary>
/// Finds a template for the current node, if any.
/// </summary>
2021-01-06 17:31:46 +11:00
/// <param name="request">The request builder.</param>
/// <param name="contentFoundByFinders">If the content was found by the finders, before anything such as 404, redirect... took place.</param>
private void FindTemplate ( IPublishedRequestBuilder request , bool contentFoundByFinders )
2017-07-20 11:21:28 +02:00
{
2021-01-06 17:04:35 +11:00
// TODO: We've removed the event, might need to re-add?
2017-07-20 11:21:28 +02:00
// NOTE: at the moment there is only 1 way to find a template, and then ppl must
// use the Prepared event to change the template if they wish. Should we also
// implement an ITemplateFinder logic?
2016-10-11 18:52:01 +02:00
if ( request . PublishedContent = = null )
{
2021-01-06 17:04:35 +11:00
request . SetTemplate ( null ) ;
2016-10-11 18:52:01 +02:00
return ;
}
2017-07-20 11:21:28 +02:00
// read the alternate template alias, from querystring, form, cookie or server vars,
// only if the published content is the initial once, else the alternate template
// does not apply
2019-01-26 10:52:19 -05:00
// + optionally, apply the alternate template on internal redirects
2021-01-06 17:31:46 +11:00
var useAltTemplate = contentFoundByFinders
2021-01-07 23:14:26 +11:00
| | ( _webRoutingSettings . InternalRedirectPreservesTemplate & & request . IsInternalRedirect ) ;
2021-01-06 17:04:35 +11:00
2016-10-11 18:52:01 +02:00
var altTemplate = useAltTemplate
2020-02-28 11:15:25 +01:00
? _requestAccessor . GetRequestValue ( Constants . Conventions . Url . AltTemplate )
2017-07-20 11:21:28 +02:00
: null ;
if ( string . IsNullOrWhiteSpace ( altTemplate ) )
{
// we don't have an alternate template specified. use the current one if there's one already,
// which can happen if a content lookup also set the template (LookupByNiceUrlAndTemplate...),
// else lookup the template id on the document then lookup the template with that id.
2021-01-06 17:04:35 +11:00
if ( request . HasTemplate ( ) )
2017-07-20 11:21:28 +02:00
{
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "FindTemplate: Has a template already, and no alternate template." ) ;
2017-07-20 11:21:28 +02:00
return ;
}
2019-02-28 11:01:53 +10:00
// TODO: We need to limit altTemplate to only allow templates that are assigned to the current document type!
// if the template isn't assigned to the document type we should log a warning and return 404
2017-07-20 11:21:28 +02:00
var templateId = request . PublishedContent . TemplateId ;
2021-01-06 17:04:35 +11:00
ITemplate template = GetTemplate ( templateId ) ;
request . SetTemplate ( template ) ;
2021-01-11 13:55:44 +11:00
if ( template ! = null )
{
_logger . LogDebug ( "FindTemplate: Running with template id={TemplateId} alias={TemplateAlias}" , template . Id , template . Alias ) ;
}
else
{
_logger . LogWarning ( "FindTemplate: Could not find template with id {TemplateId}" , templateId ) ;
}
2017-07-20 11:21:28 +02:00
}
else
{
// we have an alternate template specified. lookup the template with that alias
// this means the we override any template that a content lookup might have set
// so /path/to/page/template1?altTemplate=template2 will use template2
// ignore if the alias does not match - just trace
2021-01-06 17:04:35 +11:00
if ( request . HasTemplate ( ) )
{
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "FindTemplate: Has a template already, but also an alternative template." ) ;
2021-01-06 17:04:35 +11:00
}
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "FindTemplate: Look for alternative template alias={AltTemplate}" , altTemplate ) ;
2017-07-20 11:21:28 +02:00
2018-09-06 14:10:10 +02:00
// IsAllowedTemplate deals both with DisableAlternativeTemplates and ValidateAlternativeTemplates settings
2020-02-28 11:15:25 +01:00
if ( request . PublishedContent . IsAllowedTemplate (
_fileService ,
_contentTypeService ,
2020-03-12 09:52:34 +01:00
_webRoutingSettings . DisableAlternativeTemplates ,
_webRoutingSettings . ValidateAlternativeTemplates ,
2020-02-28 11:15:25 +01:00
altTemplate ) )
2017-07-20 11:21:28 +02:00
{
2018-09-06 14:10:10 +02:00
// allowed, use
2021-01-06 17:04:35 +11:00
ITemplate template = _fileService . GetTemplate ( altTemplate ) ;
2018-09-06 14:10:10 +02:00
if ( template ! = null )
{
2021-01-06 17:04:35 +11:00
request . SetTemplate ( template ) ;
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "FindTemplate: Got alternative template id={TemplateId} alias={TemplateAlias}" , template . Id , template . Alias ) ;
2018-09-06 14:10:10 +02:00
}
else
{
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "FindTemplate: The alternative template with alias={AltTemplate} does not exist, ignoring." , altTemplate ) ;
2018-09-06 14:10:10 +02:00
}
2017-07-20 11:21:28 +02:00
}
else
{
2020-09-15 09:00:14 +02:00
_logger . LogWarning ( "FindTemplate: Alternative template {TemplateAlias} is not allowed on node {NodeId}, ignoring." , altTemplate , request . PublishedContent . Id ) ;
2018-09-06 14:10:10 +02:00
// no allowed, back to default
var templateId = request . PublishedContent . TemplateId ;
2021-01-06 17:04:35 +11:00
ITemplate template = GetTemplate ( templateId ) ;
request . SetTemplate ( template ) ;
_logger . LogDebug ( "FindTemplate: Running with template id={TemplateId} alias={TemplateAlias}" , template . Id , template . Alias ) ;
2017-07-20 11:21:28 +02:00
}
}
2021-01-06 17:04:35 +11:00
if ( ! request . HasTemplate ( ) )
2017-07-20 11:21:28 +02:00
{
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "FindTemplate: No template was found." ) ;
2017-07-20 11:21:28 +02:00
// initial idea was: if we're not already 404 and UmbracoSettings.HandleMissingTemplateAs404 is true
// then reset _pcr.Document to null to force a 404.
//
// but: because we want to let MVC hijack routes even though no template is defined, we decide that
// a missing template is OK but the request will then be forwarded to MVC, which will need to take
// care of everything.
//
// so, don't set _pcr.Document to null here
}
}
2021-01-06 17:04:35 +11:00
private ITemplate GetTemplate ( int? templateId )
2018-09-06 14:10:10 +02:00
{
2019-02-18 19:07:51 +11:00
if ( templateId . HasValue = = false | | templateId . Value = = default )
2018-09-06 14:10:10 +02:00
{
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "GetTemplateModel: No template." ) ;
2018-09-06 14:10:10 +02:00
return null ;
}
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "GetTemplateModel: Get template id={TemplateId}" , templateId ) ;
2018-09-06 14:10:10 +02:00
2018-11-15 07:23:09 +00:00
if ( templateId = = null )
2021-01-06 17:04:35 +11:00
{
2018-11-15 07:23:09 +00:00
throw new InvalidOperationException ( "The template is not set, the page cannot render." ) ;
2021-01-06 17:04:35 +11:00
}
2018-11-15 07:23:09 +00:00
2021-01-06 17:04:35 +11:00
ITemplate template = _fileService . GetTemplate ( templateId . Value ) ;
2018-09-06 14:10:10 +02:00
if ( template = = null )
2021-01-06 17:04:35 +11:00
{
2018-09-06 14:10:10 +02:00
throw new InvalidOperationException ( "The template with Id " + templateId + " does not exist, the page cannot render." ) ;
2021-01-06 17:04:35 +11:00
}
2020-09-15 09:00:14 +02:00
_logger . LogDebug ( "GetTemplateModel: Got template id={TemplateId} alias={TemplateAlias}" , template . Id , template . Alias ) ;
2018-09-06 14:10:10 +02:00
return template ;
}
2017-07-20 11:21:28 +02:00
/// <summary>
/// Follows external redirection through <c>umbracoRedirect</c> document property.
/// </summary>
/// <remarks>As per legacy, if the redirect does not work, we just ignore it.</remarks>
2021-01-06 17:04:35 +11:00
private void FollowExternalRedirect ( IPublishedRequestBuilder request )
2017-07-20 11:21:28 +02:00
{
2021-01-06 17:04:35 +11:00
if ( request . PublishedContent = = null )
{
return ;
}
2017-07-20 11:21:28 +02:00
// don't try to find a redirect if the property doesn't exist
if ( request . PublishedContent . HasProperty ( Constants . Conventions . Content . Redirect ) = = false )
2021-01-06 17:04:35 +11:00
{
2017-07-20 11:21:28 +02:00
return ;
2021-01-06 17:04:35 +11:00
}
2017-05-30 10:50:09 +02:00
2020-02-28 11:15:25 +01:00
var redirectId = request . PublishedContent . Value ( _publishedValueFallback , Constants . Conventions . Content . Redirect , defaultValue : - 1 ) ;
2017-07-20 11:21:28 +02:00
var redirectUrl = "#" ;
if ( redirectId > 0 )
{
2020-02-14 13:04:49 +01:00
redirectUrl = _publishedUrlProvider . GetUrl ( redirectId ) ;
2017-07-20 11:21:28 +02:00
}
else
{
// might be a UDI instead of an int Id
2021-01-06 17:04:35 +11:00
GuidUdi redirectUdi = request . PublishedContent . Value < GuidUdi > ( _publishedValueFallback , Constants . Conventions . Content . Redirect ) ;
2017-07-20 11:21:28 +02:00
if ( redirectUdi ! = null )
2021-01-06 17:04:35 +11:00
{
2020-02-14 13:04:49 +01:00
redirectUrl = _publishedUrlProvider . GetUrl ( redirectUdi . Guid ) ;
2021-01-06 17:04:35 +11:00
}
2017-07-20 11:21:28 +02:00
}
2021-01-06 17:04:35 +11:00
2017-05-30 10:50:09 +02:00
if ( redirectUrl ! = "#" )
2021-01-06 17:04:35 +11:00
{
2016-10-11 18:52:01 +02:00
request . SetRedirect ( redirectUrl ) ;
2021-01-06 17:04:35 +11:00
}
2017-07-20 11:21:28 +02:00
}
}
2016-10-11 18:52:01 +02:00
}