diff --git a/build/NuSpecs/UmbracoCms.Web.nuspec b/build/NuSpecs/UmbracoCms.Web.nuspec index 7199f414b1..969ac5be3d 100644 --- a/build/NuSpecs/UmbracoCms.Web.nuspec +++ b/build/NuSpecs/UmbracoCms.Web.nuspec @@ -25,7 +25,7 @@ not want this to happen as the alpha of the next major is, really, the next major already. --> - + 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 5c6eade265..be6cee2d0c 100644 --- a/src/Umbraco.Configuration/ConfigsFactory.cs +++ b/src/Umbraco.Configuration/ConfigsFactory.cs @@ -1,7 +1,8 @@ using Umbraco.Configuration; using Umbraco.Configuration.Implementations; +using Umbraco.Configuration.Legacy; using Umbraco.Core.Configuration.HealthChecks; -using Umbraco.Core.Configuration.Implementations; +using Umbraco.Core.Configuration.Legacy; using Umbraco.Core.Configuration.UmbracoSettings; namespace Umbraco.Core.Configuration @@ -9,8 +10,7 @@ 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(); @@ -27,7 +27,7 @@ namespace Umbraco.Core.Configuration public IMemberPasswordConfiguration MemberPasswordConfigurationSettings { get; } = new MemberPasswordConfigurationSettings(); public IContentSettings ContentSettings { get; } = new ContentSettings(); public IGlobalSettings GlobalSettings { get; } = new GlobalSettings(); - public IHealthChecks HealthChecksSettings { get; } = new HealthChecksSettings(); + public IHealthChecksSettings HealthChecksSettings { get; } = new HealthChecksSettings(); public IConnectionStrings ConnectionStrings { get; } = new ConnectionStrings(); public IModelsBuilderConfig ModelsBuilderConfig { get; } = new ModelsBuilderConfig(); @@ -37,9 +37,8 @@ namespace Umbraco.Core.Configuration configs.Add(() => GlobalSettings); configs.Add(() => HostingSettings); - configs.Add(() => HealthChecksSettings); - configs.Add(() => CoreDebug); - configs.Add(() => MachineKeyConfig); + configs.Add(() => HealthChecksSettings); + configs.Add(() => CoreDebugSettings); configs.Add(() => ConnectionStrings); configs.Add(() => ModelsBuilderConfig); configs.Add(() => IndexCreatorSettings); 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 100% rename from src/Umbraco.Configuration/Implementations/ConfigurationManagerConfigBase.cs rename to src/Umbraco.Configuration/Legacy/ConfigurationManagerConfigBase.cs 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 90% rename from src/Umbraco.Configuration/GlobalSettings.cs rename to src/Umbraco.Configuration/Legacy/GlobalSettings.cs index 6fda5fa9ba..78036f9e42 100644 --- a/src/Umbraco.Configuration/GlobalSettings.cs +++ b/src/Umbraco.Configuration/Legacy/GlobalSettings.cs @@ -7,56 +7,8 @@ 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 diff --git a/src/Umbraco.Configuration/Implementations/HealthChecksSettings.cs b/src/Umbraco.Configuration/Legacy/HealthChecksSettings.cs similarity index 88% rename from src/Umbraco.Configuration/Implementations/HealthChecksSettings.cs rename to src/Umbraco.Configuration/Legacy/HealthChecksSettings.cs index 656a3ffc82..23385d1378 100644 --- a/src/Umbraco.Configuration/Implementations/HealthChecksSettings.cs +++ b/src/Umbraco.Configuration/Legacy/HealthChecksSettings.cs @@ -2,9 +2,9 @@ using System.Configuration; using Umbraco.Core.Configuration.HealthChecks; -namespace Umbraco.Core.Configuration.Implementations +namespace Umbraco.Core.Configuration.Legacy { - public class HealthChecksSettings : IHealthChecks + public class HealthChecksSettings : IHealthChecksSettings { private HealthChecksSection _healthChecksSection; 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 99% rename from src/Umbraco.Configuration/ModelsBuilderConfig.cs rename to src/Umbraco.Configuration/Legacy/ModelsBuilderConfig.cs index 79f4b065a0..f6395b23b4 100644 --- a/src/Umbraco.Configuration/ModelsBuilderConfig.cs +++ b/src/Umbraco.Configuration/Legacy/ModelsBuilderConfig.cs @@ -6,7 +6,7 @@ using Umbraco.Core.Configuration; using Umbraco.Core; using Umbraco.Core.IO; -namespace Umbraco.Configuration +namespace Umbraco.Configuration.Legacy { /// /// Represents the models builder configuration. 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/Configuration/ConfigsExtensions.cs b/src/Umbraco.Core/Configuration/ConfigsExtensions.cs index 5019282d97..f9ea352399 100644 --- a/src/Umbraco.Core/Configuration/ConfigsExtensions.cs +++ b/src/Umbraco.Core/Configuration/ConfigsExtensions.cs @@ -10,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(); @@ -37,10 +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 ICoreDebug CoreDebug(this Configs configs) - => configs.GetConfig(); + public static IHealthChecksSettings HealthChecks(this Configs configs) + => configs.GetConfig(); + public static ICoreDebugSettings CoreDebug(this Configs configs) + => configs.GetConfig(); } } 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/IConnectionStrings.cs b/src/Umbraco.Core/Configuration/IConnectionStrings.cs index f8d17d6794..0d33378669 100644 --- a/src/Umbraco.Core/Configuration/IConnectionStrings.cs +++ b/src/Umbraco.Core/Configuration/IConnectionStrings.cs @@ -1,5 +1,3 @@ -using Umbraco.Core.IO; - namespace Umbraco.Core.Configuration { public interface IConnectionStrings @@ -8,8 +6,5 @@ namespace Umbraco.Core.Configuration { get; } - - void RemoveConnectionString(string umbracoConnectionName, IIOHelper ioHelper); - void SaveConnectionString(string connectionString, string providerName, IIOHelper ioHelper); } } 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/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/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 60% rename from src/Umbraco.Configuration/ConnectionStrings.cs rename to src/Umbraco.Core/Configuration/XmlConfigManipulator.cs index 66fdb33d5b..333f9dc6f9 100644 --- a/src/Umbraco.Configuration/ConnectionStrings.cs +++ b/src/Umbraco.Core/Configuration/XmlConfigManipulator.cs @@ -9,22 +9,21 @@ 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 ConfigConnectionString this[string key] + public XmlConfigManipulator(IIOHelper ioHelper, ILogger logger) { - get - { - var settings = ConfigurationManager.ConnectionStrings[key]; - if (settings == null) return null; - return new ConfigConnectionString(settings.ConnectionString, settings.ProviderName, settings.Name); - } + _ioHelper = ioHelper; + _logger = logger; } - public void RemoveConnectionString(string key, IIOHelper ioHelper) + public void RemoveConnectionString() { - var fileName = ioHelper.MapPath(string.Format("{0}/web.config", ioHelper.Root)); + var key = Constants.System.UmbracoConnectionName; + var fileName = _ioHelper.MapPath(string.Format("{0}/web.config", _ioHelper.Root)); var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace); var appSettings = xml.Root.DescendantsAndSelf("appSettings").Single(); @@ -36,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, IIOHelper ioHelper) + 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)."); @@ -68,7 +71,7 @@ namespace Umbraco.Core.Configuration if (configSourceAttribute != null) { fileSource = configSourceAttribute.Value; - fileName = ioHelper.MapPath(ioHelper.Root + "/" + fileSource); + fileName = _ioHelper.MapPath(_ioHelper.Root + "/" + fileSource); if (!File.Exists(fileName)) throw new Exception($"Invalid configSource \"{fileSource}\" (no such file)."); @@ -77,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", @@ -96,19 +101,18 @@ namespace Umbraco.Core.Configuration } // save - Current.Logger.Info("Saving connection string to {ConfigFile}.", fileSource); + _logger.Info("Saving connection string to {ConfigFile}.", fileSource); xml.Save(fileName, SaveOptions.DisableFormatting); - Current.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.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 8c73e63b78..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, ioHelper); + 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/Migrations/Install/DatabaseBuilder.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs index b92a8499fa..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, ioHelper); + _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, _ioHelper); + _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, _ioHelper); + _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, _ioHelper); + _configManipulator.SaveConnectionString(connectionString, Constants.DbProviderNames.SqlServer); _databaseFactory.Configure(connectionString, Constants.DbProviderNames.SqlServer); } diff --git a/src/Umbraco.Infrastructure/Models/Property.cs b/src/Umbraco.Infrastructure/Models/Property.cs index 36efbad404..89875811bd 100644 --- a/src/Umbraco.Infrastructure/Models/Property.cs +++ b/src/Umbraco.Infrastructure/Models/Property.cs @@ -98,7 +98,7 @@ namespace Umbraco.Core.Models /// /// Represents a property value. /// - public class PropertyValue : IPropertyValue + public class PropertyValue : IPropertyValue, IEquatable { // TODO: Either we allow change tracking at this class level, or we add some special change tracking collections to the Property // class to deal with change tracking which variants have changed @@ -143,6 +143,27 @@ namespace Umbraco.Core.Models /// public IPropertyValue Clone() => new PropertyValue { _culture = _culture, _segment = _segment, PublishedValue = PublishedValue, EditedValue = EditedValue }; + + + public override bool Equals(object obj) + { + return Equals(obj as PropertyValue); + } + + public bool Equals(PropertyValue other) + { + return other != null && + _culture == other._culture && + _segment == other._segment; + } + + public override int GetHashCode() + { + var hashCode = -1254204277; + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(_culture); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(_segment); + return hashCode; + } } private static readonly DelegateEqualityComparer PropertyValueComparer = new DelegateEqualityComparer( @@ -508,6 +529,19 @@ namespace Umbraco.Core.Models var clonedEntity = (Property)clone; + //manually clone _values, _pvalue, _vvalues + clonedEntity._values = _values?.Select(x => x.Clone()).ToList(); // all values get copied + clonedEntity._pvalue = _pvalue?.Clone(); + // the tricky part here is that _values contains ALL values including the values in the _vvalues + // dictionary and they are by reference which is why we have equality overloads on PropertyValue + if (clonedEntity._vvalues != null) + { + clonedEntity._vvalues = new Dictionary(); + foreach (var item in _vvalues) + { + clonedEntity._vvalues[item.Key] = clonedEntity._values.First(x => x.Equals(item.Value)); + } + } //need to manually assign since this is a readonly property clonedEntity.PropertyType = (PropertyType) PropertyType.DeepClone(); } diff --git a/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs b/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs index 5f4e9aec1d..9318b223df 100644 --- a/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs +++ b/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs @@ -175,6 +175,7 @@ namespace Umbraco.Core.Runtime // 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 74a1c06eec..94497d2e13 100644 --- a/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs +++ b/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs @@ -403,9 +403,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. 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 ea08dc9135..12b12616f0 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. /// @@ -33,27 +30,12 @@ namespace Umbraco.Web.Runtime IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo, IDbProviderFactoryCreator dbProviderFactoryCreator, - IMainDom mainDom): - base(configs, umbracoVersion, ioHelper, logger, profiler ,new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, dbProviderFactoryCreator, mainDom) + IMainDom mainDom, + IRequestCache requestCache, + IUmbracoBootPermissionChecker umbracoBootPermissionChecker): + base(configs, umbracoVersion, ioHelper, logger, profiler ,umbracoBootPermissionChecker, hostingEnvironment, backOfficeInfo, dbProviderFactoryCreator, mainDom) { - - 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; } /// @@ -74,7 +56,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 @@ -93,13 +75,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/Umbraco.Infrastructure.csproj b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj index 5e0088cc2e..00f48479f8 100644 --- a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj +++ b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj @@ -11,6 +11,8 @@ + + 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 6b484bbcfc..f7427009ba 100644 --- a/src/Umbraco.Tests.Common/SettingsForTests.cs +++ b/src/Umbraco.Tests.Common/SettingsForTests.cs @@ -2,6 +2,7 @@ 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; diff --git a/src/Umbraco.Tests.Common/TestHelperBase.cs b/src/Umbraco.Tests.Common/TestHelperBase.cs index a5810715fb..d21aff89d9 100644 --- a/src/Umbraco.Tests.Common/TestHelperBase.cs +++ b/src/Umbraco.Tests.Common/TestHelperBase.cs @@ -93,7 +93,7 @@ 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; } 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 a41d86ee2e..cb8da6e23d 100644 --- a/src/Umbraco.Tests/Components/ComponentTests.cs +++ b/src/Umbraco.Tests/Components/ComponentTests.cs @@ -35,7 +35,7 @@ namespace Umbraco.Tests.Components var typeFinder = TestHelper.GetTypeFinder(); 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/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/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 d2acc90439..5ed96365fd 100644 --- a/src/Umbraco.Tests/ModelsBuilder/ConfigTests.cs +++ b/src/Umbraco.Tests/ModelsBuilder/ConfigTests.cs @@ -1,6 +1,7 @@ using System.Configuration; using NUnit.Framework; using Umbraco.Configuration; +using Umbraco.Configuration.Legacy; using Umbraco.Core; using Umbraco.Core.Configuration; 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 de411c96ec..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; @@ -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 096f2dcf59..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; @@ -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/RenderRouteHandlerTests.cs b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs index 5698d41009..b6b671fb3b 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) + : base(configs, umbracoVersion, ioHelper, Mock.Of(), Mock.Of(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, TestHelper.GetRequestCache(), new AspNetUmbracoBootPermissionChecker()) { } 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/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/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index fa47f085c9..79a2832822 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -1890,6 +1890,49 @@ namespace Umbraco.Tests.Services //Assert.AreNotEqual(content.Name, copy.Name); } + [Test] + public void Can_Copy_And_Modify_Content_With_Events() + { + // see https://github.com/umbraco/Umbraco-CMS/issues/5513 + + TypedEventHandler> copying = (sender, args) => + { + args.Copy.SetValue("title", "1"); + args.Original.SetValue("title", "2"); + }; + + TypedEventHandler> copied = (sender, args) => + { + var copyVal = args.Copy.GetValue("title"); + var origVal = args.Original.GetValue("title"); + + Assert.AreEqual("1", copyVal); + Assert.AreEqual("2", origVal); + }; + + try + { + var contentService = ServiceContext.ContentService; + + ContentService.Copying += copying; + ContentService.Copied += copied; + + var contentType = MockedContentTypes.CreateSimpleContentType(); + ServiceContext.ContentTypeService.Save(contentType); + var content = MockedContent.CreateSimpleContent(contentType); + content.SetValue("title", "New Value"); + contentService.Save(content); + + var copy = contentService.Copy(content, content.ParentId, false, Constants.Security.SuperUserId); + Assert.AreEqual("1", copy.GetValue("title")); + } + finally + { + ContentService.Copying -= copying; + ContentService.Copied -= copied; + } + } + [Test] public void Can_Copy_Recursive() { 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/TestHelper.cs b/src/Umbraco.Tests/TestHelpers/TestHelper.cs index 693fd73231..95e211db24 100644 --- a/src/Umbraco.Tests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests/TestHelpers/TestHelper.cs @@ -85,7 +85,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 be8f7db7e8..33e477df2c 100644 --- a/src/Umbraco.Tests/TestHelpers/TestObjects.cs +++ b/src/Umbraco.Tests/TestHelpers/TestObjects.cs @@ -255,7 +255,7 @@ namespace Umbraco.Tests.TestHelpers typeFinder = typeFinder ?? new TypeFinder(logger, new DefaultUmbracoAssemblyProvider(GetType().Assembly)); fileSystems = fileSystems ?? new FileSystems(Current.Factory, logger, TestHelper.IOHelper, SettingsForTests.GenerateMockGlobalSettings()); - var coreDebug = TestHelper.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 72c8d8b981..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: 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 5cd2b590c8..0da6950d04 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 c05f4af4f8..8f94fba957 100644 --- a/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoBackOfficeServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoBackOfficeServiceCollectionExtensions.cs @@ -1,56 +1,82 @@ -using System.Configuration; 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.Configuration; +using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Logging.Serilog; -using Umbraco.Core.Runtime; namespace Umbraco.Web.BackOffice.AspNetCore { public static class UmbracoBackOfficeServiceCollectionExtensions { - public static IServiceCollection AddUmbracoBackOffice(this IServiceCollection services) + 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(); - - CreateCompositionRoot(services); + services.AddSingleton(configs); return services; } - - private static void CreateCompositionRoot(IServiceCollection services) + public static IServiceCollection AddUmbracoBackOffice(this IServiceCollection services) { + services.AddSingleton(); + var serviceProvider = services.BuildServiceProvider(); var httpContextAccessor = serviceProvider.GetService(); var webHostEnvironment = serviceProvider.GetService(); var hostApplicationLifetime = serviceProvider.GetService(); - var configFactory = new ConfigsFactory(); + var configs = serviceProvider.GetService(); - var hostingSettings = configFactory.HostingSettings; - var coreDebug = configFactory.CoreDebug; - var globalSettings = configFactory.GlobalSettings; + services.CreateCompositionRoot( + httpContextAccessor, + webHostEnvironment, + hostApplicationLifetime, + configs); - var hostingEnvironment = new AspNetCoreHostingEnvironment(hostingSettings, webHostEnvironment, httpContextAccessor, hostApplicationLifetime); + return services; + } + + + 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 configs = configFactory.Create(); + 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; } } } 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/Program.cs b/src/Umbraco.Web.UI.NetCore/Program.cs index 21eb1b6585..bbe78907f1 100644 --- a/src/Umbraco.Web.UI.NetCore/Program.cs +++ b/src/Umbraco.Web.UI.NetCore/Program.cs @@ -1,11 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; + namespace Umbraco.Web.UI.BackOffice { diff --git a/src/Umbraco.Web.UI.NetCore/Startup.cs b/src/Umbraco.Web.UI.NetCore/Startup.cs index 8e4da28917..9ef4985aea 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.AddUmbracoWebsite(); services.AddUmbracoBackOffice(); } 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.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 1087cce531..fe11a8d9aa 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -84,7 +84,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/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/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/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/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/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/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index ea6ade63c8..e8aaecdf4d 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -63,7 +63,7 @@ - + 2.0.0-alpha.20200128.15 @@ -545,7 +545,6 @@ - @@ -586,4 +585,4 @@ - \ No newline at end of file + diff --git a/src/Umbraco.Web/UmbracoApplication.cs b/src/Umbraco.Web/UmbracoApplication.cs index 891d80bb81..b7cdc1039a 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; @@ -33,7 +34,9 @@ namespace Umbraco.Web var mainDom = new MainDom(logger, hostingEnvironment, mainDomLock); - return new WebRuntime(configs, umbracoVersion, ioHelper, logger, profiler, hostingEnvironment, backOfficeInfo, dbProviderFactoryCreator, mainDom); + var requestCache = new HttpRequestAppCache(() => HttpContext.Current?.Items); + var umbracoBootPermissionChecker = new AspNetUmbracoBootPermissionChecker(); + return new WebRuntime(configs, umbracoVersion, ioHelper, logger, profiler, hostingEnvironment, backOfficeInfo, dbProviderFactoryCreator, mainDom, requestCache, umbracoBootPermissionChecker); } } } diff --git a/src/Umbraco.Web/UmbracoApplicationBase.cs b/src/Umbraco.Web/UmbracoApplicationBase.cs index 889cae5002..fe4622d8fa 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 @@ -34,7 +35,7 @@ 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); @@ -43,12 +44,28 @@ namespace Umbraco.Web var configs = configFactory.Create(); var backOfficeInfo = new AspNetBackOfficeInfo(globalSettings, ioHelper, logger, configFactory.WebRoutingSettings); - var profiler = new LogProfiler(logger); + var profiler = GetWebProfiler(hostingEnvironment); Umbraco.Composing.Current.Initialize(logger, configs, ioHelper, hostingEnvironment, backOfficeInfo, profiler); } } + 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) @@ -114,7 +131,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