diff --git a/src/Umbraco.Abstractions/Hosting/IHostingEnvironment.cs b/src/Umbraco.Abstractions/Hosting/IHostingEnvironment.cs new file mode 100644 index 0000000000..19ad5614b4 --- /dev/null +++ b/src/Umbraco.Abstractions/Hosting/IHostingEnvironment.cs @@ -0,0 +1,16 @@ +namespace Umbraco.Core.Hosting +{ + public interface IHostingEnvironment + { + string SiteName { get; } + string ApplicationId { get; } + string ApplicationPhysicalPath { get; } + + string LocalTempPath { get; } + string ApplicationVirtualPath { get; } + + bool IsDebugMode { get; } + bool IsHosted { get; } + string MapPath(string path); + } +} diff --git a/src/Umbraco.Abstractions/IBackOfficeInfo.cs b/src/Umbraco.Abstractions/IBackOfficeInfo.cs new file mode 100644 index 0000000000..936fb73382 --- /dev/null +++ b/src/Umbraco.Abstractions/IBackOfficeInfo.cs @@ -0,0 +1,10 @@ +namespace Umbraco.Core +{ + public interface IBackOfficeInfo + { + /// + /// Gets the absolute url to the Umbraco Backoffice. This info can be used to build absolute urls for Backoffice to use in mails etc. + /// + string GetAbsoluteUrl { get; } + } +} diff --git a/src/Umbraco.Abstractions/Net/IIpResolver.cs b/src/Umbraco.Abstractions/Net/IIpResolver.cs new file mode 100644 index 0000000000..7fb6b8a793 --- /dev/null +++ b/src/Umbraco.Abstractions/Net/IIpResolver.cs @@ -0,0 +1,7 @@ +namespace Umbraco.Net +{ + public interface IIpResolver + { + string GetCurrentRequestIpAddress(); + } +} diff --git a/src/Umbraco.Abstractions/Net/ISessionIdResolver.cs b/src/Umbraco.Abstractions/Net/ISessionIdResolver.cs new file mode 100644 index 0000000000..745be5a435 --- /dev/null +++ b/src/Umbraco.Abstractions/Net/ISessionIdResolver.cs @@ -0,0 +1,7 @@ +namespace Umbraco.Net +{ + public interface ISessionIdResolver + { + string SessionId { get; } + } +} diff --git a/src/Umbraco.Abstractions/Runtime/IUmbracoBootPermissionChecker.cs b/src/Umbraco.Abstractions/Runtime/IUmbracoBootPermissionChecker.cs new file mode 100644 index 0000000000..4e48a8b030 --- /dev/null +++ b/src/Umbraco.Abstractions/Runtime/IUmbracoBootPermissionChecker.cs @@ -0,0 +1,7 @@ +namespace Umbraco.Core.Runtime +{ + public interface IUmbracoBootPermissionChecker + { + void ThrowIfNotPermissions(); + } +} diff --git a/src/Umbraco.Abstractions/Strings/HtmlEncodedString.cs b/src/Umbraco.Abstractions/Strings/HtmlEncodedString.cs new file mode 100644 index 0000000000..936b163615 --- /dev/null +++ b/src/Umbraco.Abstractions/Strings/HtmlEncodedString.cs @@ -0,0 +1,33 @@ +namespace Umbraco.Core.Strings +{ + /// + /// Represents an HTML-encoded string that should not be encoded again. + /// + public class HtmlEncodedString : IHtmlEncodedString + { + + private string _htmlString; + + /// Initializes a new instance of the class. + /// An HTML-encoded string that should not be encoded again. + public HtmlEncodedString(string value) + { + this._htmlString = value; + } + + /// Returns an HTML-encoded string. + /// An HTML-encoded string. + public string ToHtmlString() + { + return this._htmlString; + } + + /// Returns a string that represents the current object. + /// A string that represents the current object. + public override string ToString() + { + return this._htmlString; + } + + } +} diff --git a/src/Umbraco.Abstractions/Strings/IHtmlEncodedString.cs b/src/Umbraco.Abstractions/Strings/IHtmlEncodedString.cs new file mode 100644 index 0000000000..0096a8a1f3 --- /dev/null +++ b/src/Umbraco.Abstractions/Strings/IHtmlEncodedString.cs @@ -0,0 +1,14 @@ +namespace Umbraco.Core.Strings +{ + /// + /// Represents an HTML-encoded string that should not be encoded again. + /// + public interface IHtmlEncodedString + { + /// + /// Returns an HTML-encoded string. + /// + /// An HTML-encoded string. + string ToHtmlString(); + } +} diff --git a/src/Umbraco.Abstractions/Sync/DatabaseServerRegistrar.cs b/src/Umbraco.Abstractions/Sync/DatabaseServerRegistrar.cs index 276ce6097c..390e89843e 100644 --- a/src/Umbraco.Abstractions/Sync/DatabaseServerRegistrar.cs +++ b/src/Umbraco.Abstractions/Sync/DatabaseServerRegistrar.cs @@ -45,14 +45,5 @@ namespace Umbraco.Core.Sync return service.GetCurrentServerRole(); } - /// - /// Gets the current umbraco application url. - /// - public string GetCurrentServerUmbracoApplicationUrl() - { - // this registrar does not provide the umbraco application url - return null; - } - } } diff --git a/src/Umbraco.Abstractions/Sync/IServerRegistrar.cs b/src/Umbraco.Abstractions/Sync/IServerRegistrar.cs index a4edb1d0e9..780f865ad7 100644 --- a/src/Umbraco.Abstractions/Sync/IServerRegistrar.cs +++ b/src/Umbraco.Abstractions/Sync/IServerRegistrar.cs @@ -17,13 +17,5 @@ namespace Umbraco.Core.Sync /// ServerRole GetCurrentServerRole(); - /// - /// Gets the current umbraco application url. - /// - /// - /// If the registrar does not provide the umbraco application url, should return null. - /// Must return null, or a url that ends with SystemDirectories.Umbraco, and contains a scheme, eg "http://www.mysite.com/umbraco". - /// - string GetCurrentServerUmbracoApplicationUrl(); } } diff --git a/src/Umbraco.Abstractions/Sync/SingleServerRegistrar.cs b/src/Umbraco.Abstractions/Sync/SingleServerRegistrar.cs index b29533dd51..c423c6e624 100644 --- a/src/Umbraco.Abstractions/Sync/SingleServerRegistrar.cs +++ b/src/Umbraco.Abstractions/Sync/SingleServerRegistrar.cs @@ -29,10 +29,6 @@ namespace Umbraco.Core.Sync return ServerRole.Single; } - public string GetCurrentServerUmbracoApplicationUrl() - { - return _runtime.ApplicationUrl?.ToString(); - } private class ServerAddressImpl : IServerAddress { diff --git a/src/Umbraco.Core/Compose/AuditEventsComponent.cs b/src/Umbraco.Core/Compose/AuditEventsComponent.cs index 453fd6314a..6ebe5a2acd 100644 --- a/src/Umbraco.Core/Compose/AuditEventsComponent.cs +++ b/src/Umbraco.Core/Compose/AuditEventsComponent.cs @@ -2,7 +2,6 @@ using System.Linq; using System.Text; using System.Threading; -using System.Web; using Umbraco.Core.Composing; using Umbraco.Core.Events; using Umbraco.Core.Models; @@ -10,6 +9,7 @@ using Umbraco.Core.Models.Membership; using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Core.Services.Implement; +using Umbraco.Net; namespace Umbraco.Core.Compose { @@ -18,12 +18,14 @@ namespace Umbraco.Core.Compose private readonly IAuditService _auditService; private readonly IUserService _userService; private readonly IEntityService _entityService; + private readonly IIpResolver _ipResolver; - public AuditEventsComponent(IAuditService auditService, IUserService userService, IEntityService entityService) + public AuditEventsComponent(IAuditService auditService, IUserService userService, IEntityService entityService, IIpResolver ipResolver) { _auditService = auditService; _userService = userService; _entityService = entityService; + _ipResolver = ipResolver; } public void Initialize() @@ -62,16 +64,7 @@ namespace Umbraco.Core.Compose return found ?? UnknownUser; } - private string PerformingIp - { - get - { - var httpContext = HttpContext.Current == null ? (HttpContextBase) null : new HttpContextWrapper(HttpContext.Current); - var ip = httpContext.GetCurrentRequestIpAddress(); - if (ip.ToLowerInvariant().StartsWith("unknown")) ip = ""; - return ip; - } - } + private string PerformingIp => _ipResolver.GetCurrentRequestIpAddress(); private string FormatEmail(IMember member) { diff --git a/src/Umbraco.Core/Composing/Current.cs b/src/Umbraco.Core/Composing/Current.cs index e0cedca0ce..4eba166020 100644 --- a/src/Umbraco.Core/Composing/Current.cs +++ b/src/Umbraco.Core/Composing/Current.cs @@ -2,6 +2,7 @@ using Umbraco.Core.Cache; using Umbraco.Core.Configuration; using Umbraco.Core.Dictionary; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Mapping; @@ -15,6 +16,7 @@ using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Core.Strings; using Umbraco.Core.Sync; +using Umbraco.Net; namespace Umbraco.Core.Composing { @@ -206,9 +208,13 @@ namespace Umbraco.Core.Composing public static IVariationContextAccessor VariationContextAccessor => Factory.GetInstance(); - public static readonly IIOHelper IOHelper = Umbraco.Core.IO.IOHelper.Default; + public static IIOHelper IOHelper = new IOHelper(); + public static IHostingEnvironment HostingEnvironment => Factory.GetInstance(); + public static IBackOfficeInfo BackOfficeInfo => Factory.GetInstance(); + public static ISessionIdResolver SessionIdResolver => Factory.GetInstance(); + #endregion } } diff --git a/src/Umbraco.Core/Configuration/GlobalSettingsExtensions.cs b/src/Umbraco.Core/Configuration/GlobalSettingsExtensions.cs deleted file mode 100644 index 65b1a0d9ea..0000000000 --- a/src/Umbraco.Core/Configuration/GlobalSettingsExtensions.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using System.Web; -using System.Web.Hosting; -using Umbraco.Core.IO; - -namespace Umbraco.Core.Configuration -{ - - public static class GlobalSettingsExtensions - { - private static string _localTempPath; - - /// - /// Gets the location of temporary files. - /// - public static string LocalTempPath(this IGlobalSettings globalSettings, IIOHelper ioHelper) - { - - if (_localTempPath != null) - return _localTempPath; - - switch (globalSettings.LocalTempStorageLocation) - { - case LocalTempStorage.AspNetTemp: - return _localTempPath = System.IO.Path.Combine(HttpRuntime.CodegenDir, "UmbracoData"); - - case LocalTempStorage.EnvironmentTemp: - - // environment temp is unique, we need a folder per site - - // use a hash - // combine site name and application id - // site name is a Guid on Cloud - // application id is eg /LM/W3SVC/123456/ROOT - // the combination is unique on one server - // and, if a site moves from worker A to B and then back to A... - // hopefully it gets a new Guid or new application id? - - var siteName = HostingEnvironment.SiteName; - var applicationId = HostingEnvironment.ApplicationID; // ie HttpRuntime.AppDomainAppId - - var hashString = siteName + "::" + applicationId; - var hash = hashString.GenerateHash(); - var siteTemp = System.IO.Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData", hash); - - return _localTempPath = siteTemp; - - //case LocalTempStorage.Default: - //case LocalTempStorage.Unknown: - default: - return _localTempPath = ioHelper.MapPath("~/App_Data/TEMP"); - } - - } - - } -} diff --git a/src/Umbraco.Core/ContentExtensions.cs b/src/Umbraco.Core/ContentExtensions.cs index df3f7a6611..2a61c44323 100644 --- a/src/Umbraco.Core/ContentExtensions.cs +++ b/src/Umbraco.Core/ContentExtensions.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; -using System.Web; using System.Xml.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -129,14 +128,6 @@ namespace Umbraco.Core #region SetValue for setting file contents - /// - /// Sets the posted file value of a property. - /// - public static void SetValue(this IContentBase content, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, string propertyTypeAlias, string filename, HttpPostedFileBase postedFile, string culture = null, string segment = null) - { - content.SetValue(contentTypeBaseServiceProvider, propertyTypeAlias, postedFile.FileName, postedFile.InputStream, culture, segment); - } - /// /// Sets the posted file value of a property. /// diff --git a/src/Umbraco.Core/IO/IOHelper.cs b/src/Umbraco.Core/IO/IOHelper.cs index 0c15ac1b26..450e3862f2 100644 --- a/src/Umbraco.Core/IO/IOHelper.cs +++ b/src/Umbraco.Core/IO/IOHelper.cs @@ -6,15 +6,11 @@ using System.IO; using System.Linq; using System.Web; using System.Web.Hosting; -using Umbraco.Core.Configuration; namespace Umbraco.Core.IO { public class IOHelper : IIOHelper { - internal static IIOHelper Default { get; } = new IOHelper(); - - /// /// Gets or sets a value forcing Umbraco to consider it is non-hosted. /// @@ -298,7 +294,7 @@ namespace Umbraco.Core.IO { if (_root != null) return _root; - var appPath = HttpRuntime.AppDomainAppVirtualPath; + var appPath = HostingEnvironment.ApplicationVirtualPath; // ReSharper disable once ConditionIsAlwaysTrueOrFalse if (appPath == null || appPath == "/") appPath = string.Empty; diff --git a/src/Umbraco.Core/IO/SystemFiles.cs b/src/Umbraco.Core/IO/SystemFiles.cs index 5025a5b01f..92e9156f2f 100644 --- a/src/Umbraco.Core/IO/SystemFiles.cs +++ b/src/Umbraco.Core/IO/SystemFiles.cs @@ -1,6 +1,7 @@ using System.IO; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; +using Umbraco.Core.Hosting; namespace Umbraco.Core.IO { @@ -9,9 +10,9 @@ namespace Umbraco.Core.IO public static string TinyMceConfig => Constants.SystemDirectories.Config + "/tinyMceConfig.config"; // TODO: Kill this off we don't have umbraco.config XML cache we now have NuCache - public static string GetContentCacheXml(IGlobalSettings globalSettings) + public static string GetContentCacheXml(IHostingEnvironment hostingEnvironment) { - return Path.Combine(globalSettings.LocalTempPath(Current.IOHelper), "umbraco.config"); + return Path.Combine(hostingEnvironment.LocalTempPath, "umbraco.config"); } } } diff --git a/src/Umbraco.Core/Logging/LogHttpRequest.cs b/src/Umbraco.Core/Logging/LogHttpRequest.cs index 34c1918b76..01a2e922af 100644 --- a/src/Umbraco.Core/Logging/LogHttpRequest.cs +++ b/src/Umbraco.Core/Logging/LogHttpRequest.cs @@ -1,5 +1,5 @@ using System; -using System.Web; +using Umbraco.Core.Composing; namespace Umbraco.Core.Logging { @@ -14,17 +14,8 @@ namespace Umbraco.Core.Logging /// true if there is a request in progress; false otherwise. public static bool TryGetCurrentHttpRequestId(out Guid requestId) { - if (HttpContext.Current == null) - { - requestId = default(Guid); - return false; - } - - var requestIdItem = HttpContext.Current.Items[RequestIdItemName]; - if (requestIdItem == null) - HttpContext.Current.Items[RequestIdItemName] = requestId = Guid.NewGuid(); - else - requestId = (Guid)requestIdItem; + var requestIdItem = Current.AppCaches.RequestCache.Get(RequestIdItemName, () => Guid.NewGuid()); + requestId = (Guid)requestIdItem; return true; } diff --git a/src/Umbraco.Core/Logging/Serilog/Enrichers/HttpRequestNumberEnricher.cs b/src/Umbraco.Core/Logging/Serilog/Enrichers/HttpRequestNumberEnricher.cs index 48415cccbc..67bb3ed8d3 100644 --- a/src/Umbraco.Core/Logging/Serilog/Enrichers/HttpRequestNumberEnricher.cs +++ b/src/Umbraco.Core/Logging/Serilog/Enrichers/HttpRequestNumberEnricher.cs @@ -1,8 +1,8 @@ using System; using System.Threading; -using System.Web; using Serilog.Core; using Serilog.Events; +using Umbraco.Core.Cache; namespace Umbraco.Core.Logging.Serilog.Enrichers { @@ -14,13 +14,20 @@ namespace Umbraco.Core.Logging.Serilog.Enrichers /// internal class HttpRequestNumberEnricher : ILogEventEnricher { + private static int _lastRequestNumber; + private static readonly string _requestNumberItemName = typeof(HttpRequestNumberEnricher).Name + "+RequestNumber"; + /// /// The property name added to enriched log events. /// - public const string HttpRequestNumberPropertyName = "HttpRequestNumber"; + private const string _httpRequestNumberPropertyName = "HttpRequestNumber"; - static int _lastRequestNumber; - static readonly string RequestNumberItemName = typeof(HttpRequestNumberEnricher).Name + "+RequestNumber"; + private readonly Lazy _requestCache; + + public HttpRequestNumberEnricher(Lazy requestCache) + { + _requestCache = requestCache; + } /// /// Enrich the log event with the number assigned to the currently-executing HTTP request, if any. @@ -31,17 +38,10 @@ namespace Umbraco.Core.Logging.Serilog.Enrichers { if (logEvent == null) throw new ArgumentNullException("logEvent"); - if (HttpContext.Current == null) - return; + var requestNumber = _requestCache.Value.Get(_requestNumberItemName, + () => Interlocked.Increment(ref _lastRequestNumber)); - int requestNumber; - var requestNumberItem = HttpContext.Current.Items[RequestNumberItemName]; - if (requestNumberItem == null) - HttpContext.Current.Items[RequestNumberItemName] = requestNumber = Interlocked.Increment(ref _lastRequestNumber); - else - requestNumber = (int)requestNumberItem; - - var requestNumberProperty = new LogEventProperty(HttpRequestNumberPropertyName, new ScalarValue(requestNumber)); + var requestNumberProperty = new LogEventProperty(_httpRequestNumberPropertyName, new ScalarValue(requestNumber)); logEvent.AddPropertyIfAbsent(requestNumberProperty); } } diff --git a/src/Umbraco.Core/Logging/Serilog/Enrichers/HttpSessionIdEnricher.cs b/src/Umbraco.Core/Logging/Serilog/Enrichers/HttpSessionIdEnricher.cs index d2fbfd4627..0708cb7eb5 100644 --- a/src/Umbraco.Core/Logging/Serilog/Enrichers/HttpSessionIdEnricher.cs +++ b/src/Umbraco.Core/Logging/Serilog/Enrichers/HttpSessionIdEnricher.cs @@ -1,7 +1,7 @@ using Serilog.Core; using Serilog.Events; using System; -using System.Web; +using Umbraco.Net; namespace Umbraco.Core.Logging.Serilog.Enrichers { @@ -12,6 +12,13 @@ namespace Umbraco.Core.Logging.Serilog.Enrichers /// internal class HttpSessionIdEnricher : ILogEventEnricher { + private readonly Lazy _sessionIdResolver; + + public HttpSessionIdEnricher(Lazy sessionIdResolver) + { + _sessionIdResolver = sessionIdResolver; + } + /// /// The property name added to enriched log events. /// @@ -23,15 +30,12 @@ namespace Umbraco.Core.Logging.Serilog.Enrichers /// Factory for creating new properties to add to the event. public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) { - if (logEvent == null) throw new ArgumentNullException("logEvent"); + if (logEvent == null) throw new ArgumentNullException(nameof(logEvent)); - if (HttpContext.Current == null) + var sessionId = _sessionIdResolver.Value.SessionId; + if (sessionId is null) return; - if (HttpContext.Current.Session == null) - return; - - var sessionId = HttpContext.Current.Session.SessionID; var sessionIdProperty = new LogEventProperty(HttpSessionIdPropertyName, new ScalarValue(sessionId)); logEvent.AddPropertyIfAbsent(sessionIdProperty); } diff --git a/src/Umbraco.Core/Logging/Serilog/LoggerConfigExtensions.cs b/src/Umbraco.Core/Logging/Serilog/LoggerConfigExtensions.cs index 951d6f8787..fc6b9982ad 100644 --- a/src/Umbraco.Core/Logging/Serilog/LoggerConfigExtensions.cs +++ b/src/Umbraco.Core/Logging/Serilog/LoggerConfigExtensions.cs @@ -1,26 +1,31 @@ using System; using System.Text; -using System.Web; using Serilog; using Serilog.Configuration; using Serilog.Core; using Serilog.Events; using Serilog.Formatting; using Serilog.Formatting.Compact; +using Umbraco.Core.Cache; +using Umbraco.Core.Composing; +using Umbraco.Core.Hosting; using Umbraco.Core.Logging.Serilog.Enrichers; +using Umbraco.Net; namespace Umbraco.Core.Logging.Serilog { public static class LoggerConfigExtensions { private const string AppDomainId = "AppDomainId"; + /// /// This configures Serilog with some defaults /// Such as adding ProcessID, Thread, AppDomain etc /// It is highly recommended that you keep/use this default in your own logging config customizations /// /// A Serilog LoggerConfiguration - public static LoggerConfiguration MinimalConfiguration(this LoggerConfiguration logConfig) + /// + public static LoggerConfiguration MinimalConfiguration(this LoggerConfiguration logConfig, IHostingEnvironment hostingEnvironment) { global::Serilog.Debugging.SelfLog.Enable(msg => System.Diagnostics.Debug.WriteLine(msg)); @@ -34,11 +39,11 @@ namespace Umbraco.Core.Logging.Serilog .Enrich.WithProcessName() .Enrich.WithThreadId() .Enrich.WithProperty(AppDomainId, AppDomain.CurrentDomain.Id) - .Enrich.WithProperty("AppDomainAppId", HttpRuntime.AppDomainAppId.ReplaceNonAlphanumericChars(string.Empty)) + .Enrich.WithProperty("AppDomainAppId", hostingEnvironment.ApplicationId.ReplaceNonAlphanumericChars(string.Empty)) .Enrich.WithProperty("MachineName", Environment.MachineName) .Enrich.With() - .Enrich.With() - .Enrich.With() + .Enrich.With(new HttpSessionIdEnricher(new Lazy(() => Current.SessionIdResolver))) + .Enrich.With(new HttpRequestNumberEnricher(new Lazy(() => Current.AppCaches.RequestCache))) .Enrich.With(); return logConfig; diff --git a/src/Umbraco.Core/Logging/Serilog/SerilogLogger.cs b/src/Umbraco.Core/Logging/Serilog/SerilogLogger.cs index a51628030e..40be4e0079 100644 --- a/src/Umbraco.Core/Logging/Serilog/SerilogLogger.cs +++ b/src/Umbraco.Core/Logging/Serilog/SerilogLogger.cs @@ -5,8 +5,8 @@ using System.Threading; using Serilog; using Serilog.Events; using Umbraco.Core.Composing; -using Umbraco.Core.Configuration; using Umbraco.Core.Diagnostics; +using Umbraco.Core.Hosting; namespace Umbraco.Core.Logging.Serilog { @@ -36,11 +36,11 @@ namespace Umbraco.Core.Logging.Serilog /// Creates a logger with some pre-defined configuration and remainder from config file /// /// Used by UmbracoApplicationBase to get its logger. - public static SerilogLogger CreateWithDefaultConfiguration() + public static SerilogLogger CreateWithDefaultConfiguration(IHostingEnvironment hostingEnvironment) { var loggerConfig = new LoggerConfiguration(); loggerConfig - .MinimalConfiguration() + .MinimalConfiguration(hostingEnvironment) .ReadFromConfigFile() .ReadFromUserConfigFile(); diff --git a/src/Umbraco.Core/MainDom.cs b/src/Umbraco.Core/MainDom.cs index 5da1062275..440025a042 100644 --- a/src/Umbraco.Core/MainDom.cs +++ b/src/Umbraco.Core/MainDom.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Security.Cryptography; using System.Threading; using System.Web.Hosting; +using Umbraco.Core.Hosting; using Umbraco.Core.Logging; namespace Umbraco.Core @@ -46,14 +47,14 @@ namespace Umbraco.Core #region Ctor // initializes a new instance of MainDom - public MainDom(ILogger logger) + public MainDom(ILogger logger, IHostingEnvironment hostingEnvironment) { _logger = logger; var appId = string.Empty; // HostingEnvironment.ApplicationID is null in unit tests, making ReplaceNonAlphanumericChars fail - if (HostingEnvironment.ApplicationID != null) - appId = HostingEnvironment.ApplicationID.ReplaceNonAlphanumericChars(string.Empty); + if (hostingEnvironment.ApplicationId != null) + appId = hostingEnvironment.ApplicationId.ReplaceNonAlphanumericChars(string.Empty); // combining with the physical path because if running on eg IIS Express, // two sites could have the same appId even though they are different. @@ -64,7 +65,7 @@ namespace Umbraco.Core // we *cannot* use the process ID here because when an AppPool restarts it is // a new process for the same application path - var appPath = HostingEnvironment.ApplicationPhysicalPath; + var appPath = hostingEnvironment.ApplicationPhysicalPath; var hash = (appId + ":::" + appPath).GenerateHash(); var lockName = "UMBRACO-" + hash + "-MAINDOM-LCK"; diff --git a/src/Umbraco.Core/Models/PublishedContent/IndexedArrayItem.cs b/src/Umbraco.Core/Models/PublishedContent/IndexedArrayItem.cs index 5dc42cc542..18a5587a65 100644 --- a/src/Umbraco.Core/Models/PublishedContent/IndexedArrayItem.cs +++ b/src/Umbraco.Core/Models/PublishedContent/IndexedArrayItem.cs @@ -1,4 +1,4 @@ -using System.Web; +using Umbraco.Core.Strings; namespace Umbraco.Core.Models.PublishedContent { @@ -21,14 +21,14 @@ namespace Umbraco.Core.Models.PublishedContent return Index == 0; } - public HtmlString IsFirst(string valueIfTrue) + public IHtmlEncodedString IsFirst(string valueIfTrue) { return IsFirst(valueIfTrue, string.Empty); } - public HtmlString IsFirst(string valueIfTrue, string valueIfFalse) + public IHtmlEncodedString IsFirst(string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsFirst() ? valueIfTrue : valueIfFalse); + return new HtmlEncodedString(IsFirst() ? valueIfTrue : valueIfFalse); } public bool IsNotFirst() @@ -36,14 +36,14 @@ namespace Umbraco.Core.Models.PublishedContent return IsFirst() == false; } - public HtmlString IsNotFirst(string valueIfTrue) + public IHtmlEncodedString IsNotFirst(string valueIfTrue) { return IsNotFirst(valueIfTrue, string.Empty); } - public HtmlString IsNotFirst(string valueIfTrue, string valueIfFalse) + public IHtmlEncodedString IsNotFirst(string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsNotFirst() ? valueIfTrue : valueIfFalse); + return new HtmlEncodedString(IsNotFirst() ? valueIfTrue : valueIfFalse); } public bool IsIndex(int index) @@ -51,14 +51,14 @@ namespace Umbraco.Core.Models.PublishedContent return Index == index; } - public HtmlString IsIndex(int index, string valueIfTrue) + public IHtmlEncodedString IsIndex(int index, string valueIfTrue) { return IsIndex(index, valueIfTrue, string.Empty); } - public HtmlString IsIndex(int index, string valueIfTrue, string valueIfFalse) + public IHtmlEncodedString IsIndex(int index, string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsIndex(index) ? valueIfTrue : valueIfFalse); + return new HtmlEncodedString(IsIndex(index) ? valueIfTrue : valueIfFalse); } public bool IsModZero(int modulus) @@ -66,14 +66,14 @@ namespace Umbraco.Core.Models.PublishedContent return Index % modulus == 0; } - public HtmlString IsModZero(int modulus, string valueIfTrue) + public IHtmlEncodedString IsModZero(int modulus, string valueIfTrue) { return IsModZero(modulus, valueIfTrue, string.Empty); } - public HtmlString IsModZero(int modulus, string valueIfTrue, string valueIfFalse) + public IHtmlEncodedString IsModZero(int modulus, string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsModZero(modulus) ? valueIfTrue : valueIfFalse); + return new HtmlEncodedString(IsModZero(modulus) ? valueIfTrue : valueIfFalse); } public bool IsNotModZero(int modulus) @@ -81,14 +81,14 @@ namespace Umbraco.Core.Models.PublishedContent return IsModZero(modulus) == false; } - public HtmlString IsNotModZero(int modulus, string valueIfTrue) + public IHtmlEncodedString IsNotModZero(int modulus, string valueIfTrue) { return IsNotModZero(modulus, valueIfTrue, string.Empty); } - public HtmlString IsNotModZero(int modulus, string valueIfTrue, string valueIfFalse) + public IHtmlEncodedString IsNotModZero(int modulus, string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsNotModZero(modulus) ? valueIfTrue : valueIfFalse); + return new HtmlEncodedString(IsNotModZero(modulus) ? valueIfTrue : valueIfFalse); } public bool IsNotIndex(int index) @@ -96,14 +96,14 @@ namespace Umbraco.Core.Models.PublishedContent return IsIndex(index) == false; } - public HtmlString IsNotIndex(int index, string valueIfTrue) + public IHtmlEncodedString IsNotIndex(int index, string valueIfTrue) { return IsNotIndex(index, valueIfTrue, string.Empty); } - public HtmlString IsNotIndex(int index, string valueIfTrue, string valueIfFalse) + public IHtmlEncodedString IsNotIndex(int index, string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsNotIndex(index) ? valueIfTrue : valueIfFalse); + return new HtmlEncodedString(IsNotIndex(index) ? valueIfTrue : valueIfFalse); } public bool IsLast() @@ -111,14 +111,14 @@ namespace Umbraco.Core.Models.PublishedContent return Index == TotalCount - 1; } - public HtmlString IsLast(string valueIfTrue) + public IHtmlEncodedString IsLast(string valueIfTrue) { return IsLast(valueIfTrue, string.Empty); } - public HtmlString IsLast(string valueIfTrue, string valueIfFalse) + public IHtmlEncodedString IsLast(string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsLast() ? valueIfTrue : valueIfFalse); + return new HtmlEncodedString(IsLast() ? valueIfTrue : valueIfFalse); } public bool IsNotLast() @@ -126,14 +126,14 @@ namespace Umbraco.Core.Models.PublishedContent return IsLast() == false; } - public HtmlString IsNotLast(string valueIfTrue) + public IHtmlEncodedString IsNotLast(string valueIfTrue) { return IsNotLast(valueIfTrue, string.Empty); } - public HtmlString IsNotLast(string valueIfTrue, string valueIfFalse) + public IHtmlEncodedString IsNotLast(string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsNotLast() ? valueIfTrue : valueIfFalse); + return new HtmlEncodedString(IsNotLast() ? valueIfTrue : valueIfFalse); } public bool IsEven() @@ -141,14 +141,14 @@ namespace Umbraco.Core.Models.PublishedContent return Index % 2 == 0; } - public HtmlString IsEven(string valueIfTrue) + public IHtmlEncodedString IsEven(string valueIfTrue) { return IsEven(valueIfTrue, string.Empty); } - public HtmlString IsEven(string valueIfTrue, string valueIfFalse) + public IHtmlEncodedString IsEven(string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsEven() ? valueIfTrue : valueIfFalse); + return new HtmlEncodedString(IsEven() ? valueIfTrue : valueIfFalse); } public bool IsOdd() @@ -156,14 +156,14 @@ namespace Umbraco.Core.Models.PublishedContent return Index % 2 == 1; } - public HtmlString IsOdd(string valueIfTrue) + public IHtmlEncodedString IsOdd(string valueIfTrue) { return IsOdd(valueIfTrue, string.Empty); } - public HtmlString IsOdd(string valueIfTrue, string valueIfFalse) + public IHtmlEncodedString IsOdd(string valueIfTrue, string valueIfFalse) { - return new HtmlString(IsOdd() ? valueIfTrue : valueIfFalse); + return new HtmlEncodedString(IsOdd() ? valueIfTrue : valueIfFalse); } } } diff --git a/src/Umbraco.Core/Packaging/PackageDataInstallation.cs b/src/Umbraco.Core/Packaging/PackageDataInstallation.cs index ff50b7acde..2d031be7f1 100644 --- a/src/Umbraco.Core/Packaging/PackageDataInstallation.cs +++ b/src/Umbraco.Core/Packaging/PackageDataInstallation.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Web; +using System.Net; using System.Xml.Linq; using System.Xml.XPath; using Umbraco.Core.Collections; @@ -521,7 +521,7 @@ namespace Umbraco.Core.Packaging { var alias = documentType.Element("Info").Element("Alias").Value; var folders = foldersAttribute.Value.Split('/'); - var rootFolder = HttpUtility.UrlDecode(folders[0]); + var rootFolder = WebUtility.UrlDecode(folders[0]); //level 1 = root level folders, there can only be one with the same name var current = _contentTypeService.GetContainers(rootFolder, 1).FirstOrDefault(); @@ -541,7 +541,7 @@ namespace Umbraco.Core.Packaging for (var i = 1; i < folders.Length; i++) { - var folderName = HttpUtility.UrlDecode(folders[i]); + var folderName = WebUtility.UrlDecode(folders[i]); current = CreateContentTypeChildFolder(folderName, current); importedFolders[alias] = current.Id; } @@ -934,7 +934,7 @@ namespace Umbraco.Core.Packaging { var name = datatypeElement.Attribute("Name").Value; var folders = foldersAttribute.Value.Split('/'); - var rootFolder = HttpUtility.UrlDecode(folders[0]); + var rootFolder = WebUtility.UrlDecode(folders[0]); //there will only be a single result by name for level 1 (root) containers var current = _dataTypeService.GetContainers(rootFolder, 1).FirstOrDefault(); @@ -953,7 +953,7 @@ namespace Umbraco.Core.Packaging for (var i = 1; i < folders.Length; i++) { - var folderName = HttpUtility.UrlDecode(folders[i]); + var folderName = WebUtility.UrlDecode(folders[i]); current = CreateDataTypeChildFolder(folderName, current); importedFolders[name] = current.Id; } diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/UserRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/UserRepository.cs index f8e828a635..38cdfe3331 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/UserRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/UserRepository.cs @@ -136,7 +136,7 @@ SELECT '4CountOfLockedOut' AS colName, COUNT(id) AS num FROM umbracoUser WHERE u UNION SELECT '5CountOfInvited' AS colName, COUNT(id) AS num FROM umbracoUser WHERE lastLoginDate IS NULL AND userDisabled = 1 AND invitedDate IS NOT NULL UNION -SELECT '6CountOfDisabled' AS colName, COUNT(id) AS num FROM umbracoUser WHERE userDisabled = 0 AND userNoConsole = 0 AND lastLoginDate IS NULL +SELECT '6CountOfDisabled' AS colName, COUNT(id) AS num FROM umbracoUser WHERE userDisabled = 0 AND userNoConsole = 0 AND lastLoginDate IS NULL ORDER BY colName"; var result = Database.Fetch(sql); diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValue.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValue.cs index b211272b51..c05ab1c8fa 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValue.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValue.cs @@ -5,9 +5,9 @@ using System.Globalization; using System.Linq; using System.Runtime.Serialization; using System.Text; -using System.Web; using Newtonsoft.Json; using Umbraco.Core.Serialization; +using Umbraco.Core.Strings; namespace Umbraco.Core.PropertyEditors.ValueConverters { @@ -17,7 +17,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters [JsonConverter(typeof(NoTypeConverterJsonConverter))] [TypeConverter(typeof(ImageCropperValueTypeConverter))] [DataContract(Name="imageCropDataSet")] - public class ImageCropperValue : IHtmlString, IEquatable + public class ImageCropperValue : IHtmlEncodedString, IEquatable { /// /// Gets or sets the value source image. @@ -354,7 +354,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters public decimal Y2 { get; set; } #region IEquatable - + /// public bool Equals(ImageCropperCropCoordinates other) => ReferenceEquals(this, other) || Equals(this, other); diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs index a062561ab1..4608b5c5da 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs @@ -1,6 +1,6 @@ using System; -using System.Web; using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.Strings; namespace Umbraco.Core.PropertyEditors.ValueConverters { @@ -11,7 +11,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters => Constants.PropertyEditors.Aliases.MarkdownEditor.Equals(propertyType.EditorAlias); public override Type GetPropertyValueType(IPublishedPropertyType propertyType) - => typeof (IHtmlString); + => typeof (IHtmlEncodedString); // PropertyCacheLevel.Content is ok here because that converter does not parse {locallink} nor executes macros public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType) @@ -28,7 +28,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters public override object ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) { // source should come from ConvertSource and be a string (or null) already - return new HtmlString(inter == null ? string.Empty : (string) inter); + return new HtmlEncodedString(inter == null ? string.Empty : (string) inter); } public override object ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/TinyMceValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/TinyMceValueConverter.cs index 9938af671d..c4e384e1e8 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/TinyMceValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/TinyMceValueConverter.cs @@ -1,6 +1,6 @@ using System; -using System.Web; using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.Strings; namespace Umbraco.Core.PropertyEditors.ValueConverters { @@ -14,7 +14,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters => propertyType.EditorAlias == Constants.PropertyEditors.Aliases.TinyMce; public override Type GetPropertyValueType(IPublishedPropertyType propertyType) - => typeof (IHtmlString); + => typeof (IHtmlEncodedString); // PropertyCacheLevel.Content is ok here because that converter does not parse {locallink} nor executes macros public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType) @@ -31,7 +31,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters public override object ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) { // source should come from ConvertSource and be a string (or null) already - return new HtmlString(inter == null ? string.Empty : (string)inter); + return new HtmlEncodedString(inter == null ? string.Empty : (string)inter); } public override object ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) diff --git a/src/Umbraco.Core/Runtime/CoreInitialComposer.cs b/src/Umbraco.Core/Runtime/CoreInitialComposer.cs index 4b26fe6201..9373f7b70c 100644 --- a/src/Umbraco.Core/Runtime/CoreInitialComposer.cs +++ b/src/Umbraco.Core/Runtime/CoreInitialComposer.cs @@ -4,6 +4,7 @@ using Umbraco.Core.Composing; using Umbraco.Core.Composing.CompositionExtensions; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.Hosting; using Umbraco.Core.Dictionary; using Umbraco.Core.IO; using Umbraco.Core.Logging; @@ -104,9 +105,9 @@ namespace Umbraco.Core.Runtime factory.GetInstance(), factory.GetInstance(), factory.GetInstance(), - factory.GetInstance(), true, new DatabaseServerMessengerOptions(), - factory.GetInstance())); + factory.GetInstance() + )); composition.WithCollectionBuilder() .Add(() => composition.TypeLoader.GetCacheRefreshers()); diff --git a/src/Umbraco.Core/Runtime/CoreRuntime.cs b/src/Umbraco.Core/Runtime/CoreRuntime.cs index 98d245c04e..b21d3355a8 100644 --- a/src/Umbraco.Core/Runtime/CoreRuntime.cs +++ b/src/Umbraco.Core/Runtime/CoreRuntime.cs @@ -2,12 +2,11 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Web; -using System.Web.Hosting; using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; using Umbraco.Core.Exceptions; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Persistence; @@ -26,13 +25,19 @@ namespace Umbraco.Core.Runtime private ComponentCollection _components; private IFactory _factory; private RuntimeState _state; + private readonly IUmbracoBootPermissionChecker _umbracoBootPermissionChecker; - public CoreRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger) + public CoreRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IProfiler profiler, IUmbracoBootPermissionChecker umbracoBootPermissionChecker, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo) { IOHelper = ioHelper; Configs = configs; UmbracoVersion = umbracoVersion ; + Profiler = profiler; + HostingEnvironment = hostingEnvironment; + BackOfficeInfo = backOfficeInfo; + + _umbracoBootPermissionChecker = umbracoBootPermissionChecker; Logger = logger; // runtime state @@ -42,7 +47,7 @@ namespace Umbraco.Core.Runtime Configs.Settings(), Configs.Global(), new Lazy(() => _factory.GetInstance()), new Lazy(() => _factory.GetInstance()), - UmbracoVersion) + UmbracoVersion,HostingEnvironment, BackOfficeInfo) { Level = RuntimeLevel.Boot }; @@ -53,10 +58,12 @@ namespace Umbraco.Core.Runtime /// protected ILogger Logger { get; } + protected IBackOfficeInfo BackOfficeInfo { get; } + /// /// Gets the profiler. /// - protected IProfiler Profiler { get; private set; } + protected IProfiler Profiler { get; set; } /// /// Gets the profiling logger. @@ -72,6 +79,7 @@ namespace Umbraco.Core.Runtime /// Gets the /// protected IIOHelper IOHelper { get; } + protected IHostingEnvironment HostingEnvironment { get; } protected Configs Configs { get; } protected IUmbracoVersion UmbracoVersion { get; } @@ -84,12 +92,6 @@ namespace Umbraco.Core.Runtime // create and register the essential services // ie the bare minimum required to boot - // loggers - var profiler = Profiler = GetProfiler(); - if (profiler == null) - throw new InvalidOperationException($"The object returned from {nameof(GetProfiler)} cannot be null"); - - var profilingLogger = ProfilingLogger = new ProfilingLogger(Logger, profiler); TypeFinder = GetTypeFinder(); if (TypeFinder == null) @@ -105,16 +107,13 @@ namespace Umbraco.Core.Runtime // objects. var umbracoVersion = new UmbracoVersion(); + var profilingLogger = ProfilingLogger = new ProfilingLogger(Logger, Profiler); using (var timer = profilingLogger.TraceDuration( $"Booting Umbraco {umbracoVersion.SemanticVersion.ToSemanticString()}.", "Booted.", "Boot failed.")) { - Logger.Info("Booting site '{HostingSiteName}', app '{HostingApplicationID}', path '{HostingPhysicalPath}', server '{MachineName}'.", - HostingEnvironment.SiteName, - HostingEnvironment.ApplicationID, - HostingEnvironment.ApplicationPhysicalPath, - NetworkHelper.MachineName); + Logger.Info("Booting Core"); Logger.Debug("Runtime: {Runtime}", GetType().FullName); // application environment @@ -137,7 +136,7 @@ namespace Umbraco.Core.Runtime try { // throws if not full-trust - new AspNetHostingPermission(AspNetHostingPermissionLevel.Unrestricted).Demand(); + _umbracoBootPermissionChecker.ThrowIfNotPermissions(); // run handlers RuntimeOptions.DoRuntimeBoot(ProfilingLogger); @@ -149,10 +148,10 @@ namespace Umbraco.Core.Runtime var databaseFactory = GetDatabaseFactory(); // type finder/loader - var typeLoader = new TypeLoader(IOHelper, TypeFinder, appCaches.RuntimeCache, new DirectoryInfo(Configs.Global().LocalTempPath(IOHelper)), ProfilingLogger); + var typeLoader = new TypeLoader(IOHelper, TypeFinder, appCaches.RuntimeCache, new DirectoryInfo(HostingEnvironment.LocalTempPath), ProfilingLogger); // main dom - var mainDom = new MainDom(Logger); + var mainDom = new MainDom(Logger, HostingEnvironment); // create the composition composition = new Composition(register, typeLoader, ProfilingLogger, _state, Configs); @@ -331,12 +330,6 @@ namespace Umbraco.Core.Runtime protected virtual IEnumerable GetComposerTypes(TypeLoader typeLoader) => typeLoader.GetTypes(); - /// - /// Gets a profiler. - /// - protected virtual IProfiler GetProfiler() - => new LogProfiler(Logger); - /// /// Gets a /// diff --git a/src/Umbraco.Core/RuntimeState.cs b/src/Umbraco.Core/RuntimeState.cs index 851fb8ad47..8b639fdaec 100644 --- a/src/Umbraco.Core/RuntimeState.cs +++ b/src/Umbraco.Core/RuntimeState.cs @@ -1,11 +1,11 @@ using System; using System.Threading; -using System.Web; using Semver; using Umbraco.Core.Collections; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Exceptions; +using Umbraco.Core.Hosting; using Umbraco.Core.Logging; using Umbraco.Core.Migrations.Upgrade; using Umbraco.Core.Persistence; @@ -26,12 +26,16 @@ namespace Umbraco.Core private readonly Lazy _mainDom; private readonly Lazy _serverRegistrar; private readonly IUmbracoVersion _umbracoVersion; + private readonly IHostingEnvironment _hostingEnvironment; + private readonly IBackOfficeInfo _backOfficeInfo; /// /// Initializes a new instance of the class. /// public RuntimeState(ILogger logger, IUmbracoSettingsSection settings, IGlobalSettings globalSettings, - Lazy mainDom, Lazy serverRegistrar, IUmbracoVersion umbracoVersion) + Lazy mainDom, Lazy serverRegistrar, IUmbracoVersion umbracoVersion, + IHostingEnvironment hostingEnvironment, + IBackOfficeInfo backOfficeInfo) { _logger = logger; _settings = settings; @@ -39,6 +43,10 @@ namespace Umbraco.Core _mainDom = mainDom; _serverRegistrar = serverRegistrar; _umbracoVersion = umbracoVersion; + _hostingEnvironment = hostingEnvironment; + _backOfficeInfo = backOfficeInfo; + + ApplicationVirtualPath = _hostingEnvironment.ApplicationVirtualPath; } /// @@ -67,7 +75,7 @@ namespace Umbraco.Core public SemVersion SemanticVersion => _umbracoVersion.SemanticVersion; /// - public bool Debug => HttpContext.Current != null ? HttpContext.Current.IsDebuggingEnabled : _globalSettings.DebugMode; + public bool Debug => _hostingEnvironment.IsDebugMode; /// public bool IsMainDom => MainDom.IsMainDom; @@ -79,7 +87,7 @@ namespace Umbraco.Core public Uri ApplicationUrl { get; private set; } /// - public string ApplicationVirtualPath { get; } = HttpRuntime.AppDomainAppVirtualPath; + public string ApplicationVirtualPath { get; } /// public string CurrentMigrationState { get; internal set; } @@ -93,11 +101,11 @@ namespace Umbraco.Core /// public RuntimeLevelReason Reason { get; internal set; } = RuntimeLevelReason.Unknown; + /// /// Ensures that the property has a value. /// - /// - internal void EnsureApplicationUrl(HttpRequestBase request = null) + internal void EnsureApplicationUrl() { //Fixme: This causes problems with site swap on azure because azure pre-warms a site by calling into `localhost` and when it does that // it changes the URL to `localhost:80` which actually doesn't work for pinging itself, it only works internally in Azure. The ironic part @@ -107,16 +115,16 @@ namespace Umbraco.Core // see U4-10626 - in some cases we want to reset the application url // (this is a simplified version of what was in 7.x) // note: should this be optional? is it expensive? - var url = request == null ? null : ApplicationUrlHelper.GetApplicationUrlFromCurrentRequest(request, _globalSettings); + var url = _backOfficeInfo.GetAbsoluteUrl; + var change = url != null && !_applicationUrls.Contains(url); + if (change) { - _logger.Info(typeof(ApplicationUrlHelper), "New url {Url} detected, re-discovering application url.", url); + _logger.Info("New url {Url} detected, re-discovering application url.", url); _applicationUrls.Add(url); + ApplicationUrl = new Uri(url); } - - if (ApplicationUrl != null && !change) return; - ApplicationUrl = new Uri(ApplicationUrlHelper.GetApplicationUrl(_logger, _globalSettings, _settings, ServerRegistrar, request)); } /// diff --git a/src/Umbraco.Core/Services/Implement/EntityXmlSerializer.cs b/src/Umbraco.Core/Services/Implement/EntityXmlSerializer.cs index fa79883a0f..8c7297b552 100644 --- a/src/Umbraco.Core/Services/Implement/EntityXmlSerializer.cs +++ b/src/Umbraco.Core/Services/Implement/EntityXmlSerializer.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Web; +using System.Net; using System.Xml.Linq; using Newtonsoft.Json; using Umbraco.Core.Composing; @@ -180,7 +180,7 @@ namespace Umbraco.Core.Services.Implement //get url encoded folder names var folders = _dataTypeService.GetContainers(dataType) .OrderBy(x => x.Level) - .Select(x => HttpUtility.UrlEncode(x.Name)); + .Select(x => WebUtility.UrlEncode(x.Name)); folderNames = string.Join("/", folders.ToArray()); } @@ -521,7 +521,7 @@ namespace Umbraco.Core.Services.Implement //get url encoded folder names var folders = _contentTypeService.GetContainers(contentType) .OrderBy(x => x.Level) - .Select(x => HttpUtility.UrlEncode(x.Name)); + .Select(x => WebUtility.UrlEncode(x.Name)); folderNames = string.Join("/", folders.ToArray()); } diff --git a/src/Umbraco.Core/Services/Implement/ServerRegistrationService.cs b/src/Umbraco.Core/Services/Implement/ServerRegistrationService.cs index d9ce978274..1c582953ec 100644 --- a/src/Umbraco.Core/Services/Implement/ServerRegistrationService.cs +++ b/src/Umbraco.Core/Services/Implement/ServerRegistrationService.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Web; +using Umbraco.Core.Composing; using Umbraco.Core.Events; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -20,7 +20,7 @@ namespace Umbraco.Core.Services.Implement private readonly IServerRegistrationRepository _serverRegistrationRepository; private static readonly string CurrentServerIdentityValue = NetworkHelper.MachineName // eg DOMAIN\SERVER - + "/" + HttpRuntime.AppDomainAppId; // eg /LM/S3SVC/11/ROOT + + "/" + Current.HostingEnvironment.ApplicationId; // eg /LM/S3SVC/11/ROOT private ServerRole _currentServerRole = ServerRole.Unknown; diff --git a/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs b/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs deleted file mode 100644 index 1b451e80d5..0000000000 --- a/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using System.Web; -using Umbraco.Core.Composing; -using Umbraco.Core.Configuration; -using Umbraco.Core.Configuration.UmbracoSettings; -using Umbraco.Core.IO; -using Umbraco.Core.Logging; - -namespace Umbraco.Core.Sync -{ - /// - /// A helper used to determine the current server umbraco application url. - /// - public static class ApplicationUrlHelper - { - // because we cannot logger.Info because type is static - private static readonly Type TypeOfApplicationUrlHelper = typeof(ApplicationUrlHelper); - - /// - /// Gets or sets a custom provider for the umbraco application url. - /// - /// - /// Receives the current request as a parameter, and it may be null. Must return a properly - /// formatted url with scheme and umbraco dir and no trailing slash eg "http://www.mysite.com/umbraco", - /// or null. To be used in auto-load-balancing scenarios where the application url is not - /// in config files but is determined programmatically. - /// Must be assigned before resolution is frozen. - /// - // TODO: need another way to do it, eg an interface, injected! - public static Func ApplicationUrlProvider { get; set; } - - internal static string GetApplicationUrl(ILogger logger, IGlobalSettings globalSettings, IUmbracoSettingsSection settings, IServerRegistrar serverRegistrar, HttpRequestBase request = null) - { - var umbracoApplicationUrl = TryGetApplicationUrl(settings, logger, globalSettings, serverRegistrar); - if (umbracoApplicationUrl != null) - return umbracoApplicationUrl; - - umbracoApplicationUrl = ApplicationUrlProvider?.Invoke(request); - if (string.IsNullOrWhiteSpace(umbracoApplicationUrl) == false) - { - umbracoApplicationUrl = umbracoApplicationUrl.TrimEnd('/'); - logger.Info(TypeOfApplicationUrlHelper, "ApplicationUrl: {UmbracoAppUrl} (provider)", umbracoApplicationUrl); - return umbracoApplicationUrl; - } - - if (request == null) return null; - - umbracoApplicationUrl = GetApplicationUrlFromCurrentRequest(request, globalSettings); - logger.Info(TypeOfApplicationUrlHelper, "ApplicationUrl: {UmbracoAppUrl} (UmbracoModule request)", umbracoApplicationUrl); - return umbracoApplicationUrl; - } - - internal static string TryGetApplicationUrl(IUmbracoSettingsSection settings, ILogger logger, IGlobalSettings globalSettings, IServerRegistrar serverRegistrar) - { - // try umbracoSettings:settings/web.routing/@umbracoApplicationUrl - // which is assumed to: - // - end with SystemDirectories.Umbraco - // - contain a scheme - // - end or not with a slash, it will be taken care of - // eg "http://www.mysite.com/umbraco" - var url = settings.WebRouting.UmbracoApplicationUrl; - if (url.IsNullOrWhiteSpace() == false) - { - var umbracoApplicationUrl = url.TrimEnd('/'); - logger.Info(TypeOfApplicationUrlHelper, "ApplicationUrl: {UmbracoAppUrl} (using web.routing/@umbracoApplicationUrl)", umbracoApplicationUrl); - return umbracoApplicationUrl; - } - - // try the server registrar - // which is assumed to return a url that: - // - end with SystemDirectories.Umbraco - // - contain a scheme - // - end or not with a slash, it will be taken care of - // eg "http://www.mysite.com/umbraco" - url = serverRegistrar.GetCurrentServerUmbracoApplicationUrl(); - if (url.IsNullOrWhiteSpace() == false) - { - var umbracoApplicationUrl = url.TrimEnd('/'); - logger.Info(TypeOfApplicationUrlHelper, "ApplicationUrl: {UmbracoAppUrl} (IServerRegistrar)", umbracoApplicationUrl); - return umbracoApplicationUrl; - } - - // else give up... - return null; - } - - public static string GetApplicationUrlFromCurrentRequest(HttpRequestBase request, IGlobalSettings globalSettings) - { - // if (HTTP and SSL not required) or (HTTPS and SSL required), - // use ports from request - // otherwise, - // if non-standard ports used, - // user may need to set umbracoApplicationUrl manually per - // https://our.umbraco.com/documentation/Using-Umbraco/Config-files/umbracoSettings/#ScheduledTasks - var port = (request.IsSecureConnection == false && globalSettings.UseHttps == false) - || (request.IsSecureConnection && globalSettings.UseHttps) - ? ":" + request.ServerVariables["SERVER_PORT"] - : ""; - - var ssl = globalSettings.UseHttps ? "s" : ""; // force, whatever the first request - var url = "http" + ssl + "://" + request.ServerVariables["SERVER_NAME"] + port + Current.IOHelper.ResolveUrl(Current.Configs.Global().UmbracoPath); - - return url.TrimEnd('/'); - } - } -} diff --git a/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs b/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs index f616007f73..0e7194d5de 100644 --- a/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs +++ b/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs @@ -5,17 +5,15 @@ using System.Globalization; using System.IO; using System.Linq; using System.Threading; -using System.Web; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NPoco; using Umbraco.Core.Cache; using Umbraco.Core.Composing; -using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Dtos; -using Umbraco.Core.Configuration; +using Umbraco.Core.Hosting; using Umbraco.Core.Scoping; namespace Umbraco.Core.Sync @@ -34,7 +32,7 @@ namespace Umbraco.Core.Sync private readonly ManualResetEvent _syncIdle; private readonly object _locko = new object(); private readonly IProfilingLogger _profilingLogger; - private readonly IIOHelper _ioHelper; + private readonly IHostingEnvironment _hostingEnvironment; private readonly ISqlContext _sqlContext; private readonly Lazy _distCacheFilePath; private int _lastId = -1; @@ -47,20 +45,20 @@ namespace Umbraco.Core.Sync public DatabaseServerMessengerOptions Options { get; } public DatabaseServerMessenger( - IRuntimeState runtime, IScopeProvider scopeProvider, ISqlContext sqlContext, IProfilingLogger proflog, IGlobalSettings globalSettings, - bool distributedEnabled, DatabaseServerMessengerOptions options, IIOHelper ioHelper) + IRuntimeState runtime, IScopeProvider scopeProvider, ISqlContext sqlContext, IProfilingLogger proflog, + bool distributedEnabled, DatabaseServerMessengerOptions options, IHostingEnvironment hostingEnvironment) : base(distributedEnabled) { ScopeProvider = scopeProvider ?? throw new ArgumentNullException(nameof(scopeProvider)); _sqlContext = sqlContext; _runtime = runtime; _profilingLogger = proflog ?? throw new ArgumentNullException(nameof(proflog)); - _ioHelper = ioHelper; + _hostingEnvironment = hostingEnvironment; Logger = proflog; Options = options ?? throw new ArgumentNullException(nameof(options)); _lastPruned = _lastSync = DateTime.UtcNow; _syncIdle = new ManualResetEvent(true); - _distCacheFilePath = new Lazy(() => GetDistCacheFilePath(globalSettings)); + _distCacheFilePath = new Lazy(() => GetDistCacheFilePath(hostingEnvironment)); } protected ILogger Logger { get; } @@ -527,16 +525,16 @@ namespace Umbraco.Core.Sync /// and debugging purposes. /// protected static readonly string LocalIdentity = NetworkHelper.MachineName // eg DOMAIN\SERVER - + "/" + HttpRuntime.AppDomainAppId // eg /LM/S3SVC/11/ROOT + + "/" + Current.HostingEnvironment.ApplicationId // eg /LM/S3SVC/11/ROOT + " [P" + Process.GetCurrentProcess().Id // eg 1234 + "/D" + AppDomain.CurrentDomain.Id // eg 22 + "] " + Guid.NewGuid().ToString("N").ToUpper(); // make it truly unique - private string GetDistCacheFilePath(IGlobalSettings globalSettings) + private string GetDistCacheFilePath(IHostingEnvironment hostingEnvironment) { - var fileName = HttpRuntime.AppDomainAppId.ReplaceNonAlphanumericChars(string.Empty) + "-lastsynced.txt"; + var fileName = _hostingEnvironment.ApplicationId.ReplaceNonAlphanumericChars(string.Empty) + "-lastsynced.txt"; - var distCacheFilePath = Path.Combine(globalSettings.LocalTempPath(_ioHelper), "DistCache", fileName); + var distCacheFilePath = Path.Combine(hostingEnvironment.LocalTempPath, "DistCache", fileName); //ensure the folder exists var folder = Path.GetDirectoryName(distCacheFilePath); diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index e50ed4153b..4d3bf9ebc0 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -144,7 +144,6 @@ - @@ -161,7 +160,6 @@ - @@ -345,7 +343,7 @@ - + @@ -793,7 +791,6 @@ - diff --git a/src/Umbraco.ModelsBuilder.Embedded/LiveModelsProvider.cs b/src/Umbraco.ModelsBuilder.Embedded/LiveModelsProvider.cs index 333181f27c..d4b4636563 100644 --- a/src/Umbraco.ModelsBuilder.Embedded/LiveModelsProvider.cs +++ b/src/Umbraco.ModelsBuilder.Embedded/LiveModelsProvider.cs @@ -1,6 +1,7 @@ using System; using System.Threading; using System.Web.Hosting; +using Umbraco.Core.Hosting; using Umbraco.Core.Logging; using Umbraco.ModelsBuilder.Embedded.Building; using Umbraco.ModelsBuilder.Embedded.Configuration; @@ -17,16 +18,18 @@ namespace Umbraco.ModelsBuilder.Embedded private readonly IModelsBuilderConfig _config; private readonly ModelsGenerator _modelGenerator; private readonly ModelsGenerationError _mbErrors; + private readonly IHostingEnvironment _hostingEnvironment; // we do not manage pure live here internal bool IsEnabled => _config.ModelsMode.IsLiveNotPure(); - public LiveModelsProvider(ILogger logger, IModelsBuilderConfig config, ModelsGenerator modelGenerator, ModelsGenerationError mbErrors) + public LiveModelsProvider(ILogger logger, IModelsBuilderConfig config, ModelsGenerator modelGenerator, ModelsGenerationError mbErrors, IHostingEnvironment hostingEnvironment) { _logger = logger; _config = config ?? throw new ArgumentNullException(nameof(config)); _modelGenerator = modelGenerator; _mbErrors = mbErrors; + _hostingEnvironment = hostingEnvironment; } internal void Install() @@ -38,7 +41,7 @@ namespace Umbraco.ModelsBuilder.Embedded // initialize mutex // ApplicationId will look like "/LM/W3SVC/1/Root/AppName" // name is system-wide and must be less than 260 chars - var name = HostingEnvironment.ApplicationID + "/UmbracoLiveModelsProvider"; + var name = _hostingEnvironment.ApplicationId + "/UmbracoLiveModelsProvider"; _mutex = new Mutex(false, name); //TODO: Replace this with MainDom? Seems we now have 2x implementations of almost the same thing diff --git a/src/Umbraco.Tests/Cache/DistributedCache/DistributedCacheTests.cs b/src/Umbraco.Tests/Cache/DistributedCache/DistributedCacheTests.cs index ee78360716..851c03ad13 100644 --- a/src/Umbraco.Tests/Cache/DistributedCache/DistributedCacheTests.cs +++ b/src/Umbraco.Tests/Cache/DistributedCache/DistributedCacheTests.cs @@ -199,10 +199,6 @@ namespace Umbraco.Tests.Cache.DistributedCache throw new NotImplementedException(); } - public string GetCurrentServerUmbracoApplicationUrl() - { - throw new NotImplementedException(); - } } public class TestServerAddress : IServerAddress diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs index be160a483c..1bd6391f0e 100644 --- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs +++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs @@ -7,6 +7,7 @@ using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.Hosting; using Umbraco.Core.Services; using Umbraco.Tests.LegacyXmlPublishedCache; using Umbraco.Tests.TestHelpers; @@ -64,7 +65,7 @@ namespace Umbraco.Tests.Cache.PublishedCache _xml = new XmlDocument(); _xml.LoadXml(GetXml()); - var xmlStore = new XmlStore(() => _xml, null, null, null); + var xmlStore = new XmlStore(() => _xml, null, null, null, HostingEnvironment); var appCache = new DictionaryAppCache(); var domainCache = new DomainCache(ServiceContext.DomainService, DefaultCultureAccessor); var publishedShapshot = new PublishedSnapshot( diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs index f3d9f895ef..de64ac4e48 100644 --- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs +++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs @@ -79,7 +79,7 @@ namespace Umbraco.Tests.Cache.PublishedCache var mChild2 = MakeNewMedia("Child2", mType, user, mRoot2.Id); var ctx = GetUmbracoContext("/test"); - var cache = new PublishedMediaCache(new XmlStore((XmlDocument) null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); + var cache = new PublishedMediaCache(new XmlStore((XmlDocument) null, null, null, null, HostingEnvironment), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); var roots = cache.GetAtRoot(); Assert.AreEqual(2, roots.Count()); Assert.IsTrue(roots.Select(x => x.Id).ContainsAll(new[] {mRoot1.Id, mRoot2.Id})); @@ -97,7 +97,7 @@ namespace Umbraco.Tests.Cache.PublishedCache //var publishedMedia = PublishedMediaTests.GetNode(mRoot.Id, GetUmbracoContext("/test", 1234)); var umbracoContext = GetUmbracoContext("/test"); - var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), Current.Services.MediaService, Current.Services.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); + var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null, HostingEnvironment), Current.Services.MediaService, Current.Services.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); var publishedMedia = cache.GetById(mRoot.Id); Assert.IsNotNull(publishedMedia); @@ -208,7 +208,7 @@ namespace Umbraco.Tests.Cache.PublishedCache var result = new SearchResult("1234", 1, () => fields.ToDictionary(x => x.Key, x => new List { x.Value })); - var store = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); + var store = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null, HostingEnvironment), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); var doc = store.CreateFromCacheValues(store.ConvertFromSearchResult(result)); DoAssert(doc, 1234, key, null, 0, "/media/test.jpg", "Image", 23, "Shannon", "Shannon", 0, 0, "-1,1234", DateTime.Parse("2012-07-17T10:34:09"), DateTime.Parse("2012-07-16T10:34:09"), 2); @@ -224,7 +224,7 @@ namespace Umbraco.Tests.Cache.PublishedCache var xmlDoc = GetMediaXml(); ((XmlElement)xmlDoc.DocumentElement.FirstChild).SetAttribute("key", key.ToString()); var navigator = xmlDoc.SelectSingleNode("/root/Image").CreateNavigator(); - var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); + var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null, HostingEnvironment), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); var doc = cache.CreateFromCacheValues(cache.ConvertFromXPathNavigator(navigator, true)); DoAssert(doc, 2000, key, null, 2, "image1", "Image", 23, "Shannon", "Shannon", 33, 33, "-1,2000", DateTime.Parse("2012-06-12T14:13:17"), DateTime.Parse("2012-07-20T18:50:43"), 1); diff --git a/src/Umbraco.Tests/Components/ComponentTests.cs b/src/Umbraco.Tests/Components/ComponentTests.cs index 8211c2fa39..dc20a44696 100644 --- a/src/Umbraco.Tests/Components/ComponentTests.cs +++ b/src/Umbraco.Tests/Components/ComponentTests.cs @@ -37,8 +37,8 @@ namespace Umbraco.Tests.Components var logger = Mock.Of(); var typeFinder = new TypeFinder(logger); var f = new UmbracoDatabaseFactory(logger, new Lazy(() => new MapperCollection(Enumerable.Empty())), TestHelper.GetConfigs()); - var fs = new FileSystems(mock.Object, logger, IOHelper.Default, SettingsForTests.GenerateMockGlobalSettings()); - var p = new ScopeProvider(f, fs, logger, typeFinder, TestHelper.GetRequestCache()); + var fs = new FileSystems(mock.Object, logger, TestHelper.IOHelper, SettingsForTests.GenerateMockGlobalSettings()); + var p = new ScopeProvider(f, fs, logger, typeFinder, NoAppCache.Instance); mock.Setup(x => x.GetInstance(typeof (ILogger))).Returns(logger); mock.Setup(x => x.GetInstance(typeof (IProfilingLogger))).Returns(new ProfilingLogger(Mock.Of(), Mock.Of())); @@ -56,7 +56,7 @@ namespace Umbraco.Tests.Components private static TypeLoader MockTypeLoader() { - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; return new TypeLoader(ioHelper, Mock.Of(), Mock.Of(), new DirectoryInfo(ioHelper.MapPath("~/App_Data/TEMP")), Mock.Of()); } @@ -367,7 +367,7 @@ namespace Umbraco.Tests.Components [Test] public void AllComposers() { - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; var typeFinder = new TypeFinder(Mock.Of()); var typeLoader = new TypeLoader(ioHelper, typeFinder, AppCaches.Disabled.RuntimeCache, new DirectoryInfo(ioHelper.MapPath("~/App_Data/TEMP")), Mock.Of()); diff --git a/src/Umbraco.Tests/Composing/ComposingTestBase.cs b/src/Umbraco.Tests/Composing/ComposingTestBase.cs index 8a0dc46e7f..7b80324686 100644 --- a/src/Umbraco.Tests/Composing/ComposingTestBase.cs +++ b/src/Umbraco.Tests/Composing/ComposingTestBase.cs @@ -24,7 +24,7 @@ namespace Umbraco.Tests.Composing ProfilingLogger = new ProfilingLogger(Mock.Of(), Mock.Of()); var typeFinder = new TypeFinder(Mock.Of()); - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; TypeLoader = new TypeLoader(ioHelper, typeFinder, NoAppCache.Instance, new DirectoryInfo(ioHelper.MapPath("~/App_Data/TEMP")), ProfilingLogger, false, AssembliesToScan); } diff --git a/src/Umbraco.Tests/Composing/CompositionTests.cs b/src/Umbraco.Tests/Composing/CompositionTests.cs index 560f79fb24..fd1db16ac4 100644 --- a/src/Umbraco.Tests/Composing/CompositionTests.cs +++ b/src/Umbraco.Tests/Composing/CompositionTests.cs @@ -39,7 +39,7 @@ namespace Umbraco.Tests.Composing var logger = new ProfilingLogger(Mock.Of(), Mock.Of()); var typeFinder = new TypeFinder(Mock.Of()); - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; var typeLoader = new TypeLoader(ioHelper, typeFinder, Mock.Of(), new DirectoryInfo(ioHelper.MapPath("~/App_Data/TEMP")), logger); var composition = new Composition(mockedRegister, typeLoader, logger, Mock.Of(), TestHelper.GetConfigs()); diff --git a/src/Umbraco.Tests/Composing/TypeLoaderTests.cs b/src/Umbraco.Tests/Composing/TypeLoaderTests.cs index 5163e6a4e8..db35e71c5a 100644 --- a/src/Umbraco.Tests/Composing/TypeLoaderTests.cs +++ b/src/Umbraco.Tests/Composing/TypeLoaderTests.cs @@ -28,8 +28,8 @@ namespace Umbraco.Tests.Composing { // this ensures it's reset var typeFinder = new TypeFinder(Mock.Of()); - _typeLoader = new TypeLoader(IOHelper.Default, typeFinder, NoAppCache.Instance, - new DirectoryInfo(IOHelper.Default.MapPath("~/App_Data/TEMP")), + _typeLoader = new TypeLoader(TestHelper.IOHelper, typeFinder, NoAppCache.Instance, + new DirectoryInfo(TestHelper.IOHelper.MapPath("~/App_Data/TEMP")), new ProfilingLogger(Mock.Of(), Mock.Of()), false, // for testing, we'll specify which assemblies are scanned for the PluginTypeResolver diff --git a/src/Umbraco.Tests/Configurations/GlobalSettingsTests.cs b/src/Umbraco.Tests/Configurations/GlobalSettingsTests.cs index fba922b2c4..2b7deb23f8 100644 --- a/src/Umbraco.Tests/Configurations/GlobalSettingsTests.cs +++ b/src/Umbraco.Tests/Configurations/GlobalSettingsTests.cs @@ -1,5 +1,6 @@ using Moq; using NUnit.Framework; +using NUnit.Framework.Internal; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; using Umbraco.Tests.TestHelpers; @@ -15,13 +16,13 @@ namespace Umbraco.Tests.Configurations public override void SetUp() { base.SetUp(); - _root = Current.IOHelper.Root; + _root = TestHelper.IOHelper.Root; } public override void TearDown() { base.TearDown(); - Current.IOHelper.Root = _root; + TestHelper.IOHelper.Root = _root; } [TestCase("~/umbraco", "/", "umbraco")] @@ -34,9 +35,9 @@ namespace Umbraco.Tests.Configurations var globalSettings = SettingsForTests.GenerateMockGlobalSettings(); var globalSettingsMock = Mock.Get(globalSettings); - globalSettingsMock.Setup(x => x.Path).Returns(() => Current.IOHelper.ResolveUrl(path)); + globalSettingsMock.Setup(x => x.Path).Returns(() => TestHelper.IOHelper.ResolveUrl(path)); - Current.IOHelper.Root = rootPath; + TestHelper.IOHelper.Root = rootPath; Assert.AreEqual(outcome, globalSettings.GetUmbracoMvcAreaNoCache(IOHelper)); } diff --git a/src/Umbraco.Tests/CoreThings/UriExtensionsTests.cs b/src/Umbraco.Tests/CoreThings/UriExtensionsTests.cs index 780e204aad..8aae71d607 100644 --- a/src/Umbraco.Tests/CoreThings/UriExtensionsTests.cs +++ b/src/Umbraco.Tests/CoreThings/UriExtensionsTests.cs @@ -15,13 +15,13 @@ namespace Umbraco.Tests.CoreThings [SetUp] public void SetUp() { - _root = Current.IOHelper.Root; + _root = TestHelper.IOHelper.Root; } [TearDown] public void TearDown() { - Current.IOHelper.Root = _root; + TestHelper.IOHelper.Root = _root; } [TestCase("http://www.domain.com/umbraco", "", true)] diff --git a/src/Umbraco.Tests/IO/FileSystemsTests.cs b/src/Umbraco.Tests/IO/FileSystemsTests.cs index 8030927233..423507bcfe 100644 --- a/src/Umbraco.Tests/IO/FileSystemsTests.cs +++ b/src/Umbraco.Tests/IO/FileSystemsTests.cs @@ -33,9 +33,9 @@ namespace Umbraco.Tests.IO composition.Register(_ => Mock.Of()); composition.Register(_ => Mock.Of()); composition.Register(_ => Mock.Of()); - composition.Register(_ => IOHelper.Default); + composition.Register(_ => TestHelper.IOHelper); composition.RegisterUnique(); - composition.RegisterUnique(IOHelper.Default); + composition.RegisterUnique(TestHelper.IOHelper); composition.Configs.Add(SettingsForTests.GetDefaultGlobalSettings); composition.Configs.Add(SettingsForTests.GetDefaultUmbracoSettings); diff --git a/src/Umbraco.Tests/IO/IoHelperTests.cs b/src/Umbraco.Tests/IO/IoHelperTests.cs index 55bd34c14a..910feb47be 100644 --- a/src/Umbraco.Tests/IO/IoHelperTests.cs +++ b/src/Umbraco.Tests/IO/IoHelperTests.cs @@ -11,22 +11,21 @@ namespace Umbraco.Tests.IO [TestFixture] public class IoHelperTests { - private IIOHelper _ioHelper => IOHelper.Default; + private IIOHelper _ioHelper => TestHelper.IOHelper; [TestCase("~/Scripts", "/Scripts", null)] [TestCase("/Scripts", "/Scripts", null)] [TestCase("../Scripts", "/Scripts", typeof(ArgumentException))] public void IOHelper_ResolveUrl(string input, string expected, Type expectedExceptionType) { - var ioHelper = new IOHelper(); if (expectedExceptionType != null) { - Assert.Throws(expectedExceptionType, () =>ioHelper.ResolveUrl(input)); + Assert.Throws(expectedExceptionType, () =>_ioHelper.ResolveUrl(input)); } else { - var result = ioHelper.ResolveUrl(input); + var result = _ioHelper.ResolveUrl(input); Assert.AreEqual(expected, result); } } @@ -40,17 +39,17 @@ namespace Umbraco.Tests.IO //System.Diagnostics.Debugger.Break(); var globalSettings = SettingsForTests.GenerateMockGlobalSettings(); - Assert.AreEqual(Current.IOHelper.MapPath(Constants.SystemDirectories.Bin, true), Current.IOHelper.MapPath(Constants.SystemDirectories.Bin, false)); - Assert.AreEqual(Current.IOHelper.MapPath(Constants.SystemDirectories.Config, true), Current.IOHelper.MapPath(Constants.SystemDirectories.Config, false)); - Assert.AreEqual(Current.IOHelper.MapPath(globalSettings.UmbracoCssPath, true), Current.IOHelper.MapPath(globalSettings.UmbracoCssPath, false)); - Assert.AreEqual(Current.IOHelper.MapPath(Constants.SystemDirectories.Data, true), Current.IOHelper.MapPath(Constants.SystemDirectories.Data, false)); - Assert.AreEqual(Current.IOHelper.MapPath(Constants.SystemDirectories.Install, true), Current.IOHelper.MapPath(Constants.SystemDirectories.Install, false)); - Assert.AreEqual(Current.IOHelper.MapPath(globalSettings.UmbracoMediaPath, true), Current.IOHelper.MapPath(globalSettings.UmbracoMediaPath, false)); - Assert.AreEqual(Current.IOHelper.MapPath(Constants.SystemDirectories.Packages, true), Current.IOHelper.MapPath(Constants.SystemDirectories.Packages, false)); - Assert.AreEqual(Current.IOHelper.MapPath(Constants.SystemDirectories.Preview, true), Current.IOHelper.MapPath(Constants.SystemDirectories.Preview, false)); - Assert.AreEqual(Current.IOHelper.MapPath(_ioHelper.Root, true), Current.IOHelper.MapPath(_ioHelper.Root, false)); - Assert.AreEqual(Current.IOHelper.MapPath(globalSettings.UmbracoScriptsPath, true), Current.IOHelper.MapPath(globalSettings.UmbracoScriptsPath, false)); - Assert.AreEqual(Current.IOHelper.MapPath(globalSettings.UmbracoPath, true), Current.IOHelper.MapPath(globalSettings.UmbracoPath, false)); + Assert.AreEqual(_ioHelper.MapPath(Constants.SystemDirectories.Bin, true), _ioHelper.MapPath(Constants.SystemDirectories.Bin, false)); + Assert.AreEqual(_ioHelper.MapPath(Constants.SystemDirectories.Config, true), _ioHelper.MapPath(Constants.SystemDirectories.Config, false)); + Assert.AreEqual(_ioHelper.MapPath(globalSettings.UmbracoCssPath, true), _ioHelper.MapPath(globalSettings.UmbracoCssPath, false)); + Assert.AreEqual(_ioHelper.MapPath(Constants.SystemDirectories.Data, true), _ioHelper.MapPath(Constants.SystemDirectories.Data, false)); + Assert.AreEqual(_ioHelper.MapPath(Constants.SystemDirectories.Install, true), _ioHelper.MapPath(Constants.SystemDirectories.Install, false)); + Assert.AreEqual(_ioHelper.MapPath(globalSettings.UmbracoMediaPath, true), _ioHelper.MapPath(globalSettings.UmbracoMediaPath, false)); + Assert.AreEqual(_ioHelper.MapPath(Constants.SystemDirectories.Packages, true), _ioHelper.MapPath(Constants.SystemDirectories.Packages, false)); + Assert.AreEqual(_ioHelper.MapPath(Constants.SystemDirectories.Preview, true), _ioHelper.MapPath(Constants.SystemDirectories.Preview, false)); + Assert.AreEqual(_ioHelper.MapPath(_ioHelper.Root, true), _ioHelper.MapPath(_ioHelper.Root, false)); + Assert.AreEqual(_ioHelper.MapPath(globalSettings.UmbracoScriptsPath, true), _ioHelper.MapPath(globalSettings.UmbracoScriptsPath, false)); + Assert.AreEqual(_ioHelper.MapPath(globalSettings.UmbracoPath, true), _ioHelper.MapPath(globalSettings.UmbracoPath, false)); } [Test] diff --git a/src/Umbraco.Tests/IO/PhysicalFileSystemTests.cs b/src/Umbraco.Tests/IO/PhysicalFileSystemTests.cs index 283f32bee3..c25085f6b0 100644 --- a/src/Umbraco.Tests/IO/PhysicalFileSystemTests.cs +++ b/src/Umbraco.Tests/IO/PhysicalFileSystemTests.cs @@ -6,6 +6,7 @@ using Moq; using NUnit.Framework; using Umbraco.Core.IO; using Umbraco.Core.Logging; +using Umbraco.Tests.TestHelpers; namespace Umbraco.Tests.IO @@ -15,8 +16,7 @@ namespace Umbraco.Tests.IO public class PhysicalFileSystemTests : AbstractFileSystemTests { public PhysicalFileSystemTests() - : base(new PhysicalFileSystem(IOHelper.Default, Mock.Of(), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "FileSysTests"), - "/Media/")) + : base(new PhysicalFileSystem(TestHelper.IOHelper, Mock.Of(), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "FileSysTests"), "/Media/")) { } [SetUp] diff --git a/src/Umbraco.Tests/IO/ShadowFileSystemTests.cs b/src/Umbraco.Tests/IO/ShadowFileSystemTests.cs index 7e68761491..d6beda0614 100644 --- a/src/Umbraco.Tests/IO/ShadowFileSystemTests.cs +++ b/src/Umbraco.Tests/IO/ShadowFileSystemTests.cs @@ -26,7 +26,7 @@ namespace Umbraco.Tests.IO public void SetUp() { SafeCallContext.Clear(); - ClearFiles(IOHelper.Default); + ClearFiles(TestHelper.IOHelper); FileSystems.ResetShadowId(); } @@ -34,7 +34,7 @@ namespace Umbraco.Tests.IO public void TearDown() { SafeCallContext.Clear(); - ClearFiles(IOHelper.Default); + ClearFiles(TestHelper.IOHelper); FileSystems.ResetShadowId(); } @@ -52,7 +52,7 @@ namespace Umbraco.Tests.IO [Test] public void ShadowDeleteDirectory() { - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; var logger = Mock.Of(); var path = ioHelper.MapPath("FileSysTests"); @@ -89,15 +89,16 @@ namespace Umbraco.Tests.IO [Test] public void ShadowDeleteDirectoryInDir() { - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; + var logger = Mock.Of(); var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); Directory.CreateDirectory(path + "/ShadowTests"); Directory.CreateDirectory(path + "/ShadowSystem"); - var fs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowTests/", "ignore"); - var sfs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowSystem/", "ignore"); + var fs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowTests/", "ignore"); + var sfs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowSystem/", "ignore"); var ss = new ShadowFileSystem(fs, sfs); Directory.CreateDirectory(path + "/ShadowTests/sub"); @@ -140,15 +141,16 @@ namespace Umbraco.Tests.IO [Test] public void ShadowDeleteFile() { - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; + var logger = Mock.Of(); var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); Directory.CreateDirectory(path + "/ShadowTests"); Directory.CreateDirectory(path + "/ShadowSystem"); - var fs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowTests/", "ignore"); - var sfs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowSystem/", "ignore"); + var fs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowTests/", "ignore"); + var sfs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowSystem/", "ignore"); var ss = new ShadowFileSystem(fs, sfs); File.WriteAllText(path + "/ShadowTests/f1.txt", "foo"); @@ -181,7 +183,8 @@ namespace Umbraco.Tests.IO [Test] public void ShadowDeleteFileInDir() { - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; + var logger = Mock.Of(); var path = ioHelper.MapPath("FileSysTests"); @@ -189,8 +192,8 @@ namespace Umbraco.Tests.IO Directory.CreateDirectory(path + "/ShadowTests"); Directory.CreateDirectory(path + "/ShadowSystem"); - var fs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowTests/", "ignore"); - var sfs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowSystem/", "ignore"); + var fs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowTests/", "ignore"); + var sfs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowSystem/", "ignore"); var ss = new ShadowFileSystem(fs, sfs); Directory.CreateDirectory(path + "/ShadowTests/sub"); @@ -239,15 +242,16 @@ namespace Umbraco.Tests.IO [Test] public void ShadowCantCreateFile() { - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; + var logger = Mock.Of(); var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); Directory.CreateDirectory(path + "/ShadowTests"); Directory.CreateDirectory(path + "/ShadowSystem"); - var fs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowTests/", "ignore"); - var sfs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowSystem/", "ignore"); + var fs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowTests/", "ignore"); + var sfs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowSystem/", "ignore"); var ss = new ShadowFileSystem(fs, sfs); Assert.Throws(() => @@ -260,15 +264,16 @@ namespace Umbraco.Tests.IO [Test] public void ShadowCreateFile() { - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; + var logger = Mock.Of(); var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); Directory.CreateDirectory(path + "/ShadowTests"); Directory.CreateDirectory(path + "/ShadowSystem"); - var fs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowTests/", "ignore"); - var sfs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowSystem/", "ignore"); + var fs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowTests/", "ignore"); + var sfs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowSystem/", "ignore"); var ss = new ShadowFileSystem(fs, sfs); File.WriteAllText(path + "/ShadowTests/f2.txt", "foo"); @@ -301,15 +306,16 @@ namespace Umbraco.Tests.IO [Test] public void ShadowCreateFileInDir() { - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; + var logger = Mock.Of(); var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); Directory.CreateDirectory(path + "/ShadowTests"); Directory.CreateDirectory(path + "/ShadowSystem"); - var fs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowTests/", "ignore"); - var sfs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowSystem/", "ignore"); + var fs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowTests/", "ignore"); + var sfs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowSystem/", "ignore"); var ss = new ShadowFileSystem(fs, sfs); using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo"))) @@ -343,15 +349,16 @@ namespace Umbraco.Tests.IO [Test] public void ShadowAbort() { - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; + var logger = Mock.Of(); var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); Directory.CreateDirectory(path + "/ShadowTests"); Directory.CreateDirectory(path + "/ShadowSystem"); - var fs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowTests/", "ignore"); - var sfs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowSystem/", "ignore"); + var fs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowTests/", "ignore"); + var sfs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowSystem/", "ignore"); var ss = new ShadowFileSystem(fs, sfs); using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo"))) @@ -367,15 +374,16 @@ namespace Umbraco.Tests.IO [Test] public void ShadowComplete() { - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; + var logger = Mock.Of(); var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); Directory.CreateDirectory(path + "/ShadowTests"); Directory.CreateDirectory(path + "/ShadowSystem"); - var fs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowTests/", "ignore"); - var sfs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowSystem/", "ignore"); + var fs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowTests/", "ignore"); + var sfs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowSystem/", "ignore"); var ss = new ShadowFileSystem(fs, sfs); Directory.CreateDirectory(path + "/ShadowTests/sub/sub"); @@ -406,7 +414,7 @@ namespace Umbraco.Tests.IO public void ShadowScopeComplete() { var logger = Mock.Of(); - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; var path = ioHelper.MapPath("FileSysTests"); var shadowfs = ioHelper.MapPath(Constants.SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs"); @@ -415,7 +423,7 @@ namespace Umbraco.Tests.IO var scopedFileSystems = false; - var phy = new PhysicalFileSystem(ioHelper, Current.Logger, path, "ignore"); + var phy = new PhysicalFileSystem(ioHelper, logger, path, "ignore"); var container = Mock.Of(); var fileSystems = new FileSystems(container, logger, ioHelper, SettingsForTests.GenerateMockGlobalSettings()) { IsScoped = () => scopedFileSystems }; @@ -502,7 +510,7 @@ namespace Umbraco.Tests.IO public void ShadowScopeCompleteWithFileConflict() { var logger = Mock.Of(); - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; var path = ioHelper.MapPath("FileSysTests"); var shadowfs = ioHelper.MapPath(Constants.SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs"); @@ -510,7 +518,7 @@ namespace Umbraco.Tests.IO var scopedFileSystems = false; - var phy = new PhysicalFileSystem(ioHelper, Current.Logger, path, "ignore"); + var phy = new PhysicalFileSystem(ioHelper, logger, path, "ignore"); var container = Mock.Of(); var fileSystems = new FileSystems(container, logger, ioHelper, SettingsForTests.GenerateMockGlobalSettings()) { IsScoped = () => scopedFileSystems }; @@ -556,7 +564,7 @@ namespace Umbraco.Tests.IO public void ShadowScopeCompleteWithDirectoryConflict() { var logger = Mock.Of(); - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; var path = ioHelper.MapPath("FileSysTests"); var shadowfs = ioHelper.MapPath(Constants.SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs"); @@ -564,7 +572,7 @@ namespace Umbraco.Tests.IO var scopedFileSystems = false; - var phy = new PhysicalFileSystem(ioHelper, Current.Logger, path, "ignore"); + var phy = new PhysicalFileSystem(ioHelper, logger, path, "ignore"); var container = Mock.Of(); var fileSystems = new FileSystems(container, logger, ioHelper, SettingsForTests.GenerateMockGlobalSettings()) { IsScoped = () => scopedFileSystems }; @@ -626,7 +634,7 @@ namespace Umbraco.Tests.IO [Test] public void GetFilesReturnsChildrenOnly() { - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); @@ -650,7 +658,7 @@ namespace Umbraco.Tests.IO [Test] public void DeleteDirectoryAndFiles() { - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); @@ -673,15 +681,16 @@ namespace Umbraco.Tests.IO public void ShadowGetFiles() { // Arrange - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; + var logger = Mock.Of(); var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); Directory.CreateDirectory(path + "/ShadowTests"); Directory.CreateDirectory(path + "/ShadowSystem"); - var fs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowTests/", "ignore"); - var sfs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowSystem/", "ignore"); + var fs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowTests/", "ignore"); + var sfs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowSystem/", "ignore"); var ss = new ShadowFileSystem(fs, sfs); // Act @@ -707,15 +716,16 @@ namespace Umbraco.Tests.IO public void ShadowGetFilesUsingEmptyFilter() { // Arrange - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; + var logger = Mock.Of(); var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); Directory.CreateDirectory(path + "/ShadowTests"); Directory.CreateDirectory(path + "/ShadowSystem"); - var fs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowTests/", "ignore"); - var sfs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowSystem/", "ignore"); + var fs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowTests/", "ignore"); + var sfs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowSystem/", "ignore"); var ss = new ShadowFileSystem(fs, sfs); // Act @@ -744,15 +754,16 @@ namespace Umbraco.Tests.IO public void ShadowGetFilesUsingNullFilter() { // Arrange - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; + var logger = Mock.Of(); var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); Directory.CreateDirectory(path + "/ShadowTests"); Directory.CreateDirectory(path + "/ShadowSystem"); - var fs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowTests/", "ignore"); - var sfs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowSystem/", "ignore"); + var fs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowTests/", "ignore"); + var sfs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowSystem/", "ignore"); var ss = new ShadowFileSystem(fs, sfs); // Act @@ -778,15 +789,16 @@ namespace Umbraco.Tests.IO public void ShadowGetFilesUsingWildcardFilter() { // Arrange - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; + var logger = Mock.Of(); var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); Directory.CreateDirectory(path + "/ShadowTests"); Directory.CreateDirectory(path + "/ShadowSystem"); - var fs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowTests/", "ignore"); - var sfs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowSystem/", "ignore"); + var fs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowTests/", "ignore"); + var sfs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowSystem/", "ignore"); var ss = new ShadowFileSystem(fs, sfs); // Act @@ -815,15 +827,16 @@ namespace Umbraco.Tests.IO public void ShadowGetFilesUsingSingleCharacterFilter() { // Arrange - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; + var logger = Mock.Of(); var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); Directory.CreateDirectory(path + "/ShadowTests"); Directory.CreateDirectory(path + "/ShadowSystem"); - var fs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowTests/", "ignore"); - var sfs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowSystem/", "ignore"); + var fs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowTests/", "ignore"); + var sfs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowSystem/", "ignore"); var ss = new ShadowFileSystem(fs, sfs); // Act @@ -864,15 +877,16 @@ namespace Umbraco.Tests.IO public void ShadowGetFullPath() { // Arrange - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; + var logger = Mock.Of(); var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); Directory.CreateDirectory(path + "/ShadowTests"); Directory.CreateDirectory(path + "/ShadowSystem"); - var fs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowTests/", "ignore"); - var sfs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowSystem/", "ignore"); + var fs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowTests/", "ignore"); + var sfs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowSystem/", "ignore"); var ss = new ShadowFileSystem(fs, sfs); // Act @@ -900,15 +914,16 @@ namespace Umbraco.Tests.IO public void ShadowGetRelativePath() { // Arrange - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; + var logger = Mock.Of(); var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); Directory.CreateDirectory(path + "/ShadowTests"); Directory.CreateDirectory(path + "/ShadowSystem"); - var fs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowTests/", "ignore"); - var sfs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowSystem/", "ignore"); + var fs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowTests/", "ignore"); + var sfs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowSystem/", "ignore"); var ss = new ShadowFileSystem(fs, sfs); // Act @@ -941,15 +956,16 @@ namespace Umbraco.Tests.IO public void ShadowGetUrl() { // Arrange - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; + var logger = Mock.Of(); var path = ioHelper.MapPath("FileSysTests"); Directory.CreateDirectory(path); Directory.CreateDirectory(path + "/ShadowTests"); Directory.CreateDirectory(path + "/ShadowSystem"); - var fs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowTests/", "rootUrl"); - var sfs = new PhysicalFileSystem(ioHelper, Current.Logger, path + "/ShadowSystem/", "rootUrl"); + var fs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowTests/", "rootUrl"); + var sfs = new PhysicalFileSystem(ioHelper, logger, path + "/ShadowSystem/", "rootUrl"); var ss = new ShadowFileSystem(fs, sfs); // Act diff --git a/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedSnapshotService.cs b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedSnapshotService.cs index ec6b854a46..aed55f3f49 100644 --- a/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedSnapshotService.cs +++ b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedSnapshotService.cs @@ -3,6 +3,7 @@ using System.Linq; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Configuration; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -37,6 +38,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache private readonly ISiteDomainHelper _siteDomainHelper; private readonly IEntityXmlSerializer _entitySerializer; private readonly IUmbracoContextAccessor _umbracoContextAccessor; + private readonly IHostingEnvironment _hostingEnvironment; #region Constructors @@ -51,6 +53,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache IDefaultCultureAccessor defaultCultureAccessor, ILogger logger, IGlobalSettings globalSettings, + IHostingEnvironment hostingEnvironment, ISiteDomainHelper siteDomainHelper, IEntityXmlSerializer entitySerializer, MainDom mainDom, @@ -59,7 +62,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache publishedSnapshotAccessor, variationContextAccessor, umbracoContextAccessor, documentRepository, mediaRepository, memberRepository, defaultCultureAccessor, - logger, globalSettings, siteDomainHelper, entitySerializer, null, mainDom, testing, enableRepositoryEvents) + logger, globalSettings, hostingEnvironment, siteDomainHelper, entitySerializer, null, mainDom, testing, enableRepositoryEvents) { _umbracoContextAccessor = umbracoContextAccessor; } @@ -75,6 +78,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache IDefaultCultureAccessor defaultCultureAccessor, ILogger logger, IGlobalSettings globalSettings, + IHostingEnvironment hostingEnvironment, ISiteDomainHelper siteDomainHelper, IEntityXmlSerializer entitySerializer, PublishedContentTypeCache contentTypeCache, @@ -89,7 +93,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache _xmlStore = new XmlStore(serviceContext.ContentTypeService, serviceContext.ContentService, scopeProvider, _routesCache, _contentTypeCache, publishedSnapshotAccessor, mainDom, testing, enableRepositoryEvents, - documentRepository, mediaRepository, memberRepository, globalSettings, entitySerializer); + documentRepository, mediaRepository, memberRepository, globalSettings, entitySerializer, hostingEnvironment); _domainService = serviceContext.DomainService; _memberService = serviceContext.MemberService; @@ -102,6 +106,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache _globalSettings = globalSettings; _siteDomainHelper = siteDomainHelper; _entitySerializer = entitySerializer; + _hostingEnvironment = hostingEnvironment; } public override void Dispose() @@ -126,7 +131,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache } catch { - errors = new[] { SystemFiles.GetContentCacheXml(_globalSettings) }; + errors = new[] { SystemFiles.GetContentCacheXml(_hostingEnvironment) }; return false; } } diff --git a/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs index a9ae5a1955..f10a3975c7 100644 --- a/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs +++ b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs @@ -8,6 +8,7 @@ using System.Xml; using NPoco; using Umbraco.Core; using Umbraco.Core.Configuration; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -43,6 +44,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache private readonly IMemberRepository _memberRepository; private readonly IGlobalSettings _globalSettings; private readonly IEntityXmlSerializer _entitySerializer; + private readonly IHostingEnvironment _hostingEnvironment; private XmlStoreFilePersister _persisterTask; private volatile bool _released; private bool _withRepositoryEvents; @@ -61,8 +63,8 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache /// /// The default constructor will boot the cache, load data from file or database, /// wire events in order to manage changes, etc. public XmlStore(IContentTypeService contentTypeService, IContentService contentService, IScopeProvider scopeProvider, RoutesCache routesCache, PublishedContentTypeCache contentTypeCache, - IPublishedSnapshotAccessor publishedSnapshotAccessor, MainDom mainDom, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IGlobalSettings globalSettings, IEntityXmlSerializer entitySerializer) - : this(contentTypeService, contentService, scopeProvider, routesCache, contentTypeCache, publishedSnapshotAccessor, mainDom, false, false, documentRepository, mediaRepository, memberRepository, globalSettings, entitySerializer) + IPublishedSnapshotAccessor publishedSnapshotAccessor, MainDom mainDom, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IGlobalSettings globalSettings, IEntityXmlSerializer entitySerializer, IHostingEnvironment hostingEnvironment) + : this(contentTypeService, contentService, scopeProvider, routesCache, contentTypeCache, publishedSnapshotAccessor, mainDom, false, false, documentRepository, mediaRepository, memberRepository, globalSettings, entitySerializer, hostingEnvironment) { } // internal for unit tests @@ -70,7 +72,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache // TODO: er, we DO have a DB? internal XmlStore(IContentTypeService contentTypeService, IContentService contentService, IScopeProvider scopeProvider, RoutesCache routesCache, PublishedContentTypeCache contentTypeCache, IPublishedSnapshotAccessor publishedSnapshotAccessor, MainDom mainDom, - bool testing, bool enableRepositoryEvents, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IGlobalSettings globalSettings, IEntityXmlSerializer entitySerializer) + bool testing, bool enableRepositoryEvents, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IGlobalSettings globalSettings, IEntityXmlSerializer entitySerializer, IHostingEnvironment hostingEnvironment) { if (testing == false) EnsureConfigurationIsValid(); @@ -86,7 +88,9 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache _memberRepository = memberRepository; _globalSettings = globalSettings; _entitySerializer = entitySerializer; - _xmlFileName = Current.IOHelper.MapPath(SystemFiles.GetContentCacheXml(_globalSettings)); + _hostingEnvironment = hostingEnvironment; + + _xmlFileName = Current.IOHelper.MapPath(SystemFiles.GetContentCacheXml(_hostingEnvironment)); if (testing) { @@ -103,28 +107,28 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache // internal for unit tests // initialize with an xml document // no events, no file nor db, no config check - internal XmlStore(XmlDocument xmlDocument, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository) + internal XmlStore(XmlDocument xmlDocument, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IHostingEnvironment hostingEnvironment) { _xmlDocument = xmlDocument; _documentRepository = documentRepository; _mediaRepository = mediaRepository; _memberRepository = memberRepository; _xmlFileEnabled = false; - _xmlFileName = Current.IOHelper.MapPath(SystemFiles.GetContentCacheXml(Current.Configs.Global())); + _xmlFileName = Current.IOHelper.MapPath(SystemFiles.GetContentCacheXml(hostingEnvironment)); // do not plug events, we may not have what it takes to handle them } // internal for unit tests // initialize with a function returning an xml document // no events, no file nor db, no config check - internal XmlStore(Func getXmlDocument, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository) + internal XmlStore(Func getXmlDocument, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IHostingEnvironment hostingEnvironment) { _documentRepository = documentRepository; _mediaRepository = mediaRepository; _memberRepository = memberRepository; GetXmlDocument = getXmlDocument ?? throw new ArgumentNullException(nameof(getXmlDocument)); _xmlFileEnabled = false; - _xmlFileName = Current.IOHelper.MapPath(SystemFiles.GetContentCacheXml(Current.Configs.Global())); + _xmlFileName = Current.IOHelper.MapPath(SystemFiles.GetContentCacheXml(hostingEnvironment)); // do not plug events, we may not have what it takes to handle them } diff --git a/src/Umbraco.Tests/Logging/LogviewerTests.cs b/src/Umbraco.Tests/Logging/LogviewerTests.cs index d6e1c7ffae..cddd01c178 100644 --- a/src/Umbraco.Tests/Logging/LogviewerTests.cs +++ b/src/Umbraco.Tests/Logging/LogviewerTests.cs @@ -7,6 +7,7 @@ using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.IO; using Umbraco.Core.Logging.Viewer; +using Umbraco.Tests.TestHelpers; namespace Umbraco.Tests.Logging { @@ -33,7 +34,7 @@ namespace Umbraco.Tests.Logging { //Create an example JSON log file to check results //As a one time setup for all tets in this class/fixture - var ioHelper = new IOHelper(); + var ioHelper = TestHelper.IOHelper; var exampleLogfilePath = Path.Combine(TestContext.CurrentContext.TestDirectory, @"Logging\", _logfileName); _newLogfileDirPath = Path.Combine(TestContext.CurrentContext.TestDirectory, @"App_Data\Logs\"); diff --git a/src/Umbraco.Tests/Manifest/ManifestContentAppTests.cs b/src/Umbraco.Tests/Manifest/ManifestContentAppTests.cs index fe3e8a6bdf..5265349e69 100644 --- a/src/Umbraco.Tests/Manifest/ManifestContentAppTests.cs +++ b/src/Umbraco.Tests/Manifest/ManifestContentAppTests.cs @@ -7,6 +7,7 @@ using Umbraco.Core.IO; using Umbraco.Core.Manifest; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; +using Umbraco.Tests.TestHelpers; using Umbraco.Web.Composing; namespace Umbraco.Tests.Manifest @@ -69,7 +70,7 @@ namespace Umbraco.Tests.Manifest private void AssertDefinition(object source, bool expected, string[] show, IReadOnlyUserGroup[] groups) { var definition = JsonConvert.DeserializeObject("{" + (show.Length == 0 ? "" : " \"show\": [" + string.Join(",", show.Select(x => "\"" + x + "\"")) + "] ") + "}"); - var factory = new ManifestContentAppFactory(definition, IOHelper.Default); + var factory = new ManifestContentAppFactory(definition, TestHelper.IOHelper); var app = factory.GetContentAppFor(source, groups); if (expected) Assert.IsNotNull(app); diff --git a/src/Umbraco.Tests/Manifest/ManifestParserTests.cs b/src/Umbraco.Tests/Manifest/ManifestParserTests.cs index 955c7ba776..fb980fc986 100644 --- a/src/Umbraco.Tests/Manifest/ManifestParserTests.cs +++ b/src/Umbraco.Tests/Manifest/ManifestParserTests.cs @@ -15,6 +15,7 @@ using Umbraco.Core.Services; using Umbraco.Core.Dashboards; using Umbraco.Core.IO; using Umbraco.Core.Serialization; +using Umbraco.Tests.TestHelpers; namespace Umbraco.Tests.Manifest { @@ -31,7 +32,7 @@ namespace Umbraco.Tests.Manifest new RequiredValidator(Mock.Of()), new RegexValidator(Mock.Of(), null) }; - _parser = new ManifestParser(AppCaches.Disabled, new ManifestValueValidatorCollection(validators), new ManifestFilterCollection(Array.Empty()), Mock.Of(), IOHelper.Default, Mock.Of(), Mock.Of(), new JsonNetSerializer()); + _parser = new ManifestParser(AppCaches.Disabled, new ManifestValueValidatorCollection(validators), new ManifestFilterCollection(Array.Empty()), Mock.Of(), TestHelper.IOHelper, Mock.Of(), Mock.Of(), new JsonNetSerializer()); } [Test] diff --git a/src/Umbraco.Tests/Membership/MembershipProviderBaseTests.cs b/src/Umbraco.Tests/Membership/MembershipProviderBaseTests.cs index 92d54e9dbe..1dc261714c 100644 --- a/src/Umbraco.Tests/Membership/MembershipProviderBaseTests.cs +++ b/src/Umbraco.Tests/Membership/MembershipProviderBaseTests.cs @@ -6,7 +6,9 @@ using System.Web.Security; using Moq; using NUnit.Framework; using Umbraco.Core.Security; +using Umbraco.Tests.TestHelpers; using Umbraco.Tests.Testing; +using Umbraco.Web.Composing; using Umbraco.Web.Security; namespace Umbraco.Tests.Membership @@ -18,7 +20,7 @@ namespace Umbraco.Tests.Membership [Test] public void ChangePasswordQuestionAndAnswer_Without_RequiresQuestionAndAnswer() { - var providerMock = new Mock() { CallBase = true }; + var providerMock = new Mock(TestHelper.GetHostingEnvironment()) { CallBase = true }; providerMock.Setup(@base => @base.RequiresQuestionAndAnswer).Returns(false); var provider = providerMock.Object; @@ -28,7 +30,7 @@ namespace Umbraco.Tests.Membership [Test] public void CreateUser_Not_Whitespace() { - var providerMock = new Mock() {CallBase = true}; + var providerMock = new Mock(TestHelper.GetHostingEnvironment()) {CallBase = true}; var provider = providerMock.Object; MembershipCreateStatus status; @@ -41,7 +43,7 @@ namespace Umbraco.Tests.Membership [Test] public void CreateUser_Invalid_Question() { - var providerMock = new Mock() { CallBase = true }; + var providerMock = new Mock(TestHelper.GetHostingEnvironment()) { CallBase = true }; providerMock.Setup(@base => @base.RequiresQuestionAndAnswer).Returns(true); var provider = providerMock.Object; @@ -55,7 +57,7 @@ namespace Umbraco.Tests.Membership [Test] public void CreateUser_Invalid_Answer() { - var providerMock = new Mock() { CallBase = true }; + var providerMock = new Mock(TestHelper.GetHostingEnvironment()) { CallBase = true }; providerMock.Setup(@base => @base.RequiresQuestionAndAnswer).Returns(true); var provider = providerMock.Object; @@ -69,7 +71,7 @@ namespace Umbraco.Tests.Membership [Test] public void GetPassword_Without_EnablePasswordRetrieval() { - var providerMock = new Mock() { CallBase = true }; + var providerMock = new Mock(TestHelper.GetHostingEnvironment()) { CallBase = true }; providerMock.Setup(@base => @base.EnablePasswordRetrieval).Returns(false); var provider = providerMock.Object; @@ -79,7 +81,7 @@ namespace Umbraco.Tests.Membership [Test] public void GetPassword_With_Hashed() { - var providerMock = new Mock() { CallBase = true }; + var providerMock = new Mock(TestHelper.GetHostingEnvironment()) { CallBase = true }; providerMock.Setup(@base => @base.EnablePasswordRetrieval).Returns(true); providerMock.Setup(@base => @base.PasswordFormat).Returns(MembershipPasswordFormat.Hashed); var provider = providerMock.Object; @@ -94,7 +96,7 @@ namespace Umbraco.Tests.Membership [Ignore("makes no sense?")] public void ResetPassword_Without_EnablePasswordReset() { - var providerMock = new Mock() { CallBase = true }; + var providerMock = new Mock(TestHelper.GetHostingEnvironment()) { CallBase = true }; providerMock.Setup(@base => @base.EnablePasswordReset).Returns(false); var provider = providerMock.Object; @@ -104,12 +106,12 @@ namespace Umbraco.Tests.Membership [Test] public void Sets_Defaults() { - var providerMock = new Mock() { CallBase = true }; + var providerMock = new Mock(TestHelper.GetHostingEnvironment()) { CallBase = true }; var provider = providerMock.Object; provider.Initialize("test", new NameValueCollection()); Assert.AreEqual("test", provider.Name); - Assert.AreEqual(MembershipProviderBase.GetDefaultAppName(), provider.ApplicationName); + Assert.AreEqual(MembershipProviderBase.GetDefaultAppName(TestHelper.GetHostingEnvironment()), provider.ApplicationName); Assert.AreEqual(false, provider.EnablePasswordRetrieval); Assert.AreEqual(true, provider.EnablePasswordReset); Assert.AreEqual(false, provider.RequiresQuestionAndAnswer); @@ -126,7 +128,7 @@ namespace Umbraco.Tests.Membership [Test] public void Throws_Exception_With_Hashed_Password_And_Password_Retrieval() { - var providerMock = new Mock() { CallBase = true }; + var providerMock = new Mock(TestHelper.GetHostingEnvironment()) { CallBase = true }; var provider = providerMock.Object; Assert.Throws(() => provider.Initialize("test", new NameValueCollection() @@ -155,9 +157,9 @@ namespace Umbraco.Tests.Membership Assert.AreEqual(pass, result.Success); } - - + + } } diff --git a/src/Umbraco.Tests/Membership/UmbracoServiceMembershipProviderTests.cs b/src/Umbraco.Tests/Membership/UmbracoServiceMembershipProviderTests.cs index a606da9c90..85f57e3103 100644 --- a/src/Umbraco.Tests/Membership/UmbracoServiceMembershipProviderTests.cs +++ b/src/Umbraco.Tests/Membership/UmbracoServiceMembershipProviderTests.cs @@ -23,7 +23,7 @@ namespace Umbraco.Tests.Membership { var memberTypeServiceMock = new Mock(); memberTypeServiceMock.Setup(x => x.GetDefault()).Returns("Blah"); - var provider = new MembersMembershipProvider(Mock.Of(), memberTypeServiceMock.Object, TestHelper.GetUmbracoVersion()); + var provider = new MembersMembershipProvider(Mock.Of(), memberTypeServiceMock.Object, TestHelper.GetUmbracoVersion(), TestHelper.GetHostingEnvironment(), TestHelper.GetIpResolver()); provider.Initialize("test", new NameValueCollection()); Assert.AreEqual("Blah", provider.DefaultMemberTypeAlias); @@ -34,7 +34,7 @@ namespace Umbraco.Tests.Membership { var memberTypeServiceMock = new Mock(); memberTypeServiceMock.Setup(x => x.GetDefault()).Returns("Blah"); - var provider = new MembersMembershipProvider(Mock.Of(), memberTypeServiceMock.Object, TestHelper.GetUmbracoVersion()); + var provider = new MembersMembershipProvider(Mock.Of(), memberTypeServiceMock.Object, TestHelper.GetUmbracoVersion(), TestHelper.GetHostingEnvironment(), TestHelper.GetIpResolver()); provider.Initialize("test", new NameValueCollection { { "defaultMemberTypeAlias", "Hello" } }); Assert.AreEqual("Hello", provider.DefaultMemberTypeAlias); @@ -48,7 +48,7 @@ namespace Umbraco.Tests.Membership var membershipServiceMock = new Mock(); membershipServiceMock.Setup(service => service.Exists("test")).Returns(true); - var provider = new MembersMembershipProvider(membershipServiceMock.Object, memberTypeServiceMock.Object, TestHelper.GetUmbracoVersion()); + var provider = new MembersMembershipProvider(membershipServiceMock.Object, memberTypeServiceMock.Object, TestHelper.GetUmbracoVersion(), TestHelper.GetHostingEnvironment(), TestHelper.GetIpResolver()); provider.Initialize("test", new NameValueCollection()); MembershipCreateStatus status; @@ -65,7 +65,7 @@ namespace Umbraco.Tests.Membership var membershipServiceMock = new Mock(); membershipServiceMock.Setup(service => service.GetByEmail("test@test.com")).Returns(() => new Member("test", MockedContentTypes.CreateSimpleMemberType())); - var provider = new MembersMembershipProvider(membershipServiceMock.Object, memberTypeServiceMock.Object, TestHelper.GetUmbracoVersion()); + var provider = new MembersMembershipProvider(membershipServiceMock.Object, memberTypeServiceMock.Object, TestHelper.GetUmbracoVersion(), TestHelper.GetHostingEnvironment(), TestHelper.GetIpResolver()); provider.Initialize("test", new NameValueCollection { { "requiresUniqueEmail", "true" } }); MembershipCreateStatus status; @@ -73,7 +73,7 @@ namespace Umbraco.Tests.Membership Assert.IsNull(user); } - + [Test] public void Password_Hashed_With_Salt() { @@ -96,7 +96,7 @@ namespace Umbraco.Tests.Membership }) .Returns(() => createdMember); - var provider = new MembersMembershipProvider(membershipServiceMock.Object, memberTypeServiceMock.Object, TestHelper.GetUmbracoVersion()); + var provider = new MembersMembershipProvider(membershipServiceMock.Object, memberTypeServiceMock.Object, TestHelper.GetUmbracoVersion(), TestHelper.GetHostingEnvironment(), TestHelper.GetIpResolver()); provider.Initialize("test", new NameValueCollection { { "passwordFormat", "Hashed" }, { "hashAlgorithmType", "HMACSHA256" } }); diff --git a/src/Umbraco.Tests/Misc/ApplicationUrlHelperTests.cs b/src/Umbraco.Tests/Misc/ApplicationUrlHelperTests.cs deleted file mode 100644 index 8283b0b65a..0000000000 --- a/src/Umbraco.Tests/Misc/ApplicationUrlHelperTests.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System; -using Moq; -using NUnit.Framework; -using Umbraco.Core; -using Umbraco.Core.Configuration.UmbracoSettings; -using Umbraco.Core.Composing; -using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; -using Umbraco.Core.Sync; -using Umbraco.Tests.TestHelpers; - - -namespace Umbraco.Tests.Misc -{ - [TestFixture] - public class ApplicationUrlHelperTests - { - // note: in tests, read appContext._umbracoApplicationUrl and not the property, - // because reading the property does run some code, as long as the field is null. - - [TearDown] - public void Reset() - { - Current.Reset(); - } - - [Test] - public void NoApplicationUrlByDefault() - { - var state = new RuntimeState(Mock.Of(), Mock.Of(), Mock.Of(), new Lazy(), new Lazy(), TestHelper.GetUmbracoVersion()); - Assert.IsNull(state.ApplicationUrl); - } - - [Test] - public void SetApplicationUrlViaServerRegistrar() - { - // no applicable settings, but a provider - - var settings = Mock.Of(section => - section.WebRouting == Mock.Of(wrSection => wrSection.UmbracoApplicationUrl == (string)null)); - - var globalConfig = Mock.Get(SettingsForTests.GenerateMockGlobalSettings()); - globalConfig.Setup(x => x.UseHttps).Returns(true); - - var registrar = new Mock(); - registrar.Setup(x => x.GetCurrentServerUmbracoApplicationUrl()).Returns("http://server1.com/umbraco"); - - var state = new RuntimeState(Mock.Of(), settings, globalConfig.Object, new Lazy(), new Lazy(() => registrar.Object), TestHelper.GetUmbracoVersion()); - - state.EnsureApplicationUrl(); - - Assert.AreEqual("http://server1.com/umbraco", state.ApplicationUrl.ToString()); - } - - [Test] - public void SetApplicationUrlViaProvider() - { - // no applicable settings, but a provider - - var settings = Mock.Of(section => - section.WebRouting == Mock.Of(wrSection => wrSection.UmbracoApplicationUrl == (string) null)); - - var globalConfig = Mock.Get(SettingsForTests.GenerateMockGlobalSettings()); - globalConfig.Setup(x => x.UseHttps).Returns(true); - - ApplicationUrlHelper.ApplicationUrlProvider = request => "http://server1.com/umbraco"; - - - - var state = new RuntimeState(Mock.Of(), settings, globalConfig.Object, new Lazy(), new Lazy(() => Mock.Of()), TestHelper.GetUmbracoVersion()); - - state.EnsureApplicationUrl(); - - Assert.AreEqual("http://server1.com/umbraco", state.ApplicationUrl.ToString()); - } - - [Test] - public void SetApplicationUrlWhenNoSettings() - { - // no applicable settings, cannot set url - - var settings = Mock.Of(section => - section.WebRouting == Mock.Of(wrSection => wrSection.UmbracoApplicationUrl == (string) null)); - - var globalConfig = Mock.Get(SettingsForTests.GenerateMockGlobalSettings()); - globalConfig.Setup(x => x.UseHttps).Returns(true); - - var url = ApplicationUrlHelper.TryGetApplicationUrl(settings, Mock.Of(), globalConfig.Object, Mock.Of()); - - // still NOT set - Assert.IsNull(url); - } - - [Test] - public void SetApplicationUrlFromWrSettingsSsl() - { - var settings = Mock.Of(section => - section.WebRouting == Mock.Of(wrSection => wrSection.UmbracoApplicationUrl == "httpx://whatever.com/umbraco/")); - - var globalConfig = Mock.Get(SettingsForTests.GenerateMockGlobalSettings()); - globalConfig.Setup(x => x.UseHttps).Returns(true); - - - - var url = ApplicationUrlHelper.TryGetApplicationUrl(settings, Mock.Of(), globalConfig.Object, Mock.Of()); - - Assert.AreEqual("httpx://whatever.com/umbraco", url); - } - } -} diff --git a/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs index 31cfcb7dc8..0845daee9c 100644 --- a/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs +++ b/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs @@ -10,6 +10,7 @@ using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; using Umbraco.Core.Events; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -57,7 +58,8 @@ namespace Umbraco.Tests.PublishedContent var configs = TestHelper.GetConfigs(); Mock.Get(factory).Setup(x => x.GetInstance(typeof(Configs))).Returns(configs); - var globalSettings = new GlobalSettings(IOHelper.Default); + var globalSettings = new GlobalSettings(TestHelper.IOHelper); + var hostingEnvironment = Mock.Of(); configs.Add(SettingsForTests.GenerateMockUmbracoSettings); configs.Add(() => globalSettings); @@ -162,7 +164,8 @@ namespace Umbraco.Tests.PublishedContent Mock.Of(), Mock.Of(), new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), - typeFinder); + typeFinder, + hostingEnvironment); // invariant is the current default _variationAccesor.VariationContext = new VariationContext(); diff --git a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs index 25ff5e233b..63eac1479b 100644 --- a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs +++ b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs @@ -52,7 +52,7 @@ namespace Umbraco.Tests.PublishedContent var configs = TestHelper.GetConfigs(); Mock.Get(factory).Setup(x => x.GetInstance(typeof(Configs))).Returns(configs); - var globalSettings = new GlobalSettings(IOHelper.Default); + var globalSettings = new GlobalSettings(TestHelper.IOHelper); configs.Add(SettingsForTests.GenerateMockUmbracoSettings); configs.Add(() => globalSettings); @@ -205,7 +205,8 @@ namespace Umbraco.Tests.PublishedContent Mock.Of(), Mock.Of(), new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), - typeFinder); + typeFinder, + TestHelper.GetHostingEnvironment()); // invariant is the current default _variationAccesor.VariationContext = new VariationContext(); diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs index 882db8112c..da89e76033 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs @@ -14,6 +14,7 @@ using Umbraco.Core.Composing; using Current = Umbraco.Core.Composing.Current; using Umbraco.Core.Cache; using Umbraco.Core.Configuration; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -44,11 +45,11 @@ namespace Umbraco.Tests.PublishedContent Composition.RegisterUnique(f => new PublishedModelFactory(f.GetInstance().GetTypes())); } - protected override TypeLoader CreateTypeLoader(IIOHelper ioHelper, ITypeFinder typeFinder, IAppPolicyCache runtimeCache, IGlobalSettings globalSettings, IProfilingLogger logger) + protected override TypeLoader CreateTypeLoader(IIOHelper ioHelper, ITypeFinder typeFinder, IAppPolicyCache runtimeCache,IProfilingLogger logger, IHostingEnvironment hostingEnvironment) { - var baseLoader = base.CreateTypeLoader(ioHelper, typeFinder, runtimeCache, globalSettings, logger); + var baseLoader = base.CreateTypeLoader(ioHelper, typeFinder, runtimeCache, logger, hostingEnvironment); - return new TypeLoader(ioHelper, typeFinder, runtimeCache, new DirectoryInfo(globalSettings.LocalTempPath(ioHelper)), logger, false, + return new TypeLoader(ioHelper, typeFinder, runtimeCache, new DirectoryInfo(hostingEnvironment.LocalTempPath), logger, false, // this is so the model factory looks into the test assembly baseLoader.AssembliesToScan .Union(new[] {typeof(PublishedContentMoreTests).Assembly}) diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs index de4dd45f64..0888a4f27c 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs @@ -15,10 +15,12 @@ using Moq; using Newtonsoft.Json; using Umbraco.Core.Cache; using Umbraco.Core.Configuration; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Services; +using Umbraco.Core.Strings; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.Testing; using Umbraco.Web.Models.PublishedContent; @@ -87,11 +89,11 @@ namespace Umbraco.Tests.PublishedContent } - protected override TypeLoader CreateTypeLoader(IIOHelper ioHelper, ITypeFinder typeFinder, IAppPolicyCache runtimeCache, IGlobalSettings globalSettings, IProfilingLogger logger) + protected override TypeLoader CreateTypeLoader(IIOHelper ioHelper, ITypeFinder typeFinder, IAppPolicyCache runtimeCache, IProfilingLogger logger, IHostingEnvironment hostingEnvironment) { - var baseLoader = base.CreateTypeLoader(ioHelper, typeFinder, runtimeCache, globalSettings, logger); + var baseLoader = base.CreateTypeLoader(ioHelper, typeFinder, runtimeCache, logger, hostingEnvironment); - return new TypeLoader(ioHelper, typeFinder, runtimeCache, new DirectoryInfo(globalSettings.LocalTempPath(ioHelper)), logger, false, + return new TypeLoader(ioHelper, typeFinder, runtimeCache, new DirectoryInfo(hostingEnvironment.LocalTempPath), logger, false, // this is so the model factory looks into the test assembly baseLoader.AssembliesToScan .Union(new[] { typeof(PublishedContentTests).Assembly }) @@ -368,15 +370,15 @@ namespace Umbraco.Tests.PublishedContent var doc = GetNode(1173); var propVal = doc.Value("content"); - Assert.IsInstanceOf(typeof(IHtmlString), propVal); + Assert.IsInstanceOf(typeof(IHtmlEncodedString), propVal); Assert.AreEqual("
This is some content
", propVal.ToString()); - var propVal2 = doc.Value("content"); - Assert.IsInstanceOf(typeof(IHtmlString), propVal2); + var propVal2 = doc.Value("content"); + Assert.IsInstanceOf(typeof(IHtmlEncodedString), propVal2); Assert.AreEqual("
This is some content
", propVal2.ToString()); var propVal3 = doc.Value("Content"); - Assert.IsInstanceOf(typeof(IHtmlString), propVal3); + Assert.IsInstanceOf(typeof(IHtmlEncodedString), propVal3); Assert.AreEqual("
This is some content
", propVal3.ToString()); } diff --git a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs index 8122113516..9f14637959 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs @@ -70,7 +70,7 @@ namespace Umbraco.Tests.PublishedContent /// internal IPublishedContent GetNode(int id, UmbracoContext umbracoContext) { - var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), + var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null, HostingEnvironment), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); var doc = cache.GetById(id); @@ -102,15 +102,15 @@ namespace Umbraco.Tests.PublishedContent var publishedMedia = GetNode(media.Id); var propVal = publishedMedia.Value("content"); - Assert.IsInstanceOf(propVal); + Assert.IsInstanceOf(propVal); Assert.AreEqual("
This is some content
", propVal.ToString()); - var propVal2 = publishedMedia.Value("content"); - Assert.IsInstanceOf(propVal2); + var propVal2 = publishedMedia.Value("content"); + Assert.IsInstanceOf(propVal2); Assert.AreEqual("
This is some content
", propVal2.ToString()); var propVal3 = publishedMedia.Value("Content"); - Assert.IsInstanceOf(propVal3); + Assert.IsInstanceOf(propVal3); Assert.AreEqual("
This is some content
", propVal3.ToString()); } @@ -485,7 +485,7 @@ namespace Umbraco.Tests.PublishedContent "); var node = xml.DescendantsAndSelf("Image").Single(x => (int)x.Attribute("id") == nodeId); - var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); + var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null, HostingEnvironment), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); var nav = node.CreateNavigator(); @@ -505,7 +505,7 @@ namespace Umbraco.Tests.PublishedContent var errorXml = new XElement("error", string.Format("No media is maching '{0}'", 1234)); var nav = errorXml.CreateNavigator(); - var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); + var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null, HostingEnvironment), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); var converted = publishedMedia.ConvertFromXPathNodeIterator(nav.Select("/"), 1234); Assert.IsNull(converted); diff --git a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs index 463ef4339c..06c4b5be6d 100644 --- a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs +++ b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs @@ -19,6 +19,7 @@ using Umbraco.Core.Strings; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; using Umbraco.Core.Dictionary; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Persistence; @@ -51,12 +52,11 @@ namespace Umbraco.Tests.Routing public class TestRuntime : WebRuntime { - public TestRuntime(UmbracoApplicationBase umbracoApplication, Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger) - : base(umbracoApplication, configs, umbracoVersion, ioHelper, Mock.Of()) + public TestRuntime(UmbracoApplicationBase umbracoApplication, Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo) + : base(umbracoApplication, configs, umbracoVersion, ioHelper, Mock.Of(), Mock.Of(), hostingEnvironment, backOfficeInfo) { } - protected override IProfiler GetProfiler() => Mock.Of(); } protected override void Compose() diff --git a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs index aed4dba493..bfb3bc6ac0 100644 --- a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs +++ b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs @@ -32,9 +32,8 @@ namespace Umbraco.Tests.Routing //create the module var logger = Mock.Of(); var globalSettings = TestObjects.GetGlobalSettings(); - var umbracoVersion = TestHelper.GetUmbracoVersion(); var runtime = new RuntimeState(logger, Mock.Of(), globalSettings, - new Lazy(), new Lazy(), umbracoVersion); + new Lazy(), new Lazy(), UmbracoVersion, HostingEnvironment, BackOfficeInfo); _module = new UmbracoInjectedModule ( diff --git a/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs b/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs index 93c931c93d..a88d3146ed 100644 --- a/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs +++ b/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs @@ -10,8 +10,10 @@ using Umbraco.Core; using Umbraco.Core.Compose; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; +using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Events; using Umbraco.Core.Exceptions; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Persistence; @@ -20,6 +22,8 @@ using Umbraco.Core.Scoping; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Stubs; using Umbraco.Web; +using Umbraco.Web.Hosting; +using Umbraco.Web.Runtime; namespace Umbraco.Tests.Runtimes { @@ -80,35 +84,46 @@ namespace Umbraco.Tests.Runtimes // test application public class TestUmbracoApplication : UmbracoApplicationBase { - public TestUmbracoApplication() : base(new DebugDiagnosticsLogger(new MessageTemplates()), GetConfigs()) + public TestUmbracoApplication() : base(_logger, _configs, _ioHelper, _profiler, new AspNetHostingEnvironment(_globalSettings, _ioHelper), new AspNetBackOfficeInfo(_globalSettings, _ioHelper, _settings, _logger)) { } + private static readonly DebugDiagnosticsLogger _logger = new DebugDiagnosticsLogger(new MessageTemplates()); + private static readonly IIOHelper _ioHelper = TestHelper.IOHelper; + private static readonly IProfiler _profiler = new TestProfiler(); + private static readonly Configs _configs = GetConfigs(); + private static readonly IGlobalSettings _globalSettings = _configs.Global(); + private static readonly IUmbracoSettingsSection _settings = _configs.Settings(); + private static Configs GetConfigs() { - var configs = new ConfigsFactory(IOHelper.Default).Create(); + var configs = new ConfigsFactory(_ioHelper).Create(); configs.Add(SettingsForTests.GetDefaultGlobalSettings); configs.Add(SettingsForTests.GetDefaultUmbracoSettings); return configs; } + private static IProfiler GetProfiler() + { + return new TestProfiler(); + } + public IRuntime Runtime { get; private set; } - protected override IRuntime GetRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger) + protected override IRuntime GetRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IProfiler profiler, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo) { - return Runtime = new TestRuntime(configs, umbracoVersion, ioHelper, logger); + return Runtime = new TestRuntime(configs, umbracoVersion, ioHelper, logger, profiler, hostingEnvironment, backOfficeInfo); } } // test runtime public class TestRuntime : CoreRuntime { - public TestRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger) - :base(configs, umbracoVersion, ioHelper, logger) + public TestRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IProfiler profiler, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo) + :base(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo) { } - protected override IProfiler GetProfiler() => new TestProfiler(); // must override the database factory // else BootFailedException because U cannot connect to the configured db diff --git a/src/Umbraco.Tests/Runtimes/StandaloneTests.cs b/src/Umbraco.Tests/Runtimes/StandaloneTests.cs index d11438d4f4..ce8c1a2dd3 100644 --- a/src/Umbraco.Tests/Runtimes/StandaloneTests.cs +++ b/src/Umbraco.Tests/Runtimes/StandaloneTests.cs @@ -13,6 +13,7 @@ using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Migrations.Install; @@ -62,11 +63,13 @@ namespace Umbraco.Tests.Runtimes var appCaches = AppCaches.Disabled; var databaseFactory = new UmbracoDatabaseFactory(logger, new Lazy(() => factory.GetInstance()), TestHelper.GetConfigs()); var typeFinder = new TypeFinder(logger); - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; + var hostingEnvironment = Mock.Of(); var typeLoader = new TypeLoader(ioHelper, typeFinder, appCaches.RuntimeCache, new DirectoryInfo(ioHelper.MapPath("~/App_Data/TEMP")), profilingLogger); var mainDom = new SimpleMainDom(); var umbracoVersion = TestHelper.GetUmbracoVersion(); - var runtimeState = new RuntimeState(logger, null, null, new Lazy(() => mainDom), new Lazy(() => factory.GetInstance()), umbracoVersion); + var backOfficeInfo = TestHelper.GetBackOfficeInfo(); + var runtimeState = new RuntimeState(logger, null, null, new Lazy(() => mainDom), new Lazy(() => factory.GetInstance()), umbracoVersion, hostingEnvironment, backOfficeInfo); var configs = TestHelper.GetConfigs(); // create the register and the composition @@ -75,7 +78,7 @@ namespace Umbraco.Tests.Runtimes composition.RegisterEssentials(logger, profiler, profilingLogger, mainDom, appCaches, databaseFactory, typeLoader, runtimeState, typeFinder, ioHelper, umbracoVersion); // create the core runtime and have it compose itself - var coreRuntime = new CoreRuntime(configs, umbracoVersion, ioHelper, logger);coreRuntime.Compose(composition); + var coreRuntime = new CoreRuntime(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo);coreRuntime.Compose(composition); // determine actual runtime level runtimeState.DetermineRuntimeLevel(databaseFactory, logger); @@ -253,9 +256,11 @@ namespace Umbraco.Tests.Runtimes var appCaches = AppCaches.Disabled; var databaseFactory = Mock.Of(); var typeFinder = new TypeFinder(Mock.Of()); - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; var typeLoader = new TypeLoader(ioHelper, typeFinder, appCaches.RuntimeCache, new DirectoryInfo(ioHelper.MapPath("~/App_Data/TEMP")), profilingLogger); var runtimeState = Mock.Of(); + var hostingEnvironment = Mock.Of(); + var backOfficeInfo = TestHelper.GetBackOfficeInfo(); Mock.Get(runtimeState).Setup(x => x.Level).Returns(RuntimeLevel.Run); var mainDom = Mock.Of(); Mock.Get(mainDom).Setup(x => x.IsMainDom).Returns(true); @@ -268,7 +273,7 @@ namespace Umbraco.Tests.Runtimes composition.RegisterEssentials(logger, profiler, profilingLogger, mainDom, appCaches, databaseFactory, typeLoader, runtimeState, typeFinder, ioHelper, umbracoVersion); // create the core runtime and have it compose itself - var coreRuntime = new CoreRuntime(configs, umbracoVersion, ioHelper, logger); + var coreRuntime = new CoreRuntime(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo); coreRuntime.Compose(composition); // get the components diff --git a/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs b/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs index 708f0d29db..d48a54c625 100644 --- a/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs @@ -36,7 +36,7 @@ namespace Umbraco.Tests.Scoping _testObjects = new TestObjects(register); - composition.RegisterUnique(factory => new FileSystems(factory, factory.TryGetInstance(), IOHelper.Default, SettingsForTests.GenerateMockGlobalSettings())); + composition.RegisterUnique(factory => new FileSystems(factory, factory.TryGetInstance(), TestHelper.IOHelper, SettingsForTests.GenerateMockGlobalSettings())); composition.WithCollectionBuilder(); composition.Configs.Add(SettingsForTests.GetDefaultGlobalSettings); diff --git a/src/Umbraco.Tests/Scoping/ScopeFileSystemsTests.cs b/src/Umbraco.Tests/Scoping/ScopeFileSystemsTests.cs index fa0fdd08e2..1ed1eac663 100644 --- a/src/Umbraco.Tests/Scoping/ScopeFileSystemsTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopeFileSystemsTests.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Text; +using Moq; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Composing; @@ -8,6 +9,7 @@ using Umbraco.Core.IO; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.Testing; using Umbraco.Core.Composing.CompositionExtensions; +using Umbraco.Core.Logging; using FileSystems = Umbraco.Core.IO.FileSystems; namespace Umbraco.Tests.Scoping @@ -53,7 +55,7 @@ namespace Umbraco.Tests.Scoping [TestCase(false)] public void CreateMediaTest(bool complete) { - var physMediaFileSystem = new PhysicalFileSystem(IOHelper, Logger, IOHelper.MapPath("media"), "ignore"); + var physMediaFileSystem = new PhysicalFileSystem(IOHelper, Mock.Of(), IOHelper.MapPath("media"), "ignore"); var mediaFileSystem = Current.MediaFileSystem; Assert.IsFalse(physMediaFileSystem.FileExists("f1.txt")); @@ -86,7 +88,7 @@ namespace Umbraco.Tests.Scoping [Test] public void MultiThread() { - var physMediaFileSystem = new PhysicalFileSystem(IOHelper, Logger, IOHelper.MapPath("media"), "ignore"); + var physMediaFileSystem = new PhysicalFileSystem(IOHelper, Mock.Of(),IOHelper.MapPath("media"), "ignore"); var mediaFileSystem = Current.MediaFileSystem; var scopeProvider = ScopeProvider; diff --git a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs index 0d2243c6dc..07cbcb2686 100644 --- a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs @@ -81,6 +81,7 @@ namespace Umbraco.Tests.Scoping var documentRepository = Mock.Of(); var mediaRepository = Mock.Of(); var memberRepository = Mock.Of(); + var hostingEnvironment = TestHelper.GetHostingEnvironment(); var typeFinder = new TypeFinder(Mock.Of()); @@ -102,7 +103,8 @@ namespace Umbraco.Tests.Scoping Factory.GetInstance(), Mock.Of(), new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), - typeFinder); + typeFinder, + hostingEnvironment); } protected UmbracoContext GetUmbracoContextNu(string url, int templateId = 1234, RouteData routeData = null, bool setSingleton = false, IUmbracoSettingsSection umbracoSettings = null, IEnumerable urlProviders = null) diff --git a/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs b/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs index bc515cfea3..d22e5c19e3 100644 --- a/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs +++ b/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs @@ -8,6 +8,7 @@ using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; +using Umbraco.Core.Hosting; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; @@ -49,10 +50,12 @@ namespace Umbraco.Tests.Services var runtimeStateMock = new Mock(); runtimeStateMock.Setup(x => x.Level).Returns(() => RuntimeLevel.Run); - var contentTypeFactory = Factory.GetInstance(); + var contentTypeFactory = Factory.GetInstance(); var documentRepository = Factory.GetInstance(); var mediaRepository = Mock.Of(); var memberRepository = Mock.Of(); + var hostingEnvironment = Mock.Of(); + var typeFinder = new TypeFinder(Mock.Of()); @@ -74,7 +77,8 @@ namespace Umbraco.Tests.Services Factory.GetInstance(), Mock.Of(), new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), - typeFinder); + typeFinder, + hostingEnvironment); } public class LocalServerMessenger : ServerMessengerBase @@ -127,8 +131,8 @@ namespace Umbraco.Tests.Services [TestCase(ContentVariation.CultureAndSegment, ContentVariation.CultureAndSegment, false)] public void Change_Content_Type_Variation_Clears_Redirects(ContentVariation startingContentTypeVariation, ContentVariation changedContentTypeVariation, bool shouldUrlRedirectsBeCleared) { - var contentType = MockedContentTypes.CreateBasicContentType(); - contentType.Variations = startingContentTypeVariation; + var contentType = MockedContentTypes.CreateBasicContentType(); + contentType.Variations = startingContentTypeVariation; ServiceContext.ContentTypeService.Save(contentType); var contentType2 = MockedContentTypes.CreateBasicContentType("test"); ServiceContext.ContentTypeService.Save(contentType2); @@ -407,7 +411,7 @@ namespace Umbraco.Tests.Services Assert.AreEqual("hello world", doc.GetValue("title")); Assert.IsTrue(doc.IsCultureEdited("en-US")); //invariant prop changes show up on default lang Assert.IsTrue(doc.Edited); - + //change the property type to be variant contentType.PropertyTypes.First().Variations = variant; ServiceContext.ContentTypeService.Save(contentType); @@ -435,7 +439,7 @@ namespace Umbraco.Tests.Services { //create content type with a property type that varies by culture var contentType = MockedContentTypes.CreateBasicContentType(); - // content type supports all variations + // content type supports all variations contentType.Variations = ContentVariation.Culture | ContentVariation.Segment; var properties = CreatePropertyCollection(("title", variant)); contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" }); @@ -472,7 +476,7 @@ namespace Umbraco.Tests.Services { //create content type with a property type that varies by culture var contentType = MockedContentTypes.CreateBasicContentType(); - // content type supports all variations + // content type supports all variations contentType.Variations = ContentVariation.Culture | ContentVariation.Segment; var properties = CreatePropertyCollection(("title", variant)); contentType.PropertyGroups.Add(new PropertyGroup(properties) { Name = "Content" }); @@ -879,14 +883,14 @@ namespace Umbraco.Tests.Services // switch property type to Invariant contentType.PropertyTypes.First(x => x.Alias == "value1").Variations = invariant; ServiceContext.ContentTypeService.Save(contentType); //This is going to have to re-normalize the "Edited" flag - + document = ServiceContext.ContentService.GetById(document.Id); Assert.IsTrue(document.IsCultureEdited("en")); //This will remain true because there is now a pending change for the invariant property data which is flagged under the default lang Assert.IsFalse(document.IsCultureEdited("fr")); //This will be false because nothing has changed for this culture and the property no longer reflects variant changes Assert.IsTrue(document.Edited); //update the invariant value and publish - document.SetValue("value1", "v1inv"); + document.SetValue("value1", "v1inv"); ServiceContext.ContentService.SaveAndPublish(document); document = ServiceContext.ContentService.GetById(document.Id); @@ -906,7 +910,7 @@ namespace Umbraco.Tests.Services // switch property back to Culture contentType.PropertyTypes.First(x => x.Alias == "value1").Variations = variant; ServiceContext.ContentTypeService.Save(contentType); - + document = ServiceContext.ContentService.GetById(document.Id); Assert.AreEqual("v1inv", document.GetValue("value1", "en")); //The invariant property value gets copied over to the default language Assert.AreEqual("v1inv", document.GetValue("value1", "en", published: true)); @@ -970,9 +974,9 @@ namespace Umbraco.Tests.Services Assert.AreEqual("doc1en", document.GetCultureName("en")); Assert.AreEqual("doc1fr", document.GetCultureName("fr")); Assert.AreEqual("v1en", document.GetValue("value1")); - Assert.AreEqual("v1en-init", document.GetValue("value1", published: true)); + Assert.AreEqual("v1en-init", document.GetValue("value1", published: true)); Assert.IsTrue(document.IsCultureEdited("en")); //This is true because the invariant property reflects changes on the default lang - Assert.IsFalse(document.IsCultureEdited("fr")); + Assert.IsFalse(document.IsCultureEdited("fr")); Assert.IsTrue(document.Edited); // switch property type to Culture @@ -980,7 +984,7 @@ namespace Umbraco.Tests.Services ServiceContext.ContentTypeService.Save(contentType); //This is going to have to re-normalize the "Edited" flag document = ServiceContext.ContentService.GetById(document.Id); - Assert.IsTrue(document.IsCultureEdited("en")); //Remains true + Assert.IsTrue(document.IsCultureEdited("en")); //Remains true Assert.IsFalse(document.IsCultureEdited("fr")); //False because no french property has ever been edited Assert.IsTrue(document.Edited); @@ -1010,7 +1014,7 @@ namespace Umbraco.Tests.Services Assert.IsNull(document.GetValue("value1", "fr")); //The values are there but the business logic returns null Assert.IsNull(document.GetValue("value1", "fr", published: true)); //The values are there but the business logic returns null Assert.IsFalse(document.IsCultureEdited("en")); //The variant published AND edited values are copied over to the invariant - Assert.IsFalse(document.IsCultureEdited("fr")); + Assert.IsFalse(document.IsCultureEdited("fr")); Assert.IsFalse(document.Edited); } diff --git a/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs b/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs index 140759c3bd..e66a8d2450 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs @@ -37,7 +37,7 @@ namespace Umbraco.Tests.TestHelpers var container = TestHelper.GetRegister(); - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; var logger = new ProfilingLogger(Mock.Of(), Mock.Of()); var typeFinder = new TypeFinder(Mock.Of()); var typeLoader = new TypeLoader(ioHelper, typeFinder, NoAppCache.Instance, diff --git a/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs b/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs index a81a1062fc..231e6aef66 100644 --- a/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs +++ b/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs @@ -18,11 +18,10 @@ namespace Umbraco.Tests.TestHelpers settings.ConfigurationStatus == TestHelper.GetUmbracoVersion().SemanticVersion.ToSemanticString() && settings.UseHttps == false && settings.HideTopLevelNodeFromPath == false && - settings.Path == Current.IOHelper.ResolveUrl("~/umbraco") && + settings.Path == TestHelper.IOHelper.ResolveUrl("~/umbraco") && settings.TimeOutInMinutes == 20 && settings.DefaultUILanguage == "en" && settings.LocalTempStorageLocation == LocalTempStorage.Default && - //settings.LocalTempPath == Current.IOHelper.MapPath("~/App_Data/TEMP") && settings.ReservedPaths == (GlobalSettings.StaticReservedPaths + "~/umbraco") && settings.ReservedUrls == GlobalSettings.StaticReservedUrls && settings.UmbracoPath == "~/umbraco" && diff --git a/src/Umbraco.Tests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests/TestHelpers/TestHelper.cs index 6fc2b08e2f..797fdcb51b 100644 --- a/src/Umbraco.Tests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests/TestHelpers/TestHelper.cs @@ -13,6 +13,7 @@ using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -20,6 +21,9 @@ using Umbraco.Core.Models.Entities; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; using Umbraco.Core.Sync; +using Umbraco.Net; +using Umbraco.Web; +using Umbraco.Web.Hosting; using File = System.IO.File; namespace Umbraco.Tests.TestHelpers @@ -32,7 +36,7 @@ namespace Umbraco.Tests.TestHelpers public static TypeLoader GetMockedTypeLoader() { - return new TypeLoader(IOHelper.Default, Mock.Of(), Mock.Of(), new DirectoryInfo(IOHelper.Default.MapPath("~/App_Data/TEMP")), Mock.Of()); + return new TypeLoader(IOHelper, Mock.Of(), Mock.Of(), new DirectoryInfo(IOHelper.MapPath("~/App_Data/TEMP")), Mock.Of()); } public static Configs GetConfigs() @@ -47,12 +51,20 @@ namespace Umbraco.Tests.TestHelpers Mock.Of(), new Lazy(), new Lazy(), - TestHelper.GetUmbracoVersion()); + TestHelper.GetUmbracoVersion(), + TestHelper.GetHostingEnvironment(), + TestHelper.GetBackOfficeInfo() + ); + } + + public static IBackOfficeInfo GetBackOfficeInfo() + { + return new AspNetBackOfficeInfo(SettingsForTests.GenerateMockGlobalSettings(), TestHelper.IOHelper, SettingsForTests.GenerateMockUmbracoSettings(), Mock.Of()); } public static IConfigsFactory GetConfigsFactory() { - return new ConfigsFactory(IOHelper.Default); + return new ConfigsFactory(IOHelper); } /// @@ -70,6 +82,8 @@ namespace Umbraco.Tests.TestHelpers } } + public static IIOHelper IOHelper = new IOHelper(); + /// /// Maps the given making it rooted on . must start with ~/ /// @@ -97,9 +111,9 @@ namespace Umbraco.Tests.TestHelpers { foreach (var directory in directories) { - var directoryInfo = new DirectoryInfo(Current.IOHelper.MapPath(directory)); + var directoryInfo = new DirectoryInfo(IOHelper.MapPath(directory)); if (directoryInfo.Exists == false) - Directory.CreateDirectory(Current.IOHelper.MapPath(directory)); + Directory.CreateDirectory(IOHelper.MapPath(directory)); } } @@ -111,7 +125,7 @@ namespace Umbraco.Tests.TestHelpers }; foreach (var directory in directories) { - var directoryInfo = new DirectoryInfo(Current.IOHelper.MapPath(directory)); + var directoryInfo = new DirectoryInfo(IOHelper.MapPath(directory)); var preserve = preserves.ContainsKey(directory) ? preserves[directory] : null; if (directoryInfo.Exists) foreach (var x in directoryInfo.GetFiles().Where(x => preserve == null || preserve.Contains(x.Name) == false)) @@ -297,6 +311,16 @@ namespace Umbraco.Tests.TestHelpers return RegisterFactory.Create(GetConfigs().Global()); } + public static IHostingEnvironment GetHostingEnvironment() + { + return new AspNetHostingEnvironment(SettingsForTests.GetDefaultGlobalSettings(), TestHelper.IOHelper); + } + + public static IIpResolver GetIpResolver() + { + return new AspNetIpResolver(); + } + public static IRequestCache GetRequestCache() { return new DictionaryAppCache(); diff --git a/src/Umbraco.Tests/TestHelpers/TestObjects.cs b/src/Umbraco.Tests/TestHelpers/TestObjects.cs index 4c672549e8..d79ea3500e 100644 --- a/src/Umbraco.Tests/TestHelpers/TestObjects.cs +++ b/src/Umbraco.Tests/TestHelpers/TestObjects.cs @@ -246,7 +246,7 @@ namespace Umbraco.Tests.TestHelpers } typeFinder = typeFinder ?? new TypeFinder(logger); - fileSystems = fileSystems ?? new FileSystems(Current.Factory, logger, IOHelper.Default, SettingsForTests.GenerateMockGlobalSettings()); + fileSystems = fileSystems ?? new FileSystems(Current.Factory, logger, TestHelper.IOHelper, SettingsForTests.GenerateMockGlobalSettings()); var scopeProvider = new ScopeProvider(databaseFactory, fileSystems, logger, typeFinder, NoAppCache.Instance); return scopeProvider; } diff --git a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs index 72f99dbdab..ac9ec48c6a 100644 --- a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs +++ b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs @@ -23,6 +23,7 @@ using Umbraco.Web.Security; using Umbraco.Web.Routing; using File = System.IO.File; using Umbraco.Core.Composing; +using Umbraco.Core.Hosting; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Scoping; using Umbraco.Tests.Testing; @@ -267,7 +268,9 @@ namespace Umbraco.Tests.TestHelpers Factory.GetInstance(), Factory.GetInstance(), Factory.GetInstance(), DefaultCultureAccessor, Logger, - Factory.GetInstance(), new SiteDomainHelper(), + Factory.GetInstance(), + HostingEnvironment, + new SiteDomainHelper(), Factory.GetInstance(), ContentTypesCache, null, true, Options.PublishedRepositoryEvents); diff --git a/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs b/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs index d01721b3b9..1b1d3172d3 100644 --- a/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs +++ b/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs @@ -102,7 +102,7 @@ namespace Umbraco.Tests.Testing.TestingTests var logger = Mock.Of(); var memberService = Mock.Of(); var memberTypeService = Mock.Of(); - var membershipProvider = new MembersMembershipProvider(memberService, memberTypeService, Mock.Of()); + var membershipProvider = new MembersMembershipProvider(memberService, memberTypeService, Mock.Of(), TestHelper.GetHostingEnvironment(), TestHelper.GetIpResolver()); var membershipHelper = new MembershipHelper(umbracoContext.HttpContext, Mock.Of(), membershipProvider, Mock.Of(), memberService, memberTypeService, Mock.Of(), AppCaches.Disabled, logger); var umbracoHelper = new UmbracoHelper(Mock.Of(), Mock.Of(), Mock.Of(), Mock.Of(), Mock.Of(), membershipHelper); var umbracoMapper = new UmbracoMapper(new MapDefinitionCollection(new[] { Mock.Of() })); diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs index 4fb488c3e4..5afac8d3ab 100644 --- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs +++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs @@ -36,13 +36,16 @@ using Umbraco.Web.PublishedCache; using Umbraco.Web.Routing; using Umbraco.Web.Trees; using Umbraco.Core.Composing.CompositionExtensions; +using Umbraco.Core.Hosting; using Umbraco.Core.Mapping; using Umbraco.Core.Serialization; using Umbraco.Web.Composing.CompositionExtensions; +using Umbraco.Web.Hosting; using Umbraco.Web.Sections; using Current = Umbraco.Core.Composing.Current; using FileSystems = Umbraco.Core.IO.FileSystems; using Umbraco.Core.Dictionary; +using Umbraco.Net; namespace Umbraco.Tests.Testing { @@ -109,6 +112,9 @@ namespace Umbraco.Tests.Testing protected virtual IProfilingLogger ProfilingLogger => Factory.GetInstance(); + protected IHostingEnvironment HostingEnvironment => Factory.GetInstance(); + protected IIpResolver IpResolver => Factory.GetInstance(); + protected IBackOfficeInfo BackOfficeInfo => Factory.GetInstance(); protected AppCaches AppCaches => Factory.GetInstance(); protected virtual ISqlSyntaxProvider SqlSyntax => Factory.GetInstance(); @@ -136,13 +142,17 @@ namespace Umbraco.Tests.Testing var (logger, profiler) = GetLoggers(Options.Logger); var proflogger = new ProfilingLogger(logger, profiler); - IOHelper = Umbraco.Core.IO.IOHelper.Default; + IOHelper = TestHelper.IOHelper; TypeFinder = new TypeFinder(logger); var appCaches = GetAppCaches(); var globalSettings = SettingsForTests.GetDefaultGlobalSettings(); + var settings = SettingsForTests.GetDefaultUmbracoSettings(); + IHostingEnvironment hostingEnvironment = new AspNetHostingEnvironment(globalSettings, IOHelper); + IBackOfficeInfo backOfficeInfo = new AspNetBackOfficeInfo(globalSettings, IOHelper, settings, logger); + IIpResolver ipResolver = new AspNetIpResolver(); UmbracoVersion = new UmbracoVersion(globalSettings); - var typeLoader = GetTypeLoader(IOHelper, TypeFinder, appCaches.RuntimeCache, globalSettings, proflogger, Options.TypeLoader); + var typeLoader = GetTypeLoader(IOHelper, TypeFinder, appCaches.RuntimeCache, hostingEnvironment, proflogger, Options.TypeLoader); var register = TestHelper.GetRegister(); @@ -157,6 +167,9 @@ namespace Umbraco.Tests.Testing Composition.RegisterUnique(profiler); Composition.RegisterUnique(proflogger); Composition.RegisterUnique(appCaches); + Composition.RegisterUnique(hostingEnvironment); + Composition.RegisterUnique(backOfficeInfo); + Composition.RegisterUnique(ipResolver); TestObjects = new TestObjects(register); Compose(); @@ -281,30 +294,30 @@ namespace Umbraco.Tests.Testing .ComposeWebMappingProfiles(); } - protected virtual TypeLoader GetTypeLoader(IIOHelper ioHelper, ITypeFinder typeFinder, IAppPolicyCache runtimeCache, IGlobalSettings globalSettings, IProfilingLogger logger, UmbracoTestOptions.TypeLoader option) + protected virtual TypeLoader GetTypeLoader(IIOHelper ioHelper, ITypeFinder typeFinder, IAppPolicyCache runtimeCache, IHostingEnvironment hostingEnvironment, IProfilingLogger logger, UmbracoTestOptions.TypeLoader option) { switch (option) { case UmbracoTestOptions.TypeLoader.Default: - return _commonTypeLoader ?? (_commonTypeLoader = CreateCommonTypeLoader(ioHelper, typeFinder, runtimeCache, globalSettings, logger)); + return _commonTypeLoader ?? (_commonTypeLoader = CreateCommonTypeLoader(ioHelper, typeFinder, runtimeCache, logger, hostingEnvironment)); case UmbracoTestOptions.TypeLoader.PerFixture: - return _featureTypeLoader ?? (_featureTypeLoader = CreateTypeLoader(ioHelper, typeFinder, runtimeCache, globalSettings, logger)); + return _featureTypeLoader ?? (_featureTypeLoader = CreateTypeLoader(ioHelper, typeFinder, runtimeCache, logger, hostingEnvironment)); case UmbracoTestOptions.TypeLoader.PerTest: - return CreateTypeLoader(ioHelper, typeFinder, runtimeCache, globalSettings, logger); + return CreateTypeLoader(ioHelper, typeFinder, runtimeCache, logger, hostingEnvironment); default: throw new ArgumentOutOfRangeException(nameof(option)); } } - protected virtual TypeLoader CreateTypeLoader(IIOHelper ioHelper, ITypeFinder typeFinder, IAppPolicyCache runtimeCache, IGlobalSettings globalSettings, IProfilingLogger logger) + protected virtual TypeLoader CreateTypeLoader(IIOHelper ioHelper, ITypeFinder typeFinder, IAppPolicyCache runtimeCache, IProfilingLogger logger, IHostingEnvironment hostingEnvironment) { - return CreateCommonTypeLoader(ioHelper, typeFinder, runtimeCache, globalSettings, logger); + return CreateCommonTypeLoader(ioHelper, typeFinder, runtimeCache, logger, hostingEnvironment); } // common to all tests = cannot be overriden - private static TypeLoader CreateCommonTypeLoader(IIOHelper ioHelper, ITypeFinder typeFinder, IAppPolicyCache runtimeCache, IGlobalSettings globalSettings, IProfilingLogger logger) + private static TypeLoader CreateCommonTypeLoader(IIOHelper ioHelper, ITypeFinder typeFinder, IAppPolicyCache runtimeCache, IProfilingLogger logger, IHostingEnvironment hostingEnvironment) { - return new TypeLoader(ioHelper, typeFinder, runtimeCache, new DirectoryInfo(globalSettings.LocalTempPath(ioHelper)), logger, false, new[] + return new TypeLoader(ioHelper, typeFinder, runtimeCache, new DirectoryInfo(hostingEnvironment.LocalTempPath), logger, false, new[] { Assembly.Load("Umbraco.Core"), Assembly.Load("Umbraco.Web"), diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index e9b6e1f0cd..602a2f928e 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -354,7 +354,6 @@ - diff --git a/src/Umbraco.Tests/Web/Controllers/AuthenticationControllerTests.cs b/src/Umbraco.Tests/Web/Controllers/AuthenticationControllerTests.cs index ba5e691b0e..4d7815b991 100644 --- a/src/Umbraco.Tests/Web/Controllers/AuthenticationControllerTests.cs +++ b/src/Umbraco.Tests/Web/Controllers/AuthenticationControllerTests.cs @@ -71,10 +71,10 @@ namespace Umbraco.Tests.Web.Controllers } else { - var baseDir = Current.IOHelper.MapPath("", false).TrimEnd(Current.IOHelper.DirSepChar); + var baseDir = IOHelper.MapPath("", false).TrimEnd(IOHelper.DirSepChar); HttpContext.Current = new HttpContext(new SimpleWorkerRequest("/", baseDir, "", "", new StringWriter())); } - Current.IOHelper.ForceNotHosted = true; + IOHelper.ForceNotHosted = true; var usersController = new AuthenticationController( new DefaultPasswordConfig(), Factory.GetInstance(), diff --git a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs index 9ca17675af..6ce1eae7fe 100644 --- a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs +++ b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs @@ -425,7 +425,9 @@ namespace Umbraco.Tests.Web.Mvc null, null, umbracoContextAccessor, null, null, null, new TestDefaultCultureAccessor(), - Current.Logger, TestObjects.GetGlobalSettings(), new SiteDomainHelper(), + Current.Logger, TestObjects.GetGlobalSettings(), + TestHelper.GetHostingEnvironment(), + new SiteDomainHelper(), Factory.GetInstance(), null, true, false ); // no events diff --git a/src/Umbraco.Tests/Web/UmbracoHelperTests.cs b/src/Umbraco.Tests/Web/UmbracoHelperTests.cs index 425f24be41..826b62e599 100644 --- a/src/Umbraco.Tests/Web/UmbracoHelperTests.cs +++ b/src/Umbraco.Tests/Web/UmbracoHelperTests.cs @@ -261,7 +261,7 @@ namespace Umbraco.Tests.Web // FIXME: bad in a unit test - but Udi has a static ctor that wants it?! var container = new Mock(); var typeFinder = new TypeFinder(Mock.Of()); - var ioHelper = IOHelper.Default; + var ioHelper = TestHelper.IOHelper; container .Setup(x => x.GetInstance(typeof(TypeLoader))) .Returns(new TypeLoader( diff --git a/src/Umbraco.Web/AspNetBackOfficeInfo.cs b/src/Umbraco.Web/AspNetBackOfficeInfo.cs new file mode 100644 index 0000000000..cabe56062c --- /dev/null +++ b/src/Umbraco.Web/AspNetBackOfficeInfo.cs @@ -0,0 +1,67 @@ +using System.Web; +using Umbraco.Core; +using Umbraco.Core.Configuration; +using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.IO; +using Umbraco.Core.Logging; + +namespace Umbraco.Web +{ + public class AspNetBackOfficeInfo : IBackOfficeInfo + { + private readonly IGlobalSettings _globalSettings; + private readonly IIOHelper _ioHelper; + private readonly IUmbracoSettingsSection _settings; + private readonly ILogger _logger; + + public AspNetBackOfficeInfo(IGlobalSettings globalSettings, IIOHelper ioHelper, IUmbracoSettingsSection settings, ILogger logger) + { + _globalSettings = globalSettings; + _ioHelper = ioHelper; + _settings = settings; + _logger = logger; + } + + /// + public string GetAbsoluteUrl => GetAbsoluteUrlFromConfig() ?? GetAbsoluteUrlFromCurrentRequest() ?? null; + + private string GetAbsoluteUrlFromConfig() + { + var url = _settings.WebRouting.UmbracoApplicationUrl; + if (url.IsNullOrWhiteSpace() == false) + { + var umbracoApplicationUrl = url.TrimEnd('/'); + _logger.Info("ApplicationUrl: {UmbracoAppUrl} (using web.routing/@umbracoApplicationUrl)", umbracoApplicationUrl); + return umbracoApplicationUrl; + } + + return null; + } + + + + private string GetAbsoluteUrlFromCurrentRequest() + { + var request = HttpContext.Current?.Request; + + if (request is null) return null; + + // if (HTTP and SSL not required) or (HTTPS and SSL required), + // use ports from request + // otherwise, + // if non-standard ports used, + // user may need to set umbracoApplicationUrl manually per + // https://our.umbraco.com/documentation/Using-Umbraco/Config-files/umbracoSettings/#ScheduledTasks + var port = (request.IsSecureConnection == false && _globalSettings.UseHttps == false) + || (request.IsSecureConnection && _globalSettings.UseHttps) + ? ":" + request.ServerVariables["SERVER_PORT"] + : ""; + + var ssl = _globalSettings.UseHttps ? "s" : ""; // force, whatever the first request + var url = "http" + ssl + "://" + request.ServerVariables["SERVER_NAME"] + port + + _ioHelper.ResolveUrl(_globalSettings.UmbracoPath); + + return url.TrimEnd('/'); + } + } +} diff --git a/src/Umbraco.Web/AspNetIpResolver.cs b/src/Umbraco.Web/AspNetIpResolver.cs new file mode 100644 index 0000000000..8cec45ff30 --- /dev/null +++ b/src/Umbraco.Web/AspNetIpResolver.cs @@ -0,0 +1,17 @@ +using System.Web; +using Umbraco.Core; +using Umbraco.Net; + +namespace Umbraco.Web +{ + internal class AspNetIpResolver : IIpResolver + { + public string GetCurrentRequestIpAddress() + { + var httpContext = HttpContext.Current == null ? (HttpContextBase) null : new HttpContextWrapper(HttpContext.Current); + var ip = httpContext.GetCurrentRequestIpAddress(); + if (ip.ToLowerInvariant().StartsWith("unknown")) ip = ""; + return ip; + } + } +} diff --git a/src/Umbraco.Web/AspNetSessionIdResolver.cs b/src/Umbraco.Web/AspNetSessionIdResolver.cs new file mode 100644 index 0000000000..1b22ebaa60 --- /dev/null +++ b/src/Umbraco.Web/AspNetSessionIdResolver.cs @@ -0,0 +1,11 @@ +using System.Web; +using Umbraco.Core; +using Umbraco.Net; + +namespace Umbraco.Web +{ + internal class AspNetSessionIdResolver : ISessionIdResolver + { + public string SessionId => HttpContext.Current?.Session?.SessionID; + } +} diff --git a/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs b/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs index e9fcd6b305..85b8e62d28 100644 --- a/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs +++ b/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs @@ -14,6 +14,7 @@ using Umbraco.Core.Persistence.Dtos; using Umbraco.Core.Scoping; using Umbraco.Web.Composing; using System.ComponentModel; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; namespace Umbraco.Web @@ -29,8 +30,8 @@ namespace Umbraco.Web private readonly IUmbracoDatabaseFactory _databaseFactory; public BatchedDatabaseServerMessenger( - IRuntimeState runtime, IUmbracoDatabaseFactory databaseFactory, IScopeProvider scopeProvider, ISqlContext sqlContext, IProfilingLogger proflog, IGlobalSettings globalSettings, DatabaseServerMessengerOptions options, IIOHelper ioHelper) - : base(runtime, scopeProvider, sqlContext, proflog, globalSettings, true, options, ioHelper) + IRuntimeState runtime, IUmbracoDatabaseFactory databaseFactory, IScopeProvider scopeProvider, ISqlContext sqlContext, IProfilingLogger proflog, DatabaseServerMessengerOptions options, IHostingEnvironment hostingEnvironment) + : base(runtime, scopeProvider, sqlContext, proflog, true, options, hostingEnvironment ) { _databaseFactory = databaseFactory; } diff --git a/src/Umbraco.Web/Composing/Current.cs b/src/Umbraco.Web/Composing/Current.cs index 3a554c7039..6069ac8690 100644 --- a/src/Umbraco.Web/Composing/Current.cs +++ b/src/Umbraco.Web/Composing/Current.cs @@ -9,6 +9,7 @@ using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Persistence; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; +using Umbraco.Core.Hosting; using Umbraco.Core.Mapping; using Umbraco.Core.PackageActions; using Umbraco.Core.Packaging; @@ -17,6 +18,7 @@ using Umbraco.Core.Scoping; using Umbraco.Core.Services; using Umbraco.Core.Strings; using Umbraco.Core.Sync; +using Umbraco.Net; using Umbraco.Web.Actions; using Umbraco.Web.Cache; using Umbraco.Web.Editors; @@ -225,6 +227,8 @@ namespace Umbraco.Web.Composing public static IVariationContextAccessor VariationContextAccessor => CoreCurrent.VariationContextAccessor; public static IIOHelper IOHelper => CoreCurrent.IOHelper; + public static IHostingEnvironment HostingEnvironment => CoreCurrent.HostingEnvironment; + public static IIpResolver IpResolver => Factory.GetInstance(); public static IUmbracoVersion UmbracoVersion => Factory.GetInstance(); #endregion diff --git a/src/Umbraco.Web/Hosting/AspNetHostingEnvironment.cs b/src/Umbraco.Web/Hosting/AspNetHostingEnvironment.cs new file mode 100644 index 0000000000..07e77aa7d0 --- /dev/null +++ b/src/Umbraco.Web/Hosting/AspNetHostingEnvironment.cs @@ -0,0 +1,78 @@ +using System; +using System.Web; +using System.Web.Hosting; +using Umbraco.Core; +using Umbraco.Core.Configuration; +using Umbraco.Core.Hosting; +using Umbraco.Core.IO; + +namespace Umbraco.Web.Hosting +{ + public class AspNetHostingEnvironment : IHostingEnvironment + { + private readonly IGlobalSettings _globalSettings; + private readonly IIOHelper _ioHelper; + private string _localTempPath; + + public AspNetHostingEnvironment(IGlobalSettings globalSettings, IIOHelper ioHelper) + { + _globalSettings = globalSettings ?? throw new ArgumentNullException(nameof(globalSettings)); + _ioHelper = ioHelper ?? throw new ArgumentNullException(nameof(ioHelper)); + + SiteName = HostingEnvironment.SiteName; + ApplicationId = HostingEnvironment.ApplicationID; + ApplicationPhysicalPath = HostingEnvironment.ApplicationPhysicalPath; + ApplicationVirtualPath = HostingEnvironment.ApplicationVirtualPath; + + IsDebugMode = HttpContext.Current?.IsDebuggingEnabled ?? globalSettings.DebugMode; + } + + public string SiteName { get; } + public string ApplicationId { get; } + public string ApplicationPhysicalPath { get; } + + public string ApplicationVirtualPath { get; } + public bool IsDebugMode { get; } + public bool IsHosted => HostingEnvironment.IsHosted; + public string MapPath(string path) => HostingEnvironment.MapPath(path); + + public string LocalTempPath + { + get + { + if (_localTempPath != null) + return _localTempPath; + + switch (_globalSettings.LocalTempStorageLocation) + { + case LocalTempStorage.AspNetTemp: + return _localTempPath = System.IO.Path.Combine(HttpRuntime.CodegenDir, "UmbracoData"); + + case LocalTempStorage.EnvironmentTemp: + + // environment temp is unique, we need a folder per site + + // use a hash + // combine site name and application id + // site name is a Guid on Cloud + // application id is eg /LM/W3SVC/123456/ROOT + // the combination is unique on one server + // and, if a site moves from worker A to B and then back to A... + // hopefully it gets a new Guid or new application id? + + var hashString = SiteName + "::" + ApplicationId; + var hash = hashString.GenerateHash(); + var siteTemp = System.IO.Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData", hash); + + return _localTempPath = siteTemp; + + //case LocalTempStorage.Default: + //case LocalTempStorage.Unknown: + default: + return _localTempPath = _ioHelper.MapPath("~/App_Data/TEMP"); + } + } + } + + } +} diff --git a/src/Umbraco.Core/HttpContextExtensions.cs b/src/Umbraco.Web/HttpContextExtensions.cs similarity index 100% rename from src/Umbraco.Core/HttpContextExtensions.cs rename to src/Umbraco.Web/HttpContextExtensions.cs diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs index 974731b9bd..0ada286f07 100755 --- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs @@ -10,6 +10,7 @@ using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; +using Umbraco.Core.Hosting; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; @@ -48,6 +49,7 @@ namespace Umbraco.Web.PublishedCache.NuCache private readonly IDefaultCultureAccessor _defaultCultureAccessor; private readonly UrlSegmentProviderCollection _urlSegmentProviders; private readonly ITypeFinder _typeFinder; + private readonly IHostingEnvironment _hostingEnvironment; // volatile because we read it with no lock private volatile bool _isReady; @@ -80,7 +82,8 @@ namespace Umbraco.Web.PublishedCache.NuCache IEntityXmlSerializer entitySerializer, IPublishedModelFactory publishedModelFactory, UrlSegmentProviderCollection urlSegmentProviders, - ITypeFinder typeFinder) + ITypeFinder typeFinder, + IHostingEnvironment hostingEnvironment) : base(publishedSnapshotAccessor, variationContextAccessor) { //if (Interlocked.Increment(ref _singletonCheck) > 1) @@ -98,6 +101,7 @@ namespace Umbraco.Web.PublishedCache.NuCache _globalSettings = globalSettings; _urlSegmentProviders = urlSegmentProviders; _typeFinder = typeFinder; + _hostingEnvironment = hostingEnvironment; // we need an Xml serializer here so that the member cache can support XPath, // for members this is done by navigating the serialized-to-xml member @@ -299,7 +303,7 @@ namespace Umbraco.Web.PublishedCache.NuCache private string GetLocalFilesPath() { - var path = Path.Combine(_globalSettings.LocalTempPath(Current.IOHelper), "NuCache"); + var path = Path.Combine(_hostingEnvironment.LocalTempPath, "NuCache"); if (!Directory.Exists(path)) Directory.CreateDirectory(path); diff --git a/src/Umbraco.Web/Runtime/AspNetUmbracoBootPermissionChecker.cs b/src/Umbraco.Web/Runtime/AspNetUmbracoBootPermissionChecker.cs new file mode 100644 index 0000000000..fdf8b53852 --- /dev/null +++ b/src/Umbraco.Web/Runtime/AspNetUmbracoBootPermissionChecker.cs @@ -0,0 +1,13 @@ +using System.Web; +using Umbraco.Core.Runtime; + +namespace Umbraco.Web.Runtime +{ + public class AspNetUmbracoBootPermissionChecker : IUmbracoBootPermissionChecker + { + public void ThrowIfNotPermissions() + { + new AspNetHostingPermission(AspNetHostingPermissionLevel.Unrestricted).Demand(); + } + } +} diff --git a/src/Umbraco.Web/Runtime/WebInitialComponent.cs b/src/Umbraco.Web/Runtime/WebInitialComponent.cs index 380c3915b7..f02a3686ac 100644 --- a/src/Umbraco.Web/Runtime/WebInitialComponent.cs +++ b/src/Umbraco.Web/Runtime/WebInitialComponent.cs @@ -14,6 +14,7 @@ using ClientDependency.Core.Config; using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Web.Install; using Umbraco.Web.JavaScript; @@ -30,13 +31,15 @@ namespace Umbraco.Web.Runtime private readonly SurfaceControllerTypeCollection _surfaceControllerTypes; private readonly UmbracoApiControllerTypeCollection _apiControllerTypes; private readonly IGlobalSettings _globalSettings; + private readonly IHostingEnvironment _hostingEnvironment; - public WebInitialComponent(IUmbracoContextAccessor umbracoContextAccessor, SurfaceControllerTypeCollection surfaceControllerTypes, UmbracoApiControllerTypeCollection apiControllerTypes, IGlobalSettings globalSettings) + public WebInitialComponent(IUmbracoContextAccessor umbracoContextAccessor, SurfaceControllerTypeCollection surfaceControllerTypes, UmbracoApiControllerTypeCollection apiControllerTypes, IGlobalSettings globalSettings, IHostingEnvironment hostingEnvironment) { _umbracoContextAccessor = umbracoContextAccessor; _surfaceControllerTypes = surfaceControllerTypes; _apiControllerTypes = apiControllerTypes; _globalSettings = globalSettings; + _hostingEnvironment = hostingEnvironment; } public void Initialize() @@ -48,7 +51,7 @@ namespace Umbraco.Web.Runtime // want to access HttpContext.Current, which doesn't exist if (Current.IOHelper.IsHosted) { - ConfigureClientDependency(_globalSettings); + ConfigureClientDependency(); } // Disable the X-AspNetMvc-Version HTTP Header @@ -109,7 +112,7 @@ namespace Umbraco.Web.Runtime new NamespaceHttpControllerSelector(GlobalConfiguration.Configuration)); } - private static void ConfigureClientDependency(IGlobalSettings globalSettings) + private void ConfigureClientDependency() { // Backwards compatibility - set the path and URL type for ClientDependency 1.5.1 [LK] XmlFileMapper.FileMapDefaultFolder = Core.Constants.SystemDirectories.TempData.EnsureEndsWith('/') + "ClientDependency"; @@ -117,9 +120,9 @@ namespace Umbraco.Web.Runtime // Now we need to detect if we are running 'Umbraco.Core.LocalTempStorage' as EnvironmentTemp and in that case we want to change the CDF file // location to be there - if (globalSettings.LocalTempStorageLocation == LocalTempStorage.EnvironmentTemp) + if (_globalSettings.LocalTempStorageLocation == LocalTempStorage.EnvironmentTemp) { - var cachePath = globalSettings.LocalTempPath(Current.IOHelper); + var cachePath = _hostingEnvironment.LocalTempPath; //set the file map and composite file default location to the %temp% location BaseCompositeFileProcessingProvider.CompositeFilePathDefaultFolder diff --git a/src/Umbraco.Web/Runtime/WebInitialComposer.cs b/src/Umbraco.Web/Runtime/WebInitialComposer.cs index f475ac9e78..990fc200aa 100644 --- a/src/Umbraco.Web/Runtime/WebInitialComposer.cs +++ b/src/Umbraco.Web/Runtime/WebInitialComposer.cs @@ -8,6 +8,7 @@ using Umbraco.Core.Composing; using Umbraco.Core.Dashboards; using Umbraco.Core.Dictionary; using Umbraco.Core.Events; +using Umbraco.Core.Hosting; using Umbraco.Core.Migrations.PostMigrations; using Umbraco.Web.Migrations.PostMigrations; using Umbraco.Core.Models.PublishedContent; @@ -15,6 +16,7 @@ using Umbraco.Core.PropertyEditors; using Umbraco.Core.PropertyEditors.ValueConverters; using Umbraco.Core.Runtime; using Umbraco.Core.Services; +using Umbraco.Net; using Umbraco.Web.Actions; using Umbraco.Web.Cache; using Umbraco.Web.Composing.CompositionExtensions; @@ -23,6 +25,7 @@ using Umbraco.Web.Dashboards; using Umbraco.Web.Editors; using Umbraco.Web.Features; using Umbraco.Web.HealthCheck; +using Umbraco.Web.Hosting; using Umbraco.Web.Macros; using Umbraco.Web.Media.EmbedProviders; using Umbraco.Web.Models.PublishedContent; @@ -53,6 +56,10 @@ namespace Umbraco.Web.Runtime base.Compose(composition); composition.Register(); + composition.Register(); + composition.Register(); + composition.Register(); + composition.Register(); composition.RegisterUnique(); // required for hybrid accessors @@ -72,7 +79,7 @@ namespace Umbraco.Web.Runtime // register accessors for cultures composition.RegisterUnique(); composition.RegisterUnique(); - + // register the http context and umbraco context accessors // we *should* use the HttpContextUmbracoContextAccessor, however there are cases when // we have no http context, eg when booting Umbraco or in background threads, so instead @@ -265,7 +272,7 @@ namespace Umbraco.Web.Runtime .Append() .Append() .Append(); - + // replace with web implementation composition.RegisterUnique(); diff --git a/src/Umbraco.Web/Runtime/WebRuntime.cs b/src/Umbraco.Web/Runtime/WebRuntime.cs index bd17907cc9..8e83afada1 100644 --- a/src/Umbraco.Web/Runtime/WebRuntime.cs +++ b/src/Umbraco.Web/Runtime/WebRuntime.cs @@ -1,7 +1,9 @@ using System.Web; +using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Runtime; @@ -18,52 +20,72 @@ namespace Umbraco.Web.Runtime public class WebRuntime : CoreRuntime { private readonly UmbracoApplicationBase _umbracoApplication; - private IProfiler _webProfiler; private BuildManagerTypeFinder _typeFinder; /// /// Initializes a new instance of the class. /// /// - public WebRuntime(UmbracoApplicationBase umbracoApplication, Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger): - base(configs, umbracoVersion, ioHelper, logger) + public WebRuntime(UmbracoApplicationBase umbracoApplication, Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IProfiler profiler, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo): + base(configs, umbracoVersion, ioHelper, logger, profiler ,new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo) { _umbracoApplication = umbracoApplication; + + Profiler = GetWebProfiler(); + } + + private IProfiler GetWebProfiler() + { + // create and start asap to profile boot + if (!State.Debug) + { + // should let it be null, that's how MiniProfiler is meant to work, + // but our own IProfiler expects an instance so let's get one + return new VoidProfiler(); + } + + var webProfiler = new WebProfiler(); + webProfiler.Start(); + + return webProfiler; } /// public override IFactory Boot(IRegister register) { - // create and start asap to profile boot - if (State.Debug) + + var profilingLogger = new ProfilingLogger(Logger, Profiler); + var umbracoVersion = new UmbracoVersion(); + using (var timer = profilingLogger.TraceDuration( + $"Booting Umbraco {umbracoVersion.SemanticVersion.ToSemanticString()}.", + "Booted.", + "Boot failed.")) { - _webProfiler = new WebProfiler(); - _webProfiler.Start(); - } - else - { - // should let it be null, that's how MiniProfiler is meant to work, - // but our own IProfiler expects an instance so let's get one - _webProfiler = new VoidProfiler(); + Logger.Info("Booting site '{HostingSiteName}', app '{HostingApplicationId}', path '{HostingPhysicalPath}', server '{MachineName}'.", + HostingEnvironment.SiteName, + HostingEnvironment.ApplicationId, + HostingEnvironment.ApplicationPhysicalPath, + NetworkHelper.MachineName); + Logger.Debug("Runtime: {Runtime}", GetType().FullName); + + var factory = base.Boot(register); + + // now (and only now) is the time to switch over to perWebRequest scopes. + // up until that point we may not have a request, and scoped services would + // fail to resolve - but we run Initialize within a factory scope - and then, + // here, we switch the factory to bind scopes to requests + factory.EnablePerWebRequestScope(); + + return factory; } - var factory = base.Boot(register); - // now (and only now) is the time to switch over to perWebRequest scopes. - // up until that point we may not have a request, and scoped services would - // fail to resolve - but we run Initialize within a factory scope - and then, - // here, we switch the factory to bind scopes to requests - factory.EnablePerWebRequestScope(); - - return factory; } #region Getters protected override ITypeFinder GetTypeFinder() => _typeFinder ?? (_typeFinder = new BuildManagerTypeFinder(IOHelper, Logger, new BuildManagerTypeFinder.TypeFinderConfig())); - protected override IProfiler GetProfiler() => _webProfiler; - protected override AppCaches GetAppCaches() => new AppCaches( // we need to have the dep clone runtime cache provider to ensure // all entities are cached properly (cloned in and cloned out) diff --git a/src/Umbraco.Web/Security/AppBuilderExtensions.cs b/src/Umbraco.Web/Security/AppBuilderExtensions.cs index 9d842d1219..d252b4bc57 100644 --- a/src/Umbraco.Web/Security/AppBuilderExtensions.cs +++ b/src/Umbraco.Web/Security/AppBuilderExtensions.cs @@ -17,6 +17,7 @@ using Umbraco.Core.Mapping; using Umbraco.Core.Models.Identity; using Umbraco.Core.Security; using Umbraco.Core.Services; +using Umbraco.Net; using Umbraco.Web.Composing; using Constants = Umbraco.Core.Constants; @@ -41,7 +42,8 @@ namespace Umbraco.Web.Security IContentSection contentSettings, IGlobalSettings globalSettings, // TODO: This could probably be optional? - IPasswordConfiguration passwordConfiguration) + IPasswordConfiguration passwordConfiguration, + IIpResolver ipResolver) { if (services == null) throw new ArgumentNullException(nameof(services)); @@ -55,7 +57,8 @@ namespace Umbraco.Web.Security mapper, contentSettings, globalSettings, - passwordConfiguration)); + passwordConfiguration, + ipResolver)); app.SetBackOfficeUserManagerType(); @@ -72,13 +75,15 @@ namespace Umbraco.Web.Security /// /// /// + /// public static void ConfigureUserManagerForUmbracoBackOffice(this IAppBuilder app, IRuntimeState runtimeState, IContentSection contentSettings, IGlobalSettings globalSettings, BackOfficeUserStore customUserStore, // TODO: This could probably be optional? - IPasswordConfiguration passwordConfiguration) + IPasswordConfiguration passwordConfiguration, + IIpResolver ipResolver) { if (runtimeState == null) throw new ArgumentNullException(nameof(runtimeState)); if (customUserStore == null) throw new ArgumentNullException(nameof(customUserStore)); @@ -89,7 +94,8 @@ namespace Umbraco.Web.Security options, customUserStore, contentSettings, - passwordConfiguration)); + passwordConfiguration, + ipResolver)); app.SetBackOfficeUserManagerType(); diff --git a/src/Umbraco.Web/Security/BackOfficeUserManager.cs b/src/Umbraco.Web/Security/BackOfficeUserManager.cs index cca08318f4..52bf901bfa 100644 --- a/src/Umbraco.Web/Security/BackOfficeUserManager.cs +++ b/src/Umbraco.Web/Security/BackOfficeUserManager.cs @@ -12,6 +12,7 @@ using Umbraco.Core.Mapping; using Umbraco.Core.Models.Identity; using Umbraco.Core.Security; using Umbraco.Core.Services; +using Umbraco.Net; namespace Umbraco.Web.Security { @@ -24,13 +25,14 @@ namespace Umbraco.Web.Security public BackOfficeUserManager( IUserStore store, - IdentityFactoryOptions options, + IdentityFactoryOptions options, IContentSection contentSectionConfig, - IPasswordConfiguration passwordConfiguration) - : base(store, passwordConfiguration) + IPasswordConfiguration passwordConfiguration, + IIpResolver ipResolver) + : base(store, passwordConfiguration, ipResolver) { if (options == null) throw new ArgumentNullException("options"); - InitUserManager(this, passwordConfiguration, options.DataProtectionProvider, contentSectionConfig); + InitUserManager(this, passwordConfiguration, options.DataProtectionProvider, contentSectionConfig); } #region Static Create methods @@ -50,18 +52,19 @@ namespace Umbraco.Web.Security IdentityFactoryOptions options, IUserService userService, IEntityService entityService, - IExternalLoginService externalLoginService, + IExternalLoginService externalLoginService, UmbracoMapper mapper, IContentSection contentSectionConfig, IGlobalSettings globalSettings, - IPasswordConfiguration passwordConfiguration) + IPasswordConfiguration passwordConfiguration, + IIpResolver ipResolver) { if (options == null) throw new ArgumentNullException("options"); if (userService == null) throw new ArgumentNullException("userService"); if (externalLoginService == null) throw new ArgumentNullException("externalLoginService"); var store = new BackOfficeUserStore(userService, entityService, externalLoginService, globalSettings, mapper); - var manager = new BackOfficeUserManager(store, options, contentSectionConfig, passwordConfiguration); + var manager = new BackOfficeUserManager(store, options, contentSectionConfig, passwordConfiguration, ipResolver); return manager; } @@ -75,16 +78,17 @@ namespace Umbraco.Web.Security /// public static BackOfficeUserManager Create( IdentityFactoryOptions options, - BackOfficeUserStore customUserStore, + BackOfficeUserStore customUserStore, IContentSection contentSectionConfig, - IPasswordConfiguration passwordConfiguration) + IPasswordConfiguration passwordConfiguration, + IIpResolver ipResolver) { - var manager = new BackOfficeUserManager(customUserStore, options, contentSectionConfig, passwordConfiguration); + var manager = new BackOfficeUserManager(customUserStore, options, contentSectionConfig, passwordConfiguration, ipResolver); return manager; } #endregion - + } /// @@ -96,10 +100,12 @@ namespace Umbraco.Web.Security private PasswordGenerator _passwordGenerator; public BackOfficeUserManager(IUserStore store, - IPasswordConfiguration passwordConfiguration) + IPasswordConfiguration passwordConfiguration, + IIpResolver ipResolver) : base(store) { PasswordConfiguration = passwordConfiguration; + IpResolver = ipResolver; } #region What we support do not currently @@ -236,8 +242,7 @@ namespace Umbraco.Web.Security /// public IBackOfficeUserPasswordChecker BackOfficeUserPasswordChecker { get; set; } public IPasswordConfiguration PasswordConfiguration { get; } - - + public IIpResolver IpResolver { get; } /// /// Helper method to generate a password for a user based on the current password validator @@ -507,57 +512,57 @@ namespace Umbraco.Web.Security internal void RaiseAccountLockedEvent(int userId) { - OnAccountLocked(new IdentityAuditEventArgs(AuditEvent.AccountLocked, GetCurrentRequestIpAddress(), affectedUser: userId)); + OnAccountLocked(new IdentityAuditEventArgs(AuditEvent.AccountLocked, IpResolver.GetCurrentRequestIpAddress(), affectedUser: userId)); } internal void RaiseAccountUnlockedEvent(int userId) { - OnAccountUnlocked(new IdentityAuditEventArgs(AuditEvent.AccountUnlocked, GetCurrentRequestIpAddress(), affectedUser: userId)); + OnAccountUnlocked(new IdentityAuditEventArgs(AuditEvent.AccountUnlocked, IpResolver.GetCurrentRequestIpAddress(), affectedUser: userId)); } internal void RaiseForgotPasswordRequestedEvent(int userId) { - OnForgotPasswordRequested(new IdentityAuditEventArgs(AuditEvent.ForgotPasswordRequested, GetCurrentRequestIpAddress(), affectedUser: userId)); + OnForgotPasswordRequested(new IdentityAuditEventArgs(AuditEvent.ForgotPasswordRequested, IpResolver.GetCurrentRequestIpAddress(), affectedUser: userId)); } internal void RaiseForgotPasswordChangedSuccessEvent(int userId) { - OnForgotPasswordChangedSuccess(new IdentityAuditEventArgs(AuditEvent.ForgotPasswordChangedSuccess, GetCurrentRequestIpAddress(), affectedUser: userId)); + OnForgotPasswordChangedSuccess(new IdentityAuditEventArgs(AuditEvent.ForgotPasswordChangedSuccess, IpResolver.GetCurrentRequestIpAddress(), affectedUser: userId)); } internal void RaiseLoginFailedEvent(int userId) { - OnLoginFailed(new IdentityAuditEventArgs(AuditEvent.LoginFailed, GetCurrentRequestIpAddress(), affectedUser: userId)); + OnLoginFailed(new IdentityAuditEventArgs(AuditEvent.LoginFailed, IpResolver.GetCurrentRequestIpAddress(), affectedUser: userId)); } internal void RaiseInvalidLoginAttemptEvent(string username) { - OnLoginFailed(new IdentityAuditEventArgs(AuditEvent.LoginFailed, GetCurrentRequestIpAddress(), username, string.Format("Attempted login for username '{0}' failed", username))); + OnLoginFailed(new IdentityAuditEventArgs(AuditEvent.LoginFailed, IpResolver.GetCurrentRequestIpAddress(), username, string.Format("Attempted login for username '{0}' failed", username))); } internal void RaiseLoginRequiresVerificationEvent(int userId) { - OnLoginRequiresVerification(new IdentityAuditEventArgs(AuditEvent.LoginRequiresVerification, GetCurrentRequestIpAddress(), affectedUser: userId)); + OnLoginRequiresVerification(new IdentityAuditEventArgs(AuditEvent.LoginRequiresVerification, IpResolver.GetCurrentRequestIpAddress(), affectedUser: userId)); } internal void RaiseLoginSuccessEvent(int userId) { - OnLoginSuccess(new IdentityAuditEventArgs(AuditEvent.LoginSucces, GetCurrentRequestIpAddress(), affectedUser: userId)); + OnLoginSuccess(new IdentityAuditEventArgs(AuditEvent.LoginSucces, IpResolver.GetCurrentRequestIpAddress(), affectedUser: userId)); } internal void RaiseLogoutSuccessEvent(int userId) { - OnLogoutSuccess(new IdentityAuditEventArgs(AuditEvent.LogoutSuccess, GetCurrentRequestIpAddress(), affectedUser: userId)); + OnLogoutSuccess(new IdentityAuditEventArgs(AuditEvent.LogoutSuccess, IpResolver.GetCurrentRequestIpAddress(), affectedUser: userId)); } internal void RaisePasswordChangedEvent(int userId) { - OnPasswordChanged(new IdentityAuditEventArgs(AuditEvent.PasswordChanged, GetCurrentRequestIpAddress(), affectedUser: userId)); + OnPasswordChanged(new IdentityAuditEventArgs(AuditEvent.PasswordChanged, IpResolver.GetCurrentRequestIpAddress(), affectedUser: userId)); } internal void RaiseResetAccessFailedCountEvent(int userId) { - OnResetAccessFailedCount(new IdentityAuditEventArgs(AuditEvent.ResetAccessFailedCount, GetCurrentRequestIpAddress(), affectedUser: userId)); + OnResetAccessFailedCount(new IdentityAuditEventArgs(AuditEvent.ResetAccessFailedCount, IpResolver.GetCurrentRequestIpAddress(), affectedUser: userId)); } public static event EventHandler AccountLocked; @@ -627,17 +632,6 @@ namespace Umbraco.Web.Security if (ResetAccessFailedCount != null) ResetAccessFailedCount(this, e); } - /// - /// Returns the current request IP address for logging if there is one - /// - /// - protected virtual string GetCurrentRequestIpAddress() - { - // TODO: inject a service to get this value, we should not be relying on the old HttpContext.Current especially in the ASP.NET Identity world. - var httpContext = HttpContext.Current == null ? (HttpContextBase)null : new HttpContextWrapper(HttpContext.Current); - return httpContext.GetCurrentRequestIpAddress(); - } - } } diff --git a/src/Umbraco.Web/Security/MembershipProviderBase.cs b/src/Umbraco.Web/Security/MembershipProviderBase.cs index b3d6fa4f52..5060b417f5 100644 --- a/src/Umbraco.Web/Security/MembershipProviderBase.cs +++ b/src/Umbraco.Web/Security/MembershipProviderBase.cs @@ -6,10 +6,13 @@ using System.Text; using System.Text.RegularExpressions; using System.Web; using System.Web.Hosting; +using System.Web.Configuration; using System.Web.Security; using Umbraco.Core; using Umbraco.Core.Composing; +using Umbraco.Core.Hosting; using Umbraco.Core.Logging; +using Umbraco.Core.Security; namespace Umbraco.Web.Security { @@ -18,6 +21,13 @@ namespace Umbraco.Web.Security /// public abstract class MembershipProviderBase : MembershipProvider { + private readonly IHostingEnvironment _hostingEnvironment; + + protected MembershipProviderBase(IHostingEnvironment hostingEnvironment) + { + _hostingEnvironment = hostingEnvironment; + } + /// /// Providers can override this setting, default is 10 /// @@ -218,7 +228,7 @@ namespace Umbraco.Web.Security _applicationName = config["applicationName"]; if (string.IsNullOrEmpty(_applicationName)) - _applicationName = GetDefaultAppName(); + _applicationName = GetDefaultAppName(_hostingEnvironment); //by default we will continue using the legacy encoding. UseLegacyEncoding = config.GetValue("useLegacyEncoding", DefaultUseLegacyEncoding); @@ -549,11 +559,11 @@ namespace Umbraco.Web.Security /// Gets the name of the default app. /// /// - internal static string GetDefaultAppName() + internal static string GetDefaultAppName(IHostingEnvironment hostingEnvironment) { try { - string applicationVirtualPath = HostingEnvironment.ApplicationVirtualPath; + string applicationVirtualPath = hostingEnvironment.ApplicationVirtualPath; if (string.IsNullOrEmpty(applicationVirtualPath)) { return "/"; @@ -668,14 +678,5 @@ namespace Umbraco.Web.Security return sb.ToString(); } - /// - /// Returns the current request IP address for logging if there is one - /// - /// - protected string GetCurrentRequestIpAddress() - { - var httpContext = HttpContext.Current == null ? (HttpContextBase)null : new HttpContextWrapper(HttpContext.Current); - return httpContext.GetCurrentRequestIpAddress(); - } } } diff --git a/src/Umbraco.Web/Security/MembershipProviderExtensions.cs b/src/Umbraco.Web/Security/MembershipProviderExtensions.cs index 3e26bfeb20..fd2c9c19aa 100644 --- a/src/Umbraco.Web/Security/MembershipProviderExtensions.cs +++ b/src/Umbraco.Web/Security/MembershipProviderExtensions.cs @@ -2,8 +2,8 @@ using System.Security.Principal; using System.Threading; using System.Web; -using System.Web.Hosting; using System.Web.Security; +using Umbraco.Core.Composing; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; @@ -70,7 +70,7 @@ namespace Umbraco.Web.Security /// internal static string GetCurrentUserName(this MembershipProvider membershipProvider) { - if (HostingEnvironment.IsHosted) + if (Current.HostingEnvironment.IsHosted) { HttpContext current = HttpContext.Current; if (current != null && current.User != null && current.User.Identity != null) @@ -81,6 +81,6 @@ namespace Umbraco.Web.Security return string.Empty; else return currentPrincipal.Identity.Name; - } + } } } diff --git a/src/Umbraco.Web/Security/Providers/MembersMembershipProvider.cs b/src/Umbraco.Web/Security/Providers/MembersMembershipProvider.cs index 37c8bd37d7..d393078cc6 100644 --- a/src/Umbraco.Web/Security/Providers/MembersMembershipProvider.cs +++ b/src/Umbraco.Web/Security/Providers/MembersMembershipProvider.cs @@ -3,12 +3,14 @@ using System.Configuration.Provider; using System.Web.Security; using Umbraco.Core; using Umbraco.Core.Configuration; +using Umbraco.Core.Hosting; using Umbraco.Core.Models; using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Core.Models.Membership; using Umbraco.Web.Composing; using System; +using Umbraco.Net; namespace Umbraco.Web.Security.Providers { @@ -18,11 +20,11 @@ namespace Umbraco.Web.Security.Providers public class MembersMembershipProvider : UmbracoMembershipProvider { public MembersMembershipProvider() - : this(Current.Services.MemberService, Current.Services.MemberTypeService, Current.UmbracoVersion) + : this(Current.Services.MemberService, Current.Services.MemberTypeService, Current.UmbracoVersion, Current.HostingEnvironment, Current.IpResolver) { } - public MembersMembershipProvider(IMembershipMemberService memberService, IMemberTypeService memberTypeService, IUmbracoVersion umbracoVersion) - : base(memberService, umbracoVersion) + public MembersMembershipProvider(IMembershipMemberService memberService, IMemberTypeService memberTypeService, IUmbracoVersion umbracoVersion, IHostingEnvironment hostingEnvironment, IIpResolver ipResolver) + : base(memberService, umbracoVersion, hostingEnvironment, ipResolver) { LockPropertyTypeAlias = Constants.Conventions.Member.IsLockedOut; LastLockedOutPropertyTypeAlias = Constants.Conventions.Member.LastLockoutDate; diff --git a/src/Umbraco.Web/Security/Providers/UmbracoMembershipProvider.cs b/src/Umbraco.Web/Security/Providers/UmbracoMembershipProvider.cs index f8e165b33d..d2eeebaeaf 100644 --- a/src/Umbraco.Web/Security/Providers/UmbracoMembershipProvider.cs +++ b/src/Umbraco.Web/Security/Providers/UmbracoMembershipProvider.cs @@ -7,11 +7,13 @@ using System.Web.Configuration; using System.Web.Security; using Umbraco.Core; using Umbraco.Core.Configuration; +using Umbraco.Core.Hosting; using Umbraco.Core.Logging; using Umbraco.Core.Models.Membership; using Umbraco.Core.Persistence.Querying; using Umbraco.Core.Security; using Umbraco.Core.Services; +using Umbraco.Net; using Umbraco.Web.Composing; namespace Umbraco.Web.Security.Providers @@ -26,12 +28,15 @@ namespace Umbraco.Web.Security.Providers where TEntity : class, IMembershipUser { private readonly IUmbracoVersion _umbracoVersion; + private readonly IIpResolver _ipResolver; protected IMembershipMemberService MemberService { get; private set; } - protected UmbracoMembershipProvider(IMembershipMemberService memberService, IUmbracoVersion umbracoVersion) + protected UmbracoMembershipProvider(IMembershipMemberService memberService, IUmbracoVersion umbracoVersion, IHostingEnvironment hostingEnvironment, IIpResolver ipResolver) + :base(hostingEnvironment) { _umbracoVersion = umbracoVersion; + _ipResolver = ipResolver; MemberService = memberService; } @@ -485,7 +490,7 @@ namespace Umbraco.Web.Security.Providers if (member == null) { - Current.Logger.Info("Login attempt failed for username {Username} from IP address {IpAddress}, the user does not exist", username, GetCurrentRequestIpAddress()); + Current.Logger.Info("Login attempt failed for username {Username} from IP address {IpAddress}, the user does not exist", username, _ipResolver.GetCurrentRequestIpAddress()); return new ValidateUserResult { @@ -495,7 +500,7 @@ namespace Umbraco.Web.Security.Providers if (member.IsApproved == false) { - Current.Logger.Info("Login attempt failed for username {Username} from IP address {IpAddress}, the user is not approved", username, GetCurrentRequestIpAddress()); + Current.Logger.Info("Login attempt failed for username {Username} from IP address {IpAddress}, the user is not approved", username, _ipResolver.GetCurrentRequestIpAddress()); return new ValidateUserResult { @@ -505,7 +510,7 @@ namespace Umbraco.Web.Security.Providers } if (member.IsLockedOut) { - Current.Logger.Info("Login attempt failed for username {Username} from IP address {IpAddress}, the user is locked", username, GetCurrentRequestIpAddress()); + Current.Logger.Info("Login attempt failed for username {Username} from IP address {IpAddress}, the user is locked", username, _ipResolver.GetCurrentRequestIpAddress()); return new ValidateUserResult { @@ -529,11 +534,11 @@ namespace Umbraco.Web.Security.Providers member.IsLockedOut = true; member.LastLockoutDate = DateTime.Now; - Current.Logger.Info("Login attempt failed for username {Username} from IP address {IpAddress}, the user is now locked out, max invalid password attempts exceeded", username, GetCurrentRequestIpAddress()); + Current.Logger.Info("Login attempt failed for username {Username} from IP address {IpAddress}, the user is now locked out, max invalid password attempts exceeded", username, _ipResolver.GetCurrentRequestIpAddress()); } else { - Current.Logger.Info("Login attempt failed for username {Username} from IP address {IpAddress}", username, GetCurrentRequestIpAddress()); + Current.Logger.Info("Login attempt failed for username {Username} from IP address {IpAddress}", username, _ipResolver.GetCurrentRequestIpAddress()); } } else @@ -546,7 +551,7 @@ namespace Umbraco.Web.Security.Providers member.LastLoginDate = DateTime.Now; - Current.Logger.Info("Login attempt succeeded for username {Username} from IP address {IpAddress}", username, GetCurrentRequestIpAddress()); + Current.Logger.Info("Login attempt succeeded for username {Username} from IP address {IpAddress}", username, _ipResolver.GetCurrentRequestIpAddress()); } //don't raise events for this! It just sets the member dates, if we do raise events this will diff --git a/src/Umbraco.Web/Security/UmbracoMembershipProviderBase.cs b/src/Umbraco.Web/Security/UmbracoMembershipProviderBase.cs index 3ab0fad6cb..ef61bc40e9 100644 --- a/src/Umbraco.Web/Security/UmbracoMembershipProviderBase.cs +++ b/src/Umbraco.Web/Security/UmbracoMembershipProviderBase.cs @@ -1,5 +1,6 @@ using System.Text; using System.Web.Security; +using Umbraco.Core.Hosting; using Umbraco.Core.Security; namespace Umbraco.Web.Security @@ -9,6 +10,10 @@ namespace Umbraco.Web.Security /// public abstract class UmbracoMembershipProviderBase : MembershipProviderBase { + protected UmbracoMembershipProviderBase(IHostingEnvironment hostingEnvironment) : base(hostingEnvironment) + { + } + public abstract PasswordSecurity PasswordSecurity { get; } public abstract string DefaultMemberTypeAlias { get; } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index d18d6aa0f4..37e76c8c2d 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -126,6 +126,8 @@ + + @@ -163,6 +165,9 @@ + + + @@ -253,6 +258,7 @@ + @@ -1263,7 +1269,6 @@ umbraco_org_umbraco_update_CheckForUpgrade -