Merge pull request #7619 from umbraco/netcore/feature/AB4919-untable-umbraco-context

NetCore: Untangle and abstract UmbracoContext
This commit is contained in:
Shannon Deminick
2020-02-17 10:29:18 +11:00
committed by GitHub
112 changed files with 956 additions and 543 deletions
@@ -7,7 +7,7 @@ using Umbraco.Core.Serialization;
namespace Umbraco.Web.Cache
{
public sealed class MacroCacheRefresher : JsonCacheRefresherBase<MacroCacheRefresher, MacroCacheRefresher.JsonPayload>
public sealed class MacroCacheRefresher : PayloadCacheRefresherBase<MacroCacheRefresher, MacroCacheRefresher.JsonPayload>
{
public MacroCacheRefresher(AppCaches appCaches, IJsonSerializer jsonSerializer)
: base(appCaches, jsonSerializer)
@@ -6,7 +6,7 @@ using Umbraco.Core.Serialization;
namespace Umbraco.Web.Cache
{
public sealed class MemberGroupCacheRefresher : JsonCacheRefresherBase<MemberGroupCacheRefresher, MemberGroupCacheRefresher.JsonPayload>
public sealed class MemberGroupCacheRefresher : PayloadCacheRefresherBase<MemberGroupCacheRefresher, MemberGroupCacheRefresher.JsonPayload>
{
public MemberGroupCacheRefresher(AppCaches appCaches, IJsonSerializer jsonSerializer)
: base(appCaches, jsonSerializer)
+128
View File
@@ -0,0 +1,128 @@
using System;
using System.Web;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.Routing;
using Umbraco.Web.Security;
namespace Umbraco.Web
{
public interface IUmbracoContext
{
/// <summary>
/// This is used internally for performance calculations, the ObjectCreated DateTime is set as soon as this
/// object is instantiated which in the web site is created during the BeginRequest phase.
/// We can then determine complete rendering time from that.
/// </summary>
DateTime ObjectCreated { get; }
/// <summary>
/// This is used internally for debugging and also used to define anything required to distinguish this request from another.
/// </summary>
Guid UmbracoRequestId { get; }
/// <summary>
/// Gets the WebSecurity class
/// </summary>
IWebSecurity Security { get; }
/// <summary>
/// Gets the uri that is handled by ASP.NET after server-side rewriting took place.
/// </summary>
Uri OriginalRequestUrl { get; }
/// <summary>
/// Gets the cleaned up url that is handled by Umbraco.
/// </summary>
/// <remarks>That is, lowercase, no trailing slash after path, no .aspx...</remarks>
Uri CleanedUmbracoUrl { get; }
/// <summary>
/// Gets the published snapshot.
/// </summary>
IPublishedSnapshot PublishedSnapshot { get; }
/// <summary>
/// Gets the published content cache.
/// </summary>
IPublishedContentCache Content { get; }
/// <summary>
/// Gets the published media cache.
/// </summary>
IPublishedMediaCache Media { get; }
/// <summary>
/// Gets the domains cache.
/// </summary>
IDomainCache Domains { get; }
/// <summary>
/// Boolean value indicating whether the current request is a front-end umbraco request
/// </summary>
bool IsFrontEndUmbracoRequest { get; }
/// <summary>
/// Gets the url provider.
/// </summary>
IPublishedUrlProvider UrlProvider { get; }
/// <summary>
/// Gets/sets the PublishedRequest object
/// </summary>
IPublishedRequest PublishedRequest { get; set; }
/// <summary>
/// Gets the variation context accessor.
/// </summary>
IVariationContextAccessor VariationContextAccessor { get; }
/// <summary>
/// Gets a value indicating whether the request has debugging enabled
/// </summary>
/// <value><c>true</c> if this instance is debug; otherwise, <c>false</c>.</value>
bool IsDebug { get; }
/// <summary>
/// Determines whether the current user is in a preview mode and browsing the site (ie. not in the admin UI)
/// </summary>
bool InPreviewMode { get; }
/// <summary>
/// Gets the url of a content identified by its identifier.
/// </summary>
/// <param name="contentId">The content identifier.</param>
/// <param name="culture"></param>
/// <returns>The url for the content.</returns>
string Url(int contentId, string culture = null);
/// <summary>
/// Gets the url of a content identified by its identifier.
/// </summary>
/// <param name="contentId">The content identifier.</param>
/// <param name="culture"></param>
/// <returns>The url for the content.</returns>
string Url(Guid contentId, string culture = null);
/// <summary>
/// Gets the url of a content identified by its identifier, in a specified mode.
/// </summary>
/// <param name="contentId">The content identifier.</param>
/// <param name="mode">The mode.</param>
/// <param name="culture"></param>
/// <returns>The url for the content.</returns>
string Url(int contentId, UrlMode mode, string culture = null);
/// <summary>
/// Gets the url of a content identified by its identifier, in a specified mode.
/// </summary>
/// <param name="contentId">The content identifier.</param>
/// <param name="mode">The mode.</param>
/// <param name="culture"></param>
/// <returns>The url for the content.</returns>
string Url(Guid contentId, UrlMode mode, string culture = null);
IDisposable ForcedPreview(bool preview);
void Dispose();
}
}
@@ -5,6 +5,6 @@
/// </summary>
public interface IUmbracoContextAccessor
{
UmbracoContext UmbracoContext { get; set; }
IUmbracoContext UmbracoContext { get; set; }
}
}
@@ -27,7 +27,7 @@ namespace Umbraco.Web.Routing
/// one document per culture), and domains, withing the context of a current Uri, assign
/// a culture to that document.</para>
/// </remarks>
internal static string GetCultureFromDomains(int contentId, string contentPath, Uri current, UmbracoContext umbracoContext, ISiteDomainHelper siteDomainHelper)
internal static string GetCultureFromDomains(int contentId, string contentPath, Uri current, IUmbracoContext umbracoContext, ISiteDomainHelper siteDomainHelper)
{
if (umbracoContext == null)
throw new InvalidOperationException("A current UmbracoContext is required.");
@@ -295,7 +295,7 @@ namespace Umbraco.Web.Routing
? currentUri.GetLeftPart(UriPartial.Authority) + domainName
: domainName;
var scheme = currentUri?.Scheme ?? Uri.UriSchemeHttp;
return new Uri(UriUtility.TrimPathEndSlash(UriUtility.StartWithScheme(name, scheme)));
return new Uri(UriUtilityCore.TrimPathEndSlash(UriUtilityCore.StartWithScheme(name, scheme)));
}
#endregion
@@ -0,0 +1,224 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Web.Routing
{
public interface IPublishedRequest
{
/// <summary>
/// Gets the UmbracoContext.
/// </summary>
IUmbracoContext UmbracoContext { get; }
/// <summary>
/// Gets or sets the cleaned up Uri used for routing.
/// </summary>
/// <remarks>The cleaned up Uri has no virtual directory, no trailing slash, no .aspx extension, etc.</remarks>
Uri Uri { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the Umbraco Backoffice should ignore a collision for this request.
/// </summary>
bool IgnorePublishedContentCollisions { get; set; }
/// <summary>
/// Gets or sets the requested content.
/// </summary>
/// <remarks>Setting the requested content clears <c>Template</c>.</remarks>
IPublishedContent PublishedContent { get; set; }
/// <summary>
/// Gets the initial requested content.
/// </summary>
/// <remarks>The initial requested content is the content that was found by the finders,
/// before anything such as 404, redirect... took place.</remarks>
IPublishedContent InitialPublishedContent { get; }
/// <summary>
/// Gets value indicating whether the current published content is the initial one.
/// </summary>
bool IsInitialPublishedContent { get; }
/// <summary>
/// Gets or sets a value indicating whether the current published content has been obtained
/// from the initial published content following internal redirections exclusively.
/// </summary>
/// <remarks>Used by PublishedContentRequestEngine.FindTemplate() to figure out whether to
/// apply the internal redirect or not, when content is not the initial content.</remarks>
bool IsInternalRedirectPublishedContent { get; }
/// <summary>
/// Gets a value indicating whether the content request has a content.
/// </summary>
bool HasPublishedContent { get; }
ITemplate TemplateModel { get; set; }
/// <summary>
/// Gets the alias of the template to use to display the requested content.
/// </summary>
string TemplateAlias { get; }
/// <summary>
/// Gets a value indicating whether the content request has a template.
/// </summary>
bool HasTemplate { get; }
void UpdateToNotFound();
/// <summary>
/// Gets or sets the content request's domain.
/// </summary>
/// <remarks>Is a DomainAndUri object ie a standard Domain plus the fully qualified uri. For example,
/// the <c>Domain</c> may contain "example.com" whereas the <c>Uri</c> will be fully qualified eg "http://example.com/".</remarks>
DomainAndUri Domain { get; set; }
/// <summary>
/// Gets a value indicating whether the content request has a domain.
/// </summary>
bool HasDomain { get; }
/// <summary>
/// Gets or sets the content request's culture.
/// </summary>
CultureInfo Culture { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the requested content could not be found.
/// </summary>
/// <remarks>This is set in the <c>PublishedContentRequestBuilder</c> and can also be used in
/// custom content finders or <c>Prepared</c> event handlers, where we want to allow developers
/// to indicate a request is 404 but not to cancel it.</remarks>
bool Is404 { get; set; }
/// <summary>
/// Gets a value indicating whether the content request triggers a redirect (permanent or not).
/// </summary>
bool IsRedirect { get; }
/// <summary>
/// Gets or sets a value indicating whether the redirect is permanent.
/// </summary>
bool IsRedirectPermanent { get; }
/// <summary>
/// Gets or sets the url to redirect to, when the content request triggers a redirect.
/// </summary>
string RedirectUrl { get; }
/// <summary>
/// Gets or sets the content request http response status code.
/// </summary>
/// <remarks>Does not actually set the http response status code, only registers that the response
/// should use the specified code. The code will or will not be used, in due time.</remarks>
int ResponseStatusCode { get; }
/// <summary>
/// Gets or sets the content request http response status description.
/// </summary>
/// <remarks>Does not actually set the http response status description, only registers that the response
/// should use the specified description. The description will or will not be used, in due time.</remarks>
string ResponseStatusDescription { get; }
/// <summary>
/// Gets or sets a list of Extensions to append to the Response.Cache object.
/// </summary>
List<string> CacheExtensions { get; set; }
/// <summary>
/// Gets or sets a dictionary of Headers to append to the Response object.
/// </summary>
Dictionary<string, string> Headers { get; set; }
bool CacheabilityNoCache { get; set; }
/// <summary>
/// Prepares the request.
/// </summary>
void Prepare();
/// <summary>
/// Triggers the Preparing event.
/// </summary>
void OnPreparing();
/// <summary>
/// Triggers the Prepared event.
/// </summary>
void OnPrepared();
/// <summary>
/// Sets the requested content, following an internal redirect.
/// </summary>
/// <param name="content">The requested content.</param>
/// <remarks>Depending on <c>UmbracoSettings.InternalRedirectPreservesTemplate</c>, will
/// preserve or reset the template, if any.</remarks>
void SetInternalRedirectPublishedContent(IPublishedContent content);
/// <summary>
/// Indicates that the current PublishedContent is the initial one.
/// </summary>
void SetIsInitialPublishedContent();
/// <summary>
/// Tries to set the template to use to display the requested content.
/// </summary>
/// <param name="alias">The alias of the template.</param>
/// <returns>A value indicating whether a valid template with the specified alias was found.</returns>
/// <remarks>
/// <para>Successfully setting the template does refresh <c>RenderingEngine</c>.</para>
/// <para>If setting the template fails, then the previous template (if any) remains in place.</para>
/// </remarks>
bool TrySetTemplate(string alias);
/// <summary>
/// Sets the template to use to display the requested content.
/// </summary>
/// <param name="template">The template.</param>
/// <remarks>Setting the template does refresh <c>RenderingEngine</c>.</remarks>
void SetTemplate(ITemplate template);
/// <summary>
/// Resets the template.
/// </summary>
void ResetTemplate();
/// <summary>
/// Indicates that the content request should trigger a redirect (302).
/// </summary>
/// <param name="url">The url to redirect to.</param>
/// <remarks>Does not actually perform a redirect, only registers that the response should
/// redirect. Redirect will or will not take place in due time.</remarks>
void SetRedirect(string url);
/// <summary>
/// Indicates that the content request should trigger a permanent redirect (301).
/// </summary>
/// <param name="url">The url to redirect to.</param>
/// <remarks>Does not actually perform a redirect, only registers that the response should
/// redirect. Redirect will or will not take place in due time.</remarks>
void SetRedirectPermanent(string url);
/// <summary>
/// Indicates that the content request should trigger a redirect, with a specified status code.
/// </summary>
/// <param name="url">The url to redirect to.</param>
/// <param name="status">The status code (300-308).</param>
/// <remarks>Does not actually perform a redirect, only registers that the response should
/// redirect. Redirect will or will not take place in due time.</remarks>
void SetRedirect(string url, int status);
/// <summary>
/// Sets the http response status code, along with an optional associated description.
/// </summary>
/// <param name="code">The http status code.</param>
/// <param name="description">The description.</param>
/// <remarks>Does not actually set the http response status code and description, only registers that
/// the response should use the specified code and description. The code and description will or will
/// not be used, in due time.</remarks>
void SetResponseStatus(int code, string description = null);
}
}
@@ -0,0 +1,105 @@
using System;
using System.Collections.Generic;
using Umbraco.Core;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Web.Routing
{
public interface IPublishedUrlProvider
{
/// <summary>
/// Gets or sets the provider url mode.
/// </summary>
UrlMode Mode { get; set; }
/// <summary>
/// Gets the url of a published content.
/// </summary>
/// <param name="id">The published content identifier.</param>
/// <param name="mode">The url mode.</param>
/// <param name="culture">A culture.</param>
/// <param name="current">The current absolute url.</param>
/// <returns>The url for the published content.</returns>
string GetUrl(Guid id, UrlMode mode = UrlMode.Default, string culture = null, Uri current = null);
/// <summary>
/// Gets the url of a published content.
/// </summary>
/// <param name="id">The published content identifier.</param>
/// <param name="mode">The url mode.</param>
/// <param name="culture">A culture.</param>
/// <param name="current">The current absolute url.</param>
/// <returns>The url for the published content.</returns>
string GetUrl(int id, UrlMode mode = UrlMode.Default, string culture = null, Uri current = null);
/// <summary>
/// Gets the url of a published content.
/// </summary>
/// <param name="content">The published content.</param>
/// <param name="mode">The url mode.</param>
/// <param name="culture">A culture.</param>
/// <param name="current">The current absolute url.</param>
/// <returns>The url for the published content.</returns>
/// <remarks>
/// <para>The url is absolute or relative depending on <c>mode</c> and on <c>current</c>.</para>
/// <para>If the published content is multi-lingual, gets the url for the specified culture or,
/// when no culture is specified, the current culture.</para>
/// <para>If the provider is unable to provide a url, it returns "#".</para>
/// </remarks>
string GetUrl(IPublishedContent content, UrlMode mode = UrlMode.Default, string culture = null, Uri current = null);
string GetUrlFromRoute(int id, string route, string culture);
/// <summary>
/// Gets the other urls of a published content.
/// </summary>
/// <param name="id">The published content id.</param>
/// <returns>The other urls for the published content.</returns>
/// <remarks>
/// <para>Other urls are those that <c>GetUrl</c> would not return in the current context, but would be valid
/// urls for the node in other contexts (different domain for current request, umbracoUrlAlias...).</para>
/// <para>The results depend on the current url.</para>
/// </remarks>
IEnumerable<UrlInfo> GetOtherUrls(int id);
/// <summary>
/// Gets the other urls of a published content.
/// </summary>
/// <param name="id">The published content id.</param>
/// <param name="current">The current absolute url.</param>
/// <returns>The other urls for the published content.</returns>
/// <remarks>
/// <para>Other urls are those that <c>GetUrl</c> would not return in the current context, but would be valid
/// urls for the node in other contexts (different domain for current request, umbracoUrlAlias...).</para>
/// </remarks>
IEnumerable<UrlInfo> GetOtherUrls(int id, Uri current);
/// <summary>
/// Gets the url of a media item.
/// </summary>
/// <param name="id"></param>
/// <param name="mode"></param>
/// <param name="culture"></param>
/// <param name="propertyAlias"></param>
/// <param name="current"></param>
/// <returns></returns>
string GetMediaUrl(Guid id, UrlMode mode = UrlMode.Default, string culture = null, string propertyAlias = Constants.Conventions.Media.File, Uri current = null);
/// <summary>
/// Gets the url of a media item.
/// </summary>
/// <param name="content">The published content.</param>
/// <param name="propertyAlias">The property alias to resolve the url from.</param>
/// <param name="mode">The url mode.</param>
/// <param name="culture">The variation language.</param>
/// <param name="current">The current absolute url.</param>
/// <returns>The url for the media.</returns>
/// <remarks>
/// <para>The url is absolute or relative depending on <c>mode</c> and on <c>current</c>.</para>
/// <para>If the media is multi-lingual, gets the url for the specified culture or,
/// when no culture is specified, the current culture.</para>
/// <para>If the provider is unable to provide a url, it returns <see cref="String.Empty"/>.</para>
/// </remarks>
string GetMediaUrl(IPublishedContent content, UrlMode mode = UrlMode.Default, string culture = null, string propertyAlias = Constants.Conventions.Media.File, Uri current = null);
}
}
@@ -0,0 +1,62 @@
using System;
using Umbraco.Core;
using Umbraco.Core.Models.Membership;
namespace Umbraco.Web.Security
{
public interface IWebSecurity
{
/// <summary>
/// Gets the current user.
/// </summary>
/// <value>The current user.</value>
IUser CurrentUser { get; }
[Obsolete("This needs to be removed, ASP.NET Identity should always be used for this operation, this is currently only used in the installer which needs to be updated")]
double PerformLogin(int userId);
[Obsolete("This needs to be removed, ASP.NET Identity should always be used for this operation, this is currently only used in the installer which needs to be updated")]
void ClearCurrentLogin();
/// <summary>
/// Gets the current user's id.
/// </summary>
/// <returns></returns>
Attempt<int> GetUserId();
/// <summary>
/// Validates the currently logged in user and ensures they are not timed out
/// </summary>
/// <returns></returns>
bool ValidateCurrentUser();
/// <summary>
/// Validates the current user assigned to the request and ensures the stored user data is valid
/// </summary>
/// <param name="throwExceptions">set to true if you want exceptions to be thrown if failed</param>
/// <param name="requiresApproval">If true requires that the user is approved to be validated</param>
/// <returns></returns>
ValidateRequestAttempt ValidateCurrentUser(bool throwExceptions, bool requiresApproval = true);
/// <summary>
/// Authorizes the full request, checks for SSL and validates the current user
/// </summary>
/// <param name="throwExceptions">set to true if you want exceptions to be thrown if failed</param>
/// <returns></returns>
ValidateRequestAttempt AuthorizeRequest(bool throwExceptions = false);
/// <summary>
/// Checks if the specified user as access to the app
/// </summary>
/// <param name="section"></param>
/// <param name="user"></param>
/// <returns></returns>
bool UserHasSectionAccess(string section, IUser user);
/// <summary>
/// Ensures that a back office user is logged in
/// </summary>
/// <returns></returns>
bool IsAuthenticated();
}
}
@@ -0,0 +1,59 @@
using System;
using Umbraco.Core;
namespace Umbraco.Web
{
public static class UriUtilityCore
{
#region Uri string utilities
public static bool HasScheme(string uri)
{
return uri.IndexOf("://") > 0;
}
public static string StartWithScheme(string uri)
{
return StartWithScheme(uri, null);
}
public static string StartWithScheme(string uri, string scheme)
{
return HasScheme(uri) ? uri : String.Format("{0}://{1}", scheme ?? Uri.UriSchemeHttp, uri);
}
public static string EndPathWithSlash(string uri)
{
var pos1 = Math.Max(0, uri.IndexOf('?'));
var pos2 = Math.Max(0, uri.IndexOf('#'));
var pos = Math.Min(pos1, pos2);
var path = pos > 0 ? uri.Substring(0, pos) : uri;
path = path.EnsureEndsWith('/');
if (pos > 0)
path += uri.Substring(pos);
return path;
}
public static string TrimPathEndSlash(string uri)
{
var pos1 = Math.Max(0, uri.IndexOf('?'));
var pos2 = Math.Max(0, uri.IndexOf('#'));
var pos = Math.Min(pos1, pos2);
var path = pos > 0 ? uri.Substring(0, pos) : uri;
path = path.TrimEnd('/');
if (pos > 0)
path += uri.Substring(pos);
return path;
}
#endregion
}
}
@@ -23,7 +23,7 @@ namespace Umbraco.Tests.Cache.PublishedCache
public class PublishContentCacheTests : BaseWebTest
{
private FakeHttpContextFactory _httpContextFactory;
private UmbracoContext _umbracoContext;
private IUmbracoContext _umbracoContext;
private IPublishedContentCache _cache;
private XmlDocument _xml;
@@ -196,7 +196,7 @@ AnotherContentFinder
[Test]
public void Create_Cached_Plugin_File()
{
var types = new[] { typeof(TypeLoader), typeof(TypeLoaderTests), typeof(UmbracoContext) };
var types = new[] { typeof(TypeLoader), typeof(TypeLoaderTests), typeof(IUmbracoContext) };
var typeList1 = new TypeLoader.TypeList(typeof(object), null);
foreach (var type in types) typeList1.Add(type);
@@ -6,8 +6,8 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
{
static class UmbracoContextCache
{
static readonly ConditionalWeakTable<UmbracoContext, ConcurrentDictionary<string, object>> Caches
= new ConditionalWeakTable<UmbracoContext, ConcurrentDictionary<string, object>>();
static readonly ConditionalWeakTable<IUmbracoContext, ConcurrentDictionary<string, object>> Caches
= new ConditionalWeakTable<IUmbracoContext, ConcurrentDictionary<string, object>>();
public static ConcurrentDictionary<string, object> Current
{
@@ -13,7 +13,7 @@ namespace Umbraco.Tests.PublishedContent
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerFixture)]
public class PublishedContentExtensionTests : PublishedContentTestBase
{
private UmbracoContext _ctx;
private IUmbracoContext _ctx;
private string _xmlContent = "";
private bool _createContentTypes = true;
private Dictionary<string, PublishedContentType> _contentTypes;
@@ -56,7 +56,7 @@ namespace Umbraco.Tests.PublishedContent
.ToList());
}
private UmbracoContext GetUmbracoContext()
private IUmbracoContext GetUmbracoContext()
{
RouteData routeData = null;
@@ -68,7 +68,7 @@ namespace Umbraco.Tests.PublishedContent
/// <param name="id"></param>
/// <param name="umbracoContext"></param>
/// <returns></returns>
internal IPublishedContent GetNode(int id, UmbracoContext umbracoContext)
internal IPublishedContent GetNode(int id, IUmbracoContext umbracoContext)
{
var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null, HostingEnvironment),
ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache,
@@ -39,21 +39,6 @@ namespace Umbraco.Tests.PublishedContent
Assert.IsFalse(result);
}
[Test]
public void ConfigureRequest_Sets_UmbracoPage_When_Published_Content_Assigned()
{
var umbracoContext = GetUmbracoContext("/test");
var publishedRouter = CreatePublishedRouter();
var request = publishedRouter.CreateRequest(umbracoContext);
var content = GetPublishedContentMock();
request.Culture = new CultureInfo("en-AU");
request.PublishedContent = content.Object;
publishedRouter.ConfigureRequest(request);
Assert.IsNotNull(request.LegacyContentHashTable);
}
private Mock<IPublishedContent> GetPublishedContentMock()
{
var pc = new Mock<IPublishedContent>();
@@ -1,8 +1,10 @@
using NUnit.Framework;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using Umbraco.Web.Routing;
namespace Umbraco.Tests.Routing
@@ -18,7 +20,7 @@ namespace Umbraco.Tests.Routing
var umbracoContext = GetUmbracoContext(urlAsString);
var publishedRouter = CreatePublishedRouter();
var frequest = publishedRouter.CreateRequest(umbracoContext);
var lookup = new ContentFinderByIdPath(Factory.GetInstance<IUmbracoSettingsSection>().WebRouting, Logger);
var lookup = new ContentFinderByIdPath(Factory.GetInstance<IUmbracoSettingsSection>().WebRouting, Logger, HttpContextAccessor);
var result = lookup.TryFindContent(frequest);
@@ -1,6 +1,7 @@
using Moq;
using NUnit.Framework;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using Umbraco.Web.Routing;
namespace Umbraco.Tests.Routing
@@ -16,15 +17,18 @@ namespace Umbraco.Tests.Routing
public void Lookup_By_Page_Id(string urlAsString, int nodeMatch)
{
var umbracoContext = GetUmbracoContext(urlAsString);
var httpContext = GetHttpContextFactory(urlAsString).HttpContext;
var publishedRouter = CreatePublishedRouter();
var frequest = publishedRouter.CreateRequest(umbracoContext);
var lookup = new ContentFinderByPageIdQuery();
var mockHttpContextAccessor = new Mock<IHttpContextAccessor>();
mockHttpContextAccessor.Setup(x => x.HttpContext).Returns(httpContext);
var lookup = new ContentFinderByPageIdQuery(mockHttpContextAccessor.Object);
//we need to manually stub the return output of HttpContext.Request["umbPageId"]
var requestMock = Mock.Get(umbracoContext.HttpContext.Request);
var requestMock = Mock.Get(httpContext.Request);
requestMock.Setup(x => x["umbPageID"])
.Returns(umbracoContext.HttpContext.Request.QueryString["umbPageID"]);
.Returns(httpContext.Request.QueryString["umbPageID"]);
var result = lookup.TryFindContent(frequest);
@@ -100,10 +100,12 @@ namespace Umbraco.Tests.Routing
[Test]
public void Umbraco_Route_Umbraco_Defined_Controller_Action()
{
var url = "~/dummy-page";
var template = CreateTemplate("homePage");
var route = RouteTable.Routes["Umbraco_default"];
var routeData = new RouteData { Route = route };
var umbracoContext = GetUmbracoContext("~/dummy-page", template.Id, routeData);
var umbracoContext = GetUmbracoContext(url, template.Id, routeData);
var httpContext = GetHttpContextFactory(url, routeData).HttpContext;
var publishedRouter = CreatePublishedRouter();
var frequest = publishedRouter.CreateRequest(umbracoContext);
frequest.PublishedContent = umbracoContext.Content.GetById(1174);
@@ -112,7 +114,7 @@ namespace Umbraco.Tests.Routing
var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext);
var handler = new RenderRouteHandler(umbracoContext, new TestControllerFactory(umbracoContextAccessor, Mock.Of<ILogger>()), ShortStringHelper);
handler.GetHandlerForRoute(umbracoContext.HttpContext.Request.RequestContext, frequest);
handler.GetHandlerForRoute(httpContext.Request.RequestContext, frequest);
Assert.AreEqual("RenderMvc", routeData.Values["controller"].ToString());
//the route action will still be the one we've asked for because our RenderActionInvoker is the thing that decides
// if the action matches.
@@ -136,10 +138,12 @@ namespace Umbraco.Tests.Routing
// could exist in the database... yet creating templates should sanitize
// aliases one way or another...
var url = "~/dummy-page";
var template = CreateTemplate(templateName);
var route = RouteTable.Routes["Umbraco_default"];
var routeData = new RouteData() {Route = route};
var umbracoContext = GetUmbracoContext("~/dummy-page", template.Id, routeData, true);
var httpContext = GetHttpContextFactory(url, routeData).HttpContext;
var publishedRouter = CreatePublishedRouter();
var frequest = publishedRouter.CreateRequest(umbracoContext);
frequest.PublishedContent = umbracoContext.Content.GetById(1172);
@@ -152,7 +156,7 @@ namespace Umbraco.Tests.Routing
var handler = new RenderRouteHandler(umbracoContext, new TestControllerFactory(umbracoContextAccessor, Mock.Of<ILogger>(), context =>
{
var membershipHelper = new MembershipHelper(
umbracoContext.HttpContext, Mock.Of<IPublishedMemberCache>(), Mock.Of<MembersMembershipProvider>(), Mock.Of<RoleProvider>(), Mock.Of<IMemberService>(), Mock.Of<IMemberTypeService>(), Mock.Of<IPublicAccessService>(), AppCaches.Disabled, Mock.Of<ILogger>(), ShortStringHelper, Mock.Of<IEntityService>());
httpContext, Mock.Of<IPublishedMemberCache>(), Mock.Of<MembersMembershipProvider>(), Mock.Of<RoleProvider>(), Mock.Of<IMemberService>(), Mock.Of<IMemberTypeService>(), Mock.Of<IPublicAccessService>(), AppCaches.Disabled, Mock.Of<ILogger>(), ShortStringHelper, Mock.Of<IEntityService>());
return new CustomDocumentController(Factory.GetInstance<IGlobalSettings>(),
umbracoContextAccessor,
Factory.GetInstance<ServiceContext>(),
@@ -161,7 +165,7 @@ namespace Umbraco.Tests.Routing
new UmbracoHelper(Mock.Of<IPublishedContent>(), Mock.Of<ITagQuery>(), Mock.Of<ICultureDictionaryFactory>(), Mock.Of<IUmbracoComponentRenderer>(), Mock.Of<IPublishedContentQuery>(), membershipHelper));
}), ShortStringHelper);
handler.GetHandlerForRoute(umbracoContext.HttpContext.Request.RequestContext, frequest);
handler.GetHandlerForRoute(httpContext.Request.RequestContext, frequest);
Assert.AreEqual("CustomDocument", routeData.Values["controller"].ToString());
Assert.AreEqual(
//global::umbraco.cms.helpers.Casing.SafeAlias(template.Alias),
@@ -111,7 +111,7 @@ namespace Umbraco.Tests.Scoping
filePermissionHelper);
}
protected UmbracoContext GetUmbracoContextNu(string url, int templateId = 1234, RouteData routeData = null, bool setSingleton = false, IUmbracoSettingsSection umbracoSettings = null, IEnumerable<IUrlProvider> urlProviders = null)
protected IUmbracoContext GetUmbracoContextNu(string url, int templateId = 1234, RouteData routeData = null, bool setSingleton = false, IUmbracoSettingsSection umbracoSettings = null, IEnumerable<IUrlProvider> urlProviders = null)
{
// ensure we have a PublishedSnapshotService
var service = PublishedSnapshotService as PublishedSnapshotService;
@@ -69,7 +69,7 @@ namespace Umbraco.Tests.Templates
var media = new Mock<IPublishedContent>();
media.Setup(x => x.ContentType).Returns(mediaType);
var mediaUrlProvider = new Mock<IMediaUrlProvider>();
mediaUrlProvider.Setup(x => x.GetMediaUrl(It.IsAny<UmbracoContext>(), It.IsAny<IPublishedContent>(), It.IsAny<string>(), It.IsAny<UrlMode>(), It.IsAny<string>(), It.IsAny<Uri>()))
mediaUrlProvider.Setup(x => x.GetMediaUrl(It.IsAny<IUmbracoContext>(), It.IsAny<IPublishedContent>(), It.IsAny<string>(), It.IsAny<UrlMode>(), It.IsAny<string>(), It.IsAny<Uri>()))
.Returns(UrlInfo.Url("/media/1001/my-image.jpg"));
var umbracoContextAccessor = new TestUmbracoContextAccessor();
@@ -52,7 +52,7 @@ namespace Umbraco.Tests.Templates
//setup a mock url provider which we'll use for testing
var contentUrlProvider = new Mock<IUrlProvider>();
contentUrlProvider
.Setup(x => x.GetUrl(It.IsAny<UmbracoContext>(), It.IsAny<IPublishedContent>(), It.IsAny<UrlMode>(), It.IsAny<string>(), It.IsAny<Uri>()))
.Setup(x => x.GetUrl(It.IsAny<IUmbracoContext>(), It.IsAny<IPublishedContent>(), It.IsAny<UrlMode>(), It.IsAny<string>(), It.IsAny<Uri>()))
.Returns(UrlInfo.Url("/my-test-url"));
var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty<string>(), Enumerable.Empty<PublishedPropertyType>(), ContentVariation.Nothing);
var publishedContent = new Mock<IPublishedContent>();
@@ -63,7 +63,7 @@ namespace Umbraco.Tests.Templates
var media = new Mock<IPublishedContent>();
media.Setup(x => x.ContentType).Returns(mediaType);
var mediaUrlProvider = new Mock<IMediaUrlProvider>();
mediaUrlProvider.Setup(x => x.GetMediaUrl(It.IsAny<UmbracoContext>(), It.IsAny<IPublishedContent>(), It.IsAny<string>(), It.IsAny<UrlMode>(), It.IsAny<string>(), It.IsAny<Uri>()))
mediaUrlProvider.Setup(x => x.GetMediaUrl(It.IsAny<IUmbracoContext>(), It.IsAny<IPublishedContent>(), It.IsAny<string>(), It.IsAny<UrlMode>(), It.IsAny<string>(), It.IsAny<Uri>()))
.Returns(UrlInfo.Url("/media/1001/my-image.jpg"));
var umbracoContextAccessor = new TestUmbracoContextAccessor();
+3 -1
View File
@@ -15,6 +15,7 @@ using Umbraco.Core.Strings;
using Umbraco.Tests.PublishedContent;
using Umbraco.Tests.TestHelpers.Stubs;
using Umbraco.Tests.Testing.Objects.Accessors;
using Umbraco.Web;
using Umbraco.Web.Composing;
using Umbraco.Web.Models.PublishedContent;
using Umbraco.Web.Routing;
@@ -98,7 +99,8 @@ namespace Umbraco.Tests.TestHelpers
container?.TryGetInstance<ServiceContext>() ?? ServiceContext.CreatePartial(),
new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>()),
container?.TryGetInstance<IUmbracoSettingsSection>() ?? Current.Factory.GetInstance<IUmbracoSettingsSection>(),
Mock.Of<IUserService>());
Mock.Of<IUserService>(),
Mock.Of<IHttpContextAccessor>());
}
}
}
@@ -102,7 +102,7 @@ namespace Umbraco.Tests.TestHelpers.ControllerTesting
var backofficeIdentity = (UmbracoBackOfficeIdentity) owinContext.Authentication.User.Identity;
var webSecurity = new Mock<WebSecurity>(null, null, globalSettings, TestHelper.IOHelper);
var webSecurity = new Mock<IWebSecurity>();
//mock CurrentUser
var groups = new List<ReadOnlyUserGroup>();
@@ -151,7 +151,7 @@ namespace Umbraco.Tests.TestHelpers.ControllerTesting
umbracoContextAccessor.UmbracoContext = umbCtx;
var urlHelper = new Mock<IUrlProvider>();
urlHelper.Setup(provider => provider.GetUrl(It.IsAny<UmbracoContext>(), It.IsAny<IPublishedContent>(), It.IsAny<UrlMode>(), It.IsAny<string>(), It.IsAny<Uri>()))
urlHelper.Setup(provider => provider.GetUrl(It.IsAny<IUmbracoContext>(), It.IsAny<IPublishedContent>(), It.IsAny<UrlMode>(), It.IsAny<string>(), It.IsAny<Uri>()))
.Returns(UrlInfo.Url("/hello/world/1234"));
var membershipHelper = new MembershipHelper(umbCtx.HttpContext, Mock.Of<IPublishedMemberCache>(), Mock.Of<MembersMembershipProvider>(), Mock.Of<RoleProvider>(), Mock.Of<IMemberService>(), Mock.Of<IMemberTypeService>(), Mock.Of<IPublicAccessService>(), AppCaches.Disabled, Mock.Of<ILogger>(), new MockShortStringHelper(), Mock.Of<IEntityService>());
@@ -4,7 +4,7 @@ namespace Umbraco.Tests.TestHelpers.Stubs
{
internal class TestLastChanceFinder : IContentLastChanceFinder
{
public bool TryFindContent(PublishedRequest frequest)
public bool TryFindContent(IPublishedRequest frequest)
{
return false;
}
@@ -109,7 +109,7 @@ namespace Umbraco.Tests.TestHelpers
/// </summary>
/// <returns>An Umbraco context.</returns>
/// <remarks>This should be the minimum Umbraco context.</remarks>
public UmbracoContext GetUmbracoContextMock(IUmbracoContextAccessor accessor = null)
public IUmbracoContext GetUmbracoContextMock(IUmbracoContextAccessor accessor = null)
{
var httpContext = Mock.Of<HttpContextBase>();
@@ -337,5 +337,16 @@ namespace Umbraco.Tests.TestHelpers
}
#endregion
public IHttpContextAccessor GetHttpContextAccessor(HttpContextBase httpContextBase = null)
{
var mock = new Mock<IHttpContextAccessor>();
var httpContext = UmbracoContextFactory.EnsureHttpContext(httpContextBase);
mock.Setup(x => x.HttpContext).Returns(httpContext);
return mock.Object;
}
}
}
@@ -31,6 +31,7 @@ using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Tests.LegacyXmlPublishedCache;
using Umbraco.Tests.Testing.Objects.Accessors;
using Umbraco.Web.WebApi;
namespace Umbraco.Tests.TestHelpers
{
@@ -81,6 +82,9 @@ namespace Umbraco.Tests.TestHelpers
.Clear()
.Add(() => Composition.TypeLoader.GetDataEditors());
Composition.WithCollectionBuilder<UmbracoApiControllerTypeCollectionBuilder>()
.Add(Composition.TypeLoader.GetUmbracoApiControllers());
Composition.RegisterUnique(f =>
{
if (Options.Database == UmbracoTestOptions.Database.None)
@@ -357,7 +361,7 @@ namespace Umbraco.Tests.TestHelpers
}
}
protected UmbracoContext GetUmbracoContext(string url, int templateId = 1234, RouteData routeData = null, bool setSingleton = false, IUmbracoSettingsSection umbracoSettings = null, IEnumerable<IUrlProvider> urlProviders = null, IEnumerable<IMediaUrlProvider> mediaUrlProviders = null, IGlobalSettings globalSettings = null, IPublishedSnapshotService snapshotService = null)
protected IUmbracoContext GetUmbracoContext(string url, int templateId = 1234, RouteData routeData = null, bool setSingleton = false, IUmbracoSettingsSection umbracoSettings = null, IEnumerable<IUrlProvider> urlProviders = null, IEnumerable<IMediaUrlProvider> mediaUrlProviders = null, IGlobalSettings globalSettings = null, IPublishedSnapshotService snapshotService = null)
{
// ensure we have a PublishedCachesService
var service = snapshotService ?? PublishedSnapshotService as XmlPublishedSnapshotService;
@@ -5,6 +5,6 @@ namespace Umbraco.Tests.Testing.Objects.Accessors
{
public class NoHttpContextAccessor : IHttpContextAccessor
{
public HttpContext HttpContext { get; set; } = null;
public HttpContextBase HttpContext { get; set; } = null;
}
}
@@ -4,13 +4,13 @@ namespace Umbraco.Tests.Testing.Objects.Accessors
{
public class TestUmbracoContextAccessor : IUmbracoContextAccessor
{
public UmbracoContext UmbracoContext { get; set; }
public IUmbracoContext UmbracoContext { get; set; }
public TestUmbracoContextAccessor()
{
}
public TestUmbracoContextAccessor(UmbracoContext umbracoContext)
public TestUmbracoContextAccessor(IUmbracoContext umbracoContext)
{
UmbracoContext = umbracoContext;
}
@@ -1,6 +1,7 @@
using System;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.Security;
using Moq;
using NUnit.Framework;
@@ -71,7 +72,7 @@ namespace Umbraco.Tests.Testing.TestingTests
Mock.Of<ICultureDictionaryFactory>(),
Mock.Of<IUmbracoComponentRenderer>(),
Mock.Of<IPublishedContentQuery>(),
new MembershipHelper(umbracoContext.HttpContext, Mock.Of<IPublishedMemberCache>(), Mock.Of<MembersMembershipProvider>(), Mock.Of<RoleProvider>(), Mock.Of<IMemberService>(), Mock.Of<IMemberTypeService>(), Mock.Of<IPublicAccessService>(), AppCaches.Disabled, Mock.Of<ILogger>(), ShortStringHelper, Mock.Of<IEntityService>()));
new MembershipHelper(Mock.Of<HttpContextBase>(), Mock.Of<IPublishedMemberCache>(), Mock.Of<MembersMembershipProvider>(), Mock.Of<RoleProvider>(), Mock.Of<IMemberService>(), Mock.Of<IMemberTypeService>(), Mock.Of<IPublicAccessService>(), AppCaches.Disabled, Mock.Of<ILogger>(), ShortStringHelper, Mock.Of<IEntityService>()));
Assert.Pass();
}
@@ -81,7 +82,7 @@ namespace Umbraco.Tests.Testing.TestingTests
var umbracoContext = TestObjects.GetUmbracoContextMock();
var urlProviderMock = new Mock<IUrlProvider>();
urlProviderMock.Setup(provider => provider.GetUrl(It.IsAny<UmbracoContext>(), It.IsAny<IPublishedContent>(), It.IsAny<UrlMode>(), It.IsAny<string>(), It.IsAny<Uri>()))
urlProviderMock.Setup(provider => provider.GetUrl(It.IsAny<IUmbracoContext>(), It.IsAny<IPublishedContent>(), It.IsAny<UrlMode>(), It.IsAny<string>(), It.IsAny<Uri>()))
.Returns(UrlInfo.Url("/hello/world/1234"));
var urlProvider = urlProviderMock.Object;
@@ -103,7 +104,7 @@ namespace Umbraco.Tests.Testing.TestingTests
var memberService = Mock.Of<IMemberService>();
var memberTypeService = Mock.Of<IMemberTypeService>();
var membershipProvider = new MembersMembershipProvider(memberService, memberTypeService, Mock.Of<IUmbracoVersion>(), TestHelper.GetHostingEnvironment(), TestHelper.GetIpResolver());
var membershipHelper = new MembershipHelper(umbracoContext.HttpContext, Mock.Of<IPublishedMemberCache>(), membershipProvider, Mock.Of<RoleProvider>(), memberService, memberTypeService, Mock.Of<IPublicAccessService>(), AppCaches.Disabled, logger, ShortStringHelper, Mock.Of<IEntityService>());
var membershipHelper = new MembershipHelper(Mock.Of<HttpContextBase>(), Mock.Of<IPublishedMemberCache>(), membershipProvider, Mock.Of<RoleProvider>(), memberService, memberTypeService, Mock.Of<IPublicAccessService>(), AppCaches.Disabled, logger, ShortStringHelper, Mock.Of<IEntityService>());
var umbracoHelper = new UmbracoHelper(Mock.Of<IPublishedContent>(), Mock.Of<ITagQuery>(), Mock.Of<ICultureDictionaryFactory>(), Mock.Of<IUmbracoComponentRenderer>(), Mock.Of<IPublishedContentQuery>(), membershipHelper);
var umbracoMapper = new UmbracoMapper(new MapDefinitionCollection(new[] { Mock.Of<IMapDefinition>() }));
@@ -137,6 +137,7 @@ namespace Umbraco.Tests.Testing
protected IMapperCollection Mappers => Factory.GetInstance<IMapperCollection>();
protected UmbracoMapper Mapper => Factory.GetInstance<UmbracoMapper>();
protected IHttpContextAccessor HttpContextAccessor => Factory.GetInstance<IHttpContextAccessor>();
protected IRuntimeState RuntimeState => ComponentTests.MockRuntimeState(RuntimeLevel.Run);
#endregion
@@ -444,6 +445,9 @@ namespace Umbraco.Tests.Testing
Composition.WithCollectionBuilder<DataEditorCollectionBuilder>();
Composition.RegisterUnique<PropertyEditorCollection>();
Composition.RegisterUnique<ParameterEditorCollection>();
Composition.RegisterUnique<IHttpContextAccessor>(TestObjects.GetHttpContextAccessor());
}
#endregion
@@ -124,7 +124,7 @@ namespace Umbraco.Tests.Web.Mvc
Mock.Of<ICultureDictionaryFactory>(),
Mock.Of<IUmbracoComponentRenderer>(),
Mock.Of<IPublishedContentQuery>(query => query.Content(2) == content.Object),
new MembershipHelper(umbracoContext.HttpContext, Mock.Of<IPublishedMemberCache>(), Mock.Of<MembersMembershipProvider>(), Mock.Of<RoleProvider>(), Mock.Of<IMemberService>(), Mock.Of<IMemberTypeService>(), Mock.Of<IPublicAccessService>(), AppCaches.Disabled, Mock.Of<ILogger>(), ShortStringHelper, Mock.Of<IEntityService>()));
new MembershipHelper(Mock.Of<HttpContextBase>(), Mock.Of<IPublishedMemberCache>(), Mock.Of<MembersMembershipProvider>(), Mock.Of<RoleProvider>(), Mock.Of<IMemberService>(), Mock.Of<IMemberTypeService>(), Mock.Of<IPublicAccessService>(), AppCaches.Disabled, Mock.Of<ILogger>(), ShortStringHelper, Mock.Of<IEntityService>()));
var ctrl = new TestSurfaceController(umbracoContextAccessor, helper);
var result = ctrl.GetContent(2) as PublishedContentResult;
@@ -159,7 +159,7 @@ namespace Umbraco.Tests.Web.Mvc
var content = Mock.Of<IPublishedContent>(publishedContent => publishedContent.Id == 12345);
var contextBase = umbracoContext.HttpContext;
var publishedRouter = BaseWebTest.CreatePublishedRouter(TestObjects.GetUmbracoSettings().WebRouting);
var frequest = publishedRouter.CreateRequest(umbracoContext, new Uri("http://localhost/test"));
frequest.PublishedContent = content;
@@ -173,7 +173,7 @@ namespace Umbraco.Tests.Web.Mvc
routeData.DataTokens.Add(Core.Constants.Web.UmbracoRouteDefinitionDataToken, routeDefinition);
var ctrl = new TestSurfaceController(umbracoContextAccessor, new UmbracoHelper());
ctrl.ControllerContext = new ControllerContext(contextBase, routeData, ctrl);
ctrl.ControllerContext = new ControllerContext(Mock.Of<HttpContextBase>(), routeData, ctrl);
var result = ctrl.GetContentFromCurrentPage() as PublishedContentResult;
@@ -404,7 +404,7 @@ namespace Umbraco.Tests.Web.Mvc
return context;
}
protected UmbracoContext GetUmbracoContext(ILogger logger, IUmbracoSettingsSection umbracoSettings, string url, int templateId, RouteData routeData = null, bool setSingleton = false)
protected IUmbracoContext GetUmbracoContext(ILogger logger, IUmbracoSettingsSection umbracoSettings, string url, int templateId, RouteData routeData = null, bool setSingleton = false)
{
var svcCtx = GetServiceContext();
@@ -28,12 +28,22 @@ namespace Umbraco.Web
public class BatchedDatabaseServerMessenger : DatabaseServerMessenger
{
private readonly IUmbracoDatabaseFactory _databaseFactory;
private readonly IHttpContextAccessor _httpContextAccessor;
public BatchedDatabaseServerMessenger(
IRuntimeState runtime, IUmbracoDatabaseFactory databaseFactory, IScopeProvider scopeProvider, ISqlContext sqlContext, IProfilingLogger proflog, DatabaseServerMessengerOptions options, IHostingEnvironment hostingEnvironment, CacheRefresherCollection cacheRefreshers)
IRuntimeState runtime,
IUmbracoDatabaseFactory databaseFactory,
IScopeProvider scopeProvider,
ISqlContext sqlContext,
IProfilingLogger proflog,
DatabaseServerMessengerOptions options,
IHostingEnvironment hostingEnvironment,
CacheRefresherCollection cacheRefreshers,
IHttpContextAccessor httpContextAccessor)
: base(runtime, scopeProvider, sqlContext, proflog, true, options, hostingEnvironment, cacheRefreshers)
{
_databaseFactory = databaseFactory;
_httpContextAccessor = httpContextAccessor;
}
// invoked by DatabaseServerRegistrarAndMessengerComponent
@@ -105,7 +115,7 @@ namespace Umbraco.Web
// try get the http context from the UmbracoContext, we do this because in the case we are launching an async
// thread and we know that the cache refreshers will execute, we will ensure the UmbracoContext and therefore we
// can get the http context from it
var httpContext = (Current.UmbracoContext == null ? null : Current.UmbracoContext.HttpContext)
var httpContext = (_httpContextAccessor.HttpContext)
// if this is null, it could be that an async thread is calling this method that we weren't aware of and the UmbracoContext
// wasn't ensured at the beginning of the thread. We can try to see if the HttpContext.Current is available which might be
// the case if the asp.net synchronization context has kicked in
+1 -1
View File
@@ -108,7 +108,7 @@ namespace Umbraco.Web.Composing
#region Web Getters
public static UmbracoContext UmbracoContext
public static IUmbracoContext UmbracoContext
=> UmbracoContextAccessor.UmbracoContext;
public static UmbracoHelper UmbracoHelper
@@ -14,7 +14,7 @@ namespace Umbraco.Web.Editors
Model = (T)baseArgs.Model;
}
public EditorModelEventArgs(T model, UmbracoContext umbracoContext)
public EditorModelEventArgs(T model, IUmbracoContext umbracoContext)
: base(model, umbracoContext)
{
Model = model;
@@ -34,13 +34,13 @@ namespace Umbraco.Web.Editors
public class EditorModelEventArgs : EventArgs
{
public EditorModelEventArgs(object model, UmbracoContext umbracoContext)
public EditorModelEventArgs(object model, IUmbracoContext umbracoContext)
{
Model = model;
UmbracoContext = umbracoContext;
}
public object Model { get; set; }
public UmbracoContext UmbracoContext { get; }
public IUmbracoContext UmbracoContext { get; }
}
}
@@ -83,7 +83,7 @@ namespace Umbraco.Web.Editors.Filters
/// <param name="actionContext"></param>
/// <param name="contentItem"></param>
/// <param name="webSecurity"></param>
private bool ValidateUserAccess(ContentItemSave contentItem, HttpActionContext actionContext, WebSecurity webSecurity)
private bool ValidateUserAccess(ContentItemSave contentItem, HttpActionContext actionContext, IWebSecurity webSecurity)
{
//We now need to validate that the user is allowed to be doing what they are doing.
@@ -33,7 +33,7 @@ namespace Umbraco.Web.Editors.Filters
_paramName = paramName;
}
private UmbracoContext GetUmbracoContext()
private IUmbracoContext GetUmbracoContext()
{
return _umbracoContextAccessor?.UmbracoContext ?? Composing.Current.UmbracoContext;
}
@@ -11,8 +11,13 @@ using System.Web.SessionState;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Mvc;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Mapping;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Persistence;
using Umbraco.Core.Services;
using Umbraco.Core.Strings;
@@ -30,18 +35,39 @@ namespace Umbraco.Web.Editors
public class MacroRenderingController : UmbracoAuthorizedJsonController, IRequiresSessionState
{
private readonly IMacroService _macroService;
private readonly IContentService _contentService;
private readonly IShortStringHelper _shortStringHelper;
private readonly IUmbracoComponentRenderer _componentRenderer;
private readonly IVariationContextAccessor _variationContextAccessor;
public MacroRenderingController(IUmbracoComponentRenderer componentRenderer, IVariationContextAccessor variationContextAccessor, IMacroService macroService, IContentService contentService, IShortStringHelper shortStringHelper)
public MacroRenderingController(
IGlobalSettings globalSettings,
IUmbracoContextAccessor umbracoContextAccessor,
ISqlContext sqlContext,
ServiceContext services,
AppCaches appCaches,
IProfilingLogger logger,
IRuntimeState runtimeState,
UmbracoHelper umbracoHelper,
IShortStringHelper shortStringHelper,
UmbracoMapper umbracoMapper,
IUmbracoComponentRenderer componentRenderer,
IVariationContextAccessor variationContextAccessor,
IMacroService macroService)
: base(
globalSettings,
umbracoContextAccessor,
sqlContext,
services,
appCaches,
logger,
runtimeState,
umbracoHelper,
shortStringHelper,
umbracoMapper)
{
_componentRenderer = componentRenderer;
_variationContextAccessor = variationContextAccessor;
_macroService = macroService;
_contentService = contentService;
_shortStringHelper = shortStringHelper;
}
/// <summary>
@@ -162,7 +188,7 @@ namespace Umbraco.Web.Editors
var macroName = model.Filename.TrimEnd(".cshtml");
var macro = new Macro(_shortStringHelper)
var macro = new Macro(ShortStringHelper)
{
Alias = macroName.ToSafeAlias(ShortStringHelper),
Name = macroName,
@@ -7,6 +7,7 @@ using Umbraco.Core.Mapping;
using Umbraco.Core.Persistence;
using Umbraco.Core.Services;
using Umbraco.Core.Strings;
using Umbraco.Web.Composing;
using Umbraco.Web.WebApi;
using Umbraco.Web.WebApi.Filters;
@@ -25,6 +26,7 @@ namespace Umbraco.Web.Editors
{
protected UmbracoAuthorizedJsonController()
{
ShortStringHelper = Current.ShortStringHelper;
}
protected UmbracoAuthorizedJsonController(IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ISqlContext sqlContext, ServiceContext services, AppCaches appCaches, IProfilingLogger logger, IRuntimeState runtimeState, UmbracoHelper umbracoHelper, IShortStringHelper shortStringHelper, UmbracoMapper umbracoMapper)
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Helpers;
@@ -8,6 +9,9 @@ using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
using Umbraco.Web.Mvc;
using Umbraco.Web.Security;
using Current = Umbraco.Web.Composing.Current;
@@ -56,14 +60,14 @@ namespace Umbraco.Web
/// <remarks>
/// See: http://issues.umbraco.org/issue/U4-1614
/// </remarks>
public static MvcHtmlString PreviewBadge(this HtmlHelper helper)
public static MvcHtmlString PreviewBadge(this HtmlHelper helper, IHttpContextAccessor httpContextAccessor, IGlobalSettings globalSettings, IIOHelper ioHelper, IUmbracoSettingsSection umbracoSettingsSection)
{
if (Current.UmbracoContext.InPreviewMode)
{
var htmlBadge =
String.Format(Current.Configs.Settings().Content.PreviewBadge,
Current.IOHelper.ResolveUrl(Current.Configs.Global().UmbracoPath),
Current.UmbracoContext.HttpContext.Server.UrlEncode(Current.UmbracoContext.HttpContext.Request.Path),
String.Format(umbracoSettingsSection.Content.PreviewBadge,
ioHelper.ResolveUrl(globalSettings.UmbracoPath),
WebUtility.UrlEncode(httpContextAccessor.HttpContext.Request.Path),
Current.UmbracoContext.PublishedRequest.PublishedContent.Id);
return new MvcHtmlString(htmlBadge);
}
@@ -12,13 +12,13 @@ namespace Umbraco.Web
_httpContextAccessor = httpContextAccessor;
}
public UmbracoContext UmbracoContext
public IUmbracoContext UmbracoContext
{
get
{
var httpContext = _httpContextAccessor.HttpContext;
if (httpContext == null) throw new Exception("oops:httpContext");
return (UmbracoContext) httpContext.Items[HttpContextItemKey];
return (IUmbracoContext) httpContext.Items[HttpContextItemKey];
}
set
@@ -3,7 +3,7 @@
/// <summary>
/// Implements a hybrid <see cref="IUmbracoContextAccessor"/>.
/// </summary>
internal class HybridUmbracoContextAccessor : HybridAccessorBase<UmbracoContext>, IUmbracoContextAccessor
internal class HybridUmbracoContextAccessor : HybridAccessorBase<IUmbracoContext>, IUmbracoContextAccessor
{
/// <summary>
/// Initializes a new instance of the <see cref="HybridUmbracoContextAccessor"/> class.
@@ -18,7 +18,7 @@
/// <summary>
/// Gets or sets the <see cref="UmbracoContext"/> object.
/// </summary>
public UmbracoContext UmbracoContext
public IUmbracoContext UmbracoContext
{
get => Value;
set => Value = value;
+1 -1
View File
@@ -4,6 +4,6 @@ namespace Umbraco.Web
{
public interface IHttpContextAccessor
{
HttpContext HttpContext { get; set; }
HttpContextBase HttpContext { get; set; }
}
}
+3 -3
View File
@@ -3,15 +3,15 @@
namespace Umbraco.Web
{
/// <summary>
/// Creates and manages <see cref="UmbracoContext"/> instances.
/// Creates and manages <see cref="IUmbracoContext"/> instances.
/// </summary>
public interface IUmbracoContextFactory
{
/// <summary>
/// Ensures that a current <see cref="UmbracoContext"/> exists.
/// Ensures that a current <see cref="IUmbracoContext"/> exists.
/// </summary>
/// <remarks>
/// <para>If an <see cref="UmbracoContext"/> is already registered in the
/// <para>If an <see cref="IUmbracoContext"/> is already registered in the
/// <see cref="IUmbracoContextAccessor"/>, returns a non-root reference to it.
/// Otherwise, create a new instance, registers it, and return a root reference
/// to it.</para>
@@ -27,7 +27,7 @@ namespace Umbraco.Web.Install
private IRuntimeState RuntimeState => _runtimeState ?? Current.RuntimeState;
private UmbracoContext UmbracoContext => _umbracoContextAccessor?.UmbracoContext ?? Current.UmbracoContext;
private IUmbracoContext UmbracoContext => _umbracoContextAccessor?.UmbracoContext ?? Current.UmbracoContext;
/// <summary>
/// THIS SHOULD BE ONLY USED FOR UNIT TESTS
@@ -19,7 +19,7 @@ namespace Umbraco.Web.Install
private IRuntimeState RuntimeState => _runtimeState ?? Current.RuntimeState;
private UmbracoContext UmbracoContext => _umbracoContextAccessor?.UmbracoContext ?? Current.UmbracoContext;
private IUmbracoContext UmbracoContext => _umbracoContextAccessor?.UmbracoContext ?? Current.UmbracoContext;
/// <summary>
/// THIS SHOULD BE ONLY USED FOR UNIT TESTS
+2 -2
View File
@@ -25,11 +25,11 @@ namespace Umbraco.Web.Install
private readonly IConnectionStrings _connectionStrings;
private InstallationType? _installationType;
public InstallHelper(IUmbracoContextAccessor umbracoContextAccessor,
public InstallHelper(IHttpContextAccessor httpContextAccessor,
DatabaseBuilder databaseBuilder,
ILogger logger, IGlobalSettings globalSettings, IUmbracoVersion umbracoVersion, IConnectionStrings connectionStrings)
{
_httpContext = umbracoContextAccessor.UmbracoContext.HttpContext;
_httpContext = httpContextAccessor.HttpContext;
_logger = logger;
_globalSettings = globalSettings;
_umbracoVersion = umbracoVersion;
@@ -14,13 +14,13 @@ namespace Umbraco.Web.Install.InstallSteps
PerformsAppRestart = true)]
internal class StarterKitInstallStep : InstallSetupStep<object>
{
private readonly HttpContextBase _httContext;
private readonly IHttpContextAccessor _httContextAccessor;
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
private readonly IPackagingService _packagingService;
public StarterKitInstallStep(HttpContextBase httContext, IUmbracoContextAccessor umbracoContextAccessor, IPackagingService packagingService)
public StarterKitInstallStep(IHttpContextAccessor httContextAccessor, IUmbracoContextAccessor umbracoContextAccessor, IPackagingService packagingService)
{
_httContext = httContext;
_httContextAccessor = httContextAccessor;
_umbracoContextAccessor = umbracoContextAccessor;
_packagingService = packagingService;
}
@@ -34,7 +34,7 @@ namespace Umbraco.Web.Install.InstallSteps
InstallBusinessLogic(packageId);
UmbracoApplication.Restart(_httContext);
UmbracoApplication.Restart(_httContextAccessor.HttpContext);
return Task.FromResult<InstallSetupResult>(null);
}
+5 -3
View File
@@ -28,8 +28,9 @@ namespace Umbraco.Web.Macros
private readonly IMacroService _macroService;
private readonly IIOHelper _ioHelper;
private readonly IUserService _userService;
private readonly IHttpContextAccessor _httpContextAccessor;
public MacroRenderer(IProfilingLogger plogger, IUmbracoContextAccessor umbracoContextAccessor, IContentSection contentSection, ILocalizedTextService textService, AppCaches appCaches, IMacroService macroService, IUserService userService, IIOHelper ioHelper)
public MacroRenderer(IProfilingLogger plogger, IUmbracoContextAccessor umbracoContextAccessor, IContentSection contentSection, ILocalizedTextService textService, AppCaches appCaches, IMacroService macroService, IUserService userService, IHttpContextAccessor httpContextAccessor, IIOHelper ioHelper)
{
_plogger = plogger ?? throw new ArgumentNullException(nameof(plogger));
_umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor));
@@ -39,6 +40,7 @@ namespace Umbraco.Web.Macros
_macroService = macroService ?? throw new ArgumentNullException(nameof(macroService));
_ioHelper = ioHelper ?? throw new ArgumentNullException(nameof(ioHelper));
_userService = userService ?? throw new ArgumentNullException(nameof(userService));
_httpContextAccessor = httpContextAccessor;
}
#region MacroContent cache
@@ -58,7 +60,7 @@ namespace Umbraco.Web.Macros
{
object key = 0;
if (_umbracoContextAccessor.UmbracoContext.HttpContext?.User?.Identity?.IsAuthenticated ?? false)
if (_httpContextAccessor.HttpContext?.User?.Identity?.IsAuthenticated ?? false)
{
//ugh, membershipproviders :(
var provider = MembershipProviderExtensions.GetMembersMembershipProvider();
@@ -393,7 +395,7 @@ namespace Umbraco.Web.Macros
return attributeValue;
}
var context = _umbracoContextAccessor.UmbracoContext.HttpContext;
var context = _httpContextAccessor.HttpContext;
foreach (var token in tokens)
{
@@ -16,7 +16,7 @@ namespace Umbraco.Web.Macros
public class PartialViewMacroEngine
{
private readonly Func<HttpContextBase> _getHttpContext;
private readonly Func<UmbracoContext> _getUmbracoContext;
private readonly Func<IUmbracoContext> _getUmbracoContext;
public PartialViewMacroEngine()
{
@@ -40,7 +40,7 @@ namespace Umbraco.Web.Macros
/// </summary>
/// <param name="httpContext"></param>
/// <param name="umbracoContext"> </param>
internal PartialViewMacroEngine(HttpContextBase httpContext, UmbracoContext umbracoContext)
internal PartialViewMacroEngine(HttpContextBase httpContext, IUmbracoContext umbracoContext)
{
_getHttpContext = () => httpContext;
_getUmbracoContext = () => umbracoContext;
@@ -17,21 +17,21 @@ namespace Umbraco.Web.Macros
/// <summary>
/// Legacy class used by macros which converts a published content item into a hashset of values
/// </summary>
internal class PublishedContentHashtableConverter
public class PublishedContentHashtableConverter
{
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="PublishedContentHashtableConverter"/> class for a published document request.
/// </summary>
/// <param name="frequest">The <see cref="PublishedRequest"/> pointing to the document.</param>
/// <param name="frequest">The <see cref="IPublishedRequest"/> pointing to the document.</param>
/// <param name="userService">The <see cref="IUserService"/>.</param>
/// <remarks>
/// The difference between creating the page with PublishedRequest vs an IPublishedContent item is
/// that the PublishedRequest takes into account how a template is assigned during the routing process whereas
/// with an IPublishedContent item, the template id is assigned purely based on the default.
/// </remarks>
internal PublishedContentHashtableConverter(PublishedRequest frequest, IUserService userService)
internal PublishedContentHashtableConverter(IPublishedRequest frequest, IUserService userService)
{
if (!frequest.HasPublishedContent)
throw new ArgumentException("Document request has no node.", nameof(frequest));
@@ -23,15 +23,17 @@ namespace Umbraco.Web.Models.Mapping
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
private readonly ContentAppFactoryCollection _contentAppDefinitions;
private readonly ILocalizedTextService _localizedTextService;
private readonly IHttpContextAccessor _httpContextAccessor;
public CommonMapper(IUserService userService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor,
ContentAppFactoryCollection contentAppDefinitions, ILocalizedTextService localizedTextService)
ContentAppFactoryCollection contentAppDefinitions, ILocalizedTextService localizedTextService, IHttpContextAccessor httpContextAccessor)
{
_userService = userService;
_contentTypeBaseServiceProvider = contentTypeBaseServiceProvider;
_umbracoContextAccessor = umbracoContextAccessor;
_contentAppDefinitions = contentAppDefinitions;
_localizedTextService = localizedTextService;
_httpContextAccessor = httpContextAccessor;
}
public UserProfile GetOwner(IContentBase source, MapperContext context)
@@ -65,19 +67,19 @@ namespace Umbraco.Web.Models.Mapping
public string GetTreeNodeUrl<TController>(IContentBase source)
where TController : ContentTreeControllerBase
{
var umbracoContext = _umbracoContextAccessor.UmbracoContext;
if (umbracoContext == null) return null;
var httpContext = _httpContextAccessor.HttpContext;
if (httpContext == null) return null;
var urlHelper = new UrlHelper(umbracoContext.HttpContext.Request.RequestContext);
var urlHelper = new UrlHelper(httpContext.Request.RequestContext);
return urlHelper.GetUmbracoApiService<TController>(controller => controller.GetTreeNode(source.Key.ToString("N"), null));
}
public string GetMemberTreeNodeUrl(IContentBase source)
{
var umbracoContext = _umbracoContextAccessor.UmbracoContext;
if (umbracoContext == null) return null;
var httpContext = _httpContextAccessor.HttpContext;
if (httpContext == null) return null;
var urlHelper = new UrlHelper(umbracoContext.HttpContext.Request.RequestContext);
var urlHelper = new UrlHelper(httpContext.Request.RequestContext);
return urlHelper.GetUmbracoApiService<MemberTreeController>(controller => controller.GetTreeNode(source.Key.ToString("N"), null));
}
@@ -13,7 +13,7 @@ namespace Umbraco.Web.Models.Mapping
_umbracoContextAccessor = umbracoContextAccessor;
}
private UmbracoContext UmbracoContext => _umbracoContextAccessor.UmbracoContext;
private IUmbracoContext UmbracoContext => _umbracoContextAccessor.UmbracoContext;
public void DefineMaps(UmbracoMapper mapper)
{
@@ -10,10 +10,10 @@ namespace Umbraco.Web.Mvc
/// </summary>
/// <param name="controllerContext">The controller context.</param>
/// <returns>The Umbraco context.</returns>
public static UmbracoContext GetUmbracoContext(this ControllerContext controllerContext)
public static IUmbracoContext GetUmbracoContext(this ControllerContext controllerContext)
{
var o = controllerContext.GetDataTokenInViewContextHierarchy(Core.Constants.Web.UmbracoContextDataToken);
return o != null ? o as UmbracoContext : Current.UmbracoContext;
return o != null ? o as IUmbracoContext : Current.UmbracoContext;
}
/// <summary>
@@ -69,7 +69,7 @@ namespace Umbraco.Web.Mvc
/// <summary>
/// Exposes the UmbracoContext
/// </summary>
protected UmbracoContext UmbracoContext => _umbracoContextAccessor?.UmbracoContext ?? Current.UmbracoContext;
protected IUmbracoContext UmbracoContext => _umbracoContextAccessor?.UmbracoContext ?? Current.UmbracoContext;
// TODO: try lazy property injection?
private IPublishedRouter PublishedRouter => Current.Factory.GetInstance<IPublishedRouter>();
@@ -99,7 +99,7 @@ namespace Umbraco.Web.Mvc
/// </summary>
/// <param name="request"></param>
/// <param name="filterContext"></param>
protected virtual void ConfigurePublishedContentRequest(PublishedRequest request, ActionExecutedContext filterContext)
protected virtual void ConfigurePublishedContentRequest(IPublishedRequest request, ActionExecutedContext filterContext)
{
if (_contentId.HasValue)
{
+1 -1
View File
@@ -27,7 +27,7 @@ namespace Umbraco.Web.Mvc
/// <summary>
/// Gets the Umbraco context.
/// </summary>
public virtual UmbracoContext UmbracoContext => UmbracoContextAccessor.UmbracoContext;
public virtual IUmbracoContext UmbracoContext => UmbracoContextAccessor.UmbracoContext;
/// <summary>
/// Gets the database context accessor.
@@ -13,13 +13,13 @@ namespace Umbraco.Web.Mvc
/// </remarks>
public class RedirectToUmbracoUrlResult : ActionResult
{
private readonly UmbracoContext _umbracoContext;
private readonly IUmbracoContext _umbracoContext;
/// <summary>
/// Creates a new RedirectToUmbracoResult
/// </summary>
/// <param name="umbracoContext"></param>
public RedirectToUmbracoUrlResult(UmbracoContext umbracoContext)
public RedirectToUmbracoUrlResult(IUmbracoContext umbracoContext)
{
_umbracoContext = umbracoContext;
}
+4 -4
View File
@@ -18,7 +18,7 @@ namespace Umbraco.Web.Mvc
[ModelBindingExceptionFilter]
public class RenderMvcController : UmbracoController, IRenderMvcController
{
private PublishedRequest _publishedRequest;
private IPublishedRequest _publishedRequest;
public RenderMvcController()
{
@@ -34,7 +34,7 @@ namespace Umbraco.Web.Mvc
/// <summary>
/// Gets the Umbraco context.
/// </summary>
public override UmbracoContext UmbracoContext => PublishedRequest.UmbracoContext; //TODO: Why?
public override IUmbracoContext UmbracoContext => PublishedRequest.UmbracoContext; //TODO: Why?
/// <summary>
/// Gets the current content item.
@@ -44,7 +44,7 @@ namespace Umbraco.Web.Mvc
/// <summary>
/// Gets the current published content request.
/// </summary>
protected internal virtual PublishedRequest PublishedRequest
protected internal virtual IPublishedRequest PublishedRequest
{
get
{
@@ -54,7 +54,7 @@ namespace Umbraco.Web.Mvc
{
throw new InvalidOperationException("DataTokens must contain an 'umbraco-doc-request' key with a PublishedRequest object");
}
_publishedRequest = (PublishedRequest)RouteData.DataTokens[Core.Constants.Web.PublishedDocumentRequestDataToken];
_publishedRequest = (IPublishedRequest)RouteData.DataTokens[Core.Constants.Web.PublishedDocumentRequestDataToken];
return _publishedRequest;
}
}
+7 -7
View File
@@ -29,7 +29,7 @@ namespace Umbraco.Web.Mvc
private readonly IControllerFactory _controllerFactory;
private readonly IShortStringHelper _shortStringHelper;
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
private readonly UmbracoContext _umbracoContext;
private readonly IUmbracoContext _umbracoContext;
public RenderRouteHandler(IUmbracoContextAccessor umbracoContextAccessor, IControllerFactory controllerFactory, IShortStringHelper shortStringHelper)
{
@@ -38,14 +38,14 @@ namespace Umbraco.Web.Mvc
_shortStringHelper = shortStringHelper ?? throw new ArgumentNullException(nameof(shortStringHelper));
}
public RenderRouteHandler(UmbracoContext umbracoContext, IControllerFactory controllerFactory, IShortStringHelper shortStringHelper)
public RenderRouteHandler(IUmbracoContext umbracoContext, IControllerFactory controllerFactory, IShortStringHelper shortStringHelper)
{
_umbracoContext = umbracoContext ?? throw new ArgumentNullException(nameof(umbracoContext));
_controllerFactory = controllerFactory ?? throw new ArgumentNullException(nameof(controllerFactory));
_shortStringHelper = shortStringHelper ?? throw new ArgumentNullException(nameof(shortStringHelper));
}
private UmbracoContext UmbracoContext => _umbracoContext ?? _umbracoContextAccessor.UmbracoContext;
private IUmbracoContext UmbracoContext => _umbracoContext ?? _umbracoContextAccessor.UmbracoContext;
private UmbracoFeatures Features => Current.Factory.GetInstance<UmbracoFeatures>(); // TODO: inject
@@ -86,7 +86,7 @@ namespace Umbraco.Web.Mvc
/// <param name="contentModel"></param>
/// <param name="requestContext"></param>
/// <param name="frequest"></param>
internal void SetupRouteDataForRequest(ContentModel contentModel, RequestContext requestContext, PublishedRequest frequest)
internal void SetupRouteDataForRequest(ContentModel contentModel, RequestContext requestContext, IPublishedRequest frequest)
{
//put essential data into the data tokens, the 'umbraco' key is required to be there for the view engine
requestContext.RouteData.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, contentModel); //required for the ContentModelBinder and view engine
@@ -241,7 +241,7 @@ namespace Umbraco.Web.Mvc
/// <param name="requestContext"></param>
/// <param name="request"></param>
/// <returns></returns>
internal virtual RouteDefinition GetUmbracoRouteDefinition(RequestContext requestContext, PublishedRequest request)
internal virtual RouteDefinition GetUmbracoRouteDefinition(RequestContext requestContext, IPublishedRequest request)
{
if (requestContext == null) throw new ArgumentNullException(nameof(requestContext));
if (request == null) throw new ArgumentNullException(nameof(request));
@@ -306,7 +306,7 @@ namespace Umbraco.Web.Mvc
return def;
}
internal IHttpHandler GetHandlerOnMissingTemplate(PublishedRequest request)
internal IHttpHandler GetHandlerOnMissingTemplate(IPublishedRequest request)
{
if (request == null) throw new ArgumentNullException(nameof(request));
@@ -331,7 +331,7 @@ namespace Umbraco.Web.Mvc
/// </summary>
/// <param name="requestContext"></param>
/// <param name="request"></param>
internal IHttpHandler GetHandlerForRoute(RequestContext requestContext, PublishedRequest request)
internal IHttpHandler GetHandlerForRoute(RequestContext requestContext, IPublishedRequest request)
{
if (requestContext == null) throw new ArgumentNullException(nameof(requestContext));
if (request == null) throw new ArgumentNullException(nameof(request));
+1 -1
View File
@@ -21,7 +21,7 @@ namespace Umbraco.Web.Mvc
/// <summary>
/// Everything related to the current content request including the requested content
/// </summary>
public PublishedRequest PublishedRequest { get; set; }
public IPublishedRequest PublishedRequest { get; set; }
/// <summary>
/// Gets/sets whether the current request has a hijacked route/user controller routed for it
@@ -13,20 +13,20 @@ namespace Umbraco.Web.Mvc
public sealed class UmbracoAuthorizeAttribute : AuthorizeAttribute
{
// see note in HttpInstallAuthorizeAttribute
private readonly UmbracoContext _umbracoContext;
private readonly IUmbracoContext _umbracoContext;
private readonly IRuntimeState _runtimeState;
private readonly string _redirectUrl;
private IRuntimeState RuntimeState => _runtimeState ?? Current.RuntimeState;
private UmbracoContext UmbracoContext => _umbracoContext ?? Current.UmbracoContext;
private IUmbracoContext UmbracoContext => _umbracoContext ?? Current.UmbracoContext;
/// <summary>
/// THIS SHOULD BE ONLY USED FOR UNIT TESTS
/// </summary>
/// <param name="umbracoContext"></param>
/// <param name="runtimeState"></param>
public UmbracoAuthorizeAttribute(UmbracoContext umbracoContext, IRuntimeState runtimeState)
public UmbracoAuthorizeAttribute(IUmbracoContext umbracoContext, IRuntimeState runtimeState)
{
if (umbracoContext == null) throw new ArgumentNullException(nameof(umbracoContext));
if (runtimeState == null) throw new ArgumentNullException(nameof(runtimeState));
+2 -2
View File
@@ -28,7 +28,7 @@ namespace Umbraco.Web.Mvc
/// <summary>
/// Gets the Umbraco context.
/// </summary>
public virtual UmbracoContext UmbracoContext => UmbracoContextAccessor.UmbracoContext;
public virtual IUmbracoContext UmbracoContext => UmbracoContextAccessor.UmbracoContext;
/// <summary>
/// Gets or sets the Umbraco context accessor.
@@ -70,7 +70,7 @@ namespace Umbraco.Web.Mvc
/// <summary>
/// Gets the web security helper.
/// </summary>
public virtual WebSecurity Security => UmbracoContext.Security;
public virtual IWebSecurity Security => UmbracoContext.Security;
protected UmbracoController()
: this(
@@ -25,7 +25,7 @@ namespace Umbraco.Web.Mvc
private readonly IGlobalSettings _globalSettings;
private readonly IUmbracoSettingsSection _umbracoSettingsSection;
private UmbracoContext _umbracoContext;
private IUmbracoContext _umbracoContext;
private UmbracoHelper _helper;
/// <summary>
@@ -50,13 +50,13 @@ namespace Umbraco.Web.Mvc
/// <summary>
/// Gets the Umbraco context.
/// </summary>
public UmbracoContext UmbracoContext => _umbracoContext
public IUmbracoContext UmbracoContext => _umbracoContext
?? (_umbracoContext = ViewContext.GetUmbracoContext() ?? Current.UmbracoContext);
/// <summary>
/// Gets the public content request.
/// </summary>
internal PublishedRequest PublishedRequest
internal IPublishedRequest PublishedRequest
{
get
{
@@ -67,11 +67,11 @@ namespace Umbraco.Web.Mvc
// try view context
if (ViewContext.RouteData.DataTokens.ContainsKey(token))
return (PublishedRequest) ViewContext.RouteData.DataTokens.GetRequiredObject(token);
return (IPublishedRequest) ViewContext.RouteData.DataTokens.GetRequiredObject(token);
// child action, try parent view context
if (ViewContext.IsChildAction && ViewContext.ParentActionViewContext.RouteData.DataTokens.ContainsKey(token))
return (PublishedRequest) ViewContext.ParentActionViewContext.RouteData.DataTokens.GetRequiredObject(token);
return (IPublishedRequest) ViewContext.ParentActionViewContext.RouteData.DataTokens.GetRequiredObject(token);
// fallback to UmbracoContext
return UmbracoContext.PublishedRequest;
@@ -221,7 +221,7 @@ namespace Umbraco.Web.Mvc
markupToInject =
string.Format(_umbracoSettingsSection.Content.PreviewBadge,
Current.IOHelper.ResolveUrl(_globalSettings.UmbracoPath),
Server.UrlEncode(Current.UmbracoContext.HttpContext.Request.Url?.PathAndQuery),
Server.UrlEncode(HttpContext.Current.Request.Url?.PathAndQuery),
Current.UmbracoContext.PublishedRequest.PublishedContent.Id);
}
else
@@ -12,13 +12,13 @@ namespace Umbraco.Web.Mvc
_realNodeId = realNodeId;
}
protected sealed override IPublishedContent FindContent(RequestContext requestContext, UmbracoContext umbracoContext)
protected sealed override IPublishedContent FindContent(RequestContext requestContext, IUmbracoContext umbracoContext)
{
var byId = umbracoContext.Content.GetById(_realNodeId);
return byId == null ? null : FindContent(requestContext, umbracoContext, byId);
}
protected virtual IPublishedContent FindContent(RequestContext requestContext, UmbracoContext umbracoContext, IPublishedContent baseContent)
protected virtual IPublishedContent FindContent(RequestContext requestContext, IUmbracoContext umbracoContext, IPublishedContent baseContent)
{
return baseContent;
}
@@ -13,13 +13,13 @@ namespace Umbraco.Web.Mvc
_realNodeUdi = realNodeUdi;
}
protected sealed override IPublishedContent FindContent(RequestContext requestContext, UmbracoContext umbracoContext)
protected sealed override IPublishedContent FindContent(RequestContext requestContext, IUmbracoContext umbracoContext)
{
var byId = umbracoContext.Content.GetById(_realNodeUdi);
return byId == null ? null : FindContent(requestContext, umbracoContext, byId);
}
protected virtual IPublishedContent FindContent(RequestContext requestContext, UmbracoContext umbracoContext, IPublishedContent baseContent)
protected virtual IPublishedContent FindContent(RequestContext requestContext, IUmbracoContext umbracoContext, IPublishedContent baseContent)
{
return baseContent;
}
@@ -38,7 +38,7 @@ namespace Umbraco.Web.Mvc
/// ]]>
/// </example>
/// </remarks>
protected virtual UmbracoContext GetUmbracoContext(RequestContext requestContext)
protected virtual IUmbracoContext GetUmbracoContext(RequestContext requestContext)
{
return Composing.Current.UmbracoContext;
}
@@ -88,9 +88,9 @@ namespace Umbraco.Web.Mvc
return new MvcHandler(requestContext);
}
protected abstract IPublishedContent FindContent(RequestContext requestContext, UmbracoContext umbracoContext);
protected abstract IPublishedContent FindContent(RequestContext requestContext, IUmbracoContext umbracoContext);
protected virtual void PreparePublishedContentRequest(PublishedRequest request)
protected virtual void PreparePublishedContentRequest(IPublishedRequest request)
{
PublishedRouter.PrepareRequest(request);
}
@@ -5,11 +5,12 @@ namespace Umbraco.Web
{
internal class AspNetHttpContextAccessor : IHttpContextAccessor
{
public HttpContext HttpContext
public HttpContextBase HttpContext
{
get
{
return HttpContext.Current;
var httpContext = System.Web.HttpContext.Current;
return httpContext is null ? null : new HttpContextWrapper(httpContext);
}
set
{
@@ -25,7 +25,7 @@ namespace Umbraco.Web
//
private static IPublishedValueFallback PublishedValueFallback => Current.PublishedValueFallback;
private static IPublishedSnapshot PublishedSnapshot => Current.PublishedSnapshot;
private static UmbracoContext UmbracoContext => Current.UmbracoContext;
private static IUmbracoContext UmbracoContext => Current.UmbracoContext;
private static ISiteDomainHelper SiteDomainHelper => Current.Factory.GetInstance<ISiteDomainHelper>();
private static IVariationContextAccessor VariationContextAccessor => Current.VariationContextAccessor;
private static IExamineManager ExamineManager => Current.Factory.GetInstance<IExamineManager>();
+2 -2
View File
@@ -31,7 +31,7 @@ namespace Umbraco.Web.Routing
#region GetUrl
/// <inheritdoc />
public UrlInfo GetUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlMode mode, string culture, Uri current)
public UrlInfo GetUrl(IUmbracoContext umbracoContext, IPublishedContent content, UrlMode mode, string culture, Uri current)
{
return null; // we have nothing to say
}
@@ -51,7 +51,7 @@ namespace Umbraco.Web.Routing
/// <para>Other urls are those that <c>GetUrl</c> would not return in the current context, but would be valid
/// urls for the node in other contexts (different domain for current request, umbracoUrlAlias...).</para>
/// </remarks>
public IEnumerable<UrlInfo> GetOtherUrls(UmbracoContext umbracoContext, int id, Uri current)
public IEnumerable<UrlInfo> GetOtherUrls(IUmbracoContext umbracoContext, int id, Uri current)
{
var node = umbracoContext.Content.GetById(id);
if (node == null)
@@ -32,7 +32,7 @@ namespace Umbraco.Web.Routing
/// </summary>
/// <param name="frequest">The <c>PublishedRequest</c>.</param>
/// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
public bool TryFindContent(PublishedRequest frequest)
public bool TryFindContent(IPublishedRequest frequest)
{
_logger.Debug<ContentFinderByConfigured404>("Looking for a page to handle 404.");
@@ -16,12 +16,14 @@ namespace Umbraco.Web.Routing
public class ContentFinderByIdPath : IContentFinder
{
private readonly ILogger _logger;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IWebRoutingSection _webRoutingSection;
public ContentFinderByIdPath(IWebRoutingSection webRoutingSection, ILogger logger)
public ContentFinderByIdPath(IWebRoutingSection webRoutingSection, ILogger logger, IHttpContextAccessor httpContextAccessor)
{
_webRoutingSection = webRoutingSection ?? throw new System.ArgumentNullException(nameof(webRoutingSection));
_logger = logger ?? throw new System.ArgumentNullException(nameof(logger));
_httpContextAccessor = httpContextAccessor;
}
/// <summary>
@@ -29,7 +31,7 @@ namespace Umbraco.Web.Routing
/// </summary>
/// <param name="frequest">The <c>PublishedRequest</c>.</param>
/// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
public bool TryFindContent(PublishedRequest frequest)
public bool TryFindContent(IPublishedRequest frequest)
{
if (frequest.UmbracoContext != null && frequest.UmbracoContext.InPreviewMode == false
@@ -55,10 +57,10 @@ namespace Umbraco.Web.Routing
if (node != null)
{
//if we have a node, check if we have a culture in the query string
if (frequest.UmbracoContext.HttpContext.Request.QueryString.ContainsKey("culture"))
if (_httpContextAccessor.HttpContext.Request.QueryString.ContainsKey("culture"))
{
//we're assuming it will match a culture, if an invalid one is passed in, an exception will throw (there is no TryGetCultureInfo method), i think this is ok though
frequest.Culture = CultureInfo.GetCultureInfo(frequest.UmbracoContext.HttpContext.Request.QueryString["culture"]);
frequest.Culture = CultureInfo.GetCultureInfo(_httpContextAccessor.HttpContext.Request.QueryString["culture"]);
}
frequest.PublishedContent = node;
@@ -9,10 +9,17 @@
/// </remarks>
public class ContentFinderByPageIdQuery : IContentFinder
{
public bool TryFindContent(PublishedRequest frequest)
private readonly IHttpContextAccessor _httpContextAccessor;
public ContentFinderByPageIdQuery(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public bool TryFindContent(IPublishedRequest frequest)
{
int pageId;
if (int.TryParse(frequest.UmbracoContext.HttpContext.Request["umbPageID"], out pageId))
if (int.TryParse(_httpContextAccessor.HttpContext.Request["umbPageID"], out pageId))
{
var doc = frequest.UmbracoContext.Content.GetById(pageId);
@@ -30,7 +30,7 @@ namespace Umbraco.Web.Routing
/// <param name="frequest">The <c>PublishedRequest</c>.</param>
/// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
/// <remarks>Optionally, can also assign the template or anything else on the document request, although that is not required.</remarks>
public bool TryFindContent(PublishedRequest frequest)
public bool TryFindContent(IPublishedRequest frequest)
{
var route = frequest.HasDomain
? frequest.Domain.ContentId + DomainUtilities.PathRelativeToDomain(frequest.Domain.Uri, frequest.Uri.GetAbsolutePathDecoded())
@@ -63,7 +63,8 @@ namespace Umbraco.Web.Routing
// See http://issues.umbraco.org/issue/U4-8361#comment=67-30532
// Setting automatic 301 redirects to not be cached because browsers cache these very aggressively which then leads
// to problems if you rename a page back to it's original name or create a new page with the original name
frequest.Cacheability = HttpCacheability.NoCache;
//frequest.Cacheability = HttpCacheability.NoCache;
frequest.CacheabilityNoCache = true;
frequest.CacheExtensions = new List<string> { "no-store, must-revalidate" };
frequest.Headers = new Dictionary<string, string> { { "Pragma", "no-cache" }, { "Expires", "0" } };
@@ -24,7 +24,7 @@ namespace Umbraco.Web.Routing
/// </summary>
/// <param name="frequest">The <c>PublishedRequest</c>.</param>
/// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
public virtual bool TryFindContent(PublishedRequest frequest)
public virtual bool TryFindContent(IPublishedRequest frequest)
{
string route;
if (frequest.HasDomain)
@@ -42,7 +42,7 @@ namespace Umbraco.Web.Routing
/// <param name="docreq">The document request.</param>
/// <param name="route">The route.</param>
/// <returns>The document node, or null.</returns>
protected IPublishedContent FindContent(PublishedRequest docreq, string route)
protected IPublishedContent FindContent(IPublishedRequest docreq, string route)
{
if (docreq == null) throw new System.ArgumentNullException(nameof(docreq));
@@ -30,7 +30,7 @@ namespace Umbraco.Web.Routing
/// </summary>
/// <param name="frequest">The <c>PublishedRequest</c>.</param>
/// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
public bool TryFindContent(PublishedRequest frequest)
public bool TryFindContent(IPublishedRequest frequest)
{
IPublishedContent node = null;
@@ -32,7 +32,7 @@ namespace Umbraco.Web.Routing
/// <param name="frequest">The <c>PublishedRequest</c>.</param>
/// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
/// <remarks>If successful, also assigns the template.</remarks>
public override bool TryFindContent(PublishedRequest frequest)
public override bool TryFindContent(IPublishedRequest frequest)
{
IPublishedContent node = null;
var path = frequest.Uri.GetAbsolutePathDecoded();
@@ -18,7 +18,7 @@ namespace Umbraco.Web.Routing
}
/// <inheritdoc />
public virtual UrlInfo GetMediaUrl(UmbracoContext umbracoContext, IPublishedContent content,
public virtual UrlInfo GetMediaUrl(IUmbracoContext umbracoContext, IPublishedContent content,
string propertyAlias, UrlMode mode, string culture, Uri current)
{
var prop = content.GetProperty(propertyAlias);
@@ -29,7 +29,7 @@ namespace Umbraco.Web.Routing
#region GetUrl
/// <inheritdoc />
public virtual UrlInfo GetUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlMode mode, string culture, Uri current)
public virtual UrlInfo GetUrl(IUmbracoContext umbracoContext, IPublishedContent content, UrlMode mode, string culture, Uri current)
{
if (!current.IsAbsoluteUri) throw new ArgumentException("Current url must be absolute.", nameof(current));
@@ -39,7 +39,7 @@ namespace Umbraco.Web.Routing
return GetUrlFromRoute(route, umbracoContext, content.Id, current, mode, culture);
}
internal UrlInfo GetUrlFromRoute(string route, UmbracoContext umbracoContext, int id, Uri current, UrlMode mode, string culture)
internal UrlInfo GetUrlFromRoute(string route, IUmbracoContext umbracoContext, int id, Uri current, UrlMode mode, string culture)
{
if (string.IsNullOrWhiteSpace(route))
{
@@ -76,7 +76,7 @@ namespace Umbraco.Web.Routing
/// <para>Other urls are those that <c>GetUrl</c> would not return in the current context, but would be valid
/// urls for the node in other contexts (different domain for current request, umbracoUrlAlias...).</para>
/// </remarks>
public virtual IEnumerable<UrlInfo> GetOtherUrls(UmbracoContext umbracoContext, int id, Uri current)
public virtual IEnumerable<UrlInfo> GetOtherUrls(IUmbracoContext umbracoContext, int id, Uri current)
{
var node = umbracoContext.Content.GetById(id);
if (node == null)
+1 -1
View File
@@ -11,6 +11,6 @@ namespace Umbraco.Web.Routing
/// <param name="request">The <c>PublishedRequest</c>.</param>
/// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
/// <remarks>Optionally, can also assign the template or anything else on the document request, although that is not required.</remarks>
bool TryFindContent(PublishedRequest request);
bool TryFindContent(IPublishedRequest request);
}
}
+1 -1
View File
@@ -26,6 +26,6 @@ namespace Umbraco.Web.Routing
/// e.g. a cdn url provider will most likely always return an absolute url.</para>
/// <para>If the provider is unable to provide a url, it returns <c>null</c>.</para>
/// </remarks>
UrlInfo GetMediaUrl(UmbracoContext umbracoContext, IPublishedContent content, string propertyAlias, UrlMode mode, string culture, Uri current);
UrlInfo GetMediaUrl(IUmbracoContext umbracoContext, IPublishedContent content, string propertyAlias, UrlMode mode, string culture, Uri current);
}
}
+4 -4
View File
@@ -17,21 +17,21 @@ namespace Umbraco.Web.Routing
/// <param name="umbracoContext">The current Umbraco context.</param>
/// <param name="uri">The (optional) request Uri.</param>
/// <returns>A published request.</returns>
PublishedRequest CreateRequest(UmbracoContext umbracoContext, Uri uri = null);
IPublishedRequest CreateRequest(IUmbracoContext umbracoContext, Uri uri = null);
/// <summary>
/// Prepares a request for rendering.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>A value indicating whether the request was successfully prepared and can be rendered.</returns>
bool PrepareRequest(PublishedRequest request);
bool PrepareRequest(IPublishedRequest request);
/// <summary>
/// Tries to route a request.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>A value indicating whether the request can be routed to a document.</returns>
bool TryRouteRequest(PublishedRequest request);
bool TryRouteRequest(IPublishedRequest request);
/// <summary>
/// Gets a template.
@@ -49,6 +49,6 @@ namespace Umbraco.Web.Routing
/// the request, for whatever reason, and wants to force it to be re-routed
/// and rendered as if no document were found (404).</para>
/// </remarks>
void UpdateRequestToNotFound(PublishedRequest request);
void UpdateRequestToNotFound(IPublishedRequest request);
}
}
+2 -2
View File
@@ -24,7 +24,7 @@ namespace Umbraco.Web.Routing
/// when no culture is specified, the current culture.</para>
/// <para>If the provider is unable to provide a url, it should return <c>null</c>.</para>
/// </remarks>
UrlInfo GetUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlMode mode, string culture, Uri current);
UrlInfo GetUrl(IUmbracoContext umbracoContext, IPublishedContent content, UrlMode mode, string culture, Uri current);
/// <summary>
/// Gets the other urls of a published content.
@@ -37,6 +37,6 @@ namespace Umbraco.Web.Routing
/// <para>Other urls are those that <c>GetUrl</c> would not return in the current context, but would be valid
/// urls for the node in other contexts (different domain for current request, umbracoUrlAlias...).</para>
/// </remarks>
IEnumerable<UrlInfo> GetOtherUrls(UmbracoContext umbracoContext, int id, Uri current);
IEnumerable<UrlInfo> GetOtherUrls(IUmbracoContext umbracoContext, int id, Uri current);
}
}
+13 -29
View File
@@ -12,11 +12,12 @@ using Umbraco.Core.Configuration.UmbracoSettings;
namespace Umbraco.Web.Routing
{
/// <summary>
/// Represents a request for one specified Umbraco IPublishedContent to be rendered
/// by one specified template, using one specified Culture and RenderingEngine.
/// </summary>
public class PublishedRequest
public class PublishedRequest : IPublishedRequest
{
private readonly IPublishedRouter _publishedRouter;
private readonly IUmbracoSettingsSection _umbracoSettingsSection;
@@ -29,15 +30,14 @@ namespace Umbraco.Web.Routing
private CultureInfo _culture;
private IPublishedContent _publishedContent;
private IPublishedContent _initialPublishedContent; // found by finders before 404, redirects, etc
private PublishedContentHashtableConverter _umbracoPage; // legacy
/// <summary>
/// Initializes a new instance of the <see cref="PublishedRequest"/> class.
/// Initializes a new instance of the <see cref="IPublishedRequest"/> class.
/// </summary>
/// <param name="publishedRouter">The published router.</param>
/// <param name="umbracoContext">The Umbraco context.</param>
/// <param name="uri">The request <c>Uri</c>.</param>
internal PublishedRequest(IPublishedRouter publishedRouter, UmbracoContext umbracoContext, IUmbracoSettingsSection umbracoSettingsSection, Uri uri = null)
internal PublishedRequest(IPublishedRouter publishedRouter, IUmbracoContext umbracoContext, IUmbracoSettingsSection umbracoSettingsSection, Uri uri = null)
{
UmbracoContext = umbracoContext ?? throw new ArgumentNullException(nameof(umbracoContext));
_publishedRouter = publishedRouter ?? throw new ArgumentNullException(nameof(publishedRouter));
@@ -48,7 +48,7 @@ namespace Umbraco.Web.Routing
/// <summary>
/// Gets the UmbracoContext.
/// </summary>
public UmbracoContext UmbracoContext { get; }
public IUmbracoContext UmbracoContext { get; }
/// <summary>
/// Gets or sets the cleaned up Uri used for routing.
@@ -66,12 +66,14 @@ namespace Umbraco.Web.Routing
}
// utility for ensuring it is ok to set some properties
private void EnsureWriteable()
public void EnsureWriteable()
{
if (_readonly)
throw new InvalidOperationException("Cannot modify a PublishedRequest once it is read-only.");
}
public bool CacheabilityNoCache { get; set; }
/// <summary>
/// Prepares the request.
/// </summary>
@@ -106,7 +108,7 @@ namespace Umbraco.Web.Routing
/// <summary>
/// Triggers the Preparing event.
/// </summary>
internal void OnPreparing()
public void OnPreparing()
{
Preparing?.Invoke(this, EventArgs.Empty);
_readonlyUri = true;
@@ -115,7 +117,7 @@ namespace Umbraco.Web.Routing
/// <summary>
/// Triggers the Prepared event.
/// </summary>
internal void OnPrepared()
public void OnPrepared()
{
Prepared?.Invoke(this, EventArgs.Empty);
@@ -231,7 +233,7 @@ namespace Umbraco.Web.Routing
/// <summary>
/// Gets or sets the template model to use to display the requested content.
/// </summary>
internal ITemplate TemplateModel { get; set; }
public ITemplate TemplateModel { get; set; }
/// <summary>
/// Gets the alias of the template to use to display the requested content.
@@ -293,7 +295,7 @@ namespace Umbraco.Web.Routing
/// </summary>
public bool HasTemplate => TemplateModel != null;
internal void UpdateToNotFound()
public void UpdateToNotFound()
{
var __readonly = _readonly;
_readonly = false;
@@ -464,7 +466,7 @@ namespace Umbraco.Web.Routing
// Note: we used to set a default value here but that would then be the default
// for ALL requests, we shouldn't overwrite it though if people are using [OutputCache] for example
// see: https://our.umbraco.com/forum/using-umbraco-and-getting-started/79715-output-cache-in-umbraco-752
public HttpCacheability Cacheability { get; set; }
//public HttpCacheability Cacheability { get; set; }
/// <summary>
/// Gets or sets a list of Extensions to append to the Response.Cache object.
@@ -477,23 +479,5 @@ namespace Umbraco.Web.Routing
public Dictionary<string, string> Headers { get; set; } = new Dictionary<string, string>();
#endregion
#region Legacy
// for legacy/webforms/macro code -
// TODO: get rid of it eventually
internal PublishedContentHashtableConverter LegacyContentHashTable
{
get
{
if (_umbracoPage == null)
throw new InvalidOperationException("The UmbracoPage object has not been initialized yet.");
return _umbracoPage;
}
set => _umbracoPage = value;
}
#endregion
}
}
+20 -34
View File
@@ -29,6 +29,7 @@ namespace Umbraco.Web.Routing
private readonly ILogger _logger;
private readonly IUmbracoSettingsSection _umbracoSettingsSection;
private readonly IUserService _userService;
private readonly IHttpContextAccessor _httpContextAccessor;
/// <summary>
/// Initializes a new instance of the <see cref="PublishedRouter"/> class.
@@ -41,7 +42,8 @@ namespace Umbraco.Web.Routing
ServiceContext services,
IProfilingLogger proflog,
IUmbracoSettingsSection umbracoSettingsSection,
IUserService userService)
IUserService userService,
IHttpContextAccessor httpContextAccessor)
{
_webRoutingSection = webRoutingSection ?? throw new ArgumentNullException(nameof(webRoutingSection));
_contentFinders = contentFinders ?? throw new ArgumentNullException(nameof(contentFinders));
@@ -52,10 +54,11 @@ namespace Umbraco.Web.Routing
_logger = proflog;
_umbracoSettingsSection = umbracoSettingsSection ?? throw new ArgumentNullException(nameof(umbracoSettingsSection));
_userService = userService ?? throw new ArgumentNullException(nameof(userService));
_httpContextAccessor = httpContextAccessor;
}
/// <inheritdoc />
public PublishedRequest CreateRequest(UmbracoContext umbracoContext, Uri uri = null)
public IPublishedRequest CreateRequest(IUmbracoContext umbracoContext, Uri uri = null)
{
return new PublishedRequest(this, umbracoContext, _umbracoSettingsSection, uri ?? umbracoContext.CleanedUmbracoUrl);
}
@@ -63,7 +66,7 @@ namespace Umbraco.Web.Routing
#region Request
/// <inheritdoc />
public bool TryRouteRequest(PublishedRequest request)
public bool TryRouteRequest(IPublishedRequest request)
{
// disabled - is it going to change the routing?
//_pcr.OnPreparing();
@@ -94,7 +97,7 @@ namespace Umbraco.Web.Routing
}
/// <inheritdoc />
public bool PrepareRequest(PublishedRequest request)
public bool PrepareRequest(IPublishedRequest request)
{
// note - at that point the original legacy module did something do handle IIS custom 404 errors
// ie pages looking like /anything.aspx?404;/path/to/document - I guess the reason was to support
@@ -165,7 +168,7 @@ namespace Umbraco.Web.Routing
/// 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>
public bool ConfigureRequest(PublishedRequest frequest)
public bool ConfigureRequest(IPublishedRequest frequest)
{
if (frequest.HasPublishedContent == false)
{
@@ -188,22 +191,11 @@ namespace Umbraco.Web.Routing
// can't go beyond that point without a PublishedContent to render
// it's ok not to have a template, in order to give MVC a chance to hijack routes
// note - the page() ctor below will cause the "page" to get the value of all its
// "elements" ie of all the IPublishedContent property. If we use the object value,
// that will trigger macro execution - which can't happen because macro execution
// requires that _pcr.UmbracoPage is already initialized = catch-22. The "legacy"
// pipeline did _not_ evaluate the macros, ie it is using the data value, and we
// have to keep doing it because of that catch-22.
// assign the legacy page back to the request
// handlers like default.aspx will want it and most macros currently need it
frequest.LegacyContentHashTable = new PublishedContentHashtableConverter(frequest, _userService);
return true;
}
/// <inheritdoc />
public void UpdateRequestToNotFound(PublishedRequest request)
public void UpdateRequestToNotFound(IPublishedRequest request)
{
// clear content
var content = request.PublishedContent;
@@ -232,12 +224,6 @@ namespace Umbraco.Web.Routing
// to Mvc since Mvc can't do much either
return;
}
// see note in PrepareRequest()
// assign the legacy page back to the docrequest
// handlers like default.aspx will want it and most macros currently need it
request.LegacyContentHashTable = new PublishedContentHashtableConverter(request, _userService);
}
#endregion
@@ -248,7 +234,7 @@ namespace Umbraco.Web.Routing
/// Finds the site root (if any) matching the http request, and updates the PublishedRequest accordingly.
/// </summary>
/// <returns>A value indicating whether a domain was found.</returns>
internal bool FindDomain(PublishedRequest request)
internal bool FindDomain(IPublishedRequest request)
{
const string tracePrefix = "FindDomain: ";
@@ -319,7 +305,7 @@ namespace Umbraco.Web.Routing
/// <summary>
/// Looks for wildcard domains in the path and updates <c>Culture</c> accordingly.
/// </summary>
internal void HandleWildcardDomains(PublishedRequest request)
internal void HandleWildcardDomains(IPublishedRequest request)
{
const string tracePrefix = "HandleWildcardDomains: ";
@@ -379,7 +365,7 @@ namespace Umbraco.Web.Routing
/// Finds the Umbraco document (if any) matching the request, and updates the PublishedRequest accordingly.
/// </summary>
/// <returns>A value indicating whether a document and template were found.</returns>
private void FindPublishedContentAndTemplate(PublishedRequest request)
private void FindPublishedContentAndTemplate(IPublishedRequest request)
{
_logger.Debug<PublishedRouter>("FindPublishedContentAndTemplate: Path={UriAbsolutePath}", request.Uri.AbsolutePath);
@@ -409,7 +395,7 @@ namespace Umbraco.Web.Routing
/// Tries to find the document matching the request, by running the IPublishedContentFinder instances.
/// </summary>
/// <exception cref="InvalidOperationException">There is no finder collection.</exception>
internal void FindPublishedContent(PublishedRequest request)
internal void FindPublishedContent(IPublishedRequest request)
{
const string tracePrefix = "FindPublishedContent: ";
@@ -441,7 +427,7 @@ namespace Umbraco.Web.Routing
/// Handles "not found", internal redirects, access validation...
/// things that must be handled in one place because they can create loops
/// </remarks>
private void HandlePublishedContent(PublishedRequest request)
private void HandlePublishedContent(IPublishedRequest request)
{
// because these might loop, we have to have some sort of infinite loop detection
int i = 0, j = 0;
@@ -500,7 +486,7 @@ namespace Umbraco.Web.Routing
/// <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>
private bool FollowInternalRedirects(PublishedRequest request)
private bool FollowInternalRedirects(IPublishedRequest request)
{
if (request.PublishedContent == null)
throw new InvalidOperationException("There is no PublishedContent.");
@@ -562,7 +548,7 @@ namespace Umbraco.Web.Routing
/// Ensures that access to current node is permitted.
/// </summary>
/// <remarks>Redirecting to a different site root and/or culture will not pick the new site root nor the new culture.</remarks>
private void EnsurePublishedContentAccess(PublishedRequest request)
private void EnsurePublishedContentAccess(IPublishedRequest request)
{
if (request.PublishedContent == null)
throw new InvalidOperationException("There is no PublishedContent.");
@@ -632,7 +618,7 @@ namespace Umbraco.Web.Routing
/// <summary>
/// Finds a template for the current node, if any.
/// </summary>
private void FindTemplate(PublishedRequest request)
private void FindTemplate(IPublishedRequest request)
{
// 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
@@ -651,7 +637,7 @@ namespace Umbraco.Web.Routing
var useAltTemplate = request.IsInitialPublishedContent
|| (_webRoutingSection.InternalRedirectPreservesTemplate && request.IsInternalRedirectPublishedContent);
var altTemplate = useAltTemplate
? request.UmbracoContext.HttpContext.Request[Constants.Conventions.Url.AltTemplate]
? _httpContextAccessor.HttpContext.Request[Constants.Conventions.Url.AltTemplate]
: null;
if (string.IsNullOrWhiteSpace(altTemplate))
@@ -662,7 +648,7 @@ namespace Umbraco.Web.Routing
if (request.HasTemplate)
{
_logger.Debug<PublishedRequest>("FindTemplate: Has a template already, and no alternate template.");
_logger.Debug<IPublishedRequest>("FindTemplate: Has a template already, and no alternate template.");
return;
}
@@ -756,7 +742,7 @@ namespace Umbraco.Web.Routing
/// 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>
private void FollowExternalRedirect(PublishedRequest request)
private void FollowExternalRedirect(IPublishedRequest request)
{
if (request.HasPublishedContent == false) return;
@@ -9,7 +9,7 @@ namespace Umbraco.Web.Routing
{
public EnsureRoutableOutcome Outcome { get; private set; }
public RoutableAttemptEventArgs(EnsureRoutableOutcome reason, UmbracoContext umbracoContext, HttpContextBase httpContext)
public RoutableAttemptEventArgs(EnsureRoutableOutcome reason, IUmbracoContext umbracoContext, HttpContextBase httpContext)
: base(umbracoContext, httpContext)
{
Outcome = reason;
+1 -1
View File
@@ -266,7 +266,7 @@ namespace Umbraco.Web.Routing
return _qualifiedSites[current.Scheme] = _sites
.ToDictionary(
kvp => kvp.Key,
kvp => kvp.Value.Select(d => new Uri(UriUtility.StartWithScheme(d, current.Scheme)).GetLeftPart(UriPartial.Authority)).ToArray()
kvp => kvp.Value.Select(d => new Uri(UriUtilityCore.StartWithScheme(d, current.Scheme)).GetLeftPart(UriPartial.Authority)).ToArray()
);
// .ToDictionary will evaluate and create the dictionary immediately
@@ -8,10 +8,10 @@ namespace Umbraco.Web.Routing
/// </summary>
public class UmbracoRequestEventArgs : EventArgs
{
public UmbracoContext UmbracoContext { get; private set; }
public IUmbracoContext UmbracoContext { get; private set; }
public HttpContextBase HttpContext { get; private set; }
public UmbracoRequestEventArgs(UmbracoContext umbracoContext, HttpContextBase httpContext)
public UmbracoRequestEventArgs(IUmbracoContext umbracoContext, HttpContextBase httpContext)
{
UmbracoContext = umbracoContext;
HttpContext = httpContext;
+7 -7
View File
@@ -8,22 +8,23 @@ using Umbraco.Web.Composing;
namespace Umbraco.Web.Routing
{
/// <summary>
/// Provides urls.
/// </summary>
public class UrlProvider
public class UrlProvider : IPublishedUrlProvider
{
#region Ctor and configuration
/// <summary>
/// Initializes a new instance of the <see cref="UrlProvider"/> class with an Umbraco context and a list of url providers.
/// InitialiIUrlProviderzes a new instance of the <see cref="UrlProvider"/> class with an Umbraco context and a list of url providers.
/// </summary>
/// <param name="umbracoContext">The Umbraco context.</param>
/// <param name="routingSettings">Routing settings.</param>
/// <param name="urlProviders">The list of url providers.</param>
/// <param name="mediaUrlProviders">The list of media url providers.</param>
/// <param name="variationContextAccessor">The current variation accessor.</param>
public UrlProvider(UmbracoContext umbracoContext, IWebRoutingSection routingSettings, IEnumerable<IUrlProvider> urlProviders, IEnumerable<IMediaUrlProvider> mediaUrlProviders, IVariationContextAccessor variationContextAccessor)
public UrlProvider(IUmbracoContext umbracoContext, IWebRoutingSection routingSettings, IEnumerable<IUrlProvider> urlProviders, IEnumerable<IMediaUrlProvider> mediaUrlProviders, IVariationContextAccessor variationContextAccessor)
{
if (routingSettings == null) throw new ArgumentNullException(nameof(routingSettings));
@@ -48,7 +49,7 @@ namespace Umbraco.Web.Routing
/// <param name="mediaUrlProviders">The list of media url providers</param>
/// <param name="variationContextAccessor">The current variation accessor.</param>
/// <param name="mode">An optional provider mode.</param>
public UrlProvider(UmbracoContext umbracoContext, IEnumerable<IUrlProvider> urlProviders, IEnumerable<IMediaUrlProvider> mediaUrlProviders, IVariationContextAccessor variationContextAccessor, UrlMode mode = UrlMode.Auto)
public UrlProvider(IUmbracoContext umbracoContext, IEnumerable<IUrlProvider> urlProviders, IEnumerable<IMediaUrlProvider> mediaUrlProviders, IVariationContextAccessor variationContextAccessor, UrlMode mode = UrlMode.Auto)
{
_umbracoContext = umbracoContext ?? throw new ArgumentNullException(nameof(umbracoContext));
_urlProviders = urlProviders;
@@ -58,7 +59,7 @@ namespace Umbraco.Web.Routing
Mode = mode;
}
private readonly UmbracoContext _umbracoContext;
private readonly IUmbracoContext _umbracoContext;
private readonly IEnumerable<IUrlProvider> _urlProviders;
private readonly IEnumerable<IMediaUrlProvider> _mediaUrlProviders;
private readonly IVariationContextAccessor _variationContextAccessor;
@@ -72,7 +73,6 @@ namespace Umbraco.Web.Routing
#region GetUrl
private UrlMode GetMode(bool absolute) => absolute ? UrlMode.Absolute : Mode;
private IPublishedContent GetDocument(int id) => _umbracoContext.Content.GetById(id);
private IPublishedContent GetDocument(Guid id) => _umbracoContext.Content.GetById(id);
private IPublishedContent GetMedia(Guid id) => _umbracoContext.Media.GetById(id);
@@ -138,7 +138,7 @@ namespace Umbraco.Web.Routing
return url?.Text ?? "#"; // legacy wants this
}
internal string GetUrlFromRoute(int id, string route, string culture)
public string GetUrlFromRoute(int id, string route, string culture)
{
var provider = _urlProviders.OfType<DefaultUrlProvider>().FirstOrDefault();
var url = provider == null
@@ -20,7 +20,7 @@ namespace Umbraco.Web.Routing
/// </remarks>
public static IEnumerable<UrlInfo> GetContentUrls(this IContent content,
IPublishedRouter publishedRouter,
UmbracoContext umbracoContext,
IUmbracoContext umbracoContext,
ILocalizationService localizationService,
ILocalizedTextService textService,
IContentService contentService,
@@ -96,7 +96,7 @@ namespace Umbraco.Web.Routing
private static IEnumerable<UrlInfo> GetContentUrlsByCulture(IContent content,
IEnumerable<string> cultures,
IPublishedRouter publishedRouter,
UmbracoContext umbracoContext,
IUmbracoContext umbracoContext,
IContentService contentService,
ILocalizedTextService textService,
IVariationContextAccessor variationContextAccessor,
@@ -165,7 +165,7 @@ namespace Umbraco.Web.Routing
return UrlInfo.Message(textService.Localize("content/parentCultureNotPublished", new[] {parent.Name}), culture);
}
private static bool DetectCollision(IContent content, string url, string culture, UmbracoContext umbracoContext, IPublishedRouter publishedRouter, ILocalizedTextService textService, IVariationContextAccessor variationContextAccessor, out UrlInfo urlInfo)
private static bool DetectCollision(IContent content, string url, string culture, IUmbracoContext umbracoContext, IPublishedRouter publishedRouter, ILocalizedTextService textService, IVariationContextAccessor variationContextAccessor, out UrlInfo urlInfo)
{
// test for collisions on the 'main' url
var uri = new Uri(url.TrimEnd('/'), UriKind.RelativeOrAbsolute);
@@ -83,7 +83,7 @@ namespace Umbraco.Web.Runtime
composition.Register(factory => MembershipProviderExtensions.GetMembersMembershipProvider());
composition.Register(factory => Roles.Enabled ? Roles.Provider : new MembersRoleProvider(factory.GetInstance<IMemberService>()));
composition.Register<MembershipHelper>(Lifetime.Request);
composition.Register<IPublishedMemberCache>(factory => factory.GetInstance<UmbracoContext>().PublishedSnapshot.Members);
composition.Register<IPublishedMemberCache>(factory => factory.GetInstance<IUmbracoContext>().PublishedSnapshot.Members);
// register accessors for cultures
composition.RegisterUnique<IDefaultCultureAccessor, DefaultCultureAccessor>();
@@ -100,7 +100,7 @@ namespace Umbraco.Web.Runtime
// register a per-request HttpContextBase object
// is per-request so only one wrapper is created per request
composition.Register<HttpContextBase>(factory => new HttpContextWrapper(factory.GetInstance<IHttpContextAccessor>().HttpContext), Lifetime.Request);
composition.Register<HttpContextBase>(factory => factory.GetInstance<IHttpContextAccessor>().HttpContext, Lifetime.Request);
// register the published snapshot accessor - the "current" published snapshot is in the umbraco context
composition.RegisterUnique<IPublishedSnapshotAccessor, UmbracoContextPublishedSnapshotAccessor>();
@@ -133,7 +133,7 @@ namespace Umbraco.Web.Runtime
if (composition.RuntimeState.Level == RuntimeLevel.Run)
composition.Register<UmbracoHelper>(factory =>
{
var umbCtx = factory.GetInstance<UmbracoContext>();
var umbCtx = factory.GetInstance<IUmbracoContext>();
return new UmbracoHelper(umbCtx.IsFrontEndUmbracoRequest ? umbCtx.PublishedRequest?.PublishedContent : null,
factory.GetInstance<ITagQuery>(), factory.GetInstance<ICultureDictionaryFactory>(),
factory.GetInstance<IUmbracoComponentRenderer>(), factory.GetInstance<IPublishedContentQuery>(),
@@ -20,7 +20,7 @@ namespace Umbraco.Web.Search
/// </summary>
public class UmbracoTreeSearcher
{
private readonly UmbracoContext _umbracoContext;
private readonly IUmbracoContext _umbracoContext;
private readonly ILocalizationService _languageService;
private readonly IEntityService _entityService;
private readonly UmbracoMapper _mapper;
@@ -28,7 +28,7 @@ namespace Umbraco.Web.Search
private readonly IBackOfficeExamineSearcher _backOfficeExamineSearcher;
public UmbracoTreeSearcher(UmbracoContext umbracoContext,
public UmbracoTreeSearcher(IUmbracoContext umbracoContext,
ILocalizationService languageService,
IEntityService entityService,
UmbracoMapper mapper,
@@ -48,7 +48,7 @@ namespace Umbraco.Web.Security
/// <param name="umbracoContext"></param>
/// <param name="loginInfo"></param>
/// <returns></returns>
public string[] GetDefaultUserGroups(UmbracoContext umbracoContext, ExternalLoginInfo loginInfo)
public string[] GetDefaultUserGroups(IUmbracoContext umbracoContext, ExternalLoginInfo loginInfo)
{
return _defaultUserGroups;
}
@@ -61,7 +61,7 @@ namespace Umbraco.Web.Security
///
/// For public auth providers this should always be false!!!
/// </summary>
public bool ShouldAutoLinkExternalAccount(UmbracoContext umbracoContext, ExternalLoginInfo loginInfo)
public bool ShouldAutoLinkExternalAccount(IUmbracoContext umbracoContext, ExternalLoginInfo loginInfo)
{
return _autoLinkExternalAccount;
}
@@ -71,7 +71,7 @@ namespace Umbraco.Web.Security
/// <summary>
/// The default Culture to use for auto-linking users
/// </summary>
public string GetDefaultCulture(UmbracoContext umbracoContext, ExternalLoginInfo loginInfo)
public string GetDefaultCulture(IUmbracoContext umbracoContext, ExternalLoginInfo loginInfo)
{
return _defaultCulture;
}
@@ -7,6 +7,6 @@ namespace Umbraco.Web.Security
/// </summary>
public interface IUmbracoBackOfficeTwoFactorOptions
{
string GetTwoFactorView(IOwinContext owinContext, UmbracoContext umbracoContext, string username);
string GetTwoFactorView(IOwinContext owinContext, IUmbracoContext umbracoContext, string username);
}
}
+12 -77
View File
@@ -10,9 +10,7 @@ using Microsoft.Owin;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Identity;
using Umbraco.Web.Models.Identity;
using Current = Umbraco.Web.Composing.Current;
namespace Umbraco.Web.Security
{
@@ -20,7 +18,7 @@ namespace Umbraco.Web.Security
/// <summary>
/// A utility class used for dealing with USER security in Umbraco
/// </summary>
public class WebSecurity
public class WebSecurity : IWebSecurity
{
private readonly HttpContextBase _httpContext;
private readonly IUserService _userService;
@@ -41,7 +39,7 @@ namespace Umbraco.Web.Security
/// Gets the current user.
/// </summary>
/// <value>The current user.</value>
public virtual IUser CurrentUser
public IUser CurrentUser
{
get
{
@@ -78,12 +76,8 @@ namespace Umbraco.Web.Security
protected BackOfficeUserManager<BackOfficeIdentityUser> UserManager
=> _userManager ?? (_userManager = _httpContext.GetOwinContext().GetBackOfficeUserManager());
/// <summary>
/// Logs a user in.
/// </summary>
/// <param name="userId">The user Id</param>
/// <returns>returns the number of seconds until their session times out</returns>
public virtual double PerformLogin(int userId)
[Obsolete("This needs to be removed, ASP.NET Identity should always be used for this operation, this is currently only used in the installer which needs to be updated")]
public double PerformLogin(int userId)
{
var owinCtx = _httpContext.GetOwinContext();
//ensure it's done for owin too
@@ -98,10 +92,8 @@ namespace Umbraco.Web.Security
return TimeSpan.FromMinutes(_globalSettings.TimeOutInMinutes).TotalSeconds;
}
/// <summary>
/// Clears the current login for the currently logged in user
/// </summary>
public virtual void ClearCurrentLogin()
[Obsolete("This needs to be removed, ASP.NET Identity should always be used for this operation, this is currently only used in the installer which needs to be updated")]
public void ClearCurrentLogin()
{
_httpContext.UmbracoLogout();
_httpContext.GetOwinContext().Authentication.SignOut(
@@ -112,67 +104,26 @@ namespace Umbraco.Web.Security
/// <summary>
/// Renews the user's login ticket
/// </summary>
public virtual void RenewLoginTimeout()
public void RenewLoginTimeout()
{
_httpContext.RenewUmbracoAuthTicket();
}
/// <summary>
/// Validates credentials for a back office user
/// </summary>
/// <param name="username"></param>
/// <param name="password"></param>
/// <returns></returns>
/// <remarks>
/// This uses ASP.NET Identity to perform the validation
/// </remarks>
public virtual bool ValidateBackOfficeCredentials(string username, string password)
{
//find the user by username
var user = UserManager.FindByNameAsync(username).Result;
return user != null && UserManager.CheckPasswordAsync(user, password).Result;
}
/// <summary>
/// Validates the current user to see if they have access to the specified app
/// </summary>
/// <param name="app"></param>
/// <returns></returns>
internal bool ValidateUserApp(string app)
{
//if it is empty, don't validate
if (app.IsNullOrWhiteSpace())
{
return true;
}
return CurrentUser.AllowedSections.Any(uApp => uApp.InvariantEquals(app));
}
/// <summary>
/// Gets the current user's id.
/// </summary>
/// <returns></returns>
public virtual Attempt<int> GetUserId()
public Attempt<int> GetUserId()
{
var identity = _httpContext.GetCurrentIdentity(false);
return identity == null ? Attempt.Fail<int>() : Attempt.Succeed(Convert.ToInt32(identity.Id));
}
/// <summary>
/// Returns the current user's unique session id - used to mitigate csrf attacks or any other reason to validate a request
/// </summary>
/// <returns></returns>
public virtual string GetSessionId()
{
var identity = _httpContext.GetCurrentIdentity(false);
return identity?.SessionId;
}
/// <summary>
/// Validates the currently logged in user and ensures they are not timed out
/// </summary>
/// <returns></returns>
public virtual bool ValidateCurrentUser()
public bool ValidateCurrentUser()
{
return ValidateCurrentUser(false, true) == ValidateRequestAttempt.Success;
}
@@ -183,7 +134,7 @@ namespace Umbraco.Web.Security
/// <param name="throwExceptions">set to true if you want exceptions to be thrown if failed</param>
/// <param name="requiresApproval">If true requires that the user is approved to be validated</param>
/// <returns></returns>
public virtual ValidateRequestAttempt ValidateCurrentUser(bool throwExceptions, bool requiresApproval = true)
public ValidateRequestAttempt ValidateCurrentUser(bool throwExceptions, bool requiresApproval = true)
{
//This will first check if the current user is already authenticated - which should be the case in nearly all circumstances
// since the authentication happens in the Module, that authentication also checks the ticket expiry. We don't
@@ -218,7 +169,7 @@ namespace Umbraco.Web.Security
/// </summary>
/// <param name="throwExceptions">set to true if you want exceptions to be thrown if failed</param>
/// <returns></returns>
internal ValidateRequestAttempt AuthorizeRequest(bool throwExceptions = false)
public ValidateRequestAttempt AuthorizeRequest(bool throwExceptions = false)
{
// check for secure connection
if (_globalSettings.UseHttps && _httpContext.Request.IsSecureConnection == false)
@@ -235,27 +186,11 @@ namespace Umbraco.Web.Security
/// <param name="section"></param>
/// <param name="user"></param>
/// <returns></returns>
internal virtual bool UserHasSectionAccess(string section, IUser user)
public bool UserHasSectionAccess(string section, IUser user)
{
return user.HasSectionAccess(section);
}
/// <summary>
/// Checks if the specified user by username as access to the app
/// </summary>
/// <param name="section"></param>
/// <param name="username"></param>
/// <returns></returns>
internal bool UserHasSectionAccess(string section, string username)
{
var user = _userService.GetByUsername(username);
if (user == null)
{
return false;
}
return user.HasSectionAccess(section);
}
/// <summary>
/// Ensures that a back office user is logged in
/// </summary>
@@ -2,6 +2,7 @@ using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Umbraco.Core.Configuration.UmbracoSettings;
@@ -28,8 +29,9 @@ namespace Umbraco.Web.Templates
private readonly ILocalizationService _languageService;
private readonly IWebRoutingSection _webRoutingSection;
private readonly IShortStringHelper _shortStringHelper;
private readonly IHttpContextAccessor _httpContextAccessor;
public TemplateRenderer(IUmbracoContextAccessor umbracoContextAccessor, IPublishedRouter publishedRouter, IFileService fileService, ILocalizationService textService, IWebRoutingSection webRoutingSection, IShortStringHelper shortStringHelper)
public TemplateRenderer(IUmbracoContextAccessor umbracoContextAccessor, IPublishedRouter publishedRouter, IFileService fileService, ILocalizationService textService, IWebRoutingSection webRoutingSection, IShortStringHelper shortStringHelper, IHttpContextAccessor httpContextAccessor)
{
_umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor));
_publishedRouter = publishedRouter ?? throw new ArgumentNullException(nameof(publishedRouter));
@@ -37,6 +39,7 @@ namespace Umbraco.Web.Templates
_languageService = textService ?? throw new ArgumentNullException(nameof(textService));
_webRoutingSection = webRoutingSection ?? throw new ArgumentNullException(nameof(webRoutingSection));
_shortStringHelper = shortStringHelper ?? throw new ArgumentNullException(nameof(shortStringHelper));
_httpContextAccessor = httpContextAccessor;
}
public void Render(int pageId, int? altTemplateId, StringWriter writer)
@@ -114,7 +117,7 @@ namespace Umbraco.Web.Templates
}
private void ExecuteTemplateRendering(TextWriter sw, PublishedRequest request)
private void ExecuteTemplateRendering(TextWriter sw, IPublishedRequest request)
{
//NOTE: Before we used to build up the query strings here but this is not necessary because when we do a
// Server.Execute in the TemplateRenderer, we pass in a 'true' to 'preserveForm' which automatically preserves all current
@@ -124,7 +127,7 @@ namespace Umbraco.Web.Templates
//var queryString = _umbracoContext.HttpContext.Request.QueryString.AllKeys
// .ToDictionary(key => key, key => context.Request.QueryString[key]);
var requestContext = new RequestContext(_umbracoContextAccessor.UmbracoContext.HttpContext, new RouteData()
var requestContext = new RequestContext(_httpContextAccessor.HttpContext, new RouteData()
{
Route = RouteTable.Routes["Umbraco_default"]
});
@@ -169,7 +172,7 @@ namespace Umbraco.Web.Templates
return newWriter.ToString();
}
private void SetNewItemsOnContextObjects(PublishedRequest request)
private void SetNewItemsOnContextObjects(IPublishedRequest request)
{
//now, set the new ones for this page execution
_umbracoContextAccessor.UmbracoContext.PublishedRequest = request;
@@ -178,7 +181,7 @@ namespace Umbraco.Web.Templates
/// <summary>
/// Save all items that we know are used for rendering execution to variables so we can restore after rendering
/// </summary>
private void SaveExistingItems(out PublishedRequest oldPublishedRequest)
private void SaveExistingItems(out IPublishedRequest oldPublishedRequest)
{
//Many objects require that these legacy items are in the http context items... before we render this template we need to first
//save the values in them so that we can re-set them after we render so the rest of the execution works as per normal
@@ -188,7 +191,7 @@ namespace Umbraco.Web.Templates
/// <summary>
/// Restores all items back to their context's to continue normal page rendering execution
/// </summary>
private void RestoreItems(PublishedRequest oldPublishedRequest)
private void RestoreItems(IPublishedRequest oldPublishedRequest)
{
_umbracoContextAccessor.UmbracoContext.PublishedRequest = oldPublishedRequest;
}

Some files were not shown because too many files have changed in this diff Show More