From 00418959f2fdb9bf81870c05c1fee505df3d1310 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Wed, 18 Mar 2020 19:17:51 +0100 Subject: [PATCH] Extracted IConfigManipulator from IConnectionStrings, and implemented a XML (legacy) and JSON version. --- .../Legacy/ConnectionStrings.cs | 99 +-------- .../Models/ConnectionStrings.cs | 15 +- .../Umbraco.Configuration.csproj | 1 + .../Configuration/IConfigManipulator.cs | 10 + .../Configuration/IConnectionStrings.cs | 5 - .../Configuration/XmlConfigManipulator.cs | 118 ++++++++++ .../Configuration/JsonConfigManipulator.cs | 157 ++++++++++++++ .../InstallSteps/DatabaseInstallStep.cs | 10 +- .../InstallSteps/DatabaseUpgradeStep.cs | 14 +- .../Migrations/Install/DatabaseBuilder.cs | 14 +- .../Runtime/CoreInitialComposer.cs | 1 + .../Umbraco.Infrastructure.csproj | 2 + ...coBackOfficeServiceCollectionExtensions.cs | 12 +- .../appsettings.Development.json | 3 + src/Umbraco.Web.UI.NetCore/appsettings.json | 202 +++++++++--------- src/Umbraco.Web/Runtime/WebInitialComposer.cs | 4 + 16 files changed, 431 insertions(+), 236 deletions(-) create mode 100644 src/Umbraco.Core/Configuration/IConfigManipulator.cs create mode 100644 src/Umbraco.Core/Configuration/XmlConfigManipulator.cs create mode 100644 src/Umbraco.Infrastructure/Configuration/JsonConfigManipulator.cs diff --git a/src/Umbraco.Configuration/Legacy/ConnectionStrings.cs b/src/Umbraco.Configuration/Legacy/ConnectionStrings.cs index 66fdb33d5b..a02c351118 100644 --- a/src/Umbraco.Configuration/Legacy/ConnectionStrings.cs +++ b/src/Umbraco.Configuration/Legacy/ConnectionStrings.cs @@ -1,17 +1,9 @@ -using System; -using System.Configuration; -using System.IO; -using System.Linq; -using System.Xml.Linq; -using Umbraco.Composing; -using Umbraco.Core.IO; -using Umbraco.Core.Logging; +using System.Configuration; namespace Umbraco.Core.Configuration { public class ConnectionStrings : IConnectionStrings { - public ConfigConnectionString this[string key] { get @@ -21,94 +13,5 @@ namespace Umbraco.Core.Configuration return new ConfigConnectionString(settings.ConnectionString, settings.ProviderName, settings.Name); } } - - public void RemoveConnectionString(string key, IIOHelper ioHelper) - { - 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(); - var setting = appSettings.Descendants("add").FirstOrDefault(s => s.Attribute("key").Value == key); - - if (setting != null) - { - setting.Remove(); - 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 ConnectionString in the very nasty 'medium trust'-supportive way. - /// The connection string. - /// The provider name. - public void SaveConnectionString(string connectionString, string providerName, IIOHelper ioHelper) - { - - 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 (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)); - - - var fileSource = "web.config"; - 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)."); - - var connectionStrings = xml.Root.DescendantsAndSelf("connectionStrings").FirstOrDefault(); - if (connectionStrings == null) throw new Exception($"Invalid {fileSource} file (no connection strings)."); - - // handle configSource - var configSourceAttribute = connectionStrings.Attribute("configSource"); - if (configSourceAttribute != null) - { - fileSource = configSourceAttribute.Value; - fileName = ioHelper.MapPath(ioHelper.Root + "/" + fileSource); - - if (!File.Exists(fileName)) - throw new Exception($"Invalid configSource \"{fileSource}\" (no such file)."); - - xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace); - 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)."); - } - - // create or update connection string - var setting = connectionStrings.Descendants("add").FirstOrDefault(s => s.Attribute("name")?.Value == Constants.System.UmbracoConnectionName); - if (setting == null) - { - connectionStrings.Add(new XElement("add", - new XAttribute("name", Constants.System.UmbracoConnectionName), - new XAttribute("connectionString", connectionString), - new XAttribute("providerName", providerName))); - } - else - { - AddOrUpdateAttribute(setting, "connectionString", connectionString); - AddOrUpdateAttribute(setting, "providerName", providerName); - } - - // save - Current.Logger.Info("Saving connection string to {ConfigFile}.", fileSource); - xml.Save(fileName, SaveOptions.DisableFormatting); - Current.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; - } - } } diff --git a/src/Umbraco.Configuration/Models/ConnectionStrings.cs b/src/Umbraco.Configuration/Models/ConnectionStrings.cs index 167e636bfb..f29ce4ea8f 100644 --- a/src/Umbraco.Configuration/Models/ConnectionStrings.cs +++ b/src/Umbraco.Configuration/Models/ConnectionStrings.cs @@ -1,7 +1,8 @@ using System; +using System.Linq; +using System.Text.Json.Serialization; using Microsoft.Extensions.Configuration; using Umbraco.Core.Configuration; -using Umbraco.Core.IO; namespace Umbraco.Configuration.Models { @@ -19,17 +20,5 @@ namespace Umbraco.Configuration.Models get => new ConfigConnectionString(_configuration.GetConnectionString(key), "System.Data.SqlClient", key); set => throw new NotImplementedException(); } - - public void RemoveConnectionString(string umbracoConnectionName, IIOHelper ioHelper) - { - //TODO We need to figure out what to do here.. We cond have another config setting, that tells with file(s) to update? or should we assume appsettings.json - throw new NotImplementedException(); - } - - public void SaveConnectionString(string connectionString, string providerName, IIOHelper ioHelper) - { - //TODO We need to figure out what to do here.. We cond have another config setting, that tells with file(s) to update? or should we assume appsettings.json - throw new NotImplementedException(); - } } } diff --git a/src/Umbraco.Configuration/Umbraco.Configuration.csproj b/src/Umbraco.Configuration/Umbraco.Configuration.csproj index 8505d6b9b0..88bb3639d0 100644 --- a/src/Umbraco.Configuration/Umbraco.Configuration.csproj +++ b/src/Umbraco.Configuration/Umbraco.Configuration.csproj @@ -24,6 +24,7 @@ + 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/XmlConfigManipulator.cs b/src/Umbraco.Core/Configuration/XmlConfigManipulator.cs new file mode 100644 index 0000000000..333f9dc6f9 --- /dev/null +++ b/src/Umbraco.Core/Configuration/XmlConfigManipulator.cs @@ -0,0 +1,118 @@ +using System; +using System.Configuration; +using System.IO; +using System.Linq; +using System.Xml.Linq; +using Umbraco.Composing; +using Umbraco.Core.IO; +using Umbraco.Core.Logging; + +namespace Umbraco.Core.Configuration +{ + public class XmlConfigManipulator : IConfigManipulator + { + private readonly IIOHelper _ioHelper; + private readonly ILogger _logger; + + public XmlConfigManipulator(IIOHelper ioHelper, ILogger logger) + { + _ioHelper = ioHelper; + _logger = logger; + } + + public void RemoveConnectionString() + { + var key = Constants.System.UmbracoConnectionName; + var fileName = _ioHelper.MapPath(string.Format("{0}/web.config", _ioHelper.Root)); + var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace); + + var appSettings = xml.Root.DescendantsAndSelf("appSettings").Single(); + var setting = appSettings.Descendants("add").FirstOrDefault(s => s.Attribute("key").Value == key); + + if (setting != null) + { + setting.Remove(); + 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 ConnectionString in the very nasty 'medium trust'-supportive way. + /// The connection string. + /// The provider name. + 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 (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)); + + + var fileSource = "web.config"; + 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)."); + + var connectionStrings = xml.Root.DescendantsAndSelf("connectionStrings").FirstOrDefault(); + if (connectionStrings == null) throw new Exception($"Invalid {fileSource} file (no connection strings)."); + + // handle configSource + var configSourceAttribute = connectionStrings.Attribute("configSource"); + if (configSourceAttribute != null) + { + fileSource = configSourceAttribute.Value; + fileName = _ioHelper.MapPath(_ioHelper.Root + "/" + fileSource); + + if (!File.Exists(fileName)) + throw new Exception($"Invalid configSource \"{fileSource}\" (no such file)."); + + xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace); + 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)."); + } + + // create or update connection string + var setting = connectionStrings.Descendants("add").FirstOrDefault(s => + s.Attribute("name")?.Value == Constants.System.UmbracoConnectionName); + if (setting == null) + { + connectionStrings.Add(new XElement("add", + new XAttribute("name", Constants.System.UmbracoConnectionName), + new XAttribute("connectionString", connectionString), + new XAttribute("providerName", providerName))); + } + else + { + AddOrUpdateAttribute(setting, "connectionString", connectionString); + AddOrUpdateAttribute(setting, "providerName", providerName); + } + + // save + _logger.Info("Saving connection string to {ConfigFile}.", fileSource); + xml.Save(fileName, SaveOptions.DisableFormatting); + _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; + } + } +} 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/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/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/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/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.Web.BackOffice/AspNetCore/UmbracoBackOfficeServiceCollectionExtensions.cs b/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoBackOfficeServiceCollectionExtensions.cs index d06039f3f5..334e992617 100644 --- a/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoBackOfficeServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoBackOfficeServiceCollectionExtensions.cs @@ -8,7 +8,6 @@ using Umbraco.Configuration; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Configuration; -using Umbraco.Core.Configuration.HealthChecks; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Logging.Serilog; @@ -24,7 +23,6 @@ namespace Umbraco.Web.BackOffice.AspNetCore var configsFactory = new AspNetCoreConfigsFactory(configuration); var configs = configsFactory.Create(); - services.AddSingleton(configs); return services; @@ -39,6 +37,7 @@ namespace Umbraco.Web.BackOffice.AspNetCore var httpContextAccessor = serviceProvider.GetService(); var webHostEnvironment = serviceProvider.GetService(); var hostApplicationLifetime = serviceProvider.GetService(); + var configs = serviceProvider.GetService(); services.CreateCompositionRoot( @@ -62,10 +61,13 @@ namespace Umbraco.Web.BackOffice.AspNetCore var coreDebug = configs.CoreDebug(); var globalSettings = configs.Global(); - var hostingEnvironment = new AspNetCoreHostingEnvironment(hostingSettings, webHostEnvironment, httpContextAccessor, hostApplicationLifetime); + 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 logger = SerilogLogger.CreateWithDefaultConfiguration(hostingEnvironment, + new AspNetCoreSessionIdResolver(httpContextAccessor), + () => services.BuildServiceProvider().GetService(), coreDebug, ioHelper, + new AspNetCoreMarchal()); var backOfficeInfo = new AspNetCoreBackOfficeInfo(globalSettings); var profiler = new LogProfiler(logger); 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 a1cbdba994..de282cf66b 100644 --- a/src/Umbraco.Web.UI.NetCore/appsettings.json +++ b/src/Umbraco.Web.UI.NetCore/appsettings.json @@ -1,105 +1,103 @@ { - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } - }, - "AllowedHosts": "*", - "Umbraco": { - "CMS": { - "Imaging": { - - "Resize": { - "MaxWidth": 5000, - "MaxHeight": 5000 - }, - "CacheFolder" : "../App_Data/Cache", - "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": { - " ": "-", - "\"":"", - "'":"", - "%":"", - ".":"", - ";":"", - "/":"", - "\\":"", - ":":"", - "#":"", - "+":"plus", - "*":"star", - "&":"", - "?":"", - "æ":"ae", - "ø":"oe", - "å":"aa", - "ä":"ae", - "ö":"oe", - "ü":"ue", - "ß":"ss", - "|":"-", - "<":"", - ">":"" - } - } - }, - + "ConnectionStrings": { + "umbracoDbDSN": "" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" } + }, + "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": { + " ": "-", + "\"": "", + "'": "", + "%": "", + ".": "", + ";": "", + "/": "", + "\\": "", + ":": "", + "#": "", + "+": "plus", + "*": "star", + "&": "", + "?": "", + "æ": "ae", + "ø": "oe", + "å": "aa", + "ä": "ae", + "ö": "oe", + "ü": "ue", + "ß": "ss", + "|": "-", + "<": "", + ">": "" + } + } + } + } } diff --git a/src/Umbraco.Web/Runtime/WebInitialComposer.cs b/src/Umbraco.Web/Runtime/WebInitialComposer.cs index 1224262901..c1cf76d168 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; @@ -290,6 +291,9 @@ namespace Umbraco.Web.Runtime // replace with web implementation composition.RegisterUnique(); + + // Config manipulator + composition.RegisterUnique(); } } }