diff --git a/build/build-bootstrap.ps1 b/build/build-bootstrap.ps1 index 71a25bfd7e..82c789ff22 100644 --- a/build/build-bootstrap.ps1 +++ b/build/build-bootstrap.ps1 @@ -22,6 +22,8 @@ # get NuGet $cache = 4 $nuget = "$scriptTemp\nuget.exe" + # ensure the correct NuGet-source is used. This one is used by Umbraco + $nugetsourceUmbraco = "https://www.myget.org/F/umbracocore/api/v3/index.json" if (-not $local) { $source = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" @@ -61,7 +63,7 @@ # get the build system if (-not $local) { - $params = "-OutputDirectory", $scriptTemp, "-Verbosity", "quiet", "-PreRelease" + $params = "-OutputDirectory", $scriptTemp, "-Verbosity", "quiet", "-PreRelease", "-Source", $nugetsourceUmbraco &$nuget install Umbraco.Build @params if (-not $?) { throw "Failed to download Umbraco.Build." } } diff --git a/build/build.ps1 b/build/build.ps1 index ea07e4516f..6e124d1508 100644 --- a/build/build.ps1 +++ b/build/build.ps1 @@ -375,11 +375,14 @@ }) + $nugetsourceUmbraco = "https://api.nuget.org/v3/index.json" + $ubuild.DefineMethod("RestoreNuGet", { Write-Host "Restore NuGet" Write-Host "Logging to $($this.BuildTemp)\nuget.restore.log" - &$this.BuildEnv.NuGet restore "$($this.SolutionRoot)\src\Umbraco.sln" > "$($this.BuildTemp)\nuget.restore.log" + $params = "-Source", $nugetsourceUmbraco + &$this.BuildEnv.NuGet restore "$($this.SolutionRoot)\src\Umbraco.sln" > "$($this.BuildTemp)\nuget.restore.log" @params if (-not $?) { throw "Failed to restore NuGet packages." } }) diff --git a/src/Umbraco.Configuration/AspNetCoreConfigsFactory.cs b/src/Umbraco.Configuration/AspNetCoreConfigsFactory.cs new file mode 100644 index 0000000000..1e9f7976d5 --- /dev/null +++ b/src/Umbraco.Configuration/AspNetCoreConfigsFactory.cs @@ -0,0 +1,50 @@ +using Microsoft.Extensions.Configuration; +using Umbraco.Configuration.Models; +using Umbraco.Core.Configuration; +using Umbraco.Core.Configuration.HealthChecks; +using Umbraco.Core.Configuration.UmbracoSettings; +using ConnectionStrings = Umbraco.Configuration.Models.ConnectionStrings; +using CoreDebugSettings = Umbraco.Configuration.Models.CoreDebugSettings; + +namespace Umbraco.Configuration +{ + public class AspNetCoreConfigsFactory : IConfigsFactory + { + private readonly IConfiguration _configuration; + + public AspNetCoreConfigsFactory(IConfiguration configuration) + { + _configuration = configuration; + } + + public Configs Create() + { + var configs = new Configs(); + + configs.Add(() => new TourSettings(_configuration)); + configs.Add(() => new CoreDebugSettings(_configuration)); + configs.Add(() => new RequestHandlerSettings(_configuration)); + configs.Add(() => new SecuritySettings(_configuration)); + configs.Add(() => new UserPasswordConfigurationSettings(_configuration)); + configs.Add(() => new MemberPasswordConfigurationSettings(_configuration)); + configs.Add(() => new KeepAliveSettings(_configuration)); + configs.Add(() => new ContentSettings(_configuration)); + configs.Add(() => new HealthChecksSettings(_configuration)); + configs.Add(() => new LoggingSettings(_configuration)); + configs.Add(() => new ExceptionFilterSettings(_configuration)); + configs.Add(() => new ActiveDirectorySettings(_configuration)); + configs.Add(() => new RuntimeSettings(_configuration)); + configs.Add(() => new TypeFinderSettings(_configuration)); + configs.Add(() => new NuCacheSettings(_configuration)); + configs.Add(() => new WebRoutingSettings(_configuration)); + configs.Add(() => new IndexCreatorSettings(_configuration)); + configs.Add(() => new ModelsBuilderConfig(_configuration)); + configs.Add(() => new HostingSettings(_configuration)); + configs.Add(() => new GlobalSettings(_configuration)); + configs.Add(() => new ConnectionStrings(_configuration)); + configs.Add(() => new ImagingSettings(_configuration)); + + return configs; + } + } +} diff --git a/src/Umbraco.Configuration/CaseInsensitiveEnumConfigConverter.cs b/src/Umbraco.Configuration/CaseInsensitiveEnumConfigConverter.cs deleted file mode 100644 index f07e5133ef..0000000000 --- a/src/Umbraco.Configuration/CaseInsensitiveEnumConfigConverter.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.ComponentModel; -using System.Globalization; -using System.Linq; -using System.Configuration; - -namespace Umbraco.Core.Configuration -{ - /// - /// A case-insensitive configuration converter for enumerations. - /// - /// The type of the enumeration. - public class CaseInsensitiveEnumConfigConverter : ConfigurationConverterBase - where T : struct - { - public override object ConvertFrom(ITypeDescriptorContext ctx, CultureInfo ci, object data) - { - if (data == null) - throw new ArgumentNullException("data"); - - //return Enum.Parse(typeof(T), (string)data, true); - - T value; - if (Enum.TryParse((string)data, true, out value)) - return value; - - throw new Exception(string.Format("\"{0}\" is not valid {1} value. Valid values are: {2}.", - data, typeof(T).Name, - string.Join(", ", Enum.GetValues(typeof(T)).Cast()))); - } - } -} diff --git a/src/Umbraco.Configuration/ConfigsFactory.cs b/src/Umbraco.Configuration/ConfigsFactory.cs index 2ba3a109e1..be6cee2d0c 100644 --- a/src/Umbraco.Configuration/ConfigsFactory.cs +++ b/src/Umbraco.Configuration/ConfigsFactory.cs @@ -1,19 +1,16 @@ -using System.Configuration; using Umbraco.Configuration; using Umbraco.Configuration.Implementations; +using Umbraco.Configuration.Legacy; using Umbraco.Core.Configuration.HealthChecks; +using Umbraco.Core.Configuration.Legacy; using Umbraco.Core.Configuration.UmbracoSettings; -using Umbraco.Core.IO; -using Umbraco.Core.Logging; namespace Umbraco.Core.Configuration { public class ConfigsFactory : IConfigsFactory { public IHostingSettings HostingSettings { get; } = new HostingSettings(); - - public ICoreDebug CoreDebug { get; } = new CoreDebug(); - public IMachineKeyConfig MachineKeyConfig { get; } = new MachineKeyConfig(); + public ICoreDebugSettings CoreDebugSettings { get; } = new CoreDebugSettings(); public IIndexCreatorSettings IndexCreatorSettings { get; } = new IndexCreatorSettings(); public INuCacheSettings NuCacheSettings { get; } = new NuCacheSettings(); public ITypeFinderSettings TypeFinderSettings { get; } = new TypeFinderSettings(); @@ -29,28 +26,27 @@ namespace Umbraco.Core.Configuration public IUserPasswordConfiguration UserPasswordConfigurationSettings { get; } = new UserPasswordConfigurationSettings(); public IMemberPasswordConfiguration MemberPasswordConfigurationSettings { get; } = new MemberPasswordConfigurationSettings(); public IContentSettings ContentSettings { get; } = new ContentSettings(); + public IGlobalSettings GlobalSettings { get; } = new GlobalSettings(); + public IHealthChecksSettings HealthChecksSettings { get; } = new HealthChecksSettings(); + public IConnectionStrings ConnectionStrings { get; } = new ConnectionStrings(); + public IModelsBuilderConfig ModelsBuilderConfig { get; } = new ModelsBuilderConfig(); - public Configs Create(IIOHelper ioHelper, ILogger logger) + public Configs Create() { - var configs = new Configs(section => ConfigurationManager.GetSection(section)); - configs.Add(() => new GlobalSettings(ioHelper)); - configs.Add(() => HostingSettings); - - configs.Add("umbracoConfiguration/HealthChecks"); - - configs.Add(() => CoreDebug); - configs.Add(() => MachineKeyConfig); - configs.Add(() => new ConnectionStrings(ioHelper, logger)); - configs.Add(() => new ModelsBuilderConfig(ioHelper)); - + var configs = new Configs(); + configs.Add(() => GlobalSettings); + configs.Add(() => HostingSettings); + configs.Add(() => HealthChecksSettings); + configs.Add(() => CoreDebugSettings); + configs.Add(() => ConnectionStrings); + configs.Add(() => ModelsBuilderConfig); configs.Add(() => IndexCreatorSettings); configs.Add(() => NuCacheSettings); configs.Add(() => TypeFinderSettings); configs.Add(() => RuntimeSettings); configs.Add(() => ActiveDirectorySettings); configs.Add(() => ExceptionFilterSettings); - configs.Add(() => TourSettings); configs.Add(() => LoggingSettings); configs.Add(() => KeepAliveSettings); @@ -61,7 +57,6 @@ namespace Umbraco.Core.Configuration configs.Add(() => MemberPasswordConfigurationSettings); configs.Add(() => ContentSettings); - configs.AddCoreConfigs(ioHelper); return configs; } } diff --git a/src/Umbraco.Configuration/HealthChecks/HealthChecksSection.cs b/src/Umbraco.Configuration/HealthChecks/HealthChecksSection.cs index 90a7d8c567..373d846567 100644 --- a/src/Umbraco.Configuration/HealthChecks/HealthChecksSection.cs +++ b/src/Umbraco.Configuration/HealthChecks/HealthChecksSection.cs @@ -1,10 +1,9 @@ using System; -using System.Collections.Generic; using System.Configuration; namespace Umbraco.Core.Configuration.HealthChecks { - public class HealthChecksSection : ConfigurationSection, IHealthChecks + public class HealthChecksSection : ConfigurationSection { private const string DisabledChecksKey = "disabledChecks"; private const string NotificationSettingsKey = "notificationSettings"; @@ -21,14 +20,5 @@ namespace Umbraco.Core.Configuration.HealthChecks get { return ((HealthCheckNotificationSettingsElement)(base[NotificationSettingsKey])); } } - IEnumerable IHealthChecks.DisabledChecks - { - get { return DisabledChecks; } - } - - IHealthCheckNotificationSettings IHealthChecks.NotificationSettings - { - get { return NotificationSettings; } - } } } diff --git a/src/Umbraco.Configuration/ActiveDirectorySettings.cs b/src/Umbraco.Configuration/Legacy/ActiveDirectorySettings.cs similarity index 90% rename from src/Umbraco.Configuration/ActiveDirectorySettings.cs rename to src/Umbraco.Configuration/Legacy/ActiveDirectorySettings.cs index d85def7f33..ef100afed6 100644 --- a/src/Umbraco.Configuration/ActiveDirectorySettings.cs +++ b/src/Umbraco.Configuration/Legacy/ActiveDirectorySettings.cs @@ -1,7 +1,7 @@ using System.Configuration; using Umbraco.Core.Configuration; -namespace Umbraco.Configuration +namespace Umbraco.Configuration.Legacy { public class ActiveDirectorySettings : IActiveDirectorySettings { diff --git a/src/Umbraco.Configuration/CommaDelimitedConfigurationElement.cs b/src/Umbraco.Configuration/Legacy/CommaDelimitedConfigurationElement.cs similarity index 100% rename from src/Umbraco.Configuration/CommaDelimitedConfigurationElement.cs rename to src/Umbraco.Configuration/Legacy/CommaDelimitedConfigurationElement.cs diff --git a/src/Umbraco.Configuration/Implementations/ConfigurationManagerConfigBase.cs b/src/Umbraco.Configuration/Legacy/ConfigurationManagerConfigBase.cs similarity index 90% rename from src/Umbraco.Configuration/Implementations/ConfigurationManagerConfigBase.cs rename to src/Umbraco.Configuration/Legacy/ConfigurationManagerConfigBase.cs index d218ac803b..0302a7ea31 100644 --- a/src/Umbraco.Configuration/Implementations/ConfigurationManagerConfigBase.cs +++ b/src/Umbraco.Configuration/Legacy/ConfigurationManagerConfigBase.cs @@ -7,7 +7,7 @@ namespace Umbraco.Configuration.Implementations { private UmbracoSettingsSection _umbracoSettingsSection; - public UmbracoSettingsSection UmbracoSettingsSection + protected UmbracoSettingsSection UmbracoSettingsSection { get { diff --git a/src/Umbraco.Configuration/Legacy/ConnectionStrings.cs b/src/Umbraco.Configuration/Legacy/ConnectionStrings.cs new file mode 100644 index 0000000000..a02c351118 --- /dev/null +++ b/src/Umbraco.Configuration/Legacy/ConnectionStrings.cs @@ -0,0 +1,17 @@ +using System.Configuration; + +namespace Umbraco.Core.Configuration +{ + public class ConnectionStrings : IConnectionStrings + { + public ConfigConnectionString this[string key] + { + get + { + var settings = ConfigurationManager.ConnectionStrings[key]; + if (settings == null) return null; + return new ConfigConnectionString(settings.ConnectionString, settings.ProviderName, settings.Name); + } + } + } +} diff --git a/src/Umbraco.Configuration/Implementations/ContentSettings.cs b/src/Umbraco.Configuration/Legacy/ContentSettings.cs similarity index 100% rename from src/Umbraco.Configuration/Implementations/ContentSettings.cs rename to src/Umbraco.Configuration/Legacy/ContentSettings.cs diff --git a/src/Umbraco.Configuration/CoreDebug.cs b/src/Umbraco.Configuration/Legacy/CoreDebugSettings.cs similarity index 87% rename from src/Umbraco.Configuration/CoreDebug.cs rename to src/Umbraco.Configuration/Legacy/CoreDebugSettings.cs index 0ff3274565..4902d4489f 100644 --- a/src/Umbraco.Configuration/CoreDebug.cs +++ b/src/Umbraco.Configuration/Legacy/CoreDebugSettings.cs @@ -3,9 +3,9 @@ using System.Configuration; namespace Umbraco.Core.Configuration { - public class CoreDebug : ICoreDebug + public class CoreDebugSettings : ICoreDebugSettings { - public CoreDebug() + public CoreDebugSettings() { var appSettings = ConfigurationManager.AppSettings; LogUncompletedScopes = string.Equals("true", appSettings[Constants.AppSettings.Debug.LogUncompletedScopes], StringComparison.OrdinalIgnoreCase); diff --git a/src/Umbraco.Configuration/ExceptionFilterSettings.cs b/src/Umbraco.Configuration/Legacy/ExceptionFilterSettings.cs similarity index 92% rename from src/Umbraco.Configuration/ExceptionFilterSettings.cs rename to src/Umbraco.Configuration/Legacy/ExceptionFilterSettings.cs index 628b8755cc..50e2207485 100644 --- a/src/Umbraco.Configuration/ExceptionFilterSettings.cs +++ b/src/Umbraco.Configuration/Legacy/ExceptionFilterSettings.cs @@ -1,7 +1,7 @@ using System.Configuration; using Umbraco.Core.Configuration; -namespace Umbraco.Configuration +namespace Umbraco.Configuration.Legacy { public class ExceptionFilterSettings : IExceptionFilterSettings { diff --git a/src/Umbraco.Configuration/GlobalSettings.cs b/src/Umbraco.Configuration/Legacy/GlobalSettings.cs similarity index 87% rename from src/Umbraco.Configuration/GlobalSettings.cs rename to src/Umbraco.Configuration/Legacy/GlobalSettings.cs index 923cd422bf..78036f9e42 100644 --- a/src/Umbraco.Configuration/GlobalSettings.cs +++ b/src/Umbraco.Configuration/Legacy/GlobalSettings.cs @@ -3,59 +3,12 @@ using System.Configuration; using System.Linq; using System.Net.Mail; using System.Xml.Linq; +using Umbraco.Composing; using Umbraco.Configuration; using Umbraco.Core.IO; -namespace Umbraco.Core.Configuration +namespace Umbraco.Core.Configuration.Legacy { - public class HostingSettings : IHostingSettings - { - private bool? _debugMode; - - /// - public LocalTempStorage LocalTempStorageLocation - { - get - { - var setting = ConfigurationManager.AppSettings[Constants.AppSettings.LocalTempStorage]; - if (!string.IsNullOrWhiteSpace(setting)) - return Enum.Parse(setting); - - return LocalTempStorage.Default; - } - } - - /// - /// Gets a value indicating whether umbraco is running in [debug mode]. - /// - /// true if [debug mode]; otherwise, false. - public bool DebugMode - { - get - { - if (!_debugMode.HasValue) - { - try - { - if (ConfigurationManager.GetSection("system.web/compilation") is ConfigurationSection compilation) - { - var debugElement = compilation.ElementInformation.Properties["debug"]; - - _debugMode = debugElement != null && (debugElement.Value is bool debug && debug); - - } - } - catch - { - _debugMode = false; - } - } - - return _debugMode.GetValueOrDefault(); - } - } - } - // TODO: Replace checking for if the app settings exist and returning an empty string, instead return the defaults! // TODO: need to massively cleanup these configuration classes @@ -64,7 +17,6 @@ namespace Umbraco.Core.Configuration /// public class GlobalSettings : IGlobalSettings { - private readonly IIOHelper _ioHelper; // TODO these should not be static private static string _reservedPaths; @@ -74,11 +26,6 @@ namespace Umbraco.Core.Configuration internal const string StaticReservedPaths = "~/app_plugins/,~/install/,~/mini-profiler-resources/,"; //must end with a comma! internal const string StaticReservedUrls = "~/config/splashes/noNodes.aspx,~/.well-known,"; //must end with a comma! - public GlobalSettings(IIOHelper ioHelper) - { - _ioHelper = ioHelper; - } - /// /// Used in unit testing to reset all config items that were set with property setters (i.e. did not come from config) /// @@ -203,15 +150,7 @@ namespace Umbraco.Core.Configuration /// Gets the path to umbraco's root directory (/umbraco by default). /// /// The path. - public string Path - { - get - { - return ConfigurationManager.AppSettings.ContainsKey(Constants.AppSettings.Path) - ? _ioHelper.ResolveUrl(ConfigurationManager.AppSettings[Constants.AppSettings.Path]) - : string.Empty; - } - } + public string Path => ConfigurationManager.AppSettings[Constants.AppSettings.Path]; /// /// Gets or sets the configuration status. This will return the version number of the currently installed umbraco instance. @@ -227,7 +166,7 @@ namespace Umbraco.Core.Configuration } set { - SaveSetting(Constants.AppSettings.ConfigurationStatus, value, _ioHelper); + SaveSetting(Constants.AppSettings.ConfigurationStatus, value, Current.IOHelper); //TODO remove } } @@ -254,7 +193,7 @@ namespace Umbraco.Core.Configuration ConfigurationManager.RefreshSection("appSettings"); } - + /// /// Gets the time out in minutes. /// diff --git a/src/Umbraco.Configuration/Legacy/HealthChecksSettings.cs b/src/Umbraco.Configuration/Legacy/HealthChecksSettings.cs new file mode 100644 index 0000000000..23385d1378 --- /dev/null +++ b/src/Umbraco.Configuration/Legacy/HealthChecksSettings.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using System.Configuration; +using Umbraco.Core.Configuration.HealthChecks; + +namespace Umbraco.Core.Configuration.Legacy +{ + public class HealthChecksSettings : IHealthChecksSettings + { + private HealthChecksSection _healthChecksSection; + + private HealthChecksSection HealthChecksSection + { + get + { + if (_healthChecksSection is null) + { + _healthChecksSection = ConfigurationManager.GetSection("umbracoConfiguration/HealthChecks") as HealthChecksSection; + } + return _healthChecksSection; + } + } + + public IEnumerable DisabledChecks => HealthChecksSection.DisabledChecks; + public IHealthCheckNotificationSettings NotificationSettings => HealthChecksSection.NotificationSettings; + } +} diff --git a/src/Umbraco.Configuration/Legacy/HostingSettings.cs b/src/Umbraco.Configuration/Legacy/HostingSettings.cs new file mode 100644 index 0000000000..d0d09ea86f --- /dev/null +++ b/src/Umbraco.Configuration/Legacy/HostingSettings.cs @@ -0,0 +1,52 @@ +using System.Configuration; + +namespace Umbraco.Core.Configuration.Legacy +{ + public class HostingSettings : IHostingSettings + { + private bool? _debugMode; + + /// + public LocalTempStorage LocalTempStorageLocation + { + get + { + var setting = ConfigurationManager.AppSettings[Constants.AppSettings.LocalTempStorage]; + if (!string.IsNullOrWhiteSpace(setting)) + return Enum.Parse(setting); + + return LocalTempStorage.Default; + } + } + + /// + /// Gets a value indicating whether umbraco is running in [debug mode]. + /// + /// true if [debug mode]; otherwise, false. + public bool DebugMode + { + get + { + if (!_debugMode.HasValue) + { + try + { + if (ConfigurationManager.GetSection("system.web/compilation") is ConfigurationSection compilation) + { + var debugElement = compilation.ElementInformation.Properties["debug"]; + + _debugMode = debugElement != null && (debugElement.Value is bool debug && debug); + + } + } + catch + { + _debugMode = false; + } + } + + return _debugMode.GetValueOrDefault(); + } + } + } +} diff --git a/src/Umbraco.Configuration/IndexCreatorSettings.cs b/src/Umbraco.Configuration/Legacy/IndexCreatorSettings.cs similarity index 78% rename from src/Umbraco.Configuration/IndexCreatorSettings.cs rename to src/Umbraco.Configuration/Legacy/IndexCreatorSettings.cs index 00d1a29dba..d023d46246 100644 --- a/src/Umbraco.Configuration/IndexCreatorSettings.cs +++ b/src/Umbraco.Configuration/Legacy/IndexCreatorSettings.cs @@ -1,13 +1,13 @@ using System.Configuration; using Umbraco.Core.Configuration; -namespace Umbraco.Configuration +namespace Umbraco.Configuration.Legacy { public class IndexCreatorSettings : IIndexCreatorSettings { public IndexCreatorSettings() { - LuceneDirectoryFactory = ConfigurationManager.AppSettings["Umbraco.Examine.LuceneDirectoryFactory"]; + LuceneDirectoryFactory = ConfigurationManager.AppSettings["Umbraco.Examine.LuceneDirectoryFactory"]; } public string LuceneDirectoryFactory { get; } diff --git a/src/Umbraco.Configuration/InnerTextConfigurationElement.cs b/src/Umbraco.Configuration/Legacy/InnerTextConfigurationElement.cs similarity index 100% rename from src/Umbraco.Configuration/InnerTextConfigurationElement.cs rename to src/Umbraco.Configuration/Legacy/InnerTextConfigurationElement.cs diff --git a/src/Umbraco.Configuration/Implementations/KeepAliveSettings.cs b/src/Umbraco.Configuration/Legacy/KeepAliveSettings.cs similarity index 100% rename from src/Umbraco.Configuration/Implementations/KeepAliveSettings.cs rename to src/Umbraco.Configuration/Legacy/KeepAliveSettings.cs diff --git a/src/Umbraco.Configuration/Implementations/LoggingSettings.cs b/src/Umbraco.Configuration/Legacy/LoggingSettings.cs similarity index 100% rename from src/Umbraco.Configuration/Implementations/LoggingSettings.cs rename to src/Umbraco.Configuration/Legacy/LoggingSettings.cs diff --git a/src/Umbraco.Configuration/Implementations/MemberPasswordConfigurationSettings.cs b/src/Umbraco.Configuration/Legacy/MemberPasswordConfigurationSettings.cs similarity index 100% rename from src/Umbraco.Configuration/Implementations/MemberPasswordConfigurationSettings.cs rename to src/Umbraco.Configuration/Legacy/MemberPasswordConfigurationSettings.cs diff --git a/src/Umbraco.Configuration/ModelsBuilderConfig.cs b/src/Umbraco.Configuration/Legacy/ModelsBuilderConfig.cs similarity index 80% rename from src/Umbraco.Configuration/ModelsBuilderConfig.cs rename to src/Umbraco.Configuration/Legacy/ModelsBuilderConfig.cs index 151e9908a1..f6395b23b4 100644 --- a/src/Umbraco.Configuration/ModelsBuilderConfig.cs +++ b/src/Umbraco.Configuration/Legacy/ModelsBuilderConfig.cs @@ -6,14 +6,14 @@ using Umbraco.Core.Configuration; using Umbraco.Core; using Umbraco.Core.IO; -namespace Umbraco.Configuration +namespace Umbraco.Configuration.Legacy { /// /// Represents the models builder configuration. /// public class ModelsBuilderConfig : IModelsBuilderConfig { - private readonly IIOHelper _ioHelper; + private const string Prefix = "Umbraco.ModelsBuilder."; private object _modelsModelLock; private bool _modelsModelConfigured; @@ -23,15 +23,13 @@ namespace Umbraco.Configuration private bool _flagOutOfDateModels; - public string DefaultModelsDirectory => _ioHelper.MapPath("~/App_Data/Models"); + public string DefaultModelsDirectory => "~/App_Data/Models"; /// /// Initializes a new instance of the class. /// - public ModelsBuilderConfig(IIOHelper ioHelper) + public ModelsBuilderConfig() { - _ioHelper = ioHelper ?? throw new ArgumentNullException(nameof(ioHelper)); - // giant kill switch, default: false // must be explicitely set to true for anything else to happen Enable = ConfigurationManager.AppSettings[Prefix + "Enable"] == "true"; @@ -59,12 +57,8 @@ namespace Umbraco.Configuration value = ConfigurationManager.AppSettings[Prefix + "ModelsDirectory"]; if (!string.IsNullOrWhiteSpace(value)) { - var root = _ioHelper.MapPath("~/"); - if (root == null) - throw new ConfigurationErrorsException("Could not determine root directory."); - // GetModelsDirectory will ensure that the path is safe - ModelsDirectory = GetModelsDirectory(root, value, AcceptUnsafeModelsDirectory); + ModelsDirectory = value; } // default: 0 @@ -81,7 +75,7 @@ namespace Umbraco.Configuration /// /// Initializes a new instance of the class. /// - public ModelsBuilderConfig(IIOHelper ioHelper, + public ModelsBuilderConfig( bool enable = false, ModelsMode modelsMode = ModelsMode.Nothing, string modelsNamespace = null, @@ -91,7 +85,6 @@ namespace Umbraco.Configuration bool acceptUnsafeModelsDirectory = false, int debugLevel = 0) { - _ioHelper = ioHelper ?? throw new ArgumentNullException(nameof(ioHelper)); Enable = enable; _modelsMode = modelsMode; @@ -103,36 +96,7 @@ namespace Umbraco.Configuration DebugLevel = debugLevel; } - // internal for tests - internal static string GetModelsDirectory(string root, string config, bool acceptUnsafe) - { - // making sure it is safe, ie under the website root, - // unless AcceptUnsafeModelsDirectory and then everything is OK. - if (!Path.IsPathRooted(root)) - throw new ConfigurationErrorsException($"Root is not rooted \"{root}\"."); - - if (config.StartsWith("~/")) - { - var dir = Path.Combine(root, config.TrimStart("~/")); - - // sanitize - GetFullPath will take care of any relative - // segments in path, eg '../../foo.tmp' - it may throw a SecurityException - // if the combined path reaches illegal parts of the filesystem - dir = Path.GetFullPath(dir); - root = Path.GetFullPath(root); - - if (!dir.StartsWith(root) && !acceptUnsafe) - throw new ConfigurationErrorsException($"Invalid models directory \"{config}\"."); - - return dir; - } - - if (acceptUnsafe) - return Path.GetFullPath(config); - - throw new ConfigurationErrorsException($"Invalid models directory \"{config}\"."); - } /// /// Gets a value indicating whether the whole models experience is enabled. diff --git a/src/Umbraco.Configuration/NuCacheSettings.cs b/src/Umbraco.Configuration/Legacy/NuCacheSettings.cs similarity index 89% rename from src/Umbraco.Configuration/NuCacheSettings.cs rename to src/Umbraco.Configuration/Legacy/NuCacheSettings.cs index c3a286d33d..25f52a5c7d 100644 --- a/src/Umbraco.Configuration/NuCacheSettings.cs +++ b/src/Umbraco.Configuration/Legacy/NuCacheSettings.cs @@ -1,7 +1,7 @@ using System.Configuration; using Umbraco.Core.Configuration; -namespace Umbraco.Configuration +namespace Umbraco.Configuration.Legacy { public class NuCacheSettings : INuCacheSettings { diff --git a/src/Umbraco.Configuration/OptionalCommaDelimitedConfigurationElement.cs b/src/Umbraco.Configuration/Legacy/OptionalCommaDelimitedConfigurationElement.cs similarity index 100% rename from src/Umbraco.Configuration/OptionalCommaDelimitedConfigurationElement.cs rename to src/Umbraco.Configuration/Legacy/OptionalCommaDelimitedConfigurationElement.cs diff --git a/src/Umbraco.Configuration/OptionalInnerTextConfigurationElement.cs b/src/Umbraco.Configuration/Legacy/OptionalInnerTextConfigurationElement.cs similarity index 100% rename from src/Umbraco.Configuration/OptionalInnerTextConfigurationElement.cs rename to src/Umbraco.Configuration/Legacy/OptionalInnerTextConfigurationElement.cs diff --git a/src/Umbraco.Configuration/RawXmlConfigurationElement.cs b/src/Umbraco.Configuration/Legacy/RawXmlConfigurationElement.cs similarity index 100% rename from src/Umbraco.Configuration/RawXmlConfigurationElement.cs rename to src/Umbraco.Configuration/Legacy/RawXmlConfigurationElement.cs diff --git a/src/Umbraco.Configuration/Implementations/RequestHandlerSettings.cs b/src/Umbraco.Configuration/Legacy/RequestHandlerSettings.cs similarity index 100% rename from src/Umbraco.Configuration/Implementations/RequestHandlerSettings.cs rename to src/Umbraco.Configuration/Legacy/RequestHandlerSettings.cs diff --git a/src/Umbraco.Configuration/RuntimeSettings.cs b/src/Umbraco.Configuration/Legacy/RuntimeSettings.cs similarity index 96% rename from src/Umbraco.Configuration/RuntimeSettings.cs rename to src/Umbraco.Configuration/Legacy/RuntimeSettings.cs index 6dc8d6f832..200642a819 100644 --- a/src/Umbraco.Configuration/RuntimeSettings.cs +++ b/src/Umbraco.Configuration/Legacy/RuntimeSettings.cs @@ -1,7 +1,7 @@ using System.Configuration; using Umbraco.Core.Configuration; -namespace Umbraco.Configuration +namespace Umbraco.Configuration.Legacy { public class RuntimeSettings : IRuntimeSettings { @@ -24,6 +24,6 @@ namespace Umbraco.Configuration } public int? MaxQueryStringLength { get; } public int? MaxRequestLength { get; } - + } } diff --git a/src/Umbraco.Configuration/Implementations/SecuritySettings.cs b/src/Umbraco.Configuration/Legacy/SecuritySettings.cs similarity index 100% rename from src/Umbraco.Configuration/Implementations/SecuritySettings.cs rename to src/Umbraco.Configuration/Legacy/SecuritySettings.cs diff --git a/src/Umbraco.Configuration/SmtpSettings.cs b/src/Umbraco.Configuration/Legacy/SmtpSettings.cs similarity index 100% rename from src/Umbraco.Configuration/SmtpSettings.cs rename to src/Umbraco.Configuration/Legacy/SmtpSettings.cs diff --git a/src/Umbraco.Configuration/Implementations/TourSettings.cs b/src/Umbraco.Configuration/Legacy/TourSettings.cs similarity index 100% rename from src/Umbraco.Configuration/Implementations/TourSettings.cs rename to src/Umbraco.Configuration/Legacy/TourSettings.cs diff --git a/src/Umbraco.Configuration/TypeFinderSettings.cs b/src/Umbraco.Configuration/Legacy/TypeFinderSettings.cs similarity index 91% rename from src/Umbraco.Configuration/TypeFinderSettings.cs rename to src/Umbraco.Configuration/Legacy/TypeFinderSettings.cs index bb3063d7bf..b1009f754b 100644 --- a/src/Umbraco.Configuration/TypeFinderSettings.cs +++ b/src/Umbraco.Configuration/Legacy/TypeFinderSettings.cs @@ -1,8 +1,8 @@ using System.Configuration; -using Umbraco.Core.Configuration; using Umbraco.Core; +using Umbraco.Core.Configuration; -namespace Umbraco.Configuration +namespace Umbraco.Configuration.Legacy { public class TypeFinderSettings : ITypeFinderSettings { diff --git a/src/Umbraco.Configuration/UmbracoConfigurationSection.cs b/src/Umbraco.Configuration/Legacy/UmbracoConfigurationSection.cs similarity index 100% rename from src/Umbraco.Configuration/UmbracoConfigurationSection.cs rename to src/Umbraco.Configuration/Legacy/UmbracoConfigurationSection.cs diff --git a/src/Umbraco.Configuration/Implementations/UserPasswordConfigurationSettings.cs b/src/Umbraco.Configuration/Legacy/UserPasswordConfigurationSettings.cs similarity index 100% rename from src/Umbraco.Configuration/Implementations/UserPasswordConfigurationSettings.cs rename to src/Umbraco.Configuration/Legacy/UserPasswordConfigurationSettings.cs diff --git a/src/Umbraco.Configuration/Implementations/WebRoutingSettings.cs b/src/Umbraco.Configuration/Legacy/WebRoutingSettings.cs similarity index 100% rename from src/Umbraco.Configuration/Implementations/WebRoutingSettings.cs rename to src/Umbraco.Configuration/Legacy/WebRoutingSettings.cs diff --git a/src/Umbraco.Configuration/MachineKeyConfig.cs b/src/Umbraco.Configuration/MachineKeyConfig.cs deleted file mode 100644 index 4e3401e015..0000000000 --- a/src/Umbraco.Configuration/MachineKeyConfig.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Configuration; -using Umbraco.Core.Configuration; - -namespace Umbraco.Configuration -{ - public class MachineKeyConfig : IMachineKeyConfig - { - //TODO all the machineKey stuff should be replaced: https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/compatibility/replacing-machinekey?view=aspnetcore-3.1 - - public bool HasMachineKey - { - get - { - var machineKeySection = - ConfigurationManager.GetSection("system.web/machineKey") as ConfigurationSection; - return !(machineKeySection?.ElementInformation?.Source is null); - } - } - } -} diff --git a/src/Umbraco.Configuration/Models/ActiveDirectorySettings.cs b/src/Umbraco.Configuration/Models/ActiveDirectorySettings.cs new file mode 100644 index 0000000000..015fb17a8e --- /dev/null +++ b/src/Umbraco.Configuration/Models/ActiveDirectorySettings.cs @@ -0,0 +1,19 @@ +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration; + +namespace Umbraco.Configuration.Models +{ + internal class ActiveDirectorySettings : IActiveDirectorySettings + { + private const string Prefix = Constants.Configuration.ConfigPrefix + "ActiveDirectory:"; + private readonly IConfiguration _configuration; + + public ActiveDirectorySettings(IConfiguration configuration) + { + _configuration = configuration; + } + + public string ActiveDirectoryDomain => _configuration.GetValue(Prefix+"Domain"); + } +} diff --git a/src/Umbraco.Configuration/Models/ConnectionStrings.cs b/src/Umbraco.Configuration/Models/ConnectionStrings.cs new file mode 100644 index 0000000000..9fc546a88f --- /dev/null +++ b/src/Umbraco.Configuration/Models/ConnectionStrings.cs @@ -0,0 +1,24 @@ +using System; +using System.Linq; +using System.Text.Json.Serialization; +using Microsoft.Extensions.Configuration; +using Umbraco.Core.Configuration; + +namespace Umbraco.Configuration.Models +{ + internal class ConnectionStrings : IConnectionStrings + { + private readonly IConfiguration _configuration; + + public ConnectionStrings(IConfiguration configuration) + { + _configuration = configuration; + } + + public ConfigConnectionString this[string key] + { + get => new ConfigConnectionString(_configuration.GetConnectionString(key), "System.Data.SqlClient", key); + set => throw new NotImplementedException(); + } + } +} diff --git a/src/Umbraco.Configuration/Models/ContentSettings.cs b/src/Umbraco.Configuration/Models/ContentSettings.cs new file mode 100644 index 0000000000..5bc31814b7 --- /dev/null +++ b/src/Umbraco.Configuration/Models/ContentSettings.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.Macros; + +namespace Umbraco.Configuration.Models +{ + internal class ContentSettings : IContentSettings + { + private const string Prefix = Constants.Configuration.ConfigPrefix + "Content:"; + private const string NotificationsPrefix = Prefix + "Notifications:"; + private const string ImagingPrefix = Prefix + "Imaging:"; + private const string DefaultPreviewBadge = + @"
Preview modeClick to end
"; + + private static readonly ImagingAutoFillUploadField[] DefaultImagingAutoFillUploadField = + { + new ImagingAutoFillUploadField + { + Alias = "umbracoFile" + } + }; + + private readonly IConfiguration _configuration; + + public ContentSettings(IConfiguration configuration) + { + _configuration = configuration; + } + + public string NotificationEmailAddress => + _configuration.GetValue(NotificationsPrefix+"Email"); + + public bool DisableHtmlEmail => + _configuration.GetValue(NotificationsPrefix+"DisableHtmlEmail", false); + + public IEnumerable ImageFileTypes => _configuration.GetValue( + ImagingPrefix+"ImageFileTypes", new[] { "jpeg", "jpg", "gif", "bmp", "png", "tiff", "tif" }); + + public IEnumerable ImageAutoFillProperties => + _configuration.GetValue(ImagingPrefix+"AutoFillImageProperties", + DefaultImagingAutoFillUploadField); + + + public bool ResolveUrlsFromTextString => + _configuration.GetValue(Prefix+"ResolveUrlsFromTextString", false); + + public IEnumerable Error404Collection => _configuration + .GetSection(Prefix+"Errors:Error404") + .GetChildren() + .Select(x => new ContentErrorPage(x)); + + public string PreviewBadge => _configuration.GetValue(Prefix+"PreviewBadge", DefaultPreviewBadge); + + public MacroErrorBehaviour MacroErrorBehaviour => + _configuration.GetValue(Prefix+"MacroErrors", MacroErrorBehaviour.Inline); + + public IEnumerable DisallowedUploadFiles => _configuration.GetValue( + Prefix+"DisallowedUploadFiles", + new[] { "ashx", "aspx", "ascx", "config", "cshtml", "vbhtml", "asmx", "air", "axd" }); + + public IEnumerable AllowedUploadFiles => + _configuration.GetValue(Prefix+"AllowedUploadFiles", Array.Empty()); + + public bool ShowDeprecatedPropertyEditors => + _configuration.GetValue(Prefix+"ShowDeprecatedPropertyEditors", false); + + public string LoginBackgroundImage => + _configuration.GetValue(Prefix+"LoginBackgroundImage", string.Empty); + + private class ContentErrorPage : IContentErrorPage + { + public ContentErrorPage(IConfigurationSection configurationSection) + { + Culture = configurationSection.Key; + + var value = configurationSection.Value; + + if (int.TryParse(value, out var contentId)) + { + HasContentId = true; + ContentId = contentId; + } + else if (Guid.TryParse(value, out var contentKey)) + { + HasContentKey = true; + ContentKey = contentKey; + } + else + { + ContentXPath = value; + } + } + + public int ContentId { get; } + public Guid ContentKey { get; } + public string ContentXPath { get; } + public bool HasContentId { get; } + public bool HasContentKey { get; } + public string Culture { get; set; } + } + + private class ImagingAutoFillUploadField : IImagingAutoFillUploadField + { + public string Alias { get; set; } + public string WidthFieldAlias { get; set; } + public string HeightFieldAlias { get; set; } + public string LengthFieldAlias { get; set; } + public string ExtensionFieldAlias { get; set; } + } + } +} diff --git a/src/Umbraco.Configuration/Models/CoreDebugSettings.cs b/src/Umbraco.Configuration/Models/CoreDebugSettings.cs new file mode 100644 index 0000000000..6d6c0eaf0d --- /dev/null +++ b/src/Umbraco.Configuration/Models/CoreDebugSettings.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration; + +namespace Umbraco.Configuration.Models +{ + internal class CoreDebugSettings : ICoreDebugSettings + { + private const string Prefix = Constants.Configuration.ConfigPrefix + "Core:Debug:"; + private readonly IConfiguration _configuration; + + public CoreDebugSettings(IConfiguration configuration) + { + _configuration = configuration; + } + + public bool LogUncompletedScopes => + _configuration.GetValue(Prefix+"LogUncompletedScopes", false); + + public bool DumpOnTimeoutThreadAbort => + _configuration.GetValue(Prefix+"DumpOnTimeoutThreadAbort", false); + } +} diff --git a/src/Umbraco.Configuration/Models/ExceptionFilterSettings.cs b/src/Umbraco.Configuration/Models/ExceptionFilterSettings.cs new file mode 100644 index 0000000000..581daf9f40 --- /dev/null +++ b/src/Umbraco.Configuration/Models/ExceptionFilterSettings.cs @@ -0,0 +1,19 @@ +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration; + +namespace Umbraco.Configuration.Models +{ + internal class ExceptionFilterSettings : IExceptionFilterSettings + { + private const string Prefix = Constants.Configuration.ConfigPrefix + "ExceptionFilter:"; + private readonly IConfiguration _configuration; + + public ExceptionFilterSettings(IConfiguration configuration) + { + _configuration = configuration; + } + + public bool Disabled => _configuration.GetValue(Prefix+"Disabled", false); + } +} diff --git a/src/Umbraco.Configuration/Models/GlobalSettings.cs b/src/Umbraco.Configuration/Models/GlobalSettings.cs new file mode 100644 index 0000000000..4dc764a974 --- /dev/null +++ b/src/Umbraco.Configuration/Models/GlobalSettings.cs @@ -0,0 +1,97 @@ +using System; +using System.Linq; +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration; + +namespace Umbraco.Configuration.Models +{ + /// + /// The GlobalSettings Class contains general settings information for the entire Umbraco instance based on information + /// from web.config appsettings + /// + internal class GlobalSettings : IGlobalSettings + { + private const string Prefix = Constants.Configuration.ConfigPrefix + "Global:"; + + internal const string + StaticReservedPaths = "~/app_plugins/,~/install/,~/mini-profiler-resources/,"; //must end with a comma! + + internal const string + StaticReservedUrls = "~/config/splashes/noNodes.aspx,~/.well-known,"; //must end with a comma! + + private readonly IConfiguration _configuration; + + public GlobalSettings(IConfiguration configuration) + { + _configuration = configuration; + } + + public string ReservedUrls => _configuration.GetValue(Prefix + "ReservedUrls", StaticReservedUrls); + public string ReservedPaths => _configuration.GetValue(Prefix + "ReservedPaths", StaticReservedPaths); + + public string Path => _configuration.GetValue(Prefix + "Path"); + + // TODO: https://github.com/umbraco/Umbraco-CMS/issues/4238 - stop having version in web.config appSettings + public string ConfigurationStatus + { + get => _configuration.GetValue(Prefix + "ConfigurationStatus"); + set => throw new NotImplementedException("We should remove this and only use the value from database"); + } + + public int TimeOutInMinutes => _configuration.GetValue(Prefix + "TimeOutInMinutes", 20); + public string DefaultUILanguage => _configuration.GetValue(Prefix + "TimeOutInMinutes", "en-US"); + + public bool HideTopLevelNodeFromPath => + _configuration.GetValue(Prefix + "HideTopLevelNodeFromPath", false); + + public bool UseHttps => _configuration.GetValue(Prefix + "UseHttps", false); + public int VersionCheckPeriod => _configuration.GetValue(Prefix + "VersionCheckPeriod", 7); + public string UmbracoPath => _configuration.GetValue(Prefix + "UmbracoPath", "~/umbraco"); + public string UmbracoCssPath => _configuration.GetValue(Prefix + "UmbracoCssPath", "~/css"); + + public string UmbracoScriptsPath => + _configuration.GetValue(Prefix + "UmbracoScriptsPath", "~/scripts"); + + public string UmbracoMediaPath => _configuration.GetValue(Prefix + "UmbracoMediaPath", "~/media"); + + public bool InstallMissingDatabase => + _configuration.GetValue(Prefix + "InstallMissingDatabase", false); + + public bool InstallEmptyDatabase => _configuration.GetValue(Prefix + "InstallEmptyDatabase", false); + + public bool DisableElectionForSingleServer => + _configuration.GetValue(Prefix + "DisableElectionForSingleServer", false); + + public string RegisterType => _configuration.GetValue(Prefix + "RegisterType", string.Empty); + + public string DatabaseFactoryServerVersion => + _configuration.GetValue(Prefix + "DatabaseFactoryServerVersion", string.Empty); + + public string MainDomLock => _configuration.GetValue(Prefix + "MainDomLock", string.Empty); + + public string NoNodesViewPath => + _configuration.GetValue(Prefix + "NoNodesViewPath", "~/config/splashes/NoNodes.cshtml"); + + public bool IsSmtpServerConfigured => + _configuration.GetSection(Constants.Configuration.ConfigPrefix + "Smtp")?.GetChildren().Any() ?? false; + + public ISmtpSettings SmtpSettings => + new SmtpSettingsImpl(_configuration.GetSection(Constants.Configuration.ConfigPrefix + "Smtp")); + + private class SmtpSettingsImpl : ISmtpSettings + { + private readonly IConfigurationSection _configurationSection; + + public SmtpSettingsImpl(IConfigurationSection configurationSection) + { + _configurationSection = configurationSection; + } + + public string From => _configurationSection.GetValue("From"); + public string Host => _configurationSection.GetValue("Host"); + public int Port => _configurationSection.GetValue("Port"); + public string PickupDirectoryLocation => _configurationSection.GetValue("PickupDirectoryLocation"); + } + } +} diff --git a/src/Umbraco.Configuration/Models/HealthChecksSettingsSettings.cs b/src/Umbraco.Configuration/Models/HealthChecksSettingsSettings.cs new file mode 100644 index 0000000000..1d73051ec8 --- /dev/null +++ b/src/Umbraco.Configuration/Models/HealthChecksSettingsSettings.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration.HealthChecks; + +namespace Umbraco.Configuration.Models +{ + internal class HealthChecksSettings : IHealthChecksSettings + { + private const string Prefix = Constants.Configuration.ConfigPrefix + "HealthChecks:"; + private readonly IConfiguration _configuration; + + public HealthChecksSettings(IConfiguration configuration) + { + _configuration = configuration; + } + + public IEnumerable DisabledChecks => _configuration + .GetSection(Prefix+"DisabledChecks") + .GetChildren() + .Select( + x => new DisabledHealthCheck + { + Id = x.GetValue("Id"), + DisabledOn = x.GetValue("DisabledOn"), + DisabledBy = x.GetValue("DisabledBy") + }); + + public IHealthCheckNotificationSettings NotificationSettings => + new HealthCheckNotificationSettings( + _configuration.GetSection(Prefix+"NotificationSettings")); + + private class DisabledHealthCheck : IDisabledHealthCheck + { + public Guid Id { get; set; } + public DateTime DisabledOn { get; set; } + public int DisabledBy { get; set; } + } + + private class HealthCheckNotificationSettings : IHealthCheckNotificationSettings + { + private readonly IConfigurationSection _configurationSection; + + public HealthCheckNotificationSettings(IConfigurationSection configurationSection) + { + _configurationSection = configurationSection; + } + + public bool Enabled => _configurationSection.GetValue("Enabled", false); + public string FirstRunTime => _configurationSection.GetValue("FirstRunTime"); + public int PeriodInHours => _configurationSection.GetValue("PeriodInHours", 24); + + public IReadOnlyDictionary NotificationMethods => _configurationSection + .GetSection("NotificationMethods") + .GetChildren() + .ToDictionary(x => x.Key, x => (INotificationMethod) new NotificationMethod(x.Key, x)); + + public IEnumerable DisabledChecks => _configurationSection + .GetSection("DisabledChecks").GetChildren().Select( + x => new DisabledHealthCheck + { + Id = x.GetValue("Id"), + DisabledOn = x.GetValue("DisabledOn"), + DisabledBy = x.GetValue("DisabledBy") + }); + } + + private class NotificationMethod : INotificationMethod + { + private readonly IConfigurationSection _configurationSection; + + public NotificationMethod(string alias, IConfigurationSection configurationSection) + { + Alias = alias; + _configurationSection = configurationSection; + } + + public string Alias { get; } + public bool Enabled => _configurationSection.GetValue("Enabled", false); + + public HealthCheckNotificationVerbosity Verbosity => + _configurationSection.GetValue("Verbosity", HealthCheckNotificationVerbosity.Summary); + + public bool FailureOnly => _configurationSection.GetValue("FailureOnly", true); + + public IReadOnlyDictionary Settings => _configurationSection + .GetSection("Settings").GetChildren().ToDictionary(x => x.Key, + x => (INotificationMethodSettings) new NotificationMethodSettings(x.Key, x.Value)); + } + + private class NotificationMethodSettings : INotificationMethodSettings + { + public NotificationMethodSettings(string key, string value) + { + Key = key; + Value = value; + } + + public string Key { get; } + public string Value { get; } + } + } +} diff --git a/src/Umbraco.Configuration/Models/HostingSettings.cs b/src/Umbraco.Configuration/Models/HostingSettings.cs new file mode 100644 index 0000000000..4a156cee6a --- /dev/null +++ b/src/Umbraco.Configuration/Models/HostingSettings.cs @@ -0,0 +1,27 @@ +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration; + +namespace Umbraco.Configuration.Models +{ + internal class HostingSettings : IHostingSettings + { + private const string Prefix = Constants.Configuration.ConfigPrefix + "Hosting:"; + private readonly IConfiguration _configuration; + + public HostingSettings(IConfiguration configuration) + { + _configuration = configuration; + } + + /// + public LocalTempStorage LocalTempStorageLocation => + _configuration.GetValue(Prefix+"LocalTempStorage", LocalTempStorage.Default); + + /// + /// Gets a value indicating whether umbraco is running in [debug mode]. + /// + /// true if [debug mode]; otherwise, false. + public bool DebugMode => _configuration.GetValue(Prefix+":Debug", false); + } +} diff --git a/src/Umbraco.Configuration/Models/ImagingSettings.cs b/src/Umbraco.Configuration/Models/ImagingSettings.cs new file mode 100644 index 0000000000..4a9501b2ba --- /dev/null +++ b/src/Umbraco.Configuration/Models/ImagingSettings.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration; + +namespace Umbraco.Configuration.Models +{ + internal class ImagingSettings : IImagingSettings + { + private const string Prefix = Constants.Configuration.ConfigPrefix + "Imaging:"; + private const string CachePrefix = Prefix + "Cache:"; + private const string ResizePrefix = Prefix + "Resize:"; + private readonly IConfiguration _configuration; + + public ImagingSettings(IConfiguration configuration) + { + _configuration = configuration; + } + + public int MaxBrowserCacheDays => _configuration.GetValue(CachePrefix + "MaxBrowserCacheDays", 7); + public int MaxCacheDays => _configuration.GetValue(CachePrefix + "MaxCacheDays", 365); + public uint CachedNameLength => _configuration.GetValue(CachePrefix + "CachedNameLength", (uint) 8); + public string CacheFolder => _configuration.GetValue(CachePrefix + "Folder", "../App_Data/Cache"); + public int MaxResizeWidth => _configuration.GetValue(ResizePrefix + "MaxWidth", 5000); + public int MaxResizeHeight => _configuration.GetValue(ResizePrefix + "MaxHeight", 5000); + } +} diff --git a/src/Umbraco.Configuration/Models/IndexCreatorSettings.cs b/src/Umbraco.Configuration/Models/IndexCreatorSettings.cs new file mode 100644 index 0000000000..b4bb000552 --- /dev/null +++ b/src/Umbraco.Configuration/Models/IndexCreatorSettings.cs @@ -0,0 +1,20 @@ +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration; + +namespace Umbraco.Configuration.Models +{ + internal class IndexCreatorSettings : IIndexCreatorSettings + { + private const string Prefix = Constants.Configuration.ConfigPrefix + "Examine:"; + private readonly IConfiguration _configuration; + + public IndexCreatorSettings(IConfiguration configuration) + { + _configuration = configuration; + } + + public string LuceneDirectoryFactory => + _configuration.GetValue(Prefix + "LuceneDirectoryFactory"); + } +} diff --git a/src/Umbraco.Configuration/Models/KeepAliveSettings.cs b/src/Umbraco.Configuration/Models/KeepAliveSettings.cs new file mode 100644 index 0000000000..04194e1a3c --- /dev/null +++ b/src/Umbraco.Configuration/Models/KeepAliveSettings.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration.UmbracoSettings; + +namespace Umbraco.Configuration.Models +{ + internal class KeepAliveSettings : IKeepAliveSettings + { + private const string Prefix = Constants.Configuration.ConfigPrefix + "KeepAlive:"; + private readonly IConfiguration _configuration; + + public KeepAliveSettings(IConfiguration configuration) + { + _configuration = configuration; + } + + public bool DisableKeepAliveTask => + _configuration.GetValue(Prefix + "DisableKeepAliveTask", false); + + public string KeepAlivePingUrl => _configuration.GetValue(Prefix + "KeepAlivePingUrl", + "{umbracoApplicationUrl}/api/keepalive/ping"); + } +} diff --git a/src/Umbraco.Configuration/Models/LoggingSettings.cs b/src/Umbraco.Configuration/Models/LoggingSettings.cs new file mode 100644 index 0000000000..b05fe03875 --- /dev/null +++ b/src/Umbraco.Configuration/Models/LoggingSettings.cs @@ -0,0 +1,19 @@ +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration.UmbracoSettings; + +namespace Umbraco.Configuration.Models +{ + internal class LoggingSettings : ILoggingSettings + { + private const string Prefix = Constants.Configuration.ConfigPrefix + "Logging:"; + private readonly IConfiguration _configuration; + + public LoggingSettings(IConfiguration configuration) + { + _configuration = configuration; + } + + public int MaxLogAge => _configuration.GetValue(Prefix + "MaxLogAge", -1); + } +} diff --git a/src/Umbraco.Configuration/Models/MemberPasswordConfigurationSettings.cs b/src/Umbraco.Configuration/Models/MemberPasswordConfigurationSettings.cs new file mode 100644 index 0000000000..c7b147349e --- /dev/null +++ b/src/Umbraco.Configuration/Models/MemberPasswordConfigurationSettings.cs @@ -0,0 +1,38 @@ +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration; + +namespace Umbraco.Configuration.Models +{ + internal class MemberPasswordConfigurationSettings : IMemberPasswordConfiguration + { + private const string Prefix = Constants.Configuration.ConfigSecurityPrefix + "MemberPassword:"; + private readonly IConfiguration _configuration; + + public MemberPasswordConfigurationSettings(IConfiguration configuration) + { + _configuration = configuration; + } + + public int RequiredLength => + _configuration.GetValue(Prefix + "RequiredLength", 10); + + public bool RequireNonLetterOrDigit => + _configuration.GetValue(Prefix + "RequireNonLetterOrDigit", false); + + public bool RequireDigit => + _configuration.GetValue(Prefix + "RequireDigit", false); + + public bool RequireLowercase => + _configuration.GetValue(Prefix + "RequireLowercase", false); + + public bool RequireUppercase => + _configuration.GetValue(Prefix + "RequireUppercase", false); + + public string HashAlgorithmType => + _configuration.GetValue(Prefix + "HashAlgorithmType", "HMACSHA256"); + + public int MaxFailedAccessAttemptsBeforeLockout => + _configuration.GetValue(Prefix + "MaxFailedAccessAttemptsBeforeLockout", 5); + } +} diff --git a/src/Umbraco.Configuration/Models/ModelsBuilderConfig.cs b/src/Umbraco.Configuration/Models/ModelsBuilderConfig.cs new file mode 100644 index 0000000000..d111dbba70 --- /dev/null +++ b/src/Umbraco.Configuration/Models/ModelsBuilderConfig.cs @@ -0,0 +1,86 @@ +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration; + +namespace Umbraco.Configuration.Models +{ + /// + /// Represents the models builder configuration. + /// + internal class ModelsBuilderConfig : IModelsBuilderConfig + { + private const string Prefix = Constants.Configuration.ConfigModelsBuilderPrefix; + private readonly IConfiguration _configuration; + + /// + /// Initializes a new instance of the class. + /// + public ModelsBuilderConfig(IConfiguration configuration) + { + _configuration = configuration; + } + + public string DefaultModelsDirectory => "~/App_Data/Models"; + + /// + /// Gets a value indicating whether the whole models experience is enabled. + /// + /// + /// If this is false then absolutely nothing happens. + /// Default value is false which means that unless we have this setting, nothing happens. + /// + public bool Enable => _configuration.GetValue(Prefix+"Enable", false); + + /// + /// Gets the models mode. + /// + public ModelsMode ModelsMode => + _configuration.GetValue(Prefix+"ModelsMode", ModelsMode.Nothing); + + /// + /// Gets the models namespace. + /// + /// That value could be overriden by other (attribute in user's code...). Return default if no value was supplied. + public string ModelsNamespace => _configuration.GetValue(Prefix+"ModelsNamespace"); + + /// + /// Gets a value indicating whether we should enable the models factory. + /// + /// Default value is true because no factory is enabled by default in Umbraco. + public bool EnableFactory => _configuration.GetValue(Prefix+"EnableFactory", true); + + /// + /// Gets a value indicating whether we should flag out-of-date models. + /// + /// + /// Models become out-of-date when data types or content types are updated. When this + /// setting is activated the ~/App_Data/Models/ood.txt file is then created. When models are + /// generated through the dashboard, the files is cleared. Default value is false. + /// + public bool FlagOutOfDateModels => + _configuration.GetValue(Prefix+"FlagOutOfDateModels", false) && !ModelsMode.IsLive(); + + /// + /// Gets the models directory. + /// + /// Default is ~/App_Data/Models but that can be changed. + public string ModelsDirectory => + _configuration.GetValue(Prefix+"ModelsDirectory", "~/App_Data/Models"); + + /// + /// Gets a value indicating whether to accept an unsafe value for ModelsDirectory. + /// + /// + /// An unsafe value is an absolute path, or a relative path pointing outside + /// of the website root. + /// + public bool AcceptUnsafeModelsDirectory => + _configuration.GetValue(Prefix+"AcceptUnsafeModelsDirectory", false); + + /// + /// Gets a value indicating the debug log level. + /// + /// 0 means minimal (safe on live site), anything else means more and more details (maybe not safe). + public int DebugLevel => _configuration.GetValue(Prefix+"DebugLevel", 0); + } +} diff --git a/src/Umbraco.Configuration/Models/NuCacheSettings.cs b/src/Umbraco.Configuration/Models/NuCacheSettings.cs new file mode 100644 index 0000000000..51b8b1fe08 --- /dev/null +++ b/src/Umbraco.Configuration/Models/NuCacheSettings.cs @@ -0,0 +1,19 @@ +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration; + +namespace Umbraco.Configuration.Models +{ + internal class NuCacheSettings : INuCacheSettings + { + private const string Prefix = Constants.Configuration.ConfigPrefix + "NuCache:"; + private readonly IConfiguration _configuration; + + public NuCacheSettings(IConfiguration configuration) + { + _configuration = configuration; + } + + public string BTreeBlockSize => _configuration.GetValue(Prefix+"BTreeBlockSize"); + } +} diff --git a/src/Umbraco.Configuration/Models/RequestHandlerSettings.cs b/src/Umbraco.Configuration/Models/RequestHandlerSettings.cs new file mode 100644 index 0000000000..ce5cd65c20 --- /dev/null +++ b/src/Umbraco.Configuration/Models/RequestHandlerSettings.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration.UmbracoSettings; + +namespace Umbraco.Configuration.Models +{ + internal class RequestHandlerSettings : IRequestHandlerSettings + { + private const string Prefix = Constants.Configuration.ConfigPrefix + "RequestHandler:"; + private static readonly CharItem[] DefaultCharCollection = + { + new CharItem { Char = " ", Replacement = "-" }, + new CharItem { Char = "\"", Replacement = "" }, + new CharItem { Char = "'", Replacement = "" }, + new CharItem { Char = "%", Replacement = "" }, + new CharItem { Char = ".", Replacement = "" }, + new CharItem { Char = ";", Replacement = "" }, + new CharItem { Char = "/", Replacement = "" }, + new CharItem { Char = "\\", Replacement = "" }, + new CharItem { Char = ":", Replacement = "" }, + new CharItem { Char = "#", Replacement = "" }, + new CharItem { Char = "+", Replacement = "plus" }, + new CharItem { Char = "*", Replacement = "star" }, + new CharItem { Char = "&", Replacement = "" }, + new CharItem { Char = "?", Replacement = "" }, + new CharItem { Char = "æ", Replacement = "ae" }, + new CharItem { Char = "ä", Replacement = "ae" }, + new CharItem { Char = "ø", Replacement = "oe" }, + new CharItem { Char = "ö", Replacement = "oe" }, + new CharItem { Char = "å", Replacement = "aa" }, + new CharItem { Char = "ü", Replacement = "ue" }, + new CharItem { Char = "ß", Replacement = "ss" }, + new CharItem { Char = "|", Replacement = "-" }, + new CharItem { Char = "<", Replacement = "" }, + new CharItem { Char = ">", Replacement = "" } + }; + + private readonly IConfiguration _configuration; + + public RequestHandlerSettings(IConfiguration configuration) + { + _configuration = configuration; + } + + public bool AddTrailingSlash => + _configuration.GetValue(Prefix+"AddTrailingSlash", true); + + public bool ConvertUrlsToAscii => _configuration + .GetValue(Prefix+"ConvertUrlsToAscii").InvariantEquals("true"); + + public bool TryConvertUrlsToAscii => _configuration + .GetValue(Prefix+"ConvertUrlsToAscii").InvariantEquals("try"); + + + //We need to special handle ":", as this character is special in keys + public IEnumerable CharCollection + { + get + { + var collection = _configuration.GetSection(Prefix + "CharCollection").GetChildren() + .Select(x => new CharItem() + { + Char = x.GetValue("Char"), + Replacement = x.GetValue("Replacement"), + }).ToArray(); + + if (collection.Any() || _configuration.GetSection("Prefix").GetChildren().Any(x => + x.Key.Equals("CharCollection", StringComparison.OrdinalIgnoreCase))) + { + return collection; + } + + return DefaultCharCollection; + } + } + + + public class CharItem : IChar + { + public string Char { get; set; } + public string Replacement { get; set; } + } + } +} diff --git a/src/Umbraco.Configuration/Models/RuntimeSettings.cs b/src/Umbraco.Configuration/Models/RuntimeSettings.cs new file mode 100644 index 0000000000..ef129030b6 --- /dev/null +++ b/src/Umbraco.Configuration/Models/RuntimeSettings.cs @@ -0,0 +1,19 @@ +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration; + +namespace Umbraco.Configuration.Models +{ + internal class RuntimeSettings : IRuntimeSettings + { + private const string Prefix = Constants.Configuration.ConfigPrefix + "Runtime:"; + private readonly IConfiguration _configuration; + public RuntimeSettings(IConfiguration configuration) + { + _configuration = configuration; + } + + public int? MaxQueryStringLength => _configuration.GetValue(Prefix+"MaxRequestLength"); + public int? MaxRequestLength => _configuration.GetValue(Prefix+"MaxRequestLength"); + } +} diff --git a/src/Umbraco.Configuration/Models/SecuritySettings.cs b/src/Umbraco.Configuration/Models/SecuritySettings.cs new file mode 100644 index 0000000000..9244eace96 --- /dev/null +++ b/src/Umbraco.Configuration/Models/SecuritySettings.cs @@ -0,0 +1,33 @@ +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration.UmbracoSettings; + +namespace Umbraco.Configuration.Models +{ + internal class SecuritySettings : ISecuritySettings + { + private const string Prefix = Constants.Configuration.ConfigSecurityPrefix; + private readonly IConfiguration _configuration; + + public SecuritySettings(IConfiguration configuration) + { + _configuration = configuration; + } + + public bool KeepUserLoggedIn => _configuration.GetValue(Prefix + "KeepUserLoggedIn", true); + + public bool HideDisabledUsersInBackoffice => + _configuration.GetValue(Prefix + "HideDisabledUsersInBackoffice", false); + + public bool AllowPasswordReset => + _configuration.GetValue(Prefix + "AllowPasswordResetAllowPasswordReset", true); + + public string AuthCookieName => + _configuration.GetValue(Prefix + "AuthCookieName", "UMB_UCONTEXT"); + + public string AuthCookieDomain => + _configuration.GetValue(Prefix + "AuthCookieDomain"); + + public bool UsernameIsEmail => _configuration.GetValue(Prefix + "UsernameIsEmail", true); + } +} diff --git a/src/Umbraco.Configuration/Models/TourSettings.cs b/src/Umbraco.Configuration/Models/TourSettings.cs new file mode 100644 index 0000000000..9fe1814ff5 --- /dev/null +++ b/src/Umbraco.Configuration/Models/TourSettings.cs @@ -0,0 +1,21 @@ +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration.UmbracoSettings; + +namespace Umbraco.Configuration.Models +{ + internal class TourSettings : ITourSettings + { + private const string Prefix = Constants.Configuration.ConfigPrefix + "Tours:"; + private readonly IConfiguration _configuration; + + public TourSettings(IConfiguration configuration) + { + _configuration = configuration; + } + + public string Type { get; set; } + + public bool EnableTours => _configuration.GetValue(Prefix+"EnableTours", true); + } +} diff --git a/src/Umbraco.Configuration/Models/TypeFinderSettings.cs b/src/Umbraco.Configuration/Models/TypeFinderSettings.cs new file mode 100644 index 0000000000..8a1f7ac9e0 --- /dev/null +++ b/src/Umbraco.Configuration/Models/TypeFinderSettings.cs @@ -0,0 +1,20 @@ +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration; + +namespace Umbraco.Configuration.Models +{ + internal class TypeFinderSettings : ITypeFinderSettings + { + private const string Prefix = Constants.Configuration.ConfigPrefix + "TypeFinder:"; + private readonly IConfiguration _configuration; + + public TypeFinderSettings(IConfiguration configuration) + { + _configuration = configuration; + } + + public string AssembliesAcceptingLoadExceptions => + _configuration.GetValue(Prefix+"AssembliesAcceptingLoadExceptions"); + } +} diff --git a/src/Umbraco.Configuration/Models/UserPasswordConfigurationSettings.cs b/src/Umbraco.Configuration/Models/UserPasswordConfigurationSettings.cs new file mode 100644 index 0000000000..5e68b16203 --- /dev/null +++ b/src/Umbraco.Configuration/Models/UserPasswordConfigurationSettings.cs @@ -0,0 +1,36 @@ +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration; + +namespace Umbraco.Configuration.Models +{ + internal class UserPasswordConfigurationSettings : IUserPasswordConfiguration + { + private const string Prefix = Constants.Configuration.ConfigSecurityPrefix + "UserPassword:"; + private readonly IConfiguration _configuration; + + public UserPasswordConfigurationSettings(IConfiguration configuration) + { + _configuration = configuration; + } + + public int RequiredLength => _configuration.GetValue(Prefix + "RequiredLength", 10); + + public bool RequireNonLetterOrDigit => + _configuration.GetValue(Prefix + "RequireNonLetterOrDigit", false); + + public bool RequireDigit => _configuration.GetValue(Prefix + "RequireDigit", false); + + public bool RequireLowercase => + _configuration.GetValue(Prefix + "RequireLowercase", false); + + public bool RequireUppercase => + _configuration.GetValue(Prefix + "RequireUppercase", false); + + public string HashAlgorithmType => + _configuration.GetValue(Prefix + "HashAlgorithmType", "HMACSHA256"); + + public int MaxFailedAccessAttemptsBeforeLockout => + _configuration.GetValue(Prefix + "MaxFailedAccessAttemptsBeforeLockout", 5); + } +} diff --git a/src/Umbraco.Configuration/Models/WebRoutingSettings.cs b/src/Umbraco.Configuration/Models/WebRoutingSettings.cs new file mode 100644 index 0000000000..9ac856ca9f --- /dev/null +++ b/src/Umbraco.Configuration/Models/WebRoutingSettings.cs @@ -0,0 +1,42 @@ +using Microsoft.Extensions.Configuration; +using Umbraco.Core; +using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.Models.PublishedContent; + +namespace Umbraco.Configuration.Models +{ + internal class WebRoutingSettings : IWebRoutingSettings + { + private const string Prefix = Constants.Configuration.ConfigPrefix + "WebRouting:"; + private readonly IConfiguration _configuration; + + public WebRoutingSettings(IConfiguration configuration) + { + _configuration = configuration; + } + + public bool TrySkipIisCustomErrors => + _configuration.GetValue(Prefix + "TrySkipIisCustomErrors", false); + + public bool InternalRedirectPreservesTemplate => + _configuration.GetValue(Prefix + "InternalRedirectPreservesTemplate", false); + + public bool DisableAlternativeTemplates => + _configuration.GetValue(Prefix + "DisableAlternativeTemplates", false); + + public bool ValidateAlternativeTemplates => + _configuration.GetValue(Prefix + "ValidateAlternativeTemplates", false); + + public bool DisableFindContentByIdPath => + _configuration.GetValue(Prefix + "DisableFindContentByIdPath", false); + + public bool DisableRedirectUrlTracking => + _configuration.GetValue(Prefix + "DisableRedirectUrlTracking", false); + + public string UrlProviderMode => + _configuration.GetValue(Prefix + "UrlProviderMode", UrlMode.Auto.ToString()); + + public string UmbracoApplicationUrl => + _configuration.GetValue(Prefix + "UmbracoApplicationUrl"); + } +} diff --git a/src/Umbraco.Configuration/Umbraco.Configuration.csproj b/src/Umbraco.Configuration/Umbraco.Configuration.csproj index 57fca1dfd6..88bb3639d0 100644 --- a/src/Umbraco.Configuration/Umbraco.Configuration.csproj +++ b/src/Umbraco.Configuration/Umbraco.Configuration.csproj @@ -22,6 +22,9 @@ + + + diff --git a/src/Umbraco.Configuration/UmbracoVersionExtensions.cs b/src/Umbraco.Configuration/UmbracoVersionExtensions.cs deleted file mode 100644 index 168bb16f57..0000000000 --- a/src/Umbraco.Configuration/UmbracoVersionExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Configuration; -using Semver; -using Umbraco.Core; -using Umbraco.Core.Configuration; - -namespace Umbraco.Configuration -{ - public static class UmbracoVersionExtensions - { - /// - /// Gets the "local" version of the site. - /// - /// - /// Three things have a version, really: the executing code, the database model, - /// and the site/files. The database model version is entirely managed via migrations, - /// and changes during an upgrade. The executing code version changes when new code is - /// deployed. The site/files version changes during an upgrade. - /// - public static SemVersion LocalVersion(this IUmbracoVersion umbracoVersion) - { - try - { - // TODO: https://github.com/umbraco/Umbraco-CMS/issues/4238 - stop having version in web.config appSettings - var value = ConfigurationManager.AppSettings[Constants.AppSettings.ConfigurationStatus]; - return value.IsNullOrWhiteSpace() ? null : SemVersion.TryParse(value, out var semver) ? semver : null; - } - catch - { - return null; - } - } - } -} diff --git a/src/Umbraco.Core/Cache/DeepCloneAppCache.cs b/src/Umbraco.Core/Cache/DeepCloneAppCache.cs index 452f897372..e70b40160e 100644 --- a/src/Umbraco.Core/Cache/DeepCloneAppCache.cs +++ b/src/Umbraco.Core/Cache/DeepCloneAppCache.cs @@ -73,7 +73,7 @@ namespace Umbraco.Core.Cache var result = SafeLazy.GetSafeLazy(factory); var value = result.Value; // force evaluation now - this may throw if cacheItem throws, and then nothing goes into cache // do not store null values (backward compat), clone / reset to go into the cache - return value == null ? null : CheckCloneableAndTracksChanges(value); + return value == null ? null : CheckCloneableAndTracksChanges(value); // clone / reset to go into the cache }, timeout, isSliding, dependentFiles); @@ -107,9 +107,9 @@ namespace Umbraco.Core.Cache } /// - public void ClearOfType(string typeName) + public void ClearOfType(Type type) { - InnerCache.ClearOfType(typeName); + InnerCache.ClearOfType(type); } /// diff --git a/src/Umbraco.Core/Cache/DictionaryAppCache.cs b/src/Umbraco.Core/Cache/DictionaryAppCache.cs index d372916240..04ee3e0afa 100644 --- a/src/Umbraco.Core/Cache/DictionaryAppCache.cs +++ b/src/Umbraco.Core/Cache/DictionaryAppCache.cs @@ -71,16 +71,16 @@ namespace Umbraco.Core.Cache } /// - public virtual void ClearOfType(string typeName) + public virtual void ClearOfType(Type type) { - _items.RemoveAll(kvp => kvp.Value != null && kvp.Value.GetType().ToString().InvariantEquals(typeName)); + _items.RemoveAll(kvp => kvp.Value != null && kvp.Value.GetType() == type); } /// public virtual void ClearOfType() { var typeOfT = typeof(T); - _items.RemoveAll(kvp => kvp.Value != null && kvp.Value.GetType() == typeOfT); + ClearOfType(typeOfT); } /// diff --git a/src/Umbraco.Core/Cache/FastDictionaryAppCache.cs b/src/Umbraco.Core/Cache/FastDictionaryAppCache.cs index 159f9cd7cb..54009af465 100644 --- a/src/Umbraco.Core/Cache/FastDictionaryAppCache.cs +++ b/src/Umbraco.Core/Cache/FastDictionaryAppCache.cs @@ -12,12 +12,6 @@ namespace Umbraco.Core.Cache ///
public class FastDictionaryAppCache : IAppCache { - private readonly ITypeFinder _typeFinder; - - public FastDictionaryAppCache(ITypeFinder typeFinder) - { - _typeFinder = typeFinder ?? throw new ArgumentNullException(nameof(typeFinder)); - } /// /// Gets the internal items dictionary, for tests only! @@ -83,9 +77,8 @@ namespace Umbraco.Core.Cache } /// - public void ClearOfType(string typeName) + public void ClearOfType(Type type) { - var type = _typeFinder.GetTypeByName(typeName); if (type == null) return; var isInterface = type.IsInterface; diff --git a/src/Umbraco.Core/Cache/FastDictionaryAppCacheBase.cs b/src/Umbraco.Core/Cache/FastDictionaryAppCacheBase.cs index f417c5ffd0..bb55762826 100644 --- a/src/Umbraco.Core/Cache/FastDictionaryAppCacheBase.cs +++ b/src/Umbraco.Core/Cache/FastDictionaryAppCacheBase.cs @@ -12,13 +12,6 @@ namespace Umbraco.Core.Cache /// public abstract class FastDictionaryAppCacheBase : IAppCache { - private readonly ITypeFinder _typeFinder; - - protected FastDictionaryAppCacheBase(ITypeFinder typeFinder) - { - _typeFinder = typeFinder ?? throw new ArgumentNullException(nameof(typeFinder)); - } - // prefix cache keys so we know which one are ours protected const string CacheItemPrefix = "umbrtmche"; @@ -121,9 +114,8 @@ namespace Umbraco.Core.Cache } /// - public virtual void ClearOfType(string typeName) + public virtual void ClearOfType(Type type) { - var type = _typeFinder.GetTypeByName(typeName); if (type == null) return; var isInterface = type.IsInterface; try diff --git a/src/Umbraco.Core/Cache/HttpRequestAppCache.cs b/src/Umbraco.Core/Cache/HttpRequestAppCache.cs index e698d93ebe..6ce43a7bc9 100644 --- a/src/Umbraco.Core/Cache/HttpRequestAppCache.cs +++ b/src/Umbraco.Core/Cache/HttpRequestAppCache.cs @@ -20,7 +20,7 @@ namespace Umbraco.Core.Cache /// /// Initializes a new instance of the class with a context, for unit tests! /// - public HttpRequestAppCache(Func requestItems, ITypeFinder typeFinder) : base(typeFinder) + public HttpRequestAppCache(Func requestItems) : base() { ContextItems = requestItems; } diff --git a/src/Umbraco.Core/Cache/IAppCache.cs b/src/Umbraco.Core/Cache/IAppCache.cs index 674781f6d6..c84ec1135c 100644 --- a/src/Umbraco.Core/Cache/IAppCache.cs +++ b/src/Umbraco.Core/Cache/IAppCache.cs @@ -51,14 +51,14 @@ namespace Umbraco.Core.Cache /// /// Removes items of a specified type from the cache. /// - /// The name of the type to remove. + /// The type to remove. /// /// If the type is an interface, then all items of a type implementing that interface are /// removed. Otherwise, only items of that exact type are removed (items of type inheriting from /// the specified type are not removed). /// Performs a case-sensitive search. /// - void ClearOfType(string typeName); + void ClearOfType(Type type); /// /// Removes items of a specified type from the cache. diff --git a/src/Umbraco.Core/Cache/NoAppCache.cs b/src/Umbraco.Core/Cache/NoAppCache.cs index 60bc6fb8b8..cae3a7381e 100644 --- a/src/Umbraco.Core/Cache/NoAppCache.cs +++ b/src/Umbraco.Core/Cache/NoAppCache.cs @@ -67,7 +67,7 @@ namespace Umbraco.Core.Cache { } /// - public virtual void ClearOfType(string typeName) + public virtual void ClearOfType(Type type) { } /// diff --git a/src/Umbraco.Core/Cache/ObjectCacheAppCache.cs b/src/Umbraco.Core/Cache/ObjectCacheAppCache.cs index 208390276a..dc9163affb 100644 --- a/src/Umbraco.Core/Cache/ObjectCacheAppCache.cs +++ b/src/Umbraco.Core/Cache/ObjectCacheAppCache.cs @@ -13,15 +13,13 @@ namespace Umbraco.Core.Cache /// public class ObjectCacheAppCache : IAppPolicyCache { - private readonly ITypeFinder _typeFinder; private readonly ReaderWriterLockSlim _locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); /// /// Initializes a new instance of the . /// - public ObjectCacheAppCache(ITypeFinder typeFinder) + public ObjectCacheAppCache() { - _typeFinder = typeFinder ?? throw new ArgumentNullException(nameof(typeFinder)); // the MemoryCache is created with name "in-memory". That name is // used to retrieve configuration options. It does not identify the memory cache, i.e. // each instance of this class has its own, independent, memory cache. @@ -178,9 +176,8 @@ namespace Umbraco.Core.Cache } /// - public virtual void ClearOfType(string typeName) + public virtual void ClearOfType(Type type) { - var type = _typeFinder.GetTypeByName(typeName); if (type == null) return; var isInterface = type.IsInterface; try diff --git a/src/Umbraco.Core/Composing/Composition.cs b/src/Umbraco.Core/Composing/Composition.cs index a186a1f00a..9a696c2dc0 100644 --- a/src/Umbraco.Core/Composing/Composition.cs +++ b/src/Umbraco.Core/Composing/Composition.cs @@ -135,7 +135,7 @@ namespace Umbraco.Core.Composing IFactory factory = null; - Configs.RegisterWith(_register, () => factory); + Configs.RegisterWith(_register); // ReSharper disable once AccessToModifiedClosure -- on purpose _register.Register(_ => factory, Lifetime.Singleton); diff --git a/src/Umbraco.Core/Configuration/Configs.cs b/src/Umbraco.Core/Configuration/Configs.cs index abb06d525f..821ee308f0 100644 --- a/src/Umbraco.Core/Configuration/Configs.cs +++ b/src/Umbraco.Core/Configuration/Configs.cs @@ -13,16 +13,8 @@ namespace Umbraco.Core.Configuration /// public class Configs { - private readonly Func _configSectionResolver; - - public Configs(Func configSectionResolver) - { - _configSectionResolver = configSectionResolver ?? throw new ArgumentNullException(nameof(configSectionResolver)); - } - private readonly Dictionary> _configs = new Dictionary>(); private Dictionary> _registerings = new Dictionary>(); - private Lazy _factory; /// /// Gets a configuration. @@ -52,61 +44,15 @@ namespace Umbraco.Core.Configuration _registerings[typeOfConfig] = register => register.Register(_ => (TConfig) lazyConfigFactory.Value, Lifetime.Singleton); } - /// - /// Adds a configuration, provided by a factory. - /// - public void Add(Func configFactory) - where TConfig : class - { - // make sure it is not too late - if (_registerings == null) - throw new InvalidOperationException("Configurations have already been registered."); - - var typeOfConfig = typeof(TConfig); - - _configs[typeOfConfig] = new Lazy(() => - { - if (!(_factory is null)) return _factory.Value.GetInstance(); - throw new InvalidOperationException($"Cannot get configuration of type {typeOfConfig} during composition."); - }); - _registerings[typeOfConfig] = register => register.Register(configFactory, Lifetime.Singleton); - } - - /// - /// Adds a configuration, provided by a configuration section. - /// - public void Add(string sectionName) - where TConfig : class - { - Add(() => GetConfig(sectionName)); - } - - private TConfig GetConfig(string sectionName) - where TConfig : class - { - // note: need to use SafeCallContext here because ConfigurationManager.GetSection ends up getting AppDomain.Evidence - // which will want to serialize the call context including anything that is in there - what a mess! - - using (new SafeCallContext()) - { - if ((_configSectionResolver(sectionName) is TConfig config)) - return config; - var ex = new InvalidOperationException($"Could not get configuration section \"{sectionName}\" from config files."); - throw ex; - } - } - /// /// Registers configurations in a register. /// - public void RegisterWith(IRegister register, Func factory) + public void RegisterWith(IRegister register) { // do it only once if (_registerings == null) throw new InvalidOperationException("Configurations have already been registered."); - _factory = new Lazy(factory); - register.Register(this); foreach (var registering in _registerings.Values) diff --git a/src/Umbraco.Core/Configuration/ConfigsExtensions.cs b/src/Umbraco.Core/Configuration/ConfigsExtensions.cs index 93586b550b..f9ea352399 100644 --- a/src/Umbraco.Core/Configuration/ConfigsExtensions.cs +++ b/src/Umbraco.Core/Configuration/ConfigsExtensions.cs @@ -1,13 +1,7 @@ -using System.IO; -using Umbraco.Core.Cache; -using Umbraco.Core.Composing; -using Umbraco.Core.Configuration; +using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.Grid; using Umbraco.Core.Configuration.HealthChecks; using Umbraco.Core.Configuration.UmbracoSettings; -using Umbraco.Core.IO; -using Umbraco.Core.Logging; -using Umbraco.Core.Manifest; namespace Umbraco.Core { @@ -16,6 +10,9 @@ namespace Umbraco.Core /// public static class ConfigsExtensions { + + public static IImagingSettings Imaging(this Configs configs) + => configs.GetConfig(); public static IGlobalSettings Global(this Configs configs) => configs.GetConfig(); @@ -43,26 +40,10 @@ namespace Umbraco.Core public static IWebRoutingSettings WebRouting(this Configs configs) => configs.GetConfig(); - public static IHealthChecks HealthChecks(this Configs configs) - => configs.GetConfig(); + public static IHealthChecksSettings HealthChecks(this Configs configs) + => configs.GetConfig(); + public static ICoreDebugSettings CoreDebug(this Configs configs) + => configs.GetConfig(); - public static IGridConfig Grids(this Configs configs) - => configs.GetConfig(); - - public static ICoreDebug CoreDebug(this Configs configs) - => configs.GetConfig(); - - public static void AddCoreConfigs(this Configs configs, IIOHelper ioHelper) - { - var configDir = new DirectoryInfo(ioHelper.MapPath(Constants.SystemDirectories.Config)); - - // GridConfig depends on runtime caches, manifest parsers... and cannot be available during composition - configs.Add(factory => new GridConfig( - factory.GetInstance(), - factory.GetInstance(), - configDir, - factory.GetInstance(), - factory.GetInstance().Debug)); - } } } diff --git a/src/Umbraco.Core/Configuration/GlobalSettingsExtensions.cs b/src/Umbraco.Core/Configuration/GlobalSettingsExtensions.cs deleted file mode 100644 index 4d8039dfbb..0000000000 --- a/src/Umbraco.Core/Configuration/GlobalSettingsExtensions.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using Umbraco.Core.IO; - -namespace Umbraco.Core.Configuration -{ - public static class GlobalSettingsExtensions - { - private static string _mvcArea; - - - /// - /// This returns the string of the MVC Area route. - /// - /// - /// This will return the MVC area that we will route all custom routes through like surface controllers, etc... - /// We will use the 'Path' (default ~/umbraco) to create it but since it cannot contain '/' and people may specify a path of ~/asdf/asdf/admin - /// we will convert the '/' to '-' and use that as the path. its a bit lame but will work. - /// - /// We also make sure that the virtual directory (SystemDirectories.Root) is stripped off first, otherwise we'd end up with something - /// like "MyVirtualDirectory-Umbraco" instead of just "Umbraco". - /// - public static string GetUmbracoMvcArea(this IGlobalSettings globalSettings, IIOHelper ioHelper) - { - if (_mvcArea != null) return _mvcArea; - - _mvcArea = GetUmbracoMvcAreaNoCache(globalSettings, ioHelper); - - return _mvcArea; - } - - internal static string GetUmbracoMvcAreaNoCache(this IGlobalSettings globalSettings, IIOHelper ioHelper) - { - if (globalSettings.Path.IsNullOrWhiteSpace()) - { - throw new InvalidOperationException("Cannot create an MVC Area path without the umbracoPath specified"); - } - - var path = globalSettings.Path; - if (path.StartsWith(ioHelper.Root)) // beware of TrimStart, see U4-2518 - path = path.Substring(ioHelper.Root.Length); - return path.TrimStart('~').TrimStart('/').Replace('/', '-').Trim().ToLower(); - } - - } -} diff --git a/src/Umbraco.Core/Configuration/Grid/GridConfig.cs b/src/Umbraco.Core/Configuration/Grid/GridConfig.cs index de4f7ccd5a..72c720e3d6 100644 --- a/src/Umbraco.Core/Configuration/Grid/GridConfig.cs +++ b/src/Umbraco.Core/Configuration/Grid/GridConfig.cs @@ -1,15 +1,18 @@ using System.IO; using Umbraco.Core.Cache; +using Umbraco.Core.Hosting; +using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Manifest; +using Umbraco.Core.Serialization; namespace Umbraco.Core.Configuration.Grid { public class GridConfig : IGridConfig { - public GridConfig(ILogger logger, AppCaches appCaches, DirectoryInfo configFolder, IManifestParser manifestParser, bool isDebug) + public GridConfig(AppCaches appCaches, IIOHelper ioHelper, IManifestParser manifestParser, IJsonSerializer jsonSerializer, IHostingEnvironment hostingEnvironment) { - EditorsConfig = new GridEditorsConfig(logger, appCaches, configFolder, manifestParser, isDebug); + EditorsConfig = new GridEditorsConfig(appCaches, ioHelper, manifestParser, jsonSerializer, hostingEnvironment.IsDebugMode); } public IGridEditorsConfig EditorsConfig { get; } diff --git a/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs b/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs index a1ebf008fc..410c83ff1a 100644 --- a/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs +++ b/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs @@ -1,27 +1,30 @@ using System; using System.Collections.Generic; using System.IO; +using Umbraco.Composing; using Umbraco.Core.Cache; +using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Manifest; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Serialization; namespace Umbraco.Core.Configuration.Grid { internal class GridEditorsConfig : IGridEditorsConfig { - private readonly ILogger _logger; private readonly AppCaches _appCaches; - private readonly DirectoryInfo _configFolder; + private readonly IIOHelper _ioHelper; private readonly IManifestParser _manifestParser; private readonly bool _isDebug; + private readonly IJsonSerializer _jsonSerializer; - public GridEditorsConfig(ILogger logger, AppCaches appCaches, DirectoryInfo configFolder, IManifestParser manifestParser, bool isDebug) + public GridEditorsConfig(AppCaches appCaches, IIOHelper ioHelper, IManifestParser manifestParser,IJsonSerializer jsonSerializer, bool isDebug) { - _logger = logger; _appCaches = appCaches; - _configFolder = configFolder; + _ioHelper = ioHelper; _manifestParser = manifestParser; + _jsonSerializer = jsonSerializer; _isDebug = isDebug; } @@ -31,19 +34,20 @@ namespace Umbraco.Core.Configuration.Grid { List GetResult() { + var configFolder = new DirectoryInfo(_ioHelper.MapPath(Constants.SystemDirectories.Config)); var editors = new List(); - var gridConfig = Path.Combine(_configFolder.FullName, "grid.editors.config.js"); + var gridConfig = Path.Combine(configFolder.FullName, "grid.editors.config.js"); if (File.Exists(gridConfig)) { var sourceString = File.ReadAllText(gridConfig); try { - editors.AddRange(_manifestParser.ParseGridEditors(sourceString)); + editors.AddRange(_jsonSerializer.Deserialize>(sourceString)); } catch (Exception ex) { - _logger.Error(ex, "Could not parse the contents of grid.editors.config.js into a JSON array '{Json}", sourceString); + Current.Logger.Error(ex, "Could not parse the contents of grid.editors.config.js into a JSON array '{Json}", sourceString); } } @@ -63,7 +67,6 @@ namespace Umbraco.Core.Configuration.Grid return result; } - } } } diff --git a/src/Umbraco.Core/Configuration/HealthChecks/IHealthChecks.cs b/src/Umbraco.Core/Configuration/HealthChecks/IHealthChecksSettings.cs similarity index 84% rename from src/Umbraco.Core/Configuration/HealthChecks/IHealthChecks.cs rename to src/Umbraco.Core/Configuration/HealthChecks/IHealthChecksSettings.cs index fa98e3b054..785e8d5651 100644 --- a/src/Umbraco.Core/Configuration/HealthChecks/IHealthChecks.cs +++ b/src/Umbraco.Core/Configuration/HealthChecks/IHealthChecksSettings.cs @@ -2,7 +2,7 @@ namespace Umbraco.Core.Configuration.HealthChecks { - public interface IHealthChecks + public interface IHealthChecksSettings { IEnumerable DisabledChecks { get; } IHealthCheckNotificationSettings NotificationSettings { get; } diff --git a/src/Umbraco.Core/Configuration/IConfigManipulator.cs b/src/Umbraco.Core/Configuration/IConfigManipulator.cs new file mode 100644 index 0000000000..83ab2c0631 --- /dev/null +++ b/src/Umbraco.Core/Configuration/IConfigManipulator.cs @@ -0,0 +1,10 @@ +using Umbraco.Core.IO; + +namespace Umbraco.Core.Configuration +{ + public interface IConfigManipulator + { + void RemoveConnectionString(); + void SaveConnectionString(string connectionString, string providerName); + } +} diff --git a/src/Umbraco.Core/Configuration/IConfigsFactory.cs b/src/Umbraco.Core/Configuration/IConfigsFactory.cs index b2ad6295a1..dd2459b88c 100644 --- a/src/Umbraco.Core/Configuration/IConfigsFactory.cs +++ b/src/Umbraco.Core/Configuration/IConfigsFactory.cs @@ -5,6 +5,6 @@ namespace Umbraco.Core.Configuration { public interface IConfigsFactory { - Configs Create(IIOHelper ioHelper, ILogger logger); + Configs Create(); } } diff --git a/src/Umbraco.Core/Configuration/IConnectionStrings.cs b/src/Umbraco.Core/Configuration/IConnectionStrings.cs index 2a14c0e614..0d33378669 100644 --- a/src/Umbraco.Core/Configuration/IConnectionStrings.cs +++ b/src/Umbraco.Core/Configuration/IConnectionStrings.cs @@ -6,8 +6,5 @@ namespace Umbraco.Core.Configuration { get; } - - void RemoveConnectionString(string umbracoConnectionName); - void SaveConnectionString(string connectionString, string providerName); } } diff --git a/src/Umbraco.Core/Configuration/ICoreDebug.cs b/src/Umbraco.Core/Configuration/ICoreDebugSettings.cs similarity index 93% rename from src/Umbraco.Core/Configuration/ICoreDebug.cs rename to src/Umbraco.Core/Configuration/ICoreDebugSettings.cs index 4ff2a1a300..586e4bc3e4 100644 --- a/src/Umbraco.Core/Configuration/ICoreDebug.cs +++ b/src/Umbraco.Core/Configuration/ICoreDebugSettings.cs @@ -1,6 +1,6 @@ namespace Umbraco.Core.Configuration { - public interface ICoreDebug + public interface ICoreDebugSettings { /// /// When set to true, Scope logs the stack trace for any scope that gets disposed without being completed. diff --git a/src/Umbraco.Core/Configuration/IGlobalSettings.cs b/src/Umbraco.Core/Configuration/IGlobalSettings.cs index fa96f66d00..3cb211a7a7 100644 --- a/src/Umbraco.Core/Configuration/IGlobalSettings.cs +++ b/src/Umbraco.Core/Configuration/IGlobalSettings.cs @@ -21,7 +21,7 @@ string ReservedPaths { get; } /// - /// Gets the path to umbraco's root directory (/umbraco by default). + /// Gets the path to umbraco's root directory. /// string Path { get; } diff --git a/src/Umbraco.Core/Configuration/IImagingSettings.cs b/src/Umbraco.Core/Configuration/IImagingSettings.cs new file mode 100644 index 0000000000..13e1b30389 --- /dev/null +++ b/src/Umbraco.Core/Configuration/IImagingSettings.cs @@ -0,0 +1,12 @@ +namespace Umbraco.Core.Configuration +{ + public interface IImagingSettings + { + int MaxBrowserCacheDays { get;} + int MaxCacheDays { get; } + uint CachedNameLength { get; } + int MaxResizeWidth { get; } + int MaxResizeHeight { get; } + string CacheFolder { get; } + } +} diff --git a/src/Umbraco.Core/Configuration/IMachineKeyConfig.cs b/src/Umbraco.Core/Configuration/IMachineKeyConfig.cs deleted file mode 100644 index 35969e668a..0000000000 --- a/src/Umbraco.Core/Configuration/IMachineKeyConfig.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Umbraco.Core.Configuration -{ - public interface IMachineKeyConfig - { - bool HasMachineKey { get;} - } -} diff --git a/src/Umbraco.Core/Configuration/IModelsBuilderConfig.cs b/src/Umbraco.Core/Configuration/IModelsBuilderConfig.cs index 6a071ac277..990bde9843 100644 --- a/src/Umbraco.Core/Configuration/IModelsBuilderConfig.cs +++ b/src/Umbraco.Core/Configuration/IModelsBuilderConfig.cs @@ -7,7 +7,6 @@ int DebugLevel { get; } bool EnableFactory { get; } bool FlagOutOfDateModels { get; } - bool IsDebug { get; } string ModelsDirectory { get; } ModelsMode ModelsMode { get; } string ModelsNamespace { get; } diff --git a/src/Umbraco.Core/Configuration/IPasswordConfiguration.cs b/src/Umbraco.Core/Configuration/IPasswordConfiguration.cs index 98cd1010c0..6a5fd8e73f 100644 --- a/src/Umbraco.Core/Configuration/IPasswordConfiguration.cs +++ b/src/Umbraco.Core/Configuration/IPasswordConfiguration.cs @@ -6,13 +6,11 @@ /// public interface IPasswordConfiguration { - int RequiredLength { get; } + int RequiredLength { get; } bool RequireNonLetterOrDigit { get; } bool RequireDigit { get; } bool RequireLowercase { get; } bool RequireUppercase { get; } - - bool UseLegacyEncoding { get; } string HashAlgorithmType { get; } // TODO: This doesn't really belong here diff --git a/src/Umbraco.Core/Configuration/ModelsBuilderConfigExtensions.cs b/src/Umbraco.Core/Configuration/ModelsBuilderConfigExtensions.cs new file mode 100644 index 0000000000..3e3b116395 --- /dev/null +++ b/src/Umbraco.Core/Configuration/ModelsBuilderConfigExtensions.cs @@ -0,0 +1,57 @@ +using System.Configuration; +using System.IO; +using Umbraco.Core.IO; + +namespace Umbraco.Core.Configuration +{ + public static class ModelsBuilderConfigExtensions + { + private static string _modelsDirectoryAbsolute = null; + + public static string ModelsDirectoryAbsolute(this IModelsBuilderConfig modelsBuilderConfig, IIOHelper ioHelper) + { + + if (_modelsDirectoryAbsolute is null) + { + var modelsDirectory = modelsBuilderConfig.ModelsDirectory; + var root = ioHelper.MapPath("~/"); + + _modelsDirectoryAbsolute = GetModelsDirectory(root, modelsDirectory, + modelsBuilderConfig.AcceptUnsafeModelsDirectory); + } + + return _modelsDirectoryAbsolute; + } + + // internal for tests + internal static string GetModelsDirectory(string root, string config, bool acceptUnsafe) + { + // making sure it is safe, ie under the website root, + // unless AcceptUnsafeModelsDirectory and then everything is OK. + + if (!Path.IsPathRooted(root)) + throw new ConfigurationErrorsException($"Root is not rooted \"{root}\"."); + + if (config.StartsWith("~/")) + { + var dir = Path.Combine(root, config.TrimStart("~/")); + + // sanitize - GetFullPath will take care of any relative + // segments in path, eg '../../foo.tmp' - it may throw a SecurityException + // if the combined path reaches illegal parts of the filesystem + dir = Path.GetFullPath(dir); + root = Path.GetFullPath(root); + + if (!dir.StartsWith(root) && !acceptUnsafe) + throw new ConfigurationErrorsException($"Invalid models directory \"{config}\"."); + + return dir; + } + + if (acceptUnsafe) + return Path.GetFullPath(config); + + throw new ConfigurationErrorsException($"Invalid models directory \"{config}\"."); + } + } +} diff --git a/src/Umbraco.Core/Configuration/PasswordConfiguration.cs b/src/Umbraco.Core/Configuration/PasswordConfiguration.cs index 6827695b35..0c5ed9adb0 100644 --- a/src/Umbraco.Core/Configuration/PasswordConfiguration.cs +++ b/src/Umbraco.Core/Configuration/PasswordConfiguration.cs @@ -17,7 +17,6 @@ namespace Umbraco.Core.Configuration RequireDigit = configSettings.RequireDigit; RequireLowercase = configSettings.RequireLowercase; RequireUppercase = configSettings.RequireUppercase; - UseLegacyEncoding = configSettings.UseLegacyEncoding; HashAlgorithmType = configSettings.HashAlgorithmType; MaxFailedAccessAttemptsBeforeLockout = configSettings.MaxFailedAccessAttemptsBeforeLockout; } @@ -32,8 +31,6 @@ namespace Umbraco.Core.Configuration public bool RequireUppercase { get; } - public bool UseLegacyEncoding { get; } - public string HashAlgorithmType { get; } public int MaxFailedAccessAttemptsBeforeLockout { get; } diff --git a/src/Umbraco.Configuration/ConnectionStrings.cs b/src/Umbraco.Core/Configuration/XmlConfigManipulator.cs similarity index 65% rename from src/Umbraco.Configuration/ConnectionStrings.cs rename to src/Umbraco.Core/Configuration/XmlConfigManipulator.cs index 23436d6caf..333f9dc6f9 100644 --- a/src/Umbraco.Configuration/ConnectionStrings.cs +++ b/src/Umbraco.Core/Configuration/XmlConfigManipulator.cs @@ -3,34 +3,26 @@ using System.Configuration; using System.IO; using System.Linq; using System.Xml.Linq; +using Umbraco.Composing; using Umbraco.Core.IO; using Umbraco.Core.Logging; namespace Umbraco.Core.Configuration { - public class ConnectionStrings : IConnectionStrings + public class XmlConfigManipulator : IConfigManipulator { private readonly IIOHelper _ioHelper; private readonly ILogger _logger; - public ConnectionStrings(IIOHelper ioHelper, ILogger logger) + public XmlConfigManipulator(IIOHelper ioHelper, ILogger logger) { _ioHelper = ioHelper; _logger = logger; } - public ConfigConnectionString this[string key] - { - get - { - var settings = ConfigurationManager.ConnectionStrings[key]; - if (settings == null) return null; - return new ConfigConnectionString(settings.ConnectionString, settings.ProviderName, settings.Name); - } - } - - public void RemoveConnectionString(string key) + public void RemoveConnectionString() { + var key = Constants.System.UmbracoConnectionName; var fileName = _ioHelper.MapPath(string.Format("{0}/web.config", _ioHelper.Root)); var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace); @@ -43,26 +35,30 @@ namespace Umbraco.Core.Configuration xml.Save(fileName, SaveOptions.DisableFormatting); ConfigurationManager.RefreshSection("appSettings"); } + var settings = ConfigurationManager.ConnectionStrings[key]; } - /// - /// Saves the connection string as a proper .net connection string in web.config. + /// + /// Saves the connection string as a proper .net connection string in web.config. /// /// Saves the ConnectionString in the very nasty 'medium trust'-supportive way. /// The connection string. /// The provider name. - public void SaveConnectionString(string connectionString, string providerName) + public void SaveConnectionString(string connectionString, string providerName) { - if (connectionString == null) throw new ArgumentNullException(nameof(connectionString)); - if (string.IsNullOrWhiteSpace(connectionString)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(connectionString)); + if (string.IsNullOrWhiteSpace(connectionString)) + throw new ArgumentException("Value can't be empty or consist only of white-space characters.", + nameof(connectionString)); if (providerName == null) throw new ArgumentNullException(nameof(providerName)); - if (string.IsNullOrWhiteSpace(providerName)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(providerName)); + if (string.IsNullOrWhiteSpace(providerName)) + throw new ArgumentException("Value can't be empty or consist only of white-space characters.", + nameof(providerName)); var fileSource = "web.config"; - var fileName = _ioHelper.MapPath(_ioHelper.Root +"/" + fileSource); + var fileName = _ioHelper.MapPath(_ioHelper.Root + "/" + fileSource); var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace); if (xml.Root == null) throw new Exception($"Invalid {fileSource} file (no root)."); @@ -84,11 +80,13 @@ namespace Umbraco.Core.Configuration if (xml.Root == null) throw new Exception($"Invalid {fileSource} file (no root)."); connectionStrings = xml.Root.DescendantsAndSelf("connectionStrings").FirstOrDefault(); - if (connectionStrings == null) throw new Exception($"Invalid {fileSource} file (no connection strings)."); + if (connectionStrings == null) + throw new Exception($"Invalid {fileSource} file (no connection strings)."); } // create or update connection string - var setting = connectionStrings.Descendants("add").FirstOrDefault(s => s.Attribute("name")?.Value == Constants.System.UmbracoConnectionName); + var setting = connectionStrings.Descendants("add").FirstOrDefault(s => + s.Attribute("name")?.Value == Constants.System.UmbracoConnectionName); if (setting == null) { connectionStrings.Add(new XElement("add", @@ -103,19 +101,18 @@ namespace Umbraco.Core.Configuration } // save - _logger.Info("Saving connection string to {ConfigFile}.", fileSource); + _logger.Info("Saving connection string to {ConfigFile}.", fileSource); xml.Save(fileName, SaveOptions.DisableFormatting); - _logger.Info("Saved connection string to {ConfigFile}.", fileSource); + _logger.Info("Saved connection string to {ConfigFile}.", fileSource); } - private static void AddOrUpdateAttribute(XElement element, string name, string value) - { - var attribute = element.Attribute(name); - if (attribute == null) - element.Add(new XAttribute(name, value)); - else - attribute.Value = value; - } - + private static void AddOrUpdateAttribute(XElement element, string name, string value) + { + var attribute = element.Attribute(name); + if (attribute == null) + element.Add(new XAttribute(name, value)); + else + attribute.Value = value; + } } } diff --git a/src/Umbraco.Core/Constants-Configuration.cs b/src/Umbraco.Core/Constants-Configuration.cs new file mode 100644 index 0000000000..c45229d918 --- /dev/null +++ b/src/Umbraco.Core/Constants-Configuration.cs @@ -0,0 +1,18 @@ +namespace Umbraco.Core +{ + public static partial class Constants + { + public static class Configuration + { + /// + /// Case insensitive prefix for all configurations + /// + /// + /// ":" is used as marker for nested objects in json. E.g. "Umbraco:CMS:" = {"Umbraco":{"CMS":{....}} + /// + public const string ConfigPrefix = "Umbraco:CMS:"; + public const string ConfigSecurityPrefix = ConfigPrefix+"Security:"; + public const string ConfigModelsBuilderPrefix = ConfigPrefix+"ModelsBuilder:"; + } + } +} diff --git a/src/Umbraco.Core/Constants-System.cs b/src/Umbraco.Core/Constants-System.cs index abb92298f4..837db01b63 100644 --- a/src/Umbraco.Core/Constants-System.cs +++ b/src/Umbraco.Core/Constants-System.cs @@ -1,4 +1,4 @@ -namespace Umbraco.Core + namespace Umbraco.Core { public static partial class Constants { diff --git a/src/Umbraco.Core/IO/IIOHelper.cs b/src/Umbraco.Core/IO/IIOHelper.cs index 11f5c6c565..f478b49de6 100644 --- a/src/Umbraco.Core/IO/IIOHelper.cs +++ b/src/Umbraco.Core/IO/IIOHelper.cs @@ -4,6 +4,9 @@ namespace Umbraco.Core.IO { public interface IIOHelper { + + string BackOfficePath { get; } + bool ForceNotHosted { get; set; } char DirSepChar { get; } diff --git a/src/Umbraco.Core/IO/IOHelper.cs b/src/Umbraco.Core/IO/IOHelper.cs index 8e7dd500f3..9eddea6477 100644 --- a/src/Umbraco.Core/IO/IOHelper.cs +++ b/src/Umbraco.Core/IO/IOHelper.cs @@ -4,6 +4,7 @@ using System.Globalization; using System.Reflection; using System.IO; using System.Linq; +using Umbraco.Core.Configuration; using Umbraco.Core.Hosting; using Umbraco.Core.Strings; @@ -12,10 +13,22 @@ namespace Umbraco.Core.IO public class IOHelper : IIOHelper { private readonly IHostingEnvironment _hostingEnvironment; + private readonly IGlobalSettings _globalSettings; - public IOHelper(IHostingEnvironment hostingEnvironment) + public IOHelper(IHostingEnvironment hostingEnvironment, IGlobalSettings globalSettings) { _hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment)); + _globalSettings = globalSettings; + } + + public string BackOfficePath + { + get + { + var path = _globalSettings.Path; + + return string.IsNullOrEmpty(path) ? string.Empty : ResolveUrl(path); + } } /// diff --git a/src/Umbraco.Core/IO/IOHelperExtensions.cs b/src/Umbraco.Core/IO/IOHelperExtensions.cs index 64b57e7dc1..39bd5e6cc9 100644 --- a/src/Umbraco.Core/IO/IOHelperExtensions.cs +++ b/src/Umbraco.Core/IO/IOHelperExtensions.cs @@ -5,6 +5,8 @@ namespace Umbraco.Core.IO { public static class IOHelperExtensions { + private static string _mvcArea; + /// /// Tries to create a directory. /// @@ -35,5 +37,38 @@ namespace Umbraco.Core.IO { return "umbraco-test." + Guid.NewGuid().ToString("N").Substring(0, 8); } + + /// + /// This returns the string of the MVC Area route. + /// + /// + /// This will return the MVC area that we will route all custom routes through like surface controllers, etc... + /// We will use the 'Path' (default ~/umbraco) to create it but since it cannot contain '/' and people may specify a path of ~/asdf/asdf/admin + /// we will convert the '/' to '-' and use that as the path. its a bit lame but will work. + /// + /// We also make sure that the virtual directory (SystemDirectories.Root) is stripped off first, otherwise we'd end up with something + /// like "MyVirtualDirectory-Umbraco" instead of just "Umbraco". + /// + public static string GetUmbracoMvcArea(this IIOHelper ioHelper) + { + if (_mvcArea != null) return _mvcArea; + + _mvcArea = GetUmbracoMvcAreaNoCache(ioHelper); + + return _mvcArea; + } + + internal static string GetUmbracoMvcAreaNoCache(this IIOHelper ioHelper) + { + if (ioHelper.BackOfficePath.IsNullOrWhiteSpace()) + { + throw new InvalidOperationException("Cannot create an MVC Area path without the umbracoPath specified"); + } + + var path = ioHelper.BackOfficePath; + if (path.StartsWith(ioHelper.Root)) // beware of TrimStart, see U4-2518 + path = path.Substring(ioHelper.Root.Length); + return path.TrimStart('~').TrimStart('/').Replace('/', '-').Trim().ToLower(); + } } } diff --git a/src/Umbraco.Core/Manifest/IManifestParser.cs b/src/Umbraco.Core/Manifest/IManifestParser.cs index eeb0c756f6..3eec7007b3 100644 --- a/src/Umbraco.Core/Manifest/IManifestParser.cs +++ b/src/Umbraco.Core/Manifest/IManifestParser.cs @@ -17,7 +17,5 @@ namespace Umbraco.Core.Manifest /// Parses a manifest. /// PackageManifest ParseManifest(string text); - - IEnumerable ParseGridEditors(string text); } } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 7a15e7fbed..c083cccf8f 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -12,6 +12,7 @@ + diff --git a/src/Umbraco.Core/UriExtensions.cs b/src/Umbraco.Core/UriExtensions.cs index cf84d7914d..4321aefd7f 100644 --- a/src/Umbraco.Core/UriExtensions.cs +++ b/src/Umbraco.Core/UriExtensions.cs @@ -40,7 +40,7 @@ namespace Umbraco.Core /// But if we've got this far we'll just have to assume it's front-end anyways. /// /// - internal static bool IsBackOfficeRequest(this Uri url, string applicationPath, IGlobalSettings globalSettings, IIOHelper ioHelper) + internal static bool IsBackOfficeRequest(this Uri url, string applicationPath, IIOHelper ioHelper) { applicationPath = applicationPath ?? string.Empty; @@ -49,11 +49,11 @@ namespace Umbraco.Core var urlPath = fullUrlPath.TrimStart(appPath).EnsureStartsWith('/'); //check if this is in the umbraco back office - var isUmbracoPath = urlPath.InvariantStartsWith(globalSettings.Path.EnsureStartsWith('/').TrimStart(appPath.EnsureStartsWith('/')).EnsureStartsWith('/')); + var isUmbracoPath = urlPath.InvariantStartsWith(ioHelper.BackOfficePath.EnsureStartsWith('/').TrimStart(appPath.EnsureStartsWith('/')).EnsureStartsWith('/')); //if not, then def not back office if (isUmbracoPath == false) return false; - var mvcArea = globalSettings.GetUmbracoMvcArea(ioHelper); + var mvcArea = ioHelper.GetUmbracoMvcArea(); //if its the normal /umbraco path if (urlPath.InvariantEquals("/" + mvcArea) || urlPath.InvariantEquals("/" + mvcArea + "/")) @@ -127,12 +127,12 @@ namespace Umbraco.Core /// /// /// - internal static bool IsDefaultBackOfficeRequest(this Uri url, IGlobalSettings globalSettings) + internal static bool IsDefaultBackOfficeRequest(this Uri url, IIOHelper ioHelper) { - if (url.AbsolutePath.InvariantEquals(globalSettings.Path.TrimEnd("/")) - || url.AbsolutePath.InvariantEquals(globalSettings.Path.EnsureEndsWith('/')) - || url.AbsolutePath.InvariantEquals(globalSettings.Path.EnsureEndsWith('/') + "Default") - || url.AbsolutePath.InvariantEquals(globalSettings.Path.EnsureEndsWith('/') + "Default/")) + if (url.AbsolutePath.InvariantEquals(ioHelper.BackOfficePath.TrimEnd("/")) + || url.AbsolutePath.InvariantEquals(ioHelper.BackOfficePath.EnsureEndsWith('/')) + || url.AbsolutePath.InvariantEquals(ioHelper.BackOfficePath.EnsureEndsWith('/') + "Default") + || url.AbsolutePath.InvariantEquals(ioHelper.BackOfficePath.EnsureEndsWith('/') + "Default/")) { return true; } diff --git a/src/Umbraco.Infrastructure/Configuration/JsonConfigManipulator.cs b/src/Umbraco.Infrastructure/Configuration/JsonConfigManipulator.cs new file mode 100644 index 0000000000..3c78faea37 --- /dev/null +++ b/src/Umbraco.Infrastructure/Configuration/JsonConfigManipulator.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.Json.Serialization; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration.Json; +using Microsoft.Extensions.FileProviders; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Umbraco.Core.IO; +using Umbraco.Core.Serialization; + +namespace Umbraco.Core.Configuration +{ + public class JsonConfigManipulator : IConfigManipulator + { + private readonly IConfiguration _configuration; + + public JsonConfigManipulator(IConfiguration configuration) + { + _configuration = configuration; + } + + public string UmbracoConnectionPath { get; } = $"ConnectionStrings:{ Constants.System.UmbracoConnectionName}"; + public void RemoveConnectionString() + { + var provider = GetJsonConfigurationProvider(UmbracoConnectionPath); + + var json = GetJson(provider); + + RemoveJsonKey(json, UmbracoConnectionPath); + + SaveJson(provider, json); + } + + public void SaveConnectionString(string connectionString, string providerName) + { + var provider = GetJsonConfigurationProvider(); + + var json = GetJson(provider); + + var item = GetConnectionItem(connectionString, providerName); + + json.Merge(item, new JsonMergeSettings()); + + SaveJson(provider, json); + } + + + private JToken GetConnectionItem(string connectionString, string providerName) + { + JTokenWriter writer = new JTokenWriter(); + + writer.WriteStartObject(); + writer.WritePropertyName("ConnectionStrings"); + writer.WriteStartObject(); + writer.WritePropertyName(Constants.System.UmbracoConnectionName); + writer.WriteValue(connectionString); + writer.WriteEndObject(); + writer.WriteEndObject(); + + return writer.Token; + } + + private static void RemoveJsonKey(JObject json, string key) + { + JToken token = json; + foreach (var propertyName in key.Split(new[] { ':' })) + { + token = CaseSelectPropertyValues(token, propertyName); + } + + token?.Parent?.Remove(); + } + + private static void SaveJson(JsonConfigurationProvider provider, JObject json) + { + if (provider.Source.FileProvider is PhysicalFileProvider physicalFileProvider) + { + var jsonFilePath = Path.Combine(physicalFileProvider.Root, provider.Source.Path); + + using (var sw = new StreamWriter(jsonFilePath, false)) + using (var jsonTextWriter = new JsonTextWriter(sw) + { + Formatting = Formatting.Indented, + }) + { + json?.WriteTo(jsonTextWriter); + } + } + + } + + private static JObject GetJson(JsonConfigurationProvider provider) + { + if (provider.Source.FileProvider is PhysicalFileProvider physicalFileProvider) + { + var jsonFilePath = Path.Combine(physicalFileProvider.Root, provider.Source.Path); + + var serializer = new JsonSerializer(); + using (var sr = new StreamReader(jsonFilePath)) + using (var jsonTextReader = new JsonTextReader(sr)) + { + return serializer.Deserialize(jsonTextReader); + } + } + + return null; + } + + + + + private JsonConfigurationProvider GetJsonConfigurationProvider(string requiredKey = null) + { + if (_configuration is IConfigurationRoot configurationRoot) + { + foreach (var provider in configurationRoot.Providers) + { + if(provider is JsonConfigurationProvider jsonConfigurationProvider) + { + if (requiredKey is null || provider.TryGet(requiredKey, out _)) + { + return jsonConfigurationProvider; + } + } + } + } + throw new InvalidOperationException("Could not find a writable json config source"); + } + + /// + /// Returns the property value when case insensative + /// + /// + /// This method is required because keys are case insensative in IConfiguration. + /// JObject[..] do not support case insensative and JObject.Property(...) do not return a new JObject. + /// + private static JToken CaseSelectPropertyValues(JToken token, string name) + { + if (token is JObject obj) + { + + foreach (var property in obj.Properties()) + { + if (name is null) + return property.Value; + if (string.Equals(property.Name, name, StringComparison.OrdinalIgnoreCase)) + return property.Value; + } + } + return null; + } + + } +} diff --git a/src/Umbraco.Infrastructure/HealthCheck/NotificationMethods/EmailNotificationMethod.cs b/src/Umbraco.Infrastructure/HealthCheck/NotificationMethods/EmailNotificationMethod.cs index f76a69c0fa..9d36b60d83 100644 --- a/src/Umbraco.Infrastructure/HealthCheck/NotificationMethods/EmailNotificationMethod.cs +++ b/src/Umbraco.Infrastructure/HealthCheck/NotificationMethods/EmailNotificationMethod.cs @@ -20,7 +20,7 @@ namespace Umbraco.Web.HealthCheck.NotificationMethods private readonly IGlobalSettings _globalSettings; private readonly IContentSettings _contentSettings; - public EmailNotificationMethod(ILocalizedTextService textService, IRuntimeState runtimeState, ILogger logger, IGlobalSettings globalSettings, IHealthChecks healthChecks, IContentSettings contentSettings) : base(healthChecks) + public EmailNotificationMethod(ILocalizedTextService textService, IRuntimeState runtimeState, ILogger logger, IGlobalSettings globalSettings, IHealthChecksSettings healthChecksSettings, IContentSettings contentSettings) : base(healthChecksSettings) { var recipientEmail = Settings["recipientEmail"]?.Value; if (string.IsNullOrWhiteSpace(recipientEmail)) diff --git a/src/Umbraco.Infrastructure/HealthCheck/NotificationMethods/NotificationMethodBase.cs b/src/Umbraco.Infrastructure/HealthCheck/NotificationMethods/NotificationMethodBase.cs index ff6fbe2371..9c3516e712 100644 --- a/src/Umbraco.Infrastructure/HealthCheck/NotificationMethods/NotificationMethodBase.cs +++ b/src/Umbraco.Infrastructure/HealthCheck/NotificationMethods/NotificationMethodBase.cs @@ -8,7 +8,7 @@ namespace Umbraco.Web.HealthCheck.NotificationMethods { public abstract class NotificationMethodBase : IHealthCheckNotificationMethod { - protected NotificationMethodBase(IHealthChecks healthCheckConfig) + protected NotificationMethodBase(IHealthChecksSettings healthCheckSettingsConfig) { var type = GetType(); var attribute = type.GetCustomAttribute(); @@ -18,7 +18,7 @@ namespace Umbraco.Web.HealthCheck.NotificationMethods return; } - var notificationMethods = healthCheckConfig.NotificationSettings.NotificationMethods; + var notificationMethods = healthCheckSettingsConfig.NotificationSettings.NotificationMethods; var notificationMethod = notificationMethods[attribute.Alias]; if (notificationMethod == null) { diff --git a/src/Umbraco.Infrastructure/Intall/InstallSteps/ConfigureMachineKey.cs b/src/Umbraco.Infrastructure/Intall/InstallSteps/ConfigureMachineKey.cs deleted file mode 100644 index fb8201600c..0000000000 --- a/src/Umbraco.Infrastructure/Intall/InstallSteps/ConfigureMachineKey.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using System.Xml.Linq; -using Umbraco.Core.Configuration; -using Umbraco.Core.IO; -using Umbraco.Core.Security; -using Umbraco.Web.Install.Models; - -namespace Umbraco.Web.Install.InstallSteps -{ - [InstallSetupStep(InstallationType.NewInstall, - "ConfigureMachineKey", "machinekey", 2, - "Updating some security settings...", - PerformsAppRestart = true)] - public class ConfigureMachineKey : InstallSetupStep - { - private readonly IIOHelper _ioHelper; - private readonly IMachineKeyConfig _machineKeyConfig; - - public ConfigureMachineKey(IIOHelper ioHelper, IMachineKeyConfig machineKeyConfig) - { - _ioHelper = ioHelper; - _machineKeyConfig = machineKeyConfig; - } - - public override string View => HasMachineKey() == false ? base.View : ""; - - /// - /// Don't display the view or execute if a machine key already exists - /// - /// - private bool HasMachineKey() - { - return _machineKeyConfig.HasMachineKey; - } - - /// - /// The step execution method - /// - /// - /// - public override Task ExecuteAsync(bool? model) - { - if (model.HasValue && model.Value == false) return Task.FromResult(null); - - //install the machine key - var fileName = _ioHelper.MapPath($"{_ioHelper.Root}/web.config"); - var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace); - - // we only want to get the element that is under the root, (there may be more under tags we don't want them) - var systemWeb = xml.Root.Element("system.web"); - - // Update appSetting if it exists, or else create a new appSetting for the given key and value - var machineKey = systemWeb.Descendants("machineKey").FirstOrDefault(); - if (machineKey != null) return Task.FromResult(null); - - var generator = new MachineKeyGenerator(); - var generatedSection = generator.GenerateConfigurationBlock(); - systemWeb.Add(XElement.Parse(generatedSection)); - - xml.Save(fileName, SaveOptions.DisableFormatting); - - return Task.FromResult(null); - } - - public override bool RequiresExecution(bool? model) - { - return HasMachineKey() == false; - } - } -} diff --git a/src/Umbraco.Infrastructure/Intall/InstallSteps/DatabaseInstallStep.cs b/src/Umbraco.Infrastructure/Intall/InstallSteps/DatabaseInstallStep.cs index a7b3dcc218..865df4bc02 100644 --- a/src/Umbraco.Infrastructure/Intall/InstallSteps/DatabaseInstallStep.cs +++ b/src/Umbraco.Infrastructure/Intall/InstallSteps/DatabaseInstallStep.cs @@ -19,14 +19,16 @@ namespace Umbraco.Web.Install.InstallSteps private readonly ILogger _logger; private readonly IIOHelper _ioHelper; private readonly IConnectionStrings _connectionStrings; + private readonly IConfigManipulator _configManipulator; - public DatabaseInstallStep(DatabaseBuilder databaseBuilder, IRuntimeState runtime, ILogger logger, IIOHelper ioHelper, IConnectionStrings connectionStrings) + public DatabaseInstallStep(DatabaseBuilder databaseBuilder, IRuntimeState runtime, ILogger logger, IIOHelper ioHelper, IConnectionStrings connectionStrings, IConfigManipulator configManipulator) { _databaseBuilder = databaseBuilder; _runtime = runtime; _logger = logger; _ioHelper = ioHelper; _connectionStrings = connectionStrings; + _configManipulator = configManipulator; } public override Task ExecuteAsync(object model) @@ -43,7 +45,7 @@ namespace Umbraco.Web.Install.InstallSteps if (result.RequiresUpgrade == false) { - HandleConnectionStrings(_logger, _ioHelper, _connectionStrings); + HandleConnectionStrings(_logger, _ioHelper, _connectionStrings, _configManipulator); return Task.FromResult(null); } @@ -54,7 +56,7 @@ namespace Umbraco.Web.Install.InstallSteps })); } - internal static void HandleConnectionStrings(ILogger logger, IIOHelper ioHelper, IConnectionStrings connectionStrings) + internal static void HandleConnectionStrings(ILogger logger, IIOHelper ioHelper, IConnectionStrings connectionStrings, IConfigManipulator configManipulator) { @@ -65,7 +67,7 @@ namespace Umbraco.Web.Install.InstallSteps // Remove legacy umbracoDbDsn configuration setting if it exists and connectionstring also exists if (databaseSettings != null) { - connectionStrings.RemoveConnectionString(Constants.System.UmbracoConnectionName); + configManipulator.RemoveConnectionString(); } else { diff --git a/src/Umbraco.Infrastructure/Intall/InstallSteps/DatabaseUpgradeStep.cs b/src/Umbraco.Infrastructure/Intall/InstallSteps/DatabaseUpgradeStep.cs index 3cd3c1ca56..91a718d0f4 100644 --- a/src/Umbraco.Infrastructure/Intall/InstallSteps/DatabaseUpgradeStep.cs +++ b/src/Umbraco.Infrastructure/Intall/InstallSteps/DatabaseUpgradeStep.cs @@ -23,8 +23,17 @@ namespace Umbraco.Web.Install.InstallSteps private readonly IGlobalSettings _globalSettings; private readonly IConnectionStrings _connectionStrings; private readonly IIOHelper _ioHelper; + private readonly IConfigManipulator _configManipulator; - public DatabaseUpgradeStep(DatabaseBuilder databaseBuilder, IRuntimeState runtime, ILogger logger, IUmbracoVersion umbracoVersion, IGlobalSettings globalSettings, IConnectionStrings connectionStrings, IIOHelper ioHelper) + public DatabaseUpgradeStep( + DatabaseBuilder databaseBuilder, + IRuntimeState runtime, + ILogger logger, + IUmbracoVersion umbracoVersion, + IGlobalSettings globalSettings, + IConnectionStrings connectionStrings, + IIOHelper ioHelper, + IConfigManipulator configManipulator) { _databaseBuilder = databaseBuilder; _runtime = runtime; @@ -33,6 +42,7 @@ namespace Umbraco.Web.Install.InstallSteps _globalSettings = globalSettings; _connectionStrings = connectionStrings ?? throw new ArgumentNullException(nameof(connectionStrings)); _ioHelper = ioHelper; + _configManipulator = configManipulator; } public override Task ExecuteAsync(object model) @@ -55,7 +65,7 @@ namespace Umbraco.Web.Install.InstallSteps throw new InstallException("The database failed to upgrade. ERROR: " + result.Message); } - DatabaseInstallStep.HandleConnectionStrings(_logger, _ioHelper, _connectionStrings); + DatabaseInstallStep.HandleConnectionStrings(_logger, _ioHelper, _connectionStrings, _configManipulator); } return Task.FromResult(null); diff --git a/src/Umbraco.Infrastructure/Logging/Serilog/SerilogLogger.cs b/src/Umbraco.Infrastructure/Logging/Serilog/SerilogLogger.cs index 9dde28e95a..bb77869e28 100644 --- a/src/Umbraco.Infrastructure/Logging/Serilog/SerilogLogger.cs +++ b/src/Umbraco.Infrastructure/Logging/Serilog/SerilogLogger.cs @@ -18,7 +18,7 @@ namespace Umbraco.Core.Logging.Serilog /// public class SerilogLogger : ILogger, IDisposable { - private readonly ICoreDebug _coreDebug; + private readonly ICoreDebugSettings _coreDebugSettings; private readonly IIOHelper _ioHelper; private readonly IMarchal _marchal; @@ -26,9 +26,9 @@ namespace Umbraco.Core.Logging.Serilog /// Initialize a new instance of the class with a configuration file. /// /// - public SerilogLogger(ICoreDebug coreDebug, IIOHelper ioHelper, IMarchal marchal, FileInfo logConfigFile) + public SerilogLogger(ICoreDebugSettings coreDebugSettings, IIOHelper ioHelper, IMarchal marchal, FileInfo logConfigFile) { - _coreDebug = coreDebug; + _coreDebugSettings = coreDebugSettings; _ioHelper = ioHelper; _marchal = marchal; @@ -37,9 +37,9 @@ namespace Umbraco.Core.Logging.Serilog .CreateLogger(); } - public SerilogLogger(ICoreDebug coreDebug, IIOHelper ioHelper, IMarchal marchal, LoggerConfiguration logConfig) + public SerilogLogger(ICoreDebugSettings coreDebugSettings, IIOHelper ioHelper, IMarchal marchal, LoggerConfiguration logConfig) { - _coreDebug = coreDebug; + _coreDebugSettings = coreDebugSettings; _ioHelper = ioHelper; _marchal = marchal; @@ -51,7 +51,7 @@ 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(IHostingEnvironment hostingEnvironment, ISessionIdResolver sessionIdResolver, Func requestCacheGetter, ICoreDebug coreDebug, IIOHelper ioHelper, IMarchal marchal) + public static SerilogLogger CreateWithDefaultConfiguration(IHostingEnvironment hostingEnvironment, ISessionIdResolver sessionIdResolver, Func requestCacheGetter, ICoreDebugSettings coreDebugSettings, IIOHelper ioHelper, IMarchal marchal) { var loggerConfig = new LoggerConfiguration(); loggerConfig @@ -59,7 +59,7 @@ namespace Umbraco.Core.Logging.Serilog .ReadFromConfigFile() .ReadFromUserConfigFile(); - return new SerilogLogger(coreDebug, ioHelper, marchal, loggerConfig); + return new SerilogLogger(coreDebugSettings, ioHelper, marchal, loggerConfig); } /// @@ -179,7 +179,7 @@ namespace Umbraco.Core.Logging.Serilog messageTemplate += "\r\nThe thread has been aborted, because the request has timed out."; // dump if configured, or if stacktrace contains Monitor.ReliableEnter - dump = _coreDebug.DumpOnTimeoutThreadAbort || IsMonitorEnterThreadAbortException(exception); + dump = _coreDebugSettings.DumpOnTimeoutThreadAbort || IsMonitorEnterThreadAbortException(exception); // dump if it is ok to dump (might have a cap on number of dump...) dump &= MiniDump.OkToDump(_ioHelper); diff --git a/src/Umbraco.Infrastructure/Manifest/ManifestParser.cs b/src/Umbraco.Infrastructure/Manifest/ManifestParser.cs index 2074409ec8..987d3a98fb 100644 --- a/src/Umbraco.Infrastructure/Manifest/ManifestParser.cs +++ b/src/Umbraco.Infrastructure/Manifest/ManifestParser.cs @@ -220,11 +220,5 @@ namespace Umbraco.Core.Manifest return manifest; } - - // purely for tests - public IEnumerable ParseGridEditors(string text) - { - return _jsonSerializer.Deserialize>(text); - } } } diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs index a5a58dc9f1..17192fd69b 100644 --- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs +++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs @@ -28,7 +28,7 @@ namespace Umbraco.Core.Migrations.Install private readonly IIOHelper _ioHelper; private readonly IUmbracoVersion _umbracoVersion; private readonly IDbProviderFactoryCreator _dbProviderFactoryCreator; - private readonly IConnectionStrings _connectionStrings; + private readonly IConfigManipulator _configManipulator; private DatabaseSchemaResult _databaseSchemaValidationResult; @@ -46,7 +46,7 @@ namespace Umbraco.Core.Migrations.Install IIOHelper ioHelper, IUmbracoVersion umbracoVersion, IDbProviderFactoryCreator dbProviderFactoryCreator, - IConnectionStrings connectionStrings) + IConfigManipulator configManipulator) { _scopeProvider = scopeProvider; _globalSettings = globalSettings; @@ -58,7 +58,7 @@ namespace Umbraco.Core.Migrations.Install _ioHelper = ioHelper; _umbracoVersion = umbracoVersion; _dbProviderFactoryCreator = dbProviderFactoryCreator; - _connectionStrings = connectionStrings; + _configManipulator = configManipulator; } #region Status @@ -146,7 +146,7 @@ namespace Umbraco.Core.Migrations.Install private void ConfigureEmbeddedDatabaseConnection(IUmbracoDatabaseFactory factory, IIOHelper ioHelper) { - _connectionStrings.SaveConnectionString(EmbeddedDatabaseConnectionString, Constants.DbProviderNames.SqlCe); + _configManipulator.SaveConnectionString(EmbeddedDatabaseConnectionString, Constants.DbProviderNames.SqlCe); var path = Path.Combine(ioHelper.GetRootDirectorySafe(), "App_Data", "Umbraco.sdf"); if (File.Exists(path) == false) @@ -169,7 +169,7 @@ namespace Umbraco.Core.Migrations.Install { const string providerName = Constants.DbProviderNames.SqlServer; - _connectionStrings.SaveConnectionString(connectionString, providerName); + _configManipulator.SaveConnectionString(connectionString, providerName); _databaseFactory.Configure(connectionString, providerName); } @@ -185,7 +185,7 @@ namespace Umbraco.Core.Migrations.Install { var connectionString = GetDatabaseConnectionString(server, databaseName, user, password, databaseProvider, out var providerName); - _connectionStrings.SaveConnectionString(connectionString, providerName); + _configManipulator.SaveConnectionString(connectionString, providerName); _databaseFactory.Configure(connectionString, providerName); } @@ -216,7 +216,7 @@ namespace Umbraco.Core.Migrations.Install public void ConfigureIntegratedSecurityDatabaseConnection(string server, string databaseName) { var connectionString = GetIntegratedSecurityDatabaseConnectionString(server, databaseName); - _connectionStrings.SaveConnectionString(connectionString, Constants.DbProviderNames.SqlServer); + _configManipulator.SaveConnectionString(connectionString, Constants.DbProviderNames.SqlServer); _databaseFactory.Configure(connectionString, Constants.DbProviderNames.SqlServer); } diff --git a/src/Umbraco.Infrastructure/Models/Mapping/ContentTypeMapDefinition.cs b/src/Umbraco.Infrastructure/Models/Mapping/ContentTypeMapDefinition.cs index f7a2d6376b..59f63f4f15 100644 --- a/src/Umbraco.Infrastructure/Models/Mapping/ContentTypeMapDefinition.cs +++ b/src/Umbraco.Infrastructure/Models/Mapping/ContentTypeMapDefinition.cs @@ -191,7 +191,7 @@ namespace Umbraco.Web.Models.Mapping target.Icon = source.Icon; target.IconFilePath = target.IconIsClass ? string.Empty - : $"{_globalSettings.Path.EnsureEndsWith("/")}images/umbraco/{source.Icon}"; + : $"{_ioHelper.BackOfficePath.EnsureEndsWith("/")}images/umbraco/{source.Icon}"; target.Trashed = source.Trashed; target.Id = source.Id; @@ -497,7 +497,7 @@ namespace Umbraco.Web.Models.Mapping target.Icon = source.Icon; target.IconFilePath = target.IconIsClass ? string.Empty - : $"{_globalSettings.Path.EnsureEndsWith("/")}images/umbraco/{source.Icon}"; + : $"{_ioHelper.BackOfficePath.EnsureEndsWith("/")}images/umbraco/{source.Icon}"; target.Id = source.Id; target.IsContainer = source.IsContainer; target.IsElement = source.IsElement; @@ -540,7 +540,7 @@ namespace Umbraco.Web.Models.Mapping target.Icon = source.Icon; target.IconFilePath = target.IconIsClass ? string.Empty - : $"{_globalSettings.Path.EnsureEndsWith("/")}images/umbraco/{source.Icon}"; + : $"{_ioHelper.BackOfficePath.EnsureEndsWith("/")}images/umbraco/{source.Icon}"; target.Id = source.Id; target.IsContainer = source.IsContainer; target.IsElement = source.IsElement; diff --git a/src/Umbraco.Infrastructure/Persistence/UmbracoDatabaseFactory.cs b/src/Umbraco.Infrastructure/Persistence/UmbracoDatabaseFactory.cs index 9474e02d38..a93c8db409 100644 --- a/src/Umbraco.Infrastructure/Persistence/UmbracoDatabaseFactory.cs +++ b/src/Umbraco.Infrastructure/Persistence/UmbracoDatabaseFactory.cs @@ -27,8 +27,9 @@ namespace Umbraco.Core.Persistence // TODO: this class needs not be disposable! internal class UmbracoDatabaseFactory : DisposableObjectSlim, IUmbracoDatabaseFactory { - private readonly Configs _configs; private readonly IDbProviderFactoryCreator _dbProviderFactoryCreator; + private readonly IGlobalSettings _globalSettings; + private readonly IConnectionStrings _connectionStrings; private readonly Lazy _mappers; private readonly ILogger _logger; @@ -71,27 +72,28 @@ namespace Umbraco.Core.Persistence /// Initializes a new instance of the . /// /// Used by core runtime. - public UmbracoDatabaseFactory(ILogger logger, Lazy mappers, Configs configs, IDbProviderFactoryCreator dbProviderFactoryCreator) - : this(Constants.System.UmbracoConnectionName, logger, mappers, configs, dbProviderFactoryCreator) + public UmbracoDatabaseFactory(ILogger logger, IGlobalSettings globalSettings, IConnectionStrings connectionStrings, Lazy mappers,IDbProviderFactoryCreator dbProviderFactoryCreator) + : this(Constants.System.UmbracoConnectionName, globalSettings, connectionStrings, logger, mappers, dbProviderFactoryCreator) { - _configs = configs; + } /// /// Initializes a new instance of the . /// /// Used by the other ctor and in tests. - public UmbracoDatabaseFactory(string connectionStringName, ILogger logger, Lazy mappers, Configs configs, IDbProviderFactoryCreator dbProviderFactoryCreator) + public UmbracoDatabaseFactory(string connectionStringName, IGlobalSettings globalSettings, IConnectionStrings connectionStrings, ILogger logger, Lazy mappers, IDbProviderFactoryCreator dbProviderFactoryCreator) { if (connectionStringName == null) throw new ArgumentNullException(nameof(connectionStringName)); if (string.IsNullOrWhiteSpace(connectionStringName)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(connectionStringName)); + _globalSettings = globalSettings; + _connectionStrings = connectionStrings; _mappers = mappers ?? throw new ArgumentNullException(nameof(mappers)); - _configs = configs; _dbProviderFactoryCreator = dbProviderFactoryCreator ?? throw new ArgumentNullException(nameof(dbProviderFactoryCreator)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - var settings = configs.ConnectionStrings()[connectionStringName]; + var settings = connectionStrings[connectionStringName]; if (settings == null) { @@ -161,7 +163,7 @@ namespace Umbraco.Core.Persistence { // replace NPoco database type by a more efficient one - var setting = _configs.Global().DatabaseFactoryServerVersion; + var setting = _globalSettings.DatabaseFactoryServerVersion; var fromSettings = false; if (setting.IsNullOrWhiteSpace() || !setting.StartsWith("SqlServer.") diff --git a/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs b/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs index 7bb5c77e80..9318b223df 100644 --- a/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs +++ b/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs @@ -1,12 +1,15 @@ using System; +using System.IO; using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Composing.CompositionExtensions; using Umbraco.Core.Configuration; +using Umbraco.Core.Configuration.Grid; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Dashboards; using Umbraco.Core.Hosting; using Umbraco.Core.Dictionary; +using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Manifest; using Umbraco.Core.Migrations; @@ -169,6 +172,10 @@ namespace Umbraco.Core.Runtime // will be injected in controllers when needed to invoke rest endpoints on Our composition.RegisterUnique(); composition.RegisterUnique(); + + // Grid config is not a real config file as we know them + composition.RegisterUnique(); + } } } diff --git a/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs b/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs index 5de4c0d795..6c1a06ab6b 100644 --- a/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs +++ b/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs @@ -27,6 +27,8 @@ namespace Umbraco.Core.Runtime private IFactory _factory; private RuntimeState _state; private readonly IUmbracoBootPermissionChecker _umbracoBootPermissionChecker; + private readonly IGlobalSettings _globalSettings; + private readonly IConnectionStrings _connectionStrings; public CoreRuntime( @@ -56,6 +58,10 @@ namespace Umbraco.Core.Runtime MainDom = mainDom; TypeFinder = typeFinder; + _globalSettings = Configs.Global(); + _connectionStrings = configs.ConnectionStrings(); + + // runtime state // beware! must use '() => _factory.GetInstance()' and NOT '_factory.GetInstance' // as the second one captures the current value (null) and therefore fails @@ -367,9 +373,9 @@ namespace Umbraco.Core.Runtime // is overridden by the web runtime return new AppCaches( - new DeepCloneAppCache(new ObjectCacheAppCache(TypeFinder)), + new DeepCloneAppCache(new ObjectCacheAppCache()), NoAppCache.Instance, - new IsolatedCaches(type => new DeepCloneAppCache(new ObjectCacheAppCache(TypeFinder)))); + new IsolatedCaches(type => new DeepCloneAppCache(new ObjectCacheAppCache()))); } // by default, returns null, meaning that Umbraco should auto-detect the application root path. @@ -382,7 +388,7 @@ namespace Umbraco.Core.Runtime /// /// This is strictly internal, for tests only. protected internal virtual IUmbracoDatabaseFactory GetDatabaseFactory() - => new UmbracoDatabaseFactory(Logger, new Lazy(() => _factory.GetInstance()), Configs, DbProviderFactoryCreator); + => new UmbracoDatabaseFactory(Logger, _globalSettings, _connectionStrings, new Lazy(() => _factory.GetInstance()), DbProviderFactoryCreator); #endregion diff --git a/src/Umbraco.Infrastructure/Runtime/SqlMainDomLock.cs b/src/Umbraco.Infrastructure/Runtime/SqlMainDomLock.cs index 4e1feb221a..6d73934387 100644 --- a/src/Umbraco.Infrastructure/Runtime/SqlMainDomLock.cs +++ b/src/Umbraco.Infrastructure/Runtime/SqlMainDomLock.cs @@ -28,16 +28,18 @@ namespace Umbraco.Core.Runtime private bool _hasError; private object _locker = new object(); - public SqlMainDomLock(ILogger logger, Configs configs, IDbProviderFactoryCreator dbProviderFactoryCreator) + public SqlMainDomLock(ILogger logger, IGlobalSettings globalSettings, IConnectionStrings connectionStrings, IDbProviderFactoryCreator dbProviderFactoryCreator) { // unique id for our appdomain, this is more unique than the appdomain id which is just an INT counter to its safer _lockId = Guid.NewGuid().ToString(); _logger = logger; _dbFactory = new UmbracoDatabaseFactory( Constants.System.UmbracoConnectionName, + globalSettings, + connectionStrings, _logger, new Lazy(() => new MapperCollection(Enumerable.Empty())), - configs, dbProviderFactoryCreator + dbProviderFactoryCreator ); } diff --git a/src/Umbraco.Web/Runtime/WebRuntime.cs b/src/Umbraco.Infrastructure/Runtime/WebRuntime.cs similarity index 73% rename from src/Umbraco.Web/Runtime/WebRuntime.cs rename to src/Umbraco.Infrastructure/Runtime/WebRuntime.cs index b4679715f0..2f45a3e437 100644 --- a/src/Umbraco.Web/Runtime/WebRuntime.cs +++ b/src/Umbraco.Infrastructure/Runtime/WebRuntime.cs @@ -1,6 +1,4 @@ -using System.Web; -using Umbraco.Configuration; -using Umbraco.Core; +using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; @@ -9,9 +7,6 @@ using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Persistence; using Umbraco.Core.Runtime; -using Umbraco.Web.Composing; -using Umbraco.Web.Logging; -using Current = Umbraco.Web.Composing.Current; namespace Umbraco.Web.Runtime { @@ -21,6 +16,8 @@ namespace Umbraco.Web.Runtime /// On top of CoreRuntime, handles all of the web-related runtime aspects of Umbraco. public class WebRuntime : CoreRuntime { + private readonly IRequestCache _requestCache; + /// /// Initializes a new instance of the class. /// @@ -34,27 +31,12 @@ namespace Umbraco.Web.Runtime IBackOfficeInfo backOfficeInfo, IDbProviderFactoryCreator dbProviderFactoryCreator, IMainDom mainDom, - ITypeFinder typeFinder): - base(configs, umbracoVersion, ioHelper, logger, profiler ,new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, dbProviderFactoryCreator, mainDom, typeFinder) + ITypeFinder typeFinder, + IRequestCache requestCache, + IUmbracoBootPermissionChecker umbracoBootPermissionChecker): + base(configs, umbracoVersion, ioHelper, logger, profiler ,umbracoBootPermissionChecker, hostingEnvironment, backOfficeInfo, dbProviderFactoryCreator, mainDom, typeFinder) { - - 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; + _requestCache = requestCache; } /// @@ -75,7 +57,7 @@ namespace Umbraco.Web.Runtime NetworkHelper.MachineName); Logger.Debug("Runtime: {Runtime}", GetType().FullName); - var factory = Current.Factory = base.Boot(register); + 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 @@ -94,13 +76,13 @@ namespace Umbraco.Web.Runtime 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) - new DeepCloneAppCache(new ObjectCacheAppCache(TypeFinder)), + new DeepCloneAppCache(new ObjectCacheAppCache()), // we need request based cache when running in web-based context - new HttpRequestAppCache(() => HttpContext.Current?.Items, TypeFinder), + _requestCache, new IsolatedCaches(type => // we need to have the dep clone runtime cache provider to ensure // all entities are cached properly (cloned in and cloned out) - new DeepCloneAppCache(new ObjectCacheAppCache(TypeFinder)))); + new DeepCloneAppCache(new ObjectCacheAppCache()))); #endregion } diff --git a/src/Umbraco.Infrastructure/Scheduling/HealthCheckNotifier.cs b/src/Umbraco.Infrastructure/Scheduling/HealthCheckNotifier.cs index 00bbba8bb8..04c1571b3b 100644 --- a/src/Umbraco.Infrastructure/Scheduling/HealthCheckNotifier.cs +++ b/src/Umbraco.Infrastructure/Scheduling/HealthCheckNotifier.cs @@ -15,18 +15,18 @@ namespace Umbraco.Web.Scheduling private readonly HealthCheckCollection _healthChecks; private readonly HealthCheckNotificationMethodCollection _notifications; private readonly IProfilingLogger _logger; - private readonly IHealthChecks _healthChecksConfig; + private readonly IHealthChecksSettings _healthChecksSettingsConfig; public HealthCheckNotifier(IBackgroundTaskRunner runner, int delayMilliseconds, int periodMilliseconds, HealthCheckCollection healthChecks, HealthCheckNotificationMethodCollection notifications, - IRuntimeState runtimeState, IProfilingLogger logger, IHealthChecks healthChecksConfig) + IRuntimeState runtimeState, IProfilingLogger logger, IHealthChecksSettings healthChecksSettingsConfig) : base(runner, delayMilliseconds, periodMilliseconds) { _healthChecks = healthChecks; _notifications = notifications; _runtimeState = runtimeState; _logger = logger; - _healthChecksConfig = healthChecksConfig; + _healthChecksSettingsConfig = healthChecksSettingsConfig; } public override async Task PerformRunAsync(CancellationToken token) @@ -53,7 +53,7 @@ namespace Umbraco.Web.Scheduling using (_logger.DebugDuration("Health checks executing", "Health checks complete")) { - var healthCheckConfig = _healthChecksConfig; + var healthCheckConfig = _healthChecksSettingsConfig; // Don't notify for any checks that are disabled, nor for any disabled // just for notifications diff --git a/src/Umbraco.Infrastructure/Scheduling/SchedulerComponent.cs b/src/Umbraco.Infrastructure/Scheduling/SchedulerComponent.cs index 1d4a654830..c8ff67579a 100644 --- a/src/Umbraco.Infrastructure/Scheduling/SchedulerComponent.cs +++ b/src/Umbraco.Infrastructure/Scheduling/SchedulerComponent.cs @@ -34,7 +34,7 @@ namespace Umbraco.Web.Scheduling private readonly HealthCheckCollection _healthChecks; private readonly HealthCheckNotificationMethodCollection _notifications; private readonly IUmbracoContextFactory _umbracoContextFactory; - private readonly IHealthChecks _healthChecksConfig; + private readonly IHealthChecksSettings _healthChecksSettingsConfig; private readonly IIOHelper _ioHelper; private readonly IServerMessenger _serverMessenger; private readonly IRequestAccessor _requestAccessor; @@ -56,7 +56,7 @@ namespace Umbraco.Web.Scheduling IContentService contentService, IAuditService auditService, HealthCheckCollection healthChecks, HealthCheckNotificationMethodCollection notifications, IScopeProvider scopeProvider, IUmbracoContextFactory umbracoContextFactory, IProfilingLogger logger, - IHostingEnvironment hostingEnvironment, IHealthChecks healthChecksConfig, + IHostingEnvironment hostingEnvironment, IHealthChecksSettings healthChecksSettingsConfig, IIOHelper ioHelper, IServerMessenger serverMessenger, IRequestAccessor requestAccessor, ILoggingSettings loggingSettings, IKeepAliveSettings keepAliveSettings) { @@ -70,7 +70,7 @@ namespace Umbraco.Web.Scheduling _healthChecks = healthChecks; _notifications = notifications; - _healthChecksConfig = healthChecksConfig ?? throw new ArgumentNullException(nameof(healthChecksConfig)); + _healthChecksSettingsConfig = healthChecksSettingsConfig ?? throw new ArgumentNullException(nameof(healthChecksSettingsConfig)); _ioHelper = ioHelper; _serverMessenger = serverMessenger; _requestAccessor = requestAccessor; @@ -126,7 +126,7 @@ namespace Umbraco.Web.Scheduling tasks.Add(RegisterLogScrubber(_loggingSettings)); tasks.Add(RegisterTempFileCleanup()); - var healthCheckConfig = _healthChecksConfig; + var healthCheckConfig = _healthChecksSettingsConfig; if (healthCheckConfig.NotificationSettings.Enabled) tasks.Add(RegisterHealthCheckNotifier(healthCheckConfig, _healthChecks, _notifications, _logger)); @@ -152,28 +152,28 @@ namespace Umbraco.Web.Scheduling return task; } - private IBackgroundTask RegisterHealthCheckNotifier(IHealthChecks healthCheckConfig, + private IBackgroundTask RegisterHealthCheckNotifier(IHealthChecksSettings healthCheckSettingsConfig, HealthCheckCollection healthChecks, HealthCheckNotificationMethodCollection notifications, IProfilingLogger logger) { // If first run time not set, start with just small delay after application start int delayInMilliseconds; - if (string.IsNullOrEmpty(healthCheckConfig.NotificationSettings.FirstRunTime)) + if (string.IsNullOrEmpty(healthCheckSettingsConfig.NotificationSettings.FirstRunTime)) { delayInMilliseconds = DefaultDelayMilliseconds; } else { // Otherwise start at scheduled time - delayInMilliseconds = DateTime.Now.PeriodicMinutesFrom(healthCheckConfig.NotificationSettings.FirstRunTime) * 60 * 1000; + delayInMilliseconds = DateTime.Now.PeriodicMinutesFrom(healthCheckSettingsConfig.NotificationSettings.FirstRunTime) * 60 * 1000; if (delayInMilliseconds < DefaultDelayMilliseconds) { delayInMilliseconds = DefaultDelayMilliseconds; } } - var periodInMilliseconds = healthCheckConfig.NotificationSettings.PeriodInHours * 60 * 60 * 1000; - var task = new HealthCheckNotifier(_healthCheckRunner, delayInMilliseconds, periodInMilliseconds, healthChecks, notifications, _runtime, logger, _healthChecksConfig); + var periodInMilliseconds = healthCheckSettingsConfig.NotificationSettings.PeriodInHours * 60 * 60 * 1000; + var task = new HealthCheckNotifier(_healthCheckRunner, delayInMilliseconds, periodInMilliseconds, healthChecks, notifications, _runtime, logger, _healthChecksSettingsConfig); _healthCheckRunner.TryAdd(task); return task; } diff --git a/src/Umbraco.Infrastructure/Scoping/Scope.cs b/src/Umbraco.Infrastructure/Scoping/Scope.cs index 8f7a0bf958..3b17ae876d 100644 --- a/src/Umbraco.Infrastructure/Scoping/Scope.cs +++ b/src/Umbraco.Infrastructure/Scoping/Scope.cs @@ -17,7 +17,7 @@ namespace Umbraco.Core.Scoping internal class Scope : IScope { private readonly ScopeProvider _scopeProvider; - private readonly ICoreDebug _coreDebug; + private readonly ICoreDebugSettings _coreDebugSettings; private readonly IMediaFileSystem _mediaFileSystem; private readonly ILogger _logger; private readonly ITypeFinder _typeFinder; @@ -39,7 +39,7 @@ namespace Umbraco.Core.Scoping // initializes a new scope private Scope(ScopeProvider scopeProvider, - ICoreDebug coreDebug, + ICoreDebugSettings coreDebugSettings, IMediaFileSystem mediaFileSystem, ILogger logger, ITypeFinder typeFinder, FileSystems fileSystems, Scope parent, IScopeContext scopeContext, bool detachable, IsolationLevel isolationLevel = IsolationLevel.Unspecified, @@ -50,7 +50,7 @@ namespace Umbraco.Core.Scoping bool autoComplete = false) { _scopeProvider = scopeProvider; - _coreDebug = coreDebug; + _coreDebugSettings = coreDebugSettings; _mediaFileSystem = mediaFileSystem; _logger = logger; _typeFinder = typeFinder; @@ -118,7 +118,7 @@ namespace Umbraco.Core.Scoping // initializes a new scope public Scope(ScopeProvider scopeProvider, - ICoreDebug coreDebug, + ICoreDebugSettings coreDebugSettings, IMediaFileSystem mediaFileSystem, ILogger logger, ITypeFinder typeFinder, FileSystems fileSystems, bool detachable, IScopeContext scopeContext, IsolationLevel isolationLevel = IsolationLevel.Unspecified, @@ -127,12 +127,12 @@ namespace Umbraco.Core.Scoping bool? scopeFileSystems = null, bool callContext = false, bool autoComplete = false) - : this(scopeProvider, coreDebug, mediaFileSystem, logger, typeFinder, fileSystems, null, scopeContext, detachable, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete) + : this(scopeProvider, coreDebugSettings, mediaFileSystem, logger, typeFinder, fileSystems, null, scopeContext, detachable, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete) { } // initializes a new scope in a nested scopes chain, with its parent public Scope(ScopeProvider scopeProvider, - ICoreDebug coreDebug, + ICoreDebugSettings coreDebugSettings, IMediaFileSystem mediaFileSystem, ILogger logger, ITypeFinder typeFinder, FileSystems fileSystems, Scope parent, IsolationLevel isolationLevel = IsolationLevel.Unspecified, @@ -141,7 +141,7 @@ namespace Umbraco.Core.Scoping bool? scopeFileSystems = null, bool callContext = false, bool autoComplete = false) - : this(scopeProvider, coreDebug, mediaFileSystem, logger, typeFinder, fileSystems, parent, null, false, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete) + : this(scopeProvider, coreDebugSettings, mediaFileSystem, logger, typeFinder, fileSystems, parent, null, false, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete) { } public Guid InstanceId { get; } = Guid.NewGuid(); @@ -188,7 +188,7 @@ namespace Umbraco.Core.Scoping if (ParentScope != null) return ParentScope.IsolatedCaches; return _isolatedCaches ?? (_isolatedCaches - = new IsolatedCaches(type => new DeepCloneAppCache(new ObjectCacheAppCache(_typeFinder)))); + = new IsolatedCaches(type => new DeepCloneAppCache(new ObjectCacheAppCache()))); } } @@ -494,9 +494,9 @@ namespace Umbraco.Core.Scoping private static bool? _logUncompletedScopes; // caching config - // true if Umbraco.CoreDebug.LogUncompletedScope appSetting is set to "true" + // true if Umbraco.CoreDebugSettings.LogUncompletedScope appSetting is set to "true" private bool LogUncompletedScopes => (_logUncompletedScopes - ?? (_logUncompletedScopes = _coreDebug.LogUncompletedScopes)).Value; + ?? (_logUncompletedScopes = _coreDebugSettings.LogUncompletedScopes)).Value; /// public void ReadLock(params int[] lockIds) => Database.SqlContext.SqlSyntax.ReadLock(Database, lockIds); diff --git a/src/Umbraco.Infrastructure/Scoping/ScopeProvider.cs b/src/Umbraco.Infrastructure/Scoping/ScopeProvider.cs index 0dba73b55b..610f308b96 100644 --- a/src/Umbraco.Infrastructure/Scoping/ScopeProvider.cs +++ b/src/Umbraco.Infrastructure/Scoping/ScopeProvider.cs @@ -26,14 +26,14 @@ namespace Umbraco.Core.Scoping private readonly ITypeFinder _typeFinder; private readonly IRequestCache _requestCache; private readonly FileSystems _fileSystems; - private readonly ICoreDebug _coreDebug; + private readonly ICoreDebugSettings _coreDebugSettings; private readonly IMediaFileSystem _mediaFileSystem; - public ScopeProvider(IUmbracoDatabaseFactory databaseFactory, FileSystems fileSystems, ICoreDebug coreDebug, IMediaFileSystem mediaFileSystem, ILogger logger, ITypeFinder typeFinder, IRequestCache requestCache) + public ScopeProvider(IUmbracoDatabaseFactory databaseFactory, FileSystems fileSystems, ICoreDebugSettings coreDebugSettings, IMediaFileSystem mediaFileSystem, ILogger logger, ITypeFinder typeFinder, IRequestCache requestCache) { DatabaseFactory = databaseFactory; _fileSystems = fileSystems; - _coreDebug = coreDebug; + _coreDebugSettings = coreDebugSettings; _mediaFileSystem = mediaFileSystem; _logger = logger; _typeFinder = typeFinder; @@ -255,7 +255,7 @@ namespace Umbraco.Core.Scoping IEventDispatcher eventDispatcher = null, bool? scopeFileSystems = null) { - return new Scope(this, _coreDebug, _mediaFileSystem, _logger, _typeFinder, _fileSystems, true, null, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems); + return new Scope(this, _coreDebugSettings, _mediaFileSystem, _logger, _typeFinder, _fileSystems, true, null, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems); } /// @@ -311,13 +311,13 @@ namespace Umbraco.Core.Scoping { var ambientContext = AmbientContext; var newContext = ambientContext == null ? new ScopeContext() : null; - var scope = new Scope(this, _coreDebug, _mediaFileSystem, _logger, _typeFinder, _fileSystems, false, newContext, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete); + var scope = new Scope(this, _coreDebugSettings, _mediaFileSystem, _logger, _typeFinder, _fileSystems, false, newContext, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete); // assign only if scope creation did not throw! SetAmbient(scope, newContext ?? ambientContext); return scope; } - var nested = new Scope(this, _coreDebug, _mediaFileSystem, _logger, _typeFinder, _fileSystems, ambientScope, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete); + var nested = new Scope(this, _coreDebugSettings, _mediaFileSystem, _logger, _typeFinder, _fileSystems, ambientScope, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete); SetAmbient(nested, AmbientContext); return nested; } diff --git a/src/Umbraco.Infrastructure/Trees/TreeNode.cs b/src/Umbraco.Infrastructure/Trees/TreeNode.cs index cc130b1b97..7d3c657207 100644 --- a/src/Umbraco.Infrastructure/Trees/TreeNode.cs +++ b/src/Umbraco.Infrastructure/Trees/TreeNode.cs @@ -112,7 +112,7 @@ namespace Umbraco.Web.Models.Trees return Current.IOHelper.ResolveUrl("~" + Icon.TrimStart('~')); //legacy icon path - return string.Format("{0}images/umbraco/{1}", Current.Configs.Global().Path.EnsureEndsWith("/"), Icon); + return string.Format("{0}images/umbraco/{1}", Current.IOHelper.BackOfficePath.EnsureEndsWith("/"), Icon); } } diff --git a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj index a5fea12a6b..3d99c4918f 100644 --- a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj +++ b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj @@ -14,6 +14,8 @@ + + diff --git a/src/Umbraco.ModelsBuilder.Embedded/Building/ModelsGenerator.cs b/src/Umbraco.ModelsBuilder.Embedded/Building/ModelsGenerator.cs index 192f049930..648a2e76fa 100644 --- a/src/Umbraco.ModelsBuilder.Embedded/Building/ModelsGenerator.cs +++ b/src/Umbraco.ModelsBuilder.Embedded/Building/ModelsGenerator.cs @@ -1,6 +1,7 @@ using System.IO; using System.Text; using Umbraco.Core.Configuration; +using Umbraco.Core.IO; namespace Umbraco.ModelsBuilder.Embedded.Building { @@ -9,20 +10,23 @@ namespace Umbraco.ModelsBuilder.Embedded.Building private readonly UmbracoServices _umbracoService; private readonly IModelsBuilderConfig _config; private readonly OutOfDateModelsStatus _outOfDateModels; + private readonly IIOHelper _ioHelper; - public ModelsGenerator(UmbracoServices umbracoService, IModelsBuilderConfig config, OutOfDateModelsStatus outOfDateModels) + public ModelsGenerator(UmbracoServices umbracoService, IModelsBuilderConfig config, OutOfDateModelsStatus outOfDateModels, IIOHelper ioHelper) { _umbracoService = umbracoService; _config = config; _outOfDateModels = outOfDateModels; + _ioHelper = ioHelper; } internal void GenerateModels() { - if (!Directory.Exists(_config.ModelsDirectory)) - Directory.CreateDirectory(_config.ModelsDirectory); + var modelsDirectory = _config.ModelsDirectoryAbsolute(_ioHelper); + if (!Directory.Exists(modelsDirectory)) + Directory.CreateDirectory(modelsDirectory); - foreach (var file in Directory.GetFiles(_config.ModelsDirectory, "*.generated.cs")) + foreach (var file in Directory.GetFiles(modelsDirectory, "*.generated.cs")) File.Delete(file); var typeModels = _umbracoService.GetAllTypes(); @@ -33,7 +37,7 @@ namespace Umbraco.ModelsBuilder.Embedded.Building { var sb = new StringBuilder(); builder.Generate(sb, typeModel); - var filename = Path.Combine(_config.ModelsDirectory, typeModel.ClrName + ".generated.cs"); + var filename = Path.Combine(modelsDirectory, typeModel.ClrName + ".generated.cs"); File.WriteAllText(filename, sb.ToString()); } diff --git a/src/Umbraco.ModelsBuilder.Embedded/Compose/ModelsBuilderComposer.cs b/src/Umbraco.ModelsBuilder.Embedded/Compose/ModelsBuilderComposer.cs index 2914fe1b12..e582301740 100644 --- a/src/Umbraco.ModelsBuilder.Embedded/Compose/ModelsBuilderComposer.cs +++ b/src/Umbraco.ModelsBuilder.Embedded/Compose/ModelsBuilderComposer.cs @@ -31,7 +31,7 @@ namespace Umbraco.ModelsBuilder.Embedded.Compose composition.RegisterUnique(); composition.RegisterUnique(); composition.RegisterUnique(); - + if (composition.Configs.ModelsBuilder().ModelsMode == ModelsMode.PureLive) ComposeForLiveModels(composition); else if (composition.Configs.ModelsBuilder().EnableFactory) diff --git a/src/Umbraco.ModelsBuilder.Embedded/ModelsGenerationError.cs b/src/Umbraco.ModelsBuilder.Embedded/ModelsGenerationError.cs index 5b498fd5f3..f8f6e8c7bc 100644 --- a/src/Umbraco.ModelsBuilder.Embedded/ModelsGenerationError.cs +++ b/src/Umbraco.ModelsBuilder.Embedded/ModelsGenerationError.cs @@ -2,16 +2,19 @@ using System.IO; using System.Text; using Umbraco.Core.Configuration; +using Umbraco.Core.IO; namespace Umbraco.ModelsBuilder.Embedded { public sealed class ModelsGenerationError { private readonly IModelsBuilderConfig _config; + private readonly IIOHelper _ioHelper; - public ModelsGenerationError(IModelsBuilderConfig config) + public ModelsGenerationError(IModelsBuilderConfig config, IIOHelper ioHelper) { _config = config; + _ioHelper = ioHelper; } public void Clear() @@ -56,7 +59,7 @@ namespace Umbraco.ModelsBuilder.Embedded private string GetErrFile() { - var modelsDirectory = _config.ModelsDirectory; + var modelsDirectory = _config.ModelsDirectoryAbsolute(_ioHelper); if (!Directory.Exists(modelsDirectory)) return null; diff --git a/src/Umbraco.ModelsBuilder.Embedded/OutOfDateModelsStatus.cs b/src/Umbraco.ModelsBuilder.Embedded/OutOfDateModelsStatus.cs index 0e93030438..b8105eeef2 100644 --- a/src/Umbraco.ModelsBuilder.Embedded/OutOfDateModelsStatus.cs +++ b/src/Umbraco.ModelsBuilder.Embedded/OutOfDateModelsStatus.cs @@ -1,5 +1,6 @@ using System.IO; using Umbraco.Core.Configuration; +using Umbraco.Core.IO; using Umbraco.Web.Cache; namespace Umbraco.ModelsBuilder.Embedded @@ -7,10 +8,12 @@ namespace Umbraco.ModelsBuilder.Embedded public sealed class OutOfDateModelsStatus { private readonly IModelsBuilderConfig _config; + private readonly IIOHelper _ioHelper; - public OutOfDateModelsStatus(IModelsBuilderConfig config) + public OutOfDateModelsStatus(IModelsBuilderConfig config, IIOHelper ioHelper) { _config = config; + _ioHelper = ioHelper; } internal void Install() @@ -25,7 +28,7 @@ namespace Umbraco.ModelsBuilder.Embedded private string GetFlagPath() { - var modelsDirectory = _config.ModelsDirectory; + var modelsDirectory = _config.ModelsDirectoryAbsolute(_ioHelper); if (!Directory.Exists(modelsDirectory)) Directory.CreateDirectory(modelsDirectory); return Path.Combine(modelsDirectory, "ood.flag"); diff --git a/src/Umbraco.ModelsBuilder.Embedded/PureLiveModelFactory.cs b/src/Umbraco.ModelsBuilder.Embedded/PureLiveModelFactory.cs index bef2fa8414..5db79de977 100644 --- a/src/Umbraco.ModelsBuilder.Embedded/PureLiveModelFactory.cs +++ b/src/Umbraco.ModelsBuilder.Embedded/PureLiveModelFactory.cs @@ -14,6 +14,7 @@ using System.Web.WebPages.Razor; using Umbraco.Core.Configuration; using Umbraco.Core; using Umbraco.Core.Hosting; +using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models.PublishedContent; using Umbraco.ModelsBuilder.Embedded.Building; @@ -42,15 +43,22 @@ namespace Umbraco.ModelsBuilder.Embedded private readonly IModelsBuilderConfig _config; private readonly IHostingEnvironment _hostingEnvironment; + private readonly IIOHelper _ioHelper; private readonly ModelsGenerationError _errors; - public PureLiveModelFactory(Lazy umbracoServices, IProfilingLogger logger, IModelsBuilderConfig config, IHostingEnvironment hostingEnvironment) + public PureLiveModelFactory( + Lazy umbracoServices, + IProfilingLogger logger, + IModelsBuilderConfig config, + IHostingEnvironment hostingEnvironment, + IIOHelper ioHelper) { _umbracoServices = umbracoServices; _logger = logger; _config = config; _hostingEnvironment = hostingEnvironment; - _errors = new ModelsGenerationError(config); + _ioHelper = ioHelper; + _errors = new ModelsGenerationError(config, ioHelper); _ver = 1; // zero is for when we had no version _skipver = -1; // nothing to skip @@ -58,7 +66,7 @@ namespace Umbraco.ModelsBuilder.Embedded if (!_hostingEnvironment.IsHosted) return; - var modelsDirectory = _config.ModelsDirectory; + var modelsDirectory = _config.ModelsDirectoryAbsolute(_ioHelper); if (!Directory.Exists(modelsDirectory)) Directory.CreateDirectory(modelsDirectory); @@ -208,7 +216,7 @@ namespace Umbraco.ModelsBuilder.Embedded _hasModels = false; _pendingRebuild = true; - var modelsDirectory = _config.ModelsDirectory; + var modelsDirectory = _config.ModelsDirectoryAbsolute(_ioHelper); if (!Directory.Exists(modelsDirectory)) Directory.CreateDirectory(modelsDirectory); @@ -330,7 +338,7 @@ namespace Umbraco.ModelsBuilder.Embedded private Assembly GetModelsAssembly(bool forceRebuild) { - var modelsDirectory = _config.ModelsDirectory; + var modelsDirectory = _config.ModelsDirectoryAbsolute(_ioHelper); if (!Directory.Exists(modelsDirectory)) Directory.CreateDirectory(modelsDirectory); @@ -552,7 +560,7 @@ namespace Umbraco.ModelsBuilder.Embedded private string GenerateModelsCode(IList typeModels) { - var modelsDirectory = _config.ModelsDirectory; + var modelsDirectory = _config.ModelsDirectoryAbsolute(_ioHelper); if (!Directory.Exists(modelsDirectory)) Directory.CreateDirectory(modelsDirectory); diff --git a/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotService.cs b/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotService.cs index 74295b7182..09f486b5d9 100644 --- a/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotService.cs +++ b/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotService.cs @@ -49,7 +49,6 @@ namespace Umbraco.Web.PublishedCache.NuCache private readonly IPublishedModelFactory _publishedModelFactory; private readonly IDefaultCultureAccessor _defaultCultureAccessor; private readonly UrlSegmentProviderCollection _urlSegmentProviders; - private readonly ITypeFinder _typeFinder; private readonly IHostingEnvironment _hostingEnvironment; private readonly IShortStringHelper _shortStringHelper; private readonly IIOHelper _ioHelper; @@ -88,7 +87,6 @@ namespace Umbraco.Web.PublishedCache.NuCache IEntityXmlSerializer entitySerializer, IPublishedModelFactory publishedModelFactory, UrlSegmentProviderCollection urlSegmentProviders, - ITypeFinder typeFinder, IHostingEnvironment hostingEnvironment, IShortStringHelper shortStringHelper, IIOHelper ioHelper, @@ -109,7 +107,6 @@ namespace Umbraco.Web.PublishedCache.NuCache _defaultCultureAccessor = defaultCultureAccessor; _globalSettings = globalSettings; _urlSegmentProviders = urlSegmentProviders; - _typeFinder = typeFinder; _hostingEnvironment = hostingEnvironment; _shortStringHelper = shortStringHelper; _ioHelper = ioHelper; @@ -1207,7 +1204,7 @@ namespace Umbraco.Web.PublishedCache.NuCache _contentGen = contentSnap.Gen; _mediaGen = mediaSnap.Gen; _domainGen = domainSnap.Gen; - elementsCache = _elementsCache = new FastDictionaryAppCache(_typeFinder); + elementsCache = _elementsCache = new FastDictionaryAppCache(); } } diff --git a/src/Umbraco.Tests.Common/SettingsForTests.cs b/src/Umbraco.Tests.Common/SettingsForTests.cs index 3f39881ff8..f7427009ba 100644 --- a/src/Umbraco.Tests.Common/SettingsForTests.cs +++ b/src/Umbraco.Tests.Common/SettingsForTests.cs @@ -1,6 +1,8 @@ using Moq; +using Semver; using Umbraco.Core; using Umbraco.Core.Configuration; +using Umbraco.Core.Configuration.Legacy; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; using Umbraco.Core.Models.PublishedContent; @@ -13,14 +15,16 @@ namespace Umbraco.Tests.Common { } - public IGlobalSettings GenerateMockGlobalSettings(IUmbracoVersion umbVersion, IIOHelper ioHelper) + public IGlobalSettings GenerateMockGlobalSettings(IUmbracoVersion umbVersion = null) { + var semanticVersion = umbVersion?.SemanticVersion ?? new SemVersion(9); + var config = Mock.Of( settings => - settings.ConfigurationStatus == umbVersion.SemanticVersion.ToSemanticString() && + settings.ConfigurationStatus == semanticVersion.ToSemanticString() && settings.UseHttps == false && settings.HideTopLevelNodeFromPath == false && - settings.Path == ioHelper.ResolveUrl("~/umbraco") && + settings.Path == "~/umbraco" && settings.TimeOutInMinutes == 20 && settings.DefaultUILanguage == "en" && settings.ReservedPaths == (GlobalSettings.StaticReservedPaths + "~/umbraco") && @@ -102,12 +106,12 @@ namespace Umbraco.Tests.Common private IGlobalSettings _defaultGlobalSettings; private IHostingSettings _defaultHostingSettings; - - public IGlobalSettings GetDefaultGlobalSettings(IUmbracoVersion umbVersion, IIOHelper ioHelper) + + public IGlobalSettings GetDefaultGlobalSettings(IUmbracoVersion umbVersion) { if (_defaultGlobalSettings == null) { - _defaultGlobalSettings = GenerateMockGlobalSettings(umbVersion, ioHelper); + _defaultGlobalSettings = GenerateMockGlobalSettings(umbVersion); } return _defaultGlobalSettings; } diff --git a/src/Umbraco.Tests.Common/TestHelperBase.cs b/src/Umbraco.Tests.Common/TestHelperBase.cs index 7246e9487e..ef437d45a6 100644 --- a/src/Umbraco.Tests.Common/TestHelperBase.cs +++ b/src/Umbraco.Tests.Common/TestHelperBase.cs @@ -51,7 +51,7 @@ namespace Umbraco.Tests.Common public Configs GetConfigs() { if (_configs == null) - _configs = GetConfigsFactory().Create(IOHelper, Mock.Of()); + _configs = GetConfigsFactory().Create(); return _configs; } public IRuntimeState GetRuntimeState() @@ -92,14 +92,14 @@ namespace Umbraco.Tests.Common public abstract IDbProviderFactoryCreator DbProviderFactoryCreator { get; } public abstract IBulkSqlInsertProvider BulkSqlInsertProvider { get; } public abstract IMarchal Marchal { get; } - public ICoreDebug CoreDebug { get; } = new CoreDebug(); + public ICoreDebugSettings CoreDebugSettings { get; } = new CoreDebugSettings(); public IIOHelper IOHelper { get { if (_ioHelper == null) - _ioHelper = new IOHelper(GetHostingEnvironment()); + _ioHelper = new IOHelper(GetHostingEnvironment(), SettingsForTests.GenerateMockGlobalSettings()); return _ioHelper; } } diff --git a/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs b/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs index 7fe18843f7..5254892b23 100644 --- a/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs +++ b/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs @@ -69,7 +69,7 @@ namespace Umbraco.Tests.Integration.Implementations public override IBackOfficeInfo GetBackOfficeInfo() { if (_backOfficeInfo == null) - _backOfficeInfo = new AspNetCoreBackOfficeInfo(SettingsForTests.GetDefaultGlobalSettings(GetUmbracoVersion(), IOHelper)); + _backOfficeInfo = new AspNetCoreBackOfficeInfo(SettingsForTests.GetDefaultGlobalSettings(GetUmbracoVersion())); return _backOfficeInfo; } diff --git a/src/Umbraco.Tests/Cache/AppCacheTests.cs b/src/Umbraco.Tests/Cache/AppCacheTests.cs index 3a86feb90a..bb283064c7 100644 --- a/src/Umbraco.Tests/Cache/AppCacheTests.cs +++ b/src/Umbraco.Tests/Cache/AppCacheTests.cs @@ -229,7 +229,7 @@ namespace Umbraco.Tests.Cache Assert.AreEqual(4, GetTotalItemCount); //Provider.ClearCacheObjectTypes("umbraco.MacroCacheContent"); - AppCache.ClearOfType(typeof(MacroCacheContent).ToString()); + AppCache.ClearOfType(); Assert.AreEqual(1, GetTotalItemCount); } diff --git a/src/Umbraco.Tests/Cache/DeepCloneAppCacheTests.cs b/src/Umbraco.Tests/Cache/DeepCloneAppCacheTests.cs index e4844cc6be..63e481e9a5 100644 --- a/src/Umbraco.Tests/Cache/DeepCloneAppCacheTests.cs +++ b/src/Umbraco.Tests/Cache/DeepCloneAppCacheTests.cs @@ -29,8 +29,7 @@ namespace Umbraco.Tests.Cache public override void Setup() { base.Setup(); - var typeFinder = TestHelper.GetTypeFinder(); - _memberCache = new ObjectCacheAppCache(typeFinder); + _memberCache = new ObjectCacheAppCache(); _provider = new DeepCloneAppCache(_memberCache); } diff --git a/src/Umbraco.Tests/Cache/HttpRequestAppCacheTests.cs b/src/Umbraco.Tests/Cache/HttpRequestAppCacheTests.cs index dbda6fb429..2eea382bd3 100644 --- a/src/Umbraco.Tests/Cache/HttpRequestAppCacheTests.cs +++ b/src/Umbraco.Tests/Cache/HttpRequestAppCacheTests.cs @@ -16,9 +16,8 @@ namespace Umbraco.Tests.Cache public override void Setup() { base.Setup(); - var typeFinder = TestHelper.GetTypeFinder(); _ctx = new FakeHttpContextFactory("http://localhost/test"); - _appCache = new HttpRequestAppCache(() => _ctx.HttpContext.Items, typeFinder); + _appCache = new HttpRequestAppCache(() => _ctx.HttpContext.Items); } internal override IAppCache AppCache diff --git a/src/Umbraco.Tests/Cache/ObjectAppCacheTests.cs b/src/Umbraco.Tests/Cache/ObjectAppCacheTests.cs index 7957026ad8..3172738bf7 100644 --- a/src/Umbraco.Tests/Cache/ObjectAppCacheTests.cs +++ b/src/Umbraco.Tests/Cache/ObjectAppCacheTests.cs @@ -18,8 +18,7 @@ namespace Umbraco.Tests.Cache public override void Setup() { base.Setup(); - var typeFinder = TestHelper.GetTypeFinder(); - _provider = new ObjectCacheAppCache(typeFinder); + _provider = new ObjectCacheAppCache(); } internal override IAppCache AppCache diff --git a/src/Umbraco.Tests/Components/ComponentTests.cs b/src/Umbraco.Tests/Components/ComponentTests.cs index 7dc6025b0a..cb8da6e23d 100644 --- a/src/Umbraco.Tests/Components/ComponentTests.cs +++ b/src/Umbraco.Tests/Components/ComponentTests.cs @@ -33,9 +33,9 @@ namespace Umbraco.Tests.Components var logger = Mock.Of(); var typeFinder = TestHelper.GetTypeFinder(); - var f = new UmbracoDatabaseFactory(logger, new Lazy(() => new MapperCollection(Enumerable.Empty())), TestHelper.GetConfigs(), TestHelper.DbProviderFactoryCreator); + var f = new UmbracoDatabaseFactory(logger, SettingsForTests.GetDefaultGlobalSettings(), Mock.Of(), new Lazy(() => new MapperCollection(Enumerable.Empty())), TestHelper.DbProviderFactoryCreator); var fs = new FileSystems(mock.Object, logger, TestHelper.IOHelper, SettingsForTests.GenerateMockGlobalSettings()); - var coreDebug = Mock.Of(); + var coreDebug = Mock.Of(); var mediaFileSystem = Mock.Of(); var p = new ScopeProvider(f, fs, coreDebug, mediaFileSystem, logger, typeFinder, NoAppCache.Instance); diff --git a/src/Umbraco.Tests/Configurations/GlobalSettingsTests.cs b/src/Umbraco.Tests/Configurations/GlobalSettingsTests.cs index 37e2636bf4..b171199e25 100644 --- a/src/Umbraco.Tests/Configurations/GlobalSettingsTests.cs +++ b/src/Umbraco.Tests/Configurations/GlobalSettingsTests.cs @@ -1,6 +1,7 @@ using Moq; using NUnit.Framework; using Umbraco.Core.Configuration; +using Umbraco.Core.IO; using Umbraco.Tests.TestHelpers; namespace Umbraco.Tests.Configurations @@ -30,13 +31,15 @@ namespace Umbraco.Tests.Configurations [TestCase("~/some-wacky/nestedPath", "/MyVirtualDir/NestedVDir/", "some-wacky-nestedpath")] public void Umbraco_Mvc_Area(string path, string rootPath, string outcome) { + var globalSettings = SettingsForTests.GenerateMockGlobalSettings(); + var ioHelper = new IOHelper(TestHelper.GetHostingEnvironment(), globalSettings); var globalSettingsMock = Mock.Get(globalSettings); - globalSettingsMock.Setup(x => x.Path).Returns(() => TestHelper.IOHelper.ResolveUrl(path)); + globalSettingsMock.Setup(x => x.Path).Returns(() => path); - TestHelper.IOHelper.Root = rootPath; - Assert.AreEqual(outcome, globalSettings.GetUmbracoMvcAreaNoCache(IOHelper)); + ioHelper.Root = rootPath; + Assert.AreEqual(outcome, ioHelper.GetUmbracoMvcAreaNoCache()); } diff --git a/src/Umbraco.Tests/Configurations/UmbracoSettings/SecurityElementTests.cs b/src/Umbraco.Tests/Configurations/UmbracoSettings/SecurityElementTests.cs index 93f37a1e35..2eccd50295 100644 --- a/src/Umbraco.Tests/Configurations/UmbracoSettings/SecurityElementTests.cs +++ b/src/Umbraco.Tests/Configurations/UmbracoSettings/SecurityElementTests.cs @@ -66,12 +66,6 @@ namespace Umbraco.Tests.Configurations.UmbracoSettings Assert.IsTrue(UserPasswordConfiguration.RequireUppercase == false); } - [Test] - public void UserPasswordConfiguration_UseLegacyEncoding() - { - Assert.IsTrue(UserPasswordConfiguration.UseLegacyEncoding == false); - } - [Test] public void UserPasswordConfiguration_HashAlgorithmType() { @@ -114,12 +108,6 @@ namespace Umbraco.Tests.Configurations.UmbracoSettings Assert.IsTrue(MemberPasswordConfiguration.RequireUppercase == false); } - [Test] - public void MemberPasswordConfiguration_UseLegacyEncoding() - { - Assert.IsTrue(MemberPasswordConfiguration.UseLegacyEncoding == false); - } - [Test] public void MemberPasswordConfiguration_HashAlgorithmType() { diff --git a/src/Umbraco.Tests/CoreThings/UriExtensionsTests.cs b/src/Umbraco.Tests/CoreThings/UriExtensionsTests.cs index 5c0ca7a582..2fda471b70 100644 --- a/src/Umbraco.Tests/CoreThings/UriExtensionsTests.cs +++ b/src/Umbraco.Tests/CoreThings/UriExtensionsTests.cs @@ -47,9 +47,8 @@ namespace Umbraco.Tests.CoreThings { var ioHelper = TestHelper.IOHelper; ioHelper.Root = virtualPath; - var globalConfig = SettingsForTests.GenerateMockGlobalSettings(); var source = new Uri(input); - Assert.AreEqual(expected, source.IsBackOfficeRequest(virtualPath, globalConfig, ioHelper)); + Assert.AreEqual(expected, source.IsBackOfficeRequest(virtualPath, ioHelper)); } [TestCase("http://www.domain.com/install", true)] diff --git a/src/Umbraco.Tests/Macros/MacroTests.cs b/src/Umbraco.Tests/Macros/MacroTests.cs index d6ed8f33c2..6f1358e9a2 100644 --- a/src/Umbraco.Tests/Macros/MacroTests.cs +++ b/src/Umbraco.Tests/Macros/MacroTests.cs @@ -17,12 +17,11 @@ namespace Umbraco.Tests.Macros [SetUp] public void Setup() { - var typeFinder = TestHelper.GetTypeFinder(); //we DO want cache enabled for these tests var cacheHelper = new AppCaches( - new ObjectCacheAppCache(typeFinder), + new ObjectCacheAppCache(), NoAppCache.Instance, - new IsolatedCaches(type => new ObjectCacheAppCache(typeFinder))); + new IsolatedCaches(type => new ObjectCacheAppCache())); } [TestCase("anything", true)] diff --git a/src/Umbraco.Tests/Models/ContentTests.cs b/src/Umbraco.Tests/Models/ContentTests.cs index 07b7ae7cba..f24741a2cf 100644 --- a/src/Umbraco.Tests/Models/ContentTests.cs +++ b/src/Umbraco.Tests/Models/ContentTests.cs @@ -270,8 +270,7 @@ namespace Umbraco.Tests.Models content.UpdateDate = DateTime.Now; content.WriterId = 23; - var typeFinder = TestHelper.GetTypeFinder(); - var runtimeCache = new ObjectCacheAppCache(typeFinder); + var runtimeCache = new ObjectCacheAppCache(); runtimeCache.Insert(content.Id.ToString(CultureInfo.InvariantCulture), () => content); var proflog = GetTestProfilingLogger(); diff --git a/src/Umbraco.Tests/ModelsBuilder/ConfigTests.cs b/src/Umbraco.Tests/ModelsBuilder/ConfigTests.cs index 4a9e8704ec..5ed96365fd 100644 --- a/src/Umbraco.Tests/ModelsBuilder/ConfigTests.cs +++ b/src/Umbraco.Tests/ModelsBuilder/ConfigTests.cs @@ -1,8 +1,9 @@ using System.Configuration; using NUnit.Framework; using Umbraco.Configuration; +using Umbraco.Configuration.Legacy; using Umbraco.Core; -using Umbraco.Tests.TestHelpers; +using Umbraco.Core.Configuration; namespace Umbraco.Tests.ModelsBuilder { @@ -12,21 +13,21 @@ namespace Umbraco.Tests.ModelsBuilder [Test] public void Test1() { - var config = new ModelsBuilderConfig(TestHelper.IOHelper, modelsNamespace: "test1"); + var config = new ModelsBuilderConfig(modelsNamespace: "test1"); Assert.AreEqual("test1", config.ModelsNamespace); } [Test] public void Test2() { - var config = new ModelsBuilderConfig(TestHelper.IOHelper, modelsNamespace: "test2"); + var config = new ModelsBuilderConfig(modelsNamespace: "test2"); Assert.AreEqual("test2", config.ModelsNamespace); } [Test] public void DefaultModelsNamespace() { - var config = new ModelsBuilderConfig(TestHelper.IOHelper); + var config = new ModelsBuilderConfig(); Assert.AreEqual(Constants.ModelsBuilder.DefaultModelsNamespace, config.ModelsNamespace); } @@ -35,7 +36,7 @@ namespace Umbraco.Tests.ModelsBuilder [TestCase("c:/path/to/root", "c:/another/path/to/elsewhere", true, "c:\\another\\path\\to\\elsewhere")] public void GetModelsDirectoryTests(string root, string config, bool acceptUnsafe, string expected) { - Assert.AreEqual(expected, ModelsBuilderConfig.GetModelsDirectory(root, config, acceptUnsafe)); + Assert.AreEqual(expected, ModelsBuilderConfigExtensions.GetModelsDirectory(root, config, acceptUnsafe)); } [TestCase("c:/path/to/root", "~/../../dir/models", false)] @@ -44,7 +45,7 @@ namespace Umbraco.Tests.ModelsBuilder { Assert.Throws(() => { - var modelsDirectory = ModelsBuilderConfig.GetModelsDirectory(root, config, acceptUnsafe); + var modelsDirectory = ModelsBuilderConfigExtensions.GetModelsDirectory(root, config, acceptUnsafe); }); } } diff --git a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs index 531f08a72d..52f2365cbc 100644 --- a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs +++ b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs @@ -37,7 +37,9 @@ namespace Umbraco.Tests.Persistence _sqlSyntaxProviders = new[] { (ISqlSyntaxProvider) _sqlCeSyntaxProvider }; _logger = Mock.Of(); _umbracoVersion = TestHelper.GetUmbracoVersion(); - _databaseFactory = new UmbracoDatabaseFactory(_logger, new Lazy(() => Mock.Of()), TestHelper.GetConfigs(), TestHelper.DbProviderFactoryCreator); + var globalSettings = TestHelper.GetConfigs().Global(); + var connectionStrings = TestHelper.GetConfigs().ConnectionStrings(); + _databaseFactory = new UmbracoDatabaseFactory(_logger, globalSettings, connectionStrings, new Lazy(() => Mock.Of()), TestHelper.DbProviderFactoryCreator); } [TearDown] diff --git a/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs index 30bf5be17b..fe59e431ec 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs @@ -83,9 +83,9 @@ namespace Umbraco.Tests.Persistence.Repositories public void CacheActiveForIntsAndGuids() { var realCache = new AppCaches( - new ObjectCacheAppCache(TypeFinder), + new ObjectCacheAppCache(), new DictionaryAppCache(), - new IsolatedCaches(t => new ObjectCacheAppCache(TypeFinder))); + new IsolatedCaches(t => new ObjectCacheAppCache())); var provider = TestObjects.GetScopeProvider(Logger); using (var scope = provider.CreateScope()) diff --git a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs index efabddb2cd..83572180af 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs @@ -56,9 +56,9 @@ namespace Umbraco.Tests.Persistence.Repositories MediaTypeRepository mediaTypeRepository; var realCache = new AppCaches( - new ObjectCacheAppCache(TypeFinder), + new ObjectCacheAppCache(), new DictionaryAppCache(), - new IsolatedCaches(t => new ObjectCacheAppCache(TypeFinder))); + new IsolatedCaches(t => new ObjectCacheAppCache())); var provider = TestObjects.GetScopeProvider(Logger); using (var scope = provider.CreateScope()) diff --git a/src/Umbraco.Tests/Published/PropertyCacheLevelTests.cs b/src/Umbraco.Tests/Published/PropertyCacheLevelTests.cs index 769985d515..b928e5af06 100644 --- a/src/Umbraco.Tests/Published/PropertyCacheLevelTests.cs +++ b/src/Umbraco.Tests/Published/PropertyCacheLevelTests.cs @@ -127,9 +127,8 @@ namespace Umbraco.Tests.Published var setType1 = publishedContentTypeFactory.CreateContentType(1000, "set1", CreatePropertyTypes); - var typeFinder = TestHelper.GetTypeFinder(); - var elementsCache = new FastDictionaryAppCache(typeFinder); - var snapshotCache = new FastDictionaryAppCache(typeFinder); + var elementsCache = new FastDictionaryAppCache(); + var snapshotCache = new FastDictionaryAppCache(); var publishedSnapshot = new Mock(); publishedSnapshot.Setup(x => x.SnapshotCache).Returns(snapshotCache); diff --git a/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs index abadb7dde4..e9b3c49e10 100644 --- a/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs +++ b/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs @@ -7,6 +7,7 @@ using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; +using Umbraco.Core.Configuration.Legacy; using Umbraco.Core.Events; using Umbraco.Core.Hosting; using Umbraco.Core.Install; @@ -61,7 +62,7 @@ namespace Umbraco.Tests.PublishedContent var configs = TestHelper.GetConfigs(); Mock.Get(factory).Setup(x => x.GetInstance(typeof(Configs))).Returns(configs); - var globalSettings = new GlobalSettings(TestHelper.IOHelper); + var globalSettings = new GlobalSettings(); var hostingEnvironment = Mock.Of(); configs.Add(TestHelpers.SettingsForTests.GenerateMockContentSettings); configs.Add(() => globalSettings); @@ -167,7 +168,6 @@ namespace Umbraco.Tests.PublishedContent Mock.Of(), PublishedModelFactory, new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider(TestHelper.ShortStringHelper) }), - typeFinder, hostingEnvironment, new MockShortStringHelper(), TestHelper.IOHelper, diff --git a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs index 4c6ed34ccb..8003bdf236 100644 --- a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs +++ b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs @@ -7,6 +7,7 @@ using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; +using Umbraco.Core.Configuration.Legacy; using Umbraco.Core.Events; using Umbraco.Core.Install; using Umbraco.Core.Logging; @@ -54,7 +55,7 @@ namespace Umbraco.Tests.PublishedContent var configs = TestHelper.GetConfigs(); Mock.Get(factory).Setup(x => x.GetInstance(typeof(Configs))).Returns(configs); - var globalSettings = new GlobalSettings(TestHelper.IOHelper); + var globalSettings = new GlobalSettings(); configs.Add(TestHelpers.SettingsForTests.GenerateMockContentSettings); configs.Add(() => globalSettings); @@ -207,7 +208,6 @@ namespace Umbraco.Tests.PublishedContent Mock.Of(), publishedModelFactory, new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider(TestHelper.ShortStringHelper) }), - typeFinder, TestHelper.GetHostingEnvironment(), new MockShortStringHelper(), TestHelper.IOHelper, diff --git a/src/Umbraco.Tests/Routing/GetContentUrlsTests.cs b/src/Umbraco.Tests/Routing/GetContentUrlsTests.cs index 6393211791..4f11802b43 100644 --- a/src/Umbraco.Tests/Routing/GetContentUrlsTests.cs +++ b/src/Umbraco.Tests/Routing/GetContentUrlsTests.cs @@ -14,6 +14,7 @@ using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Web; using Umbraco.Web.Routing; using Umbraco.Tests.Common; +using SettingsForTests = Umbraco.Tests.TestHelpers.SettingsForTests; namespace Umbraco.Tests.Routing { @@ -77,7 +78,7 @@ namespace Umbraco.Tests.Routing content.Path = "-1,1046"; content.Published = true; - var umbracoSettings = Current.Configs.RequestHandler(); + var umbracoSettings = SettingsForTests.GenerateMockRequestHandlerSettings(); var umbContext = GetUmbracoContext("http://localhost:8000"); var umbracoContextAccessor = new TestUmbracoContextAccessor(umbContext); @@ -122,7 +123,7 @@ namespace Umbraco.Tests.Routing child.Path = "-1,1046,1173"; child.Published = true; - var umbracoSettings = Current.Configs.RequestHandler(); + var umbracoSettings = SettingsForTests.GenerateMockRequestHandlerSettings(); var umbContext = GetUmbracoContext("http://localhost:8000"); diff --git a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs index 2bbdd1534e..bc58282795 100644 --- a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs +++ b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs @@ -50,7 +50,7 @@ namespace Umbraco.Tests.Routing public class TestRuntime : WebRuntime { public TestRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo) - : base(configs, umbracoVersion, ioHelper, Mock.Of(), Mock.Of(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, TestHelper.GetTypeFinder()) + : base(configs, umbracoVersion, ioHelper, Mock.Of(), Mock.Of(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, TestHelper.GetTypeFinder(), TestHelper.GetRequestCache(), new AspNetUmbracoBootPermissionChecker()) { } diff --git a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs index e4ee8a3580..561a6d945e 100644 --- a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs +++ b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs @@ -37,14 +37,14 @@ namespace Umbraco.Tests.Routing _module = new UmbracoInjectedModule ( - globalSettings, runtime, logger, null, // FIXME: PublishedRouter complexities... Mock.Of(), new RoutableDocumentFilter(globalSettings, IOHelper), UriUtility, - AppCaches.RequestCache + AppCaches.RequestCache, + IOHelper ); runtime.Level = RuntimeLevel.Run; diff --git a/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs b/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs index c230976c98..fd9813b080 100644 --- a/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs +++ b/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs @@ -90,16 +90,17 @@ namespace Umbraco.Tests.Runtimes 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 IHostingSettings _hostingSettings = _configs.Hosting(); + private static readonly IGlobalSettings _globalSettings = SettingsForTests.GetDefaultGlobalSettings(); + private static readonly IHostingSettings _hostingSettings = SettingsForTests.GetDefaultHostingSettings(); + private static readonly IContentSettings _contentSettings = SettingsForTests.GenerateMockContentSettings(); private static readonly IWebRoutingSettings _settings = _configs.WebRouting(); private static Configs GetConfigs() { - var configs = new ConfigsFactory().Create(_ioHelper, _logger); - configs.Add(SettingsForTests.GetDefaultGlobalSettings); - configs.Add(SettingsForTests.GenerateMockContentSettings); - configs.Add(SettingsForTests.GetDefaultHostingSettings); + var configs = new ConfigsFactory().Create(); + configs.Add(() => _globalSettings); + configs.Add(() => _contentSettings); + configs.Add(() => _hostingSettings); return configs; } diff --git a/src/Umbraco.Tests/Runtimes/StandaloneTests.cs b/src/Umbraco.Tests/Runtimes/StandaloneTests.cs index d261afc0da..0cb3f3e2e1 100644 --- a/src/Umbraco.Tests/Runtimes/StandaloneTests.cs +++ b/src/Umbraco.Tests/Runtimes/StandaloneTests.cs @@ -62,8 +62,10 @@ namespace Umbraco.Tests.Runtimes var profiler = new LogProfiler(logger); var profilingLogger = new ProfilingLogger(logger, profiler); var appCaches = AppCaches.Disabled; - var databaseFactory = new UmbracoDatabaseFactory(logger, new Lazy(() => factory.GetInstance()), TestHelper.GetConfigs(), TestHelper.DbProviderFactoryCreator); + var globalSettings = TestHelper.GetConfigs().Global(); + var connectionStrings = TestHelper.GetConfigs().ConnectionStrings(); var typeFinder = TestHelper.GetTypeFinder(); + var databaseFactory = new UmbracoDatabaseFactory(logger,globalSettings, connectionStrings, new Lazy(() => factory.GetInstance()), TestHelper.DbProviderFactoryCreator); var ioHelper = TestHelper.IOHelper; var hostingEnvironment = Mock.Of(); var typeLoader = new TypeLoader(ioHelper, typeFinder, appCaches.RuntimeCache, new DirectoryInfo(ioHelper.MapPath("~/App_Data/TEMP")), profilingLogger); diff --git a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs index 8d410e3570..8603d901c2 100644 --- a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs @@ -106,7 +106,6 @@ namespace Umbraco.Tests.Scoping Factory.GetInstance(), new NoopPublishedModelFactory(), new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider(ShortStringHelper) }), - typeFinder, hostingEnvironment, new MockShortStringHelper(), IOHelper, diff --git a/src/Umbraco.Tests/Scoping/ScopedRepositoryTests.cs b/src/Umbraco.Tests/Scoping/ScopedRepositoryTests.cs index d1963a1d2e..4c3bb288e4 100644 --- a/src/Umbraco.Tests/Scoping/ScopedRepositoryTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopedRepositoryTests.cs @@ -43,9 +43,9 @@ namespace Umbraco.Tests.Scoping { // this is what's created core web runtime return new AppCaches( - new DeepCloneAppCache(new ObjectCacheAppCache(TypeFinder)), + new DeepCloneAppCache(new ObjectCacheAppCache()), NoAppCache.Instance, - new IsolatedCaches(type => new DeepCloneAppCache(new ObjectCacheAppCache(TypeFinder)))); + new IsolatedCaches(type => new DeepCloneAppCache(new ObjectCacheAppCache()))); } [TearDown] diff --git a/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs b/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs index 2f4f77cee7..8b84579fec 100644 --- a/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs +++ b/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs @@ -42,7 +42,7 @@ namespace Umbraco.Tests.Security var runtime = Mock.Of(x => x.Level == RuntimeLevel.Install); var mgr = new BackOfficeCookieManager( - Mock.Of(accessor => accessor.UmbracoContext == umbracoContext), runtime, TestObjects.GetGlobalSettings(), IOHelper, AppCaches.RequestCache); + Mock.Of(accessor => accessor.UmbracoContext == umbracoContext), runtime, IOHelper, AppCaches.RequestCache); var result = mgr.ShouldAuthenticateRequest(Mock.Of(), new Uri("http://localhost/umbraco")); @@ -65,7 +65,7 @@ namespace Umbraco.Tests.Security new AspNetCookieManager(httpContextAccessor)); var runtime = Mock.Of(x => x.Level == RuntimeLevel.Run); - var mgr = new BackOfficeCookieManager(Mock.Of(accessor => accessor.UmbracoContext == umbCtx), runtime, TestObjects.GetGlobalSettings(), IOHelper, AppCaches.RequestCache); + var mgr = new BackOfficeCookieManager(Mock.Of(accessor => accessor.UmbracoContext == umbCtx), runtime, IOHelper, AppCaches.RequestCache); var request = new Mock(); request.Setup(owinRequest => owinRequest.Uri).Returns(new Uri("http://localhost/umbraco")); diff --git a/src/Umbraco.Tests/Security/PasswordSecurityTests.cs b/src/Umbraco.Tests/Security/PasswordSecurityTests.cs index 9ed130a62b..b1646edd28 100644 --- a/src/Umbraco.Tests/Security/PasswordSecurityTests.cs +++ b/src/Umbraco.Tests/Security/PasswordSecurityTests.cs @@ -14,14 +14,6 @@ namespace Umbraco.Tests.Security [TestFixture] public class PasswordSecurityTests { - [Test] - public void Get_Hash_Algorithm_Legacy() - { - var passwordSecurity = new PasswordSecurity(Mock.Of(x => x.UseLegacyEncoding == true && x.HashAlgorithmType == "HMACSHA256")); - var alg = passwordSecurity.GetHashAlgorithm("blah"); - Assert.IsTrue(alg is HMACSHA1); - } - [Test] public void Get_Hash_Algorithm_Default() { diff --git a/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs b/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs index 33e8b0010e..0d98574504 100644 --- a/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs +++ b/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs @@ -78,7 +78,6 @@ namespace Umbraco.Tests.Services Factory.GetInstance(), Mock.Of(), new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider(ShortStringHelper) }), - typeFinder, hostingEnvironment, new MockShortStringHelper(), IOHelper, diff --git a/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs b/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs index ccb616989b..fc3d3f6b52 100644 --- a/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs +++ b/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs @@ -7,7 +7,7 @@ namespace Umbraco.Tests.TestHelpers { private static Common.SettingsForTests _settingsForTests = new Common.SettingsForTests(); - public static IGlobalSettings GenerateMockGlobalSettings() => _settingsForTests.GenerateMockGlobalSettings(TestHelper.GetUmbracoVersion(), TestHelper.IOHelper); + public static IGlobalSettings GenerateMockGlobalSettings() => _settingsForTests.GenerateMockGlobalSettings(TestHelper.GetUmbracoVersion()); /// /// Returns generated settings which can be stubbed to return whatever values necessary @@ -45,7 +45,7 @@ namespace Umbraco.Tests.TestHelpers public static void Reset() => _settingsForTests.Reset(); - internal static IGlobalSettings GetDefaultGlobalSettings() => _settingsForTests.GetDefaultGlobalSettings(TestHelper.GetUmbracoVersion(), TestHelper.IOHelper); + internal static IGlobalSettings GetDefaultGlobalSettings() => _settingsForTests.GetDefaultGlobalSettings(TestHelper.GetUmbracoVersion()); internal static IHostingSettings GetDefaultHostingSettings() => _settingsForTests.GetDefaultHostingSettings(); diff --git a/src/Umbraco.Tests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests/TestHelpers/TestHelper.cs index a22d69d68b..05d4de6e23 100644 --- a/src/Umbraco.Tests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests/TestHelpers/TestHelper.cs @@ -56,7 +56,7 @@ namespace Umbraco.Tests.TestHelpers public override IBackOfficeInfo GetBackOfficeInfo() => new AspNetBackOfficeInfo( - SettingsForTests.GenerateMockGlobalSettings(GetUmbracoVersion(), IOHelper), + SettingsForTests.GenerateMockGlobalSettings(GetUmbracoVersion()), TestHelper.IOHelper, Mock.Of(), SettingsForTests.GenerateMockWebRoutingSettings()); public override IHostingEnvironment GetHostingEnvironment() @@ -90,7 +90,7 @@ namespace Umbraco.Tests.TestHelpers public static IDbProviderFactoryCreator DbProviderFactoryCreator => _testHelperInternal.DbProviderFactoryCreator; public static IBulkSqlInsertProvider BulkSqlInsertProvider => _testHelperInternal.BulkSqlInsertProvider; public static IMarchal Marchal => _testHelperInternal.Marchal; - public static ICoreDebug CoreDebug => _testHelperInternal.CoreDebug; + public static ICoreDebugSettings CoreDebugSettings => _testHelperInternal.CoreDebugSettings; public static IIOHelper IOHelper => _testHelperInternal.IOHelper; diff --git a/src/Umbraco.Tests/TestHelpers/TestObjects.cs b/src/Umbraco.Tests/TestHelpers/TestObjects.cs index bb342c9939..33e477df2c 100644 --- a/src/Umbraco.Tests/TestHelpers/TestObjects.cs +++ b/src/Umbraco.Tests/TestHelpers/TestObjects.cs @@ -244,12 +244,18 @@ namespace Umbraco.Tests.TestHelpers // mappersBuilder.AddCore(); // var mappers = mappersBuilder.CreateCollection(); var mappers = Current.Factory.GetInstance(); - databaseFactory = new UmbracoDatabaseFactory(Constants.System.UmbracoConnectionName, logger, new Lazy(() => mappers), TestHelper.GetConfigs(), TestHelper.DbProviderFactoryCreator); + databaseFactory = new UmbracoDatabaseFactory( + Constants.System.UmbracoConnectionName, + SettingsForTests.GetDefaultGlobalSettings(), + new ConnectionStrings(), + logger, + new Lazy(() => mappers), + TestHelper.DbProviderFactoryCreator); } typeFinder = typeFinder ?? new TypeFinder(logger, new DefaultUmbracoAssemblyProvider(GetType().Assembly)); fileSystems = fileSystems ?? new FileSystems(Current.Factory, logger, TestHelper.IOHelper, SettingsForTests.GenerateMockGlobalSettings()); - var coreDebug = Current.Configs.CoreDebug(); + var coreDebug = TestHelper.CoreDebugSettings; var mediaFileSystem = Mock.Of(); var scopeProvider = new ScopeProvider(databaseFactory, fileSystems, coreDebug, mediaFileSystem, logger, typeFinder, NoAppCache.Instance); return scopeProvider; diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs index 74b3ddf7b2..ca36a6049e 100644 --- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs +++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs @@ -266,7 +266,7 @@ namespace Umbraco.Tests.Testing profiler = Mock.Of(); break; case UmbracoTestOptions.Logger.Serilog: - logger = new SerilogLogger(TestHelper.CoreDebug, IOHelper, TestHelper.Marchal, new FileInfo(TestHelper.MapPathForTest("~/unit-test.config"))); + logger = new SerilogLogger(TestHelper.CoreDebugSettings, IOHelper, TestHelper.Marchal, new FileInfo(TestHelper.MapPathForTest("~/unit-test.config"))); profiler = new LogProfiler(logger); break; case UmbracoTestOptions.Logger.Console: @@ -457,11 +457,16 @@ namespace Umbraco.Tests.Testing .AddCoreMappers(); Composition.RegisterUnique(_ => new TransientEventMessagesFactory()); + + var globalSettings = TestHelper.GetConfigs().Global(); + var connectionStrings = TestHelper.GetConfigs().ConnectionStrings(); + Composition.RegisterUnique(f => new UmbracoDatabaseFactory( Constants.System.UmbracoConnectionName, + globalSettings, + connectionStrings, Logger, new Lazy(f.GetInstance), - TestHelper.GetConfigs(), TestHelper.DbProviderFactoryCreator)); Composition.RegisterUnique(f => f.TryGetInstance().SqlContext); diff --git a/src/Umbraco.Tests/UmbracoExamine/ExamineBaseTest.cs b/src/Umbraco.Tests/UmbracoExamine/ExamineBaseTest.cs index 98c4dc96ca..91cb843eb1 100644 --- a/src/Umbraco.Tests/UmbracoExamine/ExamineBaseTest.cs +++ b/src/Umbraco.Tests/UmbracoExamine/ExamineBaseTest.cs @@ -17,7 +17,7 @@ namespace Umbraco.Tests.UmbracoExamine [OneTimeSetUp] public void InitializeFixture() { - var logger = new SerilogLogger(TestHelper.CoreDebug, IOHelper, TestHelper.Marchal, new FileInfo(TestHelper.MapPathForTest("~/unit-test.config"))); + var logger = new SerilogLogger(TestHelper.CoreDebugSettings, IOHelper, TestHelper.Marchal, new FileInfo(TestHelper.MapPathForTest("~/unit-test.config"))); _profilingLogger = new ProfilingLogger(logger, new LogProfiler(logger)); } diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHostingEnvironment.cs b/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHostingEnvironment.cs index 719b7d1323..00bc894b0d 100644 --- a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHostingEnvironment.cs +++ b/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHostingEnvironment.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Concurrent; +using System.Diagnostics; using System.IO; using System.Threading; using Microsoft.AspNetCore.Hosting; diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoBackOfficeServiceCollectionExtensions.cs b/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoBackOfficeServiceCollectionExtensions.cs index 6a74323bc4..b795d31670 100644 --- a/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoBackOfficeServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoBackOfficeServiceCollectionExtensions.cs @@ -3,13 +3,16 @@ using System.Data.Common; using System.Reflection; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Umbraco.Composing; +using Umbraco.Configuration; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; +using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Logging.Serilog; @@ -19,9 +22,24 @@ using Umbraco.Core.Runtime; namespace Umbraco.Web.BackOffice.AspNetCore { + public static class UmbracoBackOfficeServiceCollectionExtensions { + public static IServiceCollection AddUmbracoConfiguration(this IServiceCollection services) + { + var serviceProvider = services.BuildServiceProvider(); + var configuration = serviceProvider.GetService(); + var configsFactory = new AspNetCoreConfigsFactory(configuration); + + var configs = configsFactory.Create(); + + services.AddSingleton(configs); + + return services; + } + + /// /// Adds the Umbraco Back Core requirements /// @@ -79,9 +97,11 @@ namespace Umbraco.Web.BackOffice.AspNetCore DbProviderFactories.GetFactory); // Determine if we should use the sql main dom or the default - var appSettingMainDomLock = configs.Global().MainDomLock; + var globalSettings = configs.Global(); + var connStrings = configs.ConnectionStrings(); + var appSettingMainDomLock = globalSettings.MainDomLock; var mainDomLock = appSettingMainDomLock == "SqlMainDomLock" - ? (IMainDomLock)new SqlMainDomLock(logger, configs, dbProviderFactoryCreator) + ? (IMainDomLock)new SqlMainDomLock(logger, globalSettings, connStrings, dbProviderFactoryCreator) : new MainDomSemaphoreLock(logger, hostingEnvironment); var mainDom = new MainDom(logger, hostingEnvironment, mainDomLock); @@ -92,6 +112,33 @@ namespace Umbraco.Web.BackOffice.AspNetCore return coreRuntime; } + public static IServiceCollection CreateCompositionRoot( + this IServiceCollection services, + IHttpContextAccessor httpContextAccessor, + IWebHostEnvironment webHostEnvironment, + IHostApplicationLifetime hostApplicationLifetime, + Configs configs) + { + var hostingSettings = configs.Hosting(); + var coreDebug = configs.CoreDebug(); + var globalSettings = configs.Global(); + + var hostingEnvironment = new AspNetCoreHostingEnvironment(hostingSettings, webHostEnvironment, + httpContextAccessor, hostApplicationLifetime); + var ioHelper = new IOHelper(hostingEnvironment, globalSettings); + var logger = SerilogLogger.CreateWithDefaultConfiguration(hostingEnvironment, + new AspNetCoreSessionIdResolver(httpContextAccessor), + () => services.BuildServiceProvider().GetService(), coreDebug, ioHelper, + new AspNetCoreMarchal()); + + var backOfficeInfo = new AspNetCoreBackOfficeInfo(globalSettings); + var profiler = new LogProfiler(logger); + + Current.Initialize(logger, configs, ioHelper, hostingEnvironment, backOfficeInfo, profiler); + + return services; + } + private static void CreateCompositionRoot(IServiceCollection services) { // TODO: This isn't the best to have to resolve the services now but to avoid this will @@ -102,16 +149,18 @@ namespace Umbraco.Web.BackOffice.AspNetCore var webHostEnvironment = serviceProvider.GetRequiredService(); var hostApplicationLifetime = serviceProvider.GetRequiredService(); - var configFactory = new ConfigsFactory(); + var configs = serviceProvider.GetService(); - var hostingSettings = configFactory.HostingSettings; - var coreDebug = configFactory.CoreDebug; + var hostingSettings = configs.Hosting(); + var coreDebug = configs.CoreDebug(); + var globalSettings = configs.Global(); var hostingEnvironment = new AspNetCoreHostingEnvironment(hostingSettings, webHostEnvironment, httpContextAccessor, hostApplicationLifetime); - var ioHelper = new IOHelper(hostingEnvironment); - - var logger = SerilogLogger.CreateWithDefaultConfiguration(hostingEnvironment, new AspNetCoreSessionIdResolver(httpContextAccessor), () => services.BuildServiceProvider().GetService(), coreDebug, ioHelper, new AspNetCoreMarchal()); - var configs = configFactory.Create(ioHelper, logger); + var ioHelper = new IOHelper(hostingEnvironment, globalSettings); + var logger = SerilogLogger.CreateWithDefaultConfiguration(hostingEnvironment, + new AspNetCoreSessionIdResolver(httpContextAccessor), + () => serviceProvider.GetService(), coreDebug, ioHelper, + new AspNetCoreMarchal()); var backOfficeInfo = new AspNetCoreBackOfficeInfo(configs.Global()); var profiler = new LogProfiler(logger); diff --git a/src/Umbraco.Web.UI.Client/src/less/forms.less b/src/Umbraco.Web.UI.Client/src/less/forms.less index 0600c9aab6..ffc0626981 100644 --- a/src/Umbraco.Web.UI.Client/src/less/forms.less +++ b/src/Umbraco.Web.UI.Client/src/less/forms.less @@ -297,7 +297,6 @@ select[size] { } // Focus for select, file, radio, and checkbox -select, input[type="file"], input[type="radio"], input[type="checkbox"] { diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html index d8241b4dd7..2b5bceb11a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html @@ -44,7 +44,7 @@ - +
- @@ -79,7 +79,7 @@
- {{ item.comment }} - +
@@ -126,7 +126,7 @@
- + diff --git a/src/Umbraco.Web.UI.NetCore/Startup.cs b/src/Umbraco.Web.UI.NetCore/Startup.cs index 7e2d19ac02..ab8c6e021c 100644 --- a/src/Umbraco.Web.UI.NetCore/Startup.cs +++ b/src/Umbraco.Web.UI.NetCore/Startup.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Umbraco.Web.BackOffice.AspNetCore; @@ -15,10 +16,12 @@ namespace Umbraco.Web.UI.BackOffice { public class Startup { + // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { + services.AddUmbracoConfiguration(); services.AddUmbracoCore(); services.AddUmbracoWebsite(); } diff --git a/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj b/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj index 69d223bcc6..ca7c3e26fa 100644 --- a/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj +++ b/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj @@ -14,4 +14,9 @@ + + <_ContentIncludedByDefault Remove="wwwroot\~\App_Data\TEMP\TypesCache\umbraco-types.DESKTOP-2016.hash" /> + <_ContentIncludedByDefault Remove="wwwroot\~\App_Data\TEMP\TypesCache\umbraco-types.DESKTOP-2016.list" /> + + diff --git a/src/Umbraco.Web.UI.NetCore/appsettings.Development.json b/src/Umbraco.Web.UI.NetCore/appsettings.Development.json index 8983e0fc1c..834ea5f51f 100644 --- a/src/Umbraco.Web.UI.NetCore/appsettings.Development.json +++ b/src/Umbraco.Web.UI.NetCore/appsettings.Development.json @@ -1,4 +1,7 @@ { + "ConnectionStrings": { + "umbracoDbDSN": "" + }, "Logging": { "LogLevel": { "Default": "Information", diff --git a/src/Umbraco.Web.UI.NetCore/appsettings.json b/src/Umbraco.Web.UI.NetCore/appsettings.json index d9d9a9bff6..1c89647efa 100644 --- a/src/Umbraco.Web.UI.NetCore/appsettings.json +++ b/src/Umbraco.Web.UI.NetCore/appsettings.json @@ -1,4 +1,7 @@ { + "ConnectionStrings": { + "umbracoDbDSN": "" + }, "Logging": { "LogLevel": { "Default": "Information", @@ -6,5 +9,81 @@ "Microsoft.Hosting.Lifetime": "Information" } }, - "AllowedHosts": "*" + "AllowedHosts": "*", + "Umbraco": { + "CMS": { + "Imaging": { + "Resize": { + "MaxWidth": 5000, + "MaxHeight": 5000 + }, + "Cache": { + "Folder": "../App_Data/Cache", + "MaxBrowserCacheDays": 7, + "MaxCacheDays": 365, + "CachedNameLength": 8 + } + }, + "HealthChecks": { + "DisabledChecks": [ + { + "id": "1B5D221B-CE99-4193-97CB-5F3261EC73DF", + "disabledBy": 1, + "disabledOn": "2020-03-15 19:19:10" + } + ], + "NotificationSettings": { + "Enabled": true, + "FirstRunTime": "", + "PeriodInHours": 24, + "NotificationMethods": { + "Email": { + "Enabled": true, + "Verbosity": "Summary", + "Settings": { + "RecipientEmail": "" + } + } + }, + "DisabledChecks": [ + { + "id": "1B5D221B-CE99-4193-97CB-5F3261EC73DF", + "disabledBy": 1, + "disabledOn": "2020-03-15 19:19:10" + } + ] + } + }, + "Tours": { + "EnableTours": true + }, + "Core": { + "Debug": {} + }, + "Content": { + "Errors": { + "Error404": { + "default": "1047", + "en-US": "$site/error [@name = 'error']", + "en-UK": "8560867F-B88F-4C74-A9A4-679D8E5B3BFC" + } + } + }, + "RequestHandler": { + "AddTrailingSlash": true, + "CharCollection": [ + {"Char": " ", "Replacement": "-"}, + {"Char": "\"", "Replacement": ""}, + {"Char": "'", "Replacement": ""}, + {"Char": "%", "Replacement": ""}, + {"Char": ".", "Replacement": ""}, + {"Char": ";", "Replacement": ""}, + {"Char": "/", "Replacement": ""}, + {"Char": "\\", "Replacement": ""}, + {"Char": ":", "Replacement": ""}, + + ] + } + } + } } diff --git a/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml b/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml index 986fa2dc76..14ef376a2c 100644 --- a/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml @@ -17,7 +17,7 @@ - + diff --git a/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml b/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml index c48bdf4c47..ce8a0e2b9f 100644 --- a/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml @@ -28,7 +28,7 @@ - + diff --git a/src/Umbraco.Web.UI/config/imageprocessor/processing.config b/src/Umbraco.Web.UI/config/imageprocessor/processing.config index dddcddb0bd..da9b6fa180 100644 --- a/src/Umbraco.Web.UI/config/imageprocessor/processing.config +++ b/src/Umbraco.Web.UI/config/imageprocessor/processing.config @@ -2,37 +2,70 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Umbraco.Web.Website/AspNetCore/UmbracoWebsiteServiceCollectionExtensions.cs b/src/Umbraco.Web.Website/AspNetCore/UmbracoWebsiteServiceCollectionExtensions.cs index 5fb2825269..f7a198bc3b 100644 --- a/src/Umbraco.Web.Website/AspNetCore/UmbracoWebsiteServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.Website/AspNetCore/UmbracoWebsiteServiceCollectionExtensions.cs @@ -1,5 +1,17 @@ +using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Web; +using SixLabors.ImageSharp.Web.Caching; +using SixLabors.ImageSharp.Web.Commands; using SixLabors.ImageSharp.Web.DependencyInjection; +using SixLabors.ImageSharp.Web.Middleware; +using SixLabors.ImageSharp.Web.Processors; +using SixLabors.ImageSharp.Web.Providers; +using SixLabors.Memory; +using Umbraco.Core; +using Umbraco.Core.Configuration; namespace Umbraco.Web.Website.AspNetCore { @@ -7,11 +19,63 @@ namespace Umbraco.Web.Website.AspNetCore { public static IServiceCollection AddUmbracoWebsite(this IServiceCollection services) { - services.AddImageSharp(); - + var serviceProvider = services.BuildServiceProvider(); + var configs = serviceProvider.GetService(); + var imagingSettings = configs.Imaging(); + services.AddUmbracoImageSharp(imagingSettings); return services; } + public static IServiceCollection AddUmbracoImageSharp(this IServiceCollection services, IImagingSettings imagingSettings) + { + + + services.AddImageSharpCore( + options => + { + options.Configuration = SixLabors.ImageSharp.Configuration.Default; + options.MaxBrowserCacheDays = imagingSettings.MaxBrowserCacheDays; + options.MaxCacheDays = imagingSettings.MaxCacheDays; + options.CachedNameLength = imagingSettings.CachedNameLength; + options.OnParseCommands = context => + { + RemoveIntParamenterIfValueGreatherThen(context.Commands, ResizeWebProcessor.Width, imagingSettings.MaxResizeWidth); + RemoveIntParamenterIfValueGreatherThen(context.Commands, ResizeWebProcessor.Height, imagingSettings.MaxResizeHeight); + }; + options.OnBeforeSave = _ => { }; + options.OnProcessed = _ => { }; + options.OnPrepareResponse = _ => { }; + }) + .SetRequestParser() + .SetMemoryAllocator(provider => ArrayPoolMemoryAllocator.CreateWithMinimalPooling()) + .Configure(options => + { + options.CacheFolder = imagingSettings.CacheFolder; + }) + .SetCache() + .SetCacheHash() + .AddProvider() + .AddProcessor() + .AddProcessor() + .AddProcessor(); + + return services; + } + + private static void RemoveIntParamenterIfValueGreatherThen(IDictionary commands, string parameter, int maxValue) + { + if (commands.TryGetValue(parameter, out var command)) + { + if (int.TryParse(command, out var i)) + { + if (i > maxValue) + { + commands.Remove(parameter); + } + } + } + } } + } diff --git a/src/Umbraco.Web/AppBuilderExtensions.cs b/src/Umbraco.Web/AppBuilderExtensions.cs index 870cba86f3..e9833e4379 100644 --- a/src/Umbraco.Web/AppBuilderExtensions.cs +++ b/src/Umbraco.Web/AppBuilderExtensions.cs @@ -43,11 +43,10 @@ namespace Umbraco.Web /// Configures SignalR. ///
/// The app builder. - /// /// - public static IAppBuilder UseSignalR(this IAppBuilder app, IGlobalSettings globalSettings, IIOHelper ioHelper) + public static IAppBuilder UseSignalR(this IAppBuilder app, IIOHelper ioHelper) { - var umbracoPath = globalSettings.GetUmbracoMvcArea(ioHelper); + var umbracoPath = ioHelper.GetUmbracoMvcArea(); var signalrPath = HttpRuntime.AppDomainAppVirtualPath + umbracoPath + "/BackOffice/signalr"; return app.MapSignalR(signalrPath, new HubConfiguration { EnableDetailedErrors = true }); } diff --git a/src/Umbraco.Web/Composing/CompositionExtensions/Installer.cs b/src/Umbraco.Web/Composing/CompositionExtensions/Installer.cs index 9a3e8d98f8..64f91939a7 100644 --- a/src/Umbraco.Web/Composing/CompositionExtensions/Installer.cs +++ b/src/Umbraco.Web/Composing/CompositionExtensions/Installer.cs @@ -14,7 +14,6 @@ namespace Umbraco.Web.Composing.CompositionExtensions composition.Register(Lifetime.Scope); composition.Register(Lifetime.Scope); composition.Register(Lifetime.Scope); - composition.Register(Lifetime.Scope); composition.Register(Lifetime.Scope); composition.Register(Lifetime.Scope); composition.Register(Lifetime.Scope); diff --git a/src/Umbraco.Web/Editors/AuthenticationController.cs b/src/Umbraco.Web/Editors/AuthenticationController.cs index 1788484981..6519cf4cf6 100644 --- a/src/Umbraco.Web/Editors/AuthenticationController.cs +++ b/src/Umbraco.Web/Editors/AuthenticationController.cs @@ -534,7 +534,7 @@ namespace Umbraco.Web.Editors var action = urlHelper.Action("ValidatePasswordResetCode", "BackOffice", new { - area = GlobalSettings.GetUmbracoMvcArea(_ioHelper), + area = _ioHelper.GetUmbracoMvcArea(), u = userId, r = code }); diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs index 22da5b9fdd..e39d1658a2 100644 --- a/src/Umbraco.Web/Editors/BackOfficeController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeController.cs @@ -104,8 +104,8 @@ namespace Umbraco.Web.Editors public async Task Default() { return await RenderDefaultOrProcessExternalLoginAsync( - () => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings, _umbracoVersion, _contentSettings,_ioHelper, _treeCollection, _httpContextAccessor, _hostingEnvironment, _runtimeSettings, _securitySettings)), - () => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings, _umbracoVersion, _contentSettings, _ioHelper, _treeCollection, _httpContextAccessor, _hostingEnvironment, _runtimeSettings, _securitySettings))); + () => View(_ioHelper.BackOfficePath.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings, _umbracoVersion, _contentSettings,_ioHelper, _treeCollection, _httpContextAccessor, _hostingEnvironment, _runtimeSettings, _securitySettings)), + () => View(_ioHelper.BackOfficePath.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings, _umbracoVersion, _contentSettings, _ioHelper, _treeCollection, _httpContextAccessor, _hostingEnvironment, _runtimeSettings, _securitySettings))); } [HttpGet] @@ -188,7 +188,7 @@ namespace Umbraco.Web.Editors { return await RenderDefaultOrProcessExternalLoginAsync( //The default view to render when there is no external login info or errors - () => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/AuthorizeUpgrade.cshtml", new BackOfficeModel(_features, GlobalSettings, _umbracoVersion, _contentSettings, _ioHelper, _treeCollection, _httpContextAccessor, _hostingEnvironment, _runtimeSettings, _securitySettings)), + () => View(_ioHelper.BackOfficePath.EnsureEndsWith('/') + "Views/AuthorizeUpgrade.cshtml", new BackOfficeModel(_features, GlobalSettings, _umbracoVersion, _contentSettings, _ioHelper, _treeCollection, _httpContextAccessor, _hostingEnvironment, _runtimeSettings, _securitySettings)), //The ActionResult to perform if external login is successful () => Redirect("/")); } @@ -389,7 +389,7 @@ namespace Umbraco.Web.Editors if (defaultResponse == null) throw new ArgumentNullException("defaultResponse"); if (externalSignInResponse == null) throw new ArgumentNullException("externalSignInResponse"); - ViewData.SetUmbracoPath(GlobalSettings.GetUmbracoMvcArea(_ioHelper)); + ViewData.SetUmbracoPath(_ioHelper.GetUmbracoMvcArea()); //check if there is the TempData with the any token name specified, if so, assign to view bag and render the view if (ViewData.FromTempData(TempData, ViewDataExtensions.TokenExternalSignInError) || diff --git a/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs b/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs index ebefb99677..14f067a0fc 100644 --- a/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs +++ b/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs @@ -344,7 +344,7 @@ namespace Umbraco.Web.Editors { "umbracoSettings", new Dictionary { - {"umbracoPath", _globalSettings.Path}, + {"umbracoPath", _ioHelper.BackOfficePath}, {"mediaPath", _ioHelper.ResolveUrl(globalSettings.UmbracoMediaPath).TrimEnd('/')}, {"appPluginsPath", _ioHelper.ResolveUrl(Constants.SystemDirectories.AppPlugins).TrimEnd('/')}, { diff --git a/src/Umbraco.Web/Editors/PreviewController.cs b/src/Umbraco.Web/Editors/PreviewController.cs index 3db5d4faab..3539047112 100644 --- a/src/Umbraco.Web/Editors/PreviewController.cs +++ b/src/Umbraco.Web/Editors/PreviewController.cs @@ -88,7 +88,7 @@ namespace Umbraco.Web.Editors } } - return View(_globalSettings.Path.EnsureEndsWith('/') + "Views/Preview/" + "Index.cshtml", model); + return View(_ioHelper.BackOfficePath.EnsureEndsWith('/') + "Views/Preview/" + "Index.cshtml", model); } /// diff --git a/src/Umbraco.Web/Editors/UsersController.cs b/src/Umbraco.Web/Editors/UsersController.cs index f75a040e0e..9554906b0d 100644 --- a/src/Umbraco.Web/Editors/UsersController.cs +++ b/src/Umbraco.Web/Editors/UsersController.cs @@ -487,7 +487,7 @@ namespace Umbraco.Web.Editors var action = urlHelper.Action("VerifyInvite", "BackOffice", new { - area = GlobalSettings.GetUmbracoMvcArea(_ioHelper), + area = _ioHelper.GetUmbracoMvcArea(), invite = inviteToken }); diff --git a/src/Umbraco.Web/HealthCheck/HealthCheckController.cs b/src/Umbraco.Web/HealthCheck/HealthCheckController.cs index 251c5c0ae4..bfd33399d2 100644 --- a/src/Umbraco.Web/HealthCheck/HealthCheckController.cs +++ b/src/Umbraco.Web/HealthCheck/HealthCheckController.cs @@ -20,12 +20,12 @@ namespace Umbraco.Web.HealthCheck private readonly IList _disabledCheckIds; private readonly ILogger _logger; - public HealthCheckController(HealthCheckCollection checks, ILogger logger, IHealthChecks healthChecks) + public HealthCheckController(HealthCheckCollection checks, ILogger logger, IHealthChecksSettings healthChecksSettings) { _checks = checks ?? throw new ArgumentNullException(nameof(checks)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - var healthCheckConfig = healthChecks ?? throw new ArgumentNullException(nameof(healthChecks)); + var healthCheckConfig = healthChecksSettings ?? throw new ArgumentNullException(nameof(healthChecksSettings)); _disabledCheckIds = healthCheckConfig.DisabledChecks .Select(x => x.Id) .ToList(); diff --git a/src/Umbraco.Web/Install/Controllers/InstallController.cs b/src/Umbraco.Web/Install/Controllers/InstallController.cs index 8caf5e985e..8869e02129 100644 --- a/src/Umbraco.Web/Install/Controllers/InstallController.cs +++ b/src/Umbraco.Web/Install/Controllers/InstallController.cs @@ -74,7 +74,7 @@ namespace Umbraco.Web.Install.Controllers _installHelper.InstallStatus(false, ""); // always ensure full path (see NOTE in the class remarks) - return View(_globalSettings.Path.EnsureEndsWith('/') + "install/views/index.cshtml"); + return View(_ioHelper.BackOfficePath.EnsureEndsWith('/') + "install/views/index.cshtml"); } } } diff --git a/src/Umbraco.Web/Install/InstallStepCollection.cs b/src/Umbraco.Web/Install/InstallStepCollection.cs index ece9f0be12..f31f5f7dbb 100644 --- a/src/Umbraco.Web/Install/InstallStepCollection.cs +++ b/src/Umbraco.Web/Install/InstallStepCollection.cs @@ -21,7 +21,6 @@ namespace Umbraco.Web.Install a.OfType().First(), a.OfType().First(), a.OfType().First(), - a.OfType().First(), a.OfType().First(), a.OfType().First(), a.OfType().First(), diff --git a/src/Umbraco.Web/Mvc/AreaRegistrationExtensions.cs b/src/Umbraco.Web/Mvc/AreaRegistrationExtensions.cs index 7a3a3fbcf4..22e5911cf8 100644 --- a/src/Umbraco.Web/Mvc/AreaRegistrationExtensions.cs +++ b/src/Umbraco.Web/Mvc/AreaRegistrationExtensions.cs @@ -19,7 +19,7 @@ namespace Umbraco.Web.Mvc /// Creates a custom individual route for the specified controller plugin. Individual routes /// are required by controller plugins to map to a unique URL based on ID. /// - /// + /// /// /// /// An existing route collection @@ -42,7 +42,6 @@ namespace Umbraco.Web.Mvc /// /// internal static Route RouteControllerPlugin(this AreaRegistration area, - IGlobalSettings globalSettings, IIOHelper ioHelper, string controllerName, Type controllerType, RouteCollection routes, string controllerSuffixName, string defaultAction, object defaultId, @@ -59,7 +58,7 @@ namespace Umbraco.Web.Mvc if (routes == null) throw new ArgumentNullException(nameof(routes)); if (defaultId == null) throw new ArgumentNullException(nameof(defaultId)); - var umbracoArea = globalSettings.GetUmbracoMvcArea(ioHelper); + var umbracoArea = ioHelper.GetUmbracoMvcArea(); //routes are explicitly named with controller names and IDs var url = umbracoArea + "/" + diff --git a/src/Umbraco.Web/Mvc/BackOfficeArea.cs b/src/Umbraco.Web/Mvc/BackOfficeArea.cs index b4425a3239..82c0bbf909 100644 --- a/src/Umbraco.Web/Mvc/BackOfficeArea.cs +++ b/src/Umbraco.Web/Mvc/BackOfficeArea.cs @@ -11,12 +11,10 @@ namespace Umbraco.Web.Mvc /// internal class BackOfficeArea : AreaRegistration { - private readonly IGlobalSettings _globalSettings; private readonly IIOHelper _ioHelper; - public BackOfficeArea(IGlobalSettings globalSettings, IIOHelper ioHelper) + public BackOfficeArea(IIOHelper ioHelper) { - _globalSettings = globalSettings; _ioHelper = ioHelper; } @@ -51,6 +49,6 @@ namespace Umbraco.Web.Mvc new[] {typeof (BackOfficeController).Namespace}); } - public override string AreaName => _globalSettings.GetUmbracoMvcArea(_ioHelper); + public override string AreaName => _ioHelper.GetUmbracoMvcArea(); } } diff --git a/src/Umbraco.Web/Mvc/PluginControllerArea.cs b/src/Umbraco.Web/Mvc/PluginControllerArea.cs index 713b0c6551..fddf04b391 100644 --- a/src/Umbraco.Web/Mvc/PluginControllerArea.cs +++ b/src/Umbraco.Web/Mvc/PluginControllerArea.cs @@ -77,7 +77,7 @@ namespace Umbraco.Web.Mvc { foreach (var s in surfaceControllers) { - var route = this.RouteControllerPlugin(_globalSettings, _ioHelper, s.ControllerName, s.ControllerType, routes, "", "Index", UrlParameter.Optional, "surface"); + var route = this.RouteControllerPlugin(_ioHelper, s.ControllerName, s.ControllerType, routes, "", "Index", UrlParameter.Optional, "surface"); //set the route handler to our SurfaceRouteHandler route.RouteHandler = new SurfaceRouteHandler(); } @@ -92,7 +92,7 @@ namespace Umbraco.Web.Mvc { foreach (var s in apiControllers) { - this.RouteControllerPlugin(_globalSettings, _ioHelper, s.ControllerName, s.ControllerType, routes, "", "", UrlParameter.Optional, "api", + this.RouteControllerPlugin(_ioHelper, s.ControllerName, s.ControllerType, routes, "", "", UrlParameter.Optional, "api", isMvc: false, areaPathPrefix: s.IsBackOffice ? "backoffice" : null); } diff --git a/src/Umbraco.Web/Mvc/UmbracoAuthorizeAttribute.cs b/src/Umbraco.Web/Mvc/UmbracoAuthorizeAttribute.cs index 0c6898553c..593289812f 100644 --- a/src/Umbraco.Web/Mvc/UmbracoAuthorizeAttribute.cs +++ b/src/Umbraco.Web/Mvc/UmbracoAuthorizeAttribute.cs @@ -57,7 +57,7 @@ namespace Umbraco.Web.Mvc { if (redirectToUmbracoLogin) { - _redirectUrl = Current.Configs.Global().Path.EnsureStartsWith("~"); + _redirectUrl = Current.IOHelper.BackOfficePath.EnsureStartsWith("~"); } } diff --git a/src/Umbraco.Web/Runtime/WebInitialComponent.cs b/src/Umbraco.Web/Runtime/WebInitialComponent.cs index 8f07ab4837..0a668b7d65 100644 --- a/src/Umbraco.Web/Runtime/WebInitialComponent.cs +++ b/src/Umbraco.Web/Runtime/WebInitialComponent.cs @@ -172,7 +172,7 @@ namespace Umbraco.Web.Runtime UmbracoApiControllerTypeCollection apiControllerTypes, IIOHelper ioHelper) { - var umbracoPath = globalSettings.GetUmbracoMvcArea(ioHelper); + var umbracoPath = ioHelper.GetUmbracoMvcArea(); // create the front-end route var defaultRoute = RouteTable.Routes.MapRoute( @@ -189,7 +189,7 @@ namespace Umbraco.Web.Runtime RouteTable.Routes.RegisterArea(); // register all back office routes - RouteTable.Routes.RegisterArea(new BackOfficeArea(globalSettings, ioHelper)); + RouteTable.Routes.RegisterArea(new BackOfficeArea(ioHelper)); // plugin controllers must come first because the next route will catch many things RoutePluginControllers(globalSettings, surfaceControllerTypes, apiControllerTypes, ioHelper); @@ -209,7 +209,7 @@ namespace Umbraco.Web.Runtime UmbracoApiControllerTypeCollection apiControllerTypes, IIOHelper ioHelper) { - var umbracoPath = globalSettings.GetUmbracoMvcArea(ioHelper); + var umbracoPath = ioHelper.GetUmbracoMvcArea(); // need to find the plugin controllers and route them var pluginControllers = surfaceControllerTypes.Concat(apiControllerTypes).ToArray(); diff --git a/src/Umbraco.Web/Runtime/WebInitialComposer.cs b/src/Umbraco.Web/Runtime/WebInitialComposer.cs index 8b7d96e44f..b81cafdb40 100644 --- a/src/Umbraco.Web/Runtime/WebInitialComposer.cs +++ b/src/Umbraco.Web/Runtime/WebInitialComposer.cs @@ -5,6 +5,7 @@ using Microsoft.AspNet.SignalR; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Composing; +using Umbraco.Core.Configuration; using Umbraco.Core.Cookie; using Umbraco.Core.Dictionary; using Umbraco.Core.Events; @@ -42,14 +43,12 @@ using Umbraco.Web.SignalR; using Umbraco.Web.Templates; using Umbraco.Web.Trees; using Umbraco.Web.WebApi; -using Current = Umbraco.Web.Composing.Current; using Umbraco.Web.PropertyEditors; using Umbraco.Examine; using Umbraco.Core.Models; using Umbraco.Core.Request; using Umbraco.Core.Session; using Umbraco.Web.AspNet; -using Umbraco.Web.AspNet; using Umbraco.Web.Models; namespace Umbraco.Web.Runtime @@ -291,6 +290,9 @@ namespace Umbraco.Web.Runtime // replace with web implementation composition.RegisterUnique(); + + // Config manipulator + composition.RegisterUnique(); } } } diff --git a/src/Umbraco.Web/Security/AppBuilderExtensions.cs b/src/Umbraco.Web/Security/AppBuilderExtensions.cs index 17a5efd1e6..8fab9f4ea8 100644 --- a/src/Umbraco.Web/Security/AppBuilderExtensions.cs +++ b/src/Umbraco.Web/Security/AppBuilderExtensions.cs @@ -235,7 +235,7 @@ namespace Umbraco.Web.Security var cookieAuthOptions = app.CreateUmbracoCookieAuthOptions( umbracoContextAccessor, globalSettings, runtimeState, securitySettings, //This defines the explicit path read cookies from for this middleware - ioHelper, requestCache, new[] {$"{globalSettings.Path}/backoffice/UmbracoApi/Authentication/GetRemainingTimeoutSeconds"}); + ioHelper, requestCache, new[] {$"{ioHelper.BackOfficePath}/backoffice/UmbracoApi/Authentication/GetRemainingTimeoutSeconds"}); cookieAuthOptions.Provider = cookieOptions.Provider; //This is a custom middleware, we need to return the user's remaining logged in seconds @@ -243,7 +243,8 @@ namespace Umbraco.Web.Security cookieAuthOptions, Current.Configs.Global(), Current.Configs.Security(), - app.CreateLogger()); + app.CreateLogger(), + Current.IOHelper); //This is required so that we can read the auth ticket format outside of this pipeline app.CreatePerOwinContext( @@ -344,7 +345,7 @@ namespace Umbraco.Web.Security CookieName = Constants.Security.BackOfficeExternalCookieName, ExpireTimeSpan = TimeSpan.FromMinutes(5), //Custom cookie manager so we can filter requests - CookieManager = new BackOfficeCookieManager(umbracoContextAccessor, runtimeState, globalSettings, ioHelper, requestCache), + CookieManager = new BackOfficeCookieManager(umbracoContextAccessor, runtimeState, ioHelper, requestCache), CookiePath = "/", CookieSecure = globalSettings.UseHttps ? CookieSecureOption.Always : CookieSecureOption.SameAsRequest, CookieHttpOnly = true, @@ -396,7 +397,7 @@ namespace Umbraco.Web.Security if (runtimeState.Level != RuntimeLevel.Run) return app; var authOptions = app.CreateUmbracoCookieAuthOptions(umbracoContextAccessor, globalSettings, runtimeState, securitySettings, ioHelper, requestCache); - app.Use(typeof(PreviewAuthenticationMiddleware), authOptions, Current.Configs.Global(), ioHelper); + app.Use(typeof(PreviewAuthenticationMiddleware), authOptions, ioHelper); // This middleware must execute at least on PostAuthentication, by default it is on Authorize // The middleware needs to execute after the RoleManagerModule executes which is during PostAuthenticate, diff --git a/src/Umbraco.Web/Security/BackOfficeCookieManager.cs b/src/Umbraco.Web/Security/BackOfficeCookieManager.cs index b7b39ea4bf..17c5f1befb 100644 --- a/src/Umbraco.Web/Security/BackOfficeCookieManager.cs +++ b/src/Umbraco.Web/Security/BackOfficeCookieManager.cs @@ -23,25 +23,23 @@ namespace Umbraco.Web.Security { private readonly IUmbracoContextAccessor _umbracoContextAccessor; private readonly IRuntimeState _runtime; - private readonly IGlobalSettings _globalSettings; private readonly IIOHelper _ioHelper; private readonly IRequestCache _requestCache; private readonly string[] _explicitPaths; private readonly string _getRemainingSecondsPath; - public BackOfficeCookieManager(IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtime, IGlobalSettings globalSettings, IIOHelper ioHelper, IRequestCache requestCache) - : this(umbracoContextAccessor, runtime, globalSettings, ioHelper,requestCache, null) + public BackOfficeCookieManager(IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtime, IIOHelper ioHelper, IRequestCache requestCache) + : this(umbracoContextAccessor, runtime, ioHelper,requestCache, null) { } - public BackOfficeCookieManager(IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtime, IGlobalSettings globalSettings, IIOHelper ioHelper, IRequestCache requestCache, IEnumerable explicitPaths) + public BackOfficeCookieManager(IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtime, IIOHelper ioHelper, IRequestCache requestCache, IEnumerable explicitPaths) { _umbracoContextAccessor = umbracoContextAccessor; _runtime = runtime; - _globalSettings = globalSettings; _ioHelper = ioHelper; _requestCache = requestCache; _explicitPaths = explicitPaths?.ToArray(); - _getRemainingSecondsPath = $"{globalSettings.Path}/backoffice/UmbracoApi/Authentication/GetRemainingTimeoutSeconds"; + _getRemainingSecondsPath = $"{ioHelper.BackOfficePath}/backoffice/UmbracoApi/Authentication/GetRemainingTimeoutSeconds"; } /// @@ -105,7 +103,7 @@ namespace Umbraco.Web.Security (checkForceAuthTokens && owinContext.Get(Constants.Security.ForceReAuthFlag) != null) || (checkForceAuthTokens && _requestCache.IsAvailable && _requestCache.Get(Constants.Security.ForceReAuthFlag) != null) //check back office - || request.Uri.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath, _globalSettings, _ioHelper) + || request.Uri.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath, _ioHelper) //check installer || request.Uri.IsInstallerRequest(_ioHelper)) { diff --git a/src/Umbraco.Web/Security/GetUserSecondsMiddleWare.cs b/src/Umbraco.Web/Security/GetUserSecondsMiddleWare.cs index 7c1c4c558c..448ec88915 100644 --- a/src/Umbraco.Web/Security/GetUserSecondsMiddleWare.cs +++ b/src/Umbraco.Web/Security/GetUserSecondsMiddleWare.cs @@ -8,6 +8,7 @@ using Microsoft.Owin.Logging; using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.IO; using Umbraco.Core.Security; namespace Umbraco.Web.Security @@ -26,19 +27,22 @@ namespace Umbraco.Web.Security private readonly IGlobalSettings _globalSettings; private readonly ISecuritySettings _security; private readonly ILogger _logger; + private readonly IIOHelper _ioHelper; public GetUserSecondsMiddleWare( OwinMiddleware next, UmbracoBackOfficeCookieAuthOptions authOptions, IGlobalSettings globalSettings, ISecuritySettings security, - ILogger logger) + ILogger logger, + IIOHelper ioHelper) : base(next) { _authOptions = authOptions ?? throw new ArgumentNullException(nameof(authOptions)); _globalSettings = globalSettings; _security = security; _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _ioHelper = ioHelper; } public override async Task Invoke(IOwinContext context) @@ -48,7 +52,7 @@ namespace Umbraco.Web.Security if (request.Uri.Scheme.InvariantStartsWith("http") && request.Uri.AbsolutePath.InvariantEquals( - $"{_globalSettings.Path}/backoffice/UmbracoApi/Authentication/GetRemainingTimeoutSeconds")) + $"{_ioHelper.BackOfficePath}/backoffice/UmbracoApi/Authentication/GetRemainingTimeoutSeconds")) { var cookie = _authOptions.CookieManager.GetRequestCookie(context, _security.AuthCookieName); if (cookie.IsNullOrWhiteSpace() == false) diff --git a/src/Umbraco.Web/Security/PasswordSecurity.cs b/src/Umbraco.Web/Security/PasswordSecurity.cs index 3e5d65dfd7..e061478117 100644 --- a/src/Umbraco.Web/Security/PasswordSecurity.cs +++ b/src/Umbraco.Web/Security/PasswordSecurity.cs @@ -72,11 +72,6 @@ namespace Umbraco.Core.Security /// public string FormatPasswordForStorage(string hashedPassword, string salt) { - if (PasswordConfiguration.UseLegacyEncoding) - { - return hashedPassword; - } - return salt + hashedPassword; } @@ -88,13 +83,6 @@ namespace Umbraco.Core.Security /// public string HashPassword(string pass, string salt) { - //if we are doing it the old way - - if (PasswordConfiguration.UseLegacyEncoding) - { - return LegacyEncodePassword(pass); - } - //This is the correct way to implement this (as per the sql membership provider) var bytes = Encoding.Unicode.GetBytes(pass); @@ -183,11 +171,6 @@ namespace Umbraco.Core.Security public string ParseStoredHashPassword(string storedString, out string salt) { if (string.IsNullOrWhiteSpace(storedString)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(storedString)); - if (PasswordConfiguration.UseLegacyEncoding) - { - salt = string.Empty; - return storedString; - } var saltLen = GenerateSalt(); salt = storedString.Substring(0, saltLen.Length); @@ -208,15 +191,6 @@ namespace Umbraco.Core.Security /// public HashAlgorithm GetHashAlgorithm(string password) { - if (PasswordConfiguration.UseLegacyEncoding) - { - return new HMACSHA1 - { - //the legacy salt was actually the password :( - Key = Encoding.Unicode.GetBytes(password) - }; - } - if (PasswordConfiguration.HashAlgorithmType.IsNullOrWhiteSpace()) throw new InvalidOperationException("No hash algorithm type specified"); @@ -239,9 +213,9 @@ namespace Umbraco.Core.Security return encodedPassword; } - - + + } } diff --git a/src/Umbraco.Web/Security/PreviewAuthenticationMiddleware.cs b/src/Umbraco.Web/Security/PreviewAuthenticationMiddleware.cs index 18deeafcbf..c73cd061c9 100644 --- a/src/Umbraco.Web/Security/PreviewAuthenticationMiddleware.cs +++ b/src/Umbraco.Web/Security/PreviewAuthenticationMiddleware.cs @@ -12,7 +12,6 @@ namespace Umbraco.Web.Security internal class PreviewAuthenticationMiddleware : OwinMiddleware { private readonly UmbracoBackOfficeCookieAuthOptions _cookieOptions; - private readonly IGlobalSettings _globalSettings; private readonly IIOHelper _ioHelper; /// @@ -22,10 +21,9 @@ namespace Umbraco.Web.Security /// /// public PreviewAuthenticationMiddleware(OwinMiddleware next, - UmbracoBackOfficeCookieAuthOptions cookieOptions, IGlobalSettings globalSettings, IIOHelper ioHelper) : base(next) + UmbracoBackOfficeCookieAuthOptions cookieOptions, IIOHelper ioHelper) : base(next) { _cookieOptions = cookieOptions; - _globalSettings = globalSettings; _ioHelper = ioHelper; } @@ -43,7 +41,7 @@ namespace Umbraco.Web.Security var isPreview = request.HasPreviewCookie() && claimsPrincipal != null && request.Uri != null - && request.Uri.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath, _globalSettings, _ioHelper) == false; + && request.Uri.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath, _ioHelper) == false; if (isPreview) { //If we've gotten this far it means a preview cookie has been set and a front-end umbraco document request is executing. diff --git a/src/Umbraco.Web/Security/SessionIdValidator.cs b/src/Umbraco.Web/Security/SessionIdValidator.cs index 11fb28c197..2339bff7f6 100644 --- a/src/Umbraco.Web/Security/SessionIdValidator.cs +++ b/src/Umbraco.Web/Security/SessionIdValidator.cs @@ -31,7 +31,7 @@ namespace Umbraco.Web.Security public static async Task ValidateSessionAsync(TimeSpan validateInterval, CookieValidateIdentityContext context, IGlobalSettings globalSettings, IIOHelper ioHelper) { - if (context.Request.Uri.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath, globalSettings, ioHelper) == false) + if (context.Request.Uri.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath, ioHelper) == false) return; var valid = await ValidateSessionAsync(validateInterval, context.OwinContext, context.Options.CookieManager, context.Options.SystemClock, context.Properties.IssuedUtc, context.Identity, globalSettings); diff --git a/src/Umbraco.Web/Security/UmbracoBackOfficeCookieAuthOptions.cs b/src/Umbraco.Web/Security/UmbracoBackOfficeCookieAuthOptions.cs index 836c0bb53a..5e8bdffbed 100644 --- a/src/Umbraco.Web/Security/UmbracoBackOfficeCookieAuthOptions.cs +++ b/src/Umbraco.Web/Security/UmbracoBackOfficeCookieAuthOptions.cs @@ -42,7 +42,7 @@ namespace Umbraco.Web.Security TicketDataFormat = new UmbracoSecureDataFormat(LoginTimeoutMinutes, secureDataFormat1); //Custom cookie manager so we can filter requests - CookieManager = new BackOfficeCookieManager(umbracoContextAccessor, runtimeState, globalSettings, ioHelper, requestCache, explicitPaths); + CookieManager = new BackOfficeCookieManager(umbracoContextAccessor, runtimeState, ioHelper, requestCache, explicitPaths); } /// diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index ea6ade63c8..634e27fcda 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -545,7 +545,6 @@ - diff --git a/src/Umbraco.Web/UmbracoApplication.cs b/src/Umbraco.Web/UmbracoApplication.cs index 93d3a6210e..9f24da95e3 100644 --- a/src/Umbraco.Web/UmbracoApplication.cs +++ b/src/Umbraco.Web/UmbracoApplication.cs @@ -1,6 +1,7 @@ using System.Threading; using System.Web; using Umbraco.Core; +using Umbraco.Core.Cache; using Umbraco.Core.Runtime; using Umbraco.Core.Configuration; using Umbraco.Core.Hosting; @@ -22,15 +23,20 @@ namespace Umbraco.Web var dbProviderFactoryCreator = new UmbracoDbProviderFactoryCreator(connectionStringConfig?.ProviderName); + var globalSettings = configs.Global(); + var connectionStrings = configs.ConnectionStrings(); + // Determine if we should use the sql main dom or the default - var appSettingMainDomLock = configs.Global().MainDomLock; + var appSettingMainDomLock = globalSettings.MainDomLock; var mainDomLock = appSettingMainDomLock == "SqlMainDomLock" - ? (IMainDomLock)new SqlMainDomLock(logger, configs, dbProviderFactoryCreator) + ? (IMainDomLock)new SqlMainDomLock(logger, globalSettings, connectionStrings, dbProviderFactoryCreator) : new MainDomSemaphoreLock(logger, hostingEnvironment); var mainDom = new MainDom(logger, hostingEnvironment, mainDomLock); - return new WebRuntime(configs, umbracoVersion, ioHelper, logger, profiler, hostingEnvironment, backOfficeInfo, dbProviderFactoryCreator, mainDom, GetTypeFinder()); + var requestCache = new HttpRequestAppCache(() => HttpContext.Current?.Items); + var umbracoBootPermissionChecker = new AspNetUmbracoBootPermissionChecker(); + return new WebRuntime(configs, umbracoVersion, ioHelper, logger, profiler, hostingEnvironment, backOfficeInfo, dbProviderFactoryCreator, mainDom, GetTypeFinder(), requestCache, umbracoBootPermissionChecker); } } } diff --git a/src/Umbraco.Web/UmbracoApplicationBase.cs b/src/Umbraco.Web/UmbracoApplicationBase.cs index 6456e8ca1f..ce5f1304cd 100644 --- a/src/Umbraco.Web/UmbracoApplicationBase.cs +++ b/src/Umbraco.Web/UmbracoApplicationBase.cs @@ -13,6 +13,7 @@ using Umbraco.Core.Logging; using Umbraco.Core.Logging.Serilog; using Umbraco.Web.AspNet; using Umbraco.Web.Hosting; +using Umbraco.Web.Logging; using Current = Umbraco.Web.Composing.Current; namespace Umbraco.Web @@ -32,20 +33,37 @@ namespace Umbraco.Web var configFactory = new ConfigsFactory(); var hostingSettings = configFactory.HostingSettings; - var coreDebug = configFactory.CoreDebug; + var coreDebug = configFactory.CoreDebugSettings; + var globalSettings = configFactory.GlobalSettings; var hostingEnvironment = new AspNetHostingEnvironment(hostingSettings); - var ioHelper = new IOHelper(hostingEnvironment); + var ioHelper = new IOHelper(hostingEnvironment, globalSettings); var logger = SerilogLogger.CreateWithDefaultConfiguration(hostingEnvironment, new AspNetSessionManager(), () => _factory?.GetInstance(), coreDebug, ioHelper, new FrameworkMarchal()); - var configs = configFactory.Create(ioHelper, logger); + var configs = configFactory.Create(); - var backOfficeInfo = new AspNetBackOfficeInfo(configs.Global(), ioHelper, logger, configFactory.WebRoutingSettings); - var profiler = new LogProfiler(logger); + var backOfficeInfo = new AspNetBackOfficeInfo(globalSettings, ioHelper, logger, configFactory.WebRoutingSettings); + var profiler = GetWebProfiler(hostingEnvironment); Umbraco.Composing.Current.Initialize(logger, configs, ioHelper, hostingEnvironment, backOfficeInfo, profiler); Logger = logger; } } + private IProfiler GetWebProfiler(IHostingEnvironment hostingEnvironment) + { + // create and start asap to profile boot + if (!hostingEnvironment.IsDebugMode) + { + // 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; + } + protected UmbracoApplicationBase(ILogger logger, Configs configs, IIOHelper ioHelper, IProfiler profiler, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo) { if (!Umbraco.Composing.Current.IsInitialized) @@ -134,7 +152,7 @@ namespace Umbraco.Web Umbraco.Composing.Current.Profiler, Umbraco.Composing.Current.HostingEnvironment, Umbraco.Composing.Current.BackOfficeInfo); - _factory =_runtime.Boot(register); + _factory = Current.Factory = _runtime.Boot(register); } // called by ASP.NET (auto event wireup) once per app domain diff --git a/src/Umbraco.Web/UmbracoContext.cs b/src/Umbraco.Web/UmbracoContext.cs index a4f679ff5f..6f5fc26f90 100644 --- a/src/Umbraco.Web/UmbracoContext.cs +++ b/src/Umbraco.Web/UmbracoContext.cs @@ -184,7 +184,7 @@ namespace Umbraco.Web { var request = GetRequestFromContext(); if (request?.Url != null - && request.Url.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath, _globalSettings, _ioHelper) == false + && request.Url.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath, _ioHelper) == false && Security.CurrentUser != null) { var previewToken = _cookieManager.GetPreviewCookieValue(); // may be null or empty diff --git a/src/Umbraco.Web/UmbracoDefaultOwinStartup.cs b/src/Umbraco.Web/UmbracoDefaultOwinStartup.cs index 0a82c0644b..a69e6c6f8d 100644 --- a/src/Umbraco.Web/UmbracoDefaultOwinStartup.cs +++ b/src/Umbraco.Web/UmbracoDefaultOwinStartup.cs @@ -27,10 +27,10 @@ namespace Umbraco.Web public class UmbracoDefaultOwinStartup { protected IUmbracoContextAccessor UmbracoContextAccessor => Current.UmbracoContextAccessor; - protected IGlobalSettings GlobalSettings => Current.Configs.Global(); - protected IContentSettings ContentSettings => Current.Configs.Content(); - protected ISecuritySettings SecuritySettings => Current.Configs.Security(); - protected IUserPasswordConfiguration UserPasswordConfig => Current.Configs.UserPasswordConfiguration(); + protected IGlobalSettings GlobalSettings => Current.Factory.GetInstance(); + protected IContentSettings ContentSettings => Current.Factory.GetInstance(); + protected ISecuritySettings SecuritySettings => Current.Factory.GetInstance(); + protected IUserPasswordConfiguration UserPasswordConfig => Current.Factory.GetInstance(); protected IRuntimeState RuntimeState => Current.RuntimeState; protected ServiceContext Services => Current.Services; protected UmbracoMapper Mapper => Current.Mapper; @@ -76,7 +76,7 @@ namespace Umbraco.Web ConfigureUmbracoAuthentication(app); app - .UseSignalR(GlobalSettings, IOHelper) + .UseSignalR(IOHelper) .FinalizeMiddlewareConfiguration(); } diff --git a/src/Umbraco.Web/UmbracoInjectedModule.cs b/src/Umbraco.Web/UmbracoInjectedModule.cs index 3f92ca587e..73e82702a3 100644 --- a/src/Umbraco.Web/UmbracoInjectedModule.cs +++ b/src/Umbraco.Web/UmbracoInjectedModule.cs @@ -6,6 +6,7 @@ using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Configuration; using Umbraco.Core.Exceptions; +using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Web.Composing; using Umbraco.Web.Routing; @@ -30,26 +31,25 @@ namespace Umbraco.Web /// public class UmbracoInjectedModule : IHttpModule { - private readonly IGlobalSettings _globalSettings; private readonly IRuntimeState _runtime; private readonly ILogger _logger; private readonly IPublishedRouter _publishedRouter; private readonly IUmbracoContextFactory _umbracoContextFactory; private readonly RoutableDocumentFilter _routableDocumentLookup; private readonly IRequestCache _requestCache; + private readonly IIOHelper _ioHelper; private readonly UriUtility _uriUtility; public UmbracoInjectedModule( - IGlobalSettings globalSettings, IRuntimeState runtime, ILogger logger, IPublishedRouter publishedRouter, IUmbracoContextFactory umbracoContextFactory, RoutableDocumentFilter routableDocumentLookup, UriUtility uriUtility, - IRequestCache requestCache) + IRequestCache requestCache, + IIOHelper ioHelper) { - _globalSettings = globalSettings; _runtime = runtime; _logger = logger; _publishedRouter = publishedRouter; @@ -57,6 +57,7 @@ namespace Umbraco.Web _routableDocumentLookup = routableDocumentLookup; _uriUtility = uriUtility; _requestCache = requestCache; + _ioHelper = ioHelper; } #region HttpModule event handlers @@ -110,7 +111,7 @@ namespace Umbraco.Web var umbracoContext = Current.UmbracoContext; // re-write for the default back office path - if (httpContext.Request.Url.IsDefaultBackOfficeRequest(_globalSettings)) + if (httpContext.Request.Url.IsDefaultBackOfficeRequest(_ioHelper)) { if (EnsureRuntime(httpContext, umbracoContext.OriginalRequestUrl)) RewriteToBackOfficeHandler(httpContext); @@ -256,7 +257,7 @@ namespace Umbraco.Web private void RewriteToBackOfficeHandler(HttpContextBase context) { // GlobalSettings.Path has already been through IOHelper.ResolveUrl() so it begins with / and vdir (if any) - var rewritePath = _globalSettings.Path.TrimEnd('/') + "/Default"; + var rewritePath = _ioHelper.BackOfficePath.TrimEnd('/') + "/Default"; // rewrite the path to the path of the handler (i.e. /umbraco/RenderMvc) context.RewritePath(rewritePath, "", "", false); @@ -289,7 +290,7 @@ namespace Umbraco.Web var query = pcr.Uri.Query.TrimStart('?'); // GlobalSettings.Path has already been through IOHelper.ResolveUrl() so it begins with / and vdir (if any) - var rewritePath = _globalSettings.Path.TrimEnd('/') + "/RenderMvc"; + var rewritePath = _ioHelper.BackOfficePath.TrimEnd('/') + "/RenderMvc"; // rewrite the path to the path of the handler (i.e. /umbraco/RenderMvc) context.RewritePath(rewritePath, "", query, false);