From 5f13dde1cd32e602327dfbe9435c7a44f8d2e1e4 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Thu, 12 Mar 2020 16:56:39 +0100 Subject: [PATCH] Moved functionality to write to the connection strings into the configuration area --- src/Umbraco.Configuration/ConfigsFactory.cs | 5 +- .../ConnectionStrings.cs | 78 ++++++++++++++++- .../Configuration/IConfigsFactory.cs | 3 +- .../Configuration/IConnectionStrings.cs | 1 + .../Migrations/Install/DatabaseBuilder.cs | 84 +++---------------- .../Runtimes/CoreRuntimeTests.cs | 2 +- src/Umbraco.Tests/TestHelpers/TestHelper.cs | 2 +- ...coBackOfficeServiceCollectionExtensions.cs | 4 +- src/Umbraco.Web/UmbracoApplicationBase.cs | 4 +- 9 files changed, 99 insertions(+), 84 deletions(-) diff --git a/src/Umbraco.Configuration/ConfigsFactory.cs b/src/Umbraco.Configuration/ConfigsFactory.cs index 8650cc585e..2ba3a109e1 100644 --- a/src/Umbraco.Configuration/ConfigsFactory.cs +++ b/src/Umbraco.Configuration/ConfigsFactory.cs @@ -4,6 +4,7 @@ using Umbraco.Configuration.Implementations; using Umbraco.Core.Configuration.HealthChecks; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; +using Umbraco.Core.Logging; namespace Umbraco.Core.Configuration { @@ -29,7 +30,7 @@ namespace Umbraco.Core.Configuration public IMemberPasswordConfiguration MemberPasswordConfigurationSettings { get; } = new MemberPasswordConfigurationSettings(); public IContentSettings ContentSettings { get; } = new ContentSettings(); - public Configs Create(IIOHelper ioHelper) + public Configs Create(IIOHelper ioHelper, ILogger logger) { var configs = new Configs(section => ConfigurationManager.GetSection(section)); configs.Add(() => new GlobalSettings(ioHelper)); @@ -39,7 +40,7 @@ namespace Umbraco.Core.Configuration configs.Add(() => CoreDebug); configs.Add(() => MachineKeyConfig); - configs.Add(() => new ConnectionStrings(ioHelper)); + configs.Add(() => new ConnectionStrings(ioHelper, logger)); configs.Add(() => new ModelsBuilderConfig(ioHelper)); diff --git a/src/Umbraco.Configuration/ConnectionStrings.cs b/src/Umbraco.Configuration/ConnectionStrings.cs index 6a00974831..23436d6caf 100644 --- a/src/Umbraco.Configuration/ConnectionStrings.cs +++ b/src/Umbraco.Configuration/ConnectionStrings.cs @@ -1,18 +1,22 @@ using System; using System.Configuration; +using System.IO; using System.Linq; using System.Xml.Linq; using Umbraco.Core.IO; +using Umbraco.Core.Logging; namespace Umbraco.Core.Configuration { public class ConnectionStrings : IConnectionStrings { private readonly IIOHelper _ioHelper; + private readonly ILogger _logger; - public ConnectionStrings(IIOHelper ioHelper) + public ConnectionStrings(IIOHelper ioHelper, ILogger logger) { _ioHelper = ioHelper; + _logger = logger; } public ConfigConnectionString this[string key] @@ -41,5 +45,77 @@ namespace Umbraco.Core.Configuration } 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.Core/Configuration/IConfigsFactory.cs b/src/Umbraco.Core/Configuration/IConfigsFactory.cs index 98a24ca37f..b2ad6295a1 100644 --- a/src/Umbraco.Core/Configuration/IConfigsFactory.cs +++ b/src/Umbraco.Core/Configuration/IConfigsFactory.cs @@ -1,9 +1,10 @@ using Umbraco.Core.IO; +using Umbraco.Core.Logging; namespace Umbraco.Core.Configuration { public interface IConfigsFactory { - Configs Create(IIOHelper ioHelper); + Configs Create(IIOHelper ioHelper, ILogger logger); } } diff --git a/src/Umbraco.Core/Configuration/IConnectionStrings.cs b/src/Umbraco.Core/Configuration/IConnectionStrings.cs index acd2281a1e..2a14c0e614 100644 --- a/src/Umbraco.Core/Configuration/IConnectionStrings.cs +++ b/src/Umbraco.Core/Configuration/IConnectionStrings.cs @@ -8,5 +8,6 @@ namespace Umbraco.Core.Configuration } void RemoveConnectionString(string umbracoConnectionName); + void SaveConnectionString(string connectionString, string providerName); } } diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs index 8b1e6d741b..a5a58dc9f1 100644 --- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs +++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs @@ -28,6 +28,7 @@ namespace Umbraco.Core.Migrations.Install private readonly IIOHelper _ioHelper; private readonly IUmbracoVersion _umbracoVersion; private readonly IDbProviderFactoryCreator _dbProviderFactoryCreator; + private readonly IConnectionStrings _connectionStrings; private DatabaseSchemaResult _databaseSchemaValidationResult; @@ -44,7 +45,8 @@ namespace Umbraco.Core.Migrations.Install IKeyValueService keyValueService, IIOHelper ioHelper, IUmbracoVersion umbracoVersion, - IDbProviderFactoryCreator dbProviderFactoryCreator) + IDbProviderFactoryCreator dbProviderFactoryCreator, + IConnectionStrings connectionStrings) { _scopeProvider = scopeProvider; _globalSettings = globalSettings; @@ -56,6 +58,7 @@ namespace Umbraco.Core.Migrations.Install _ioHelper = ioHelper; _umbracoVersion = umbracoVersion; _dbProviderFactoryCreator = dbProviderFactoryCreator; + _connectionStrings = connectionStrings; } #region Status @@ -138,12 +141,12 @@ namespace Umbraco.Core.Migrations.Install /// public void ConfigureEmbeddedDatabaseConnection() { - ConfigureEmbeddedDatabaseConnection(_databaseFactory, _ioHelper, _logger); + ConfigureEmbeddedDatabaseConnection(_databaseFactory, _ioHelper); } - private void ConfigureEmbeddedDatabaseConnection(IUmbracoDatabaseFactory factory, IIOHelper ioHelper, ILogger logger) + private void ConfigureEmbeddedDatabaseConnection(IUmbracoDatabaseFactory factory, IIOHelper ioHelper) { - SaveConnectionString(EmbeddedDatabaseConnectionString, Constants.DbProviderNames.SqlCe, ioHelper, logger); + _connectionStrings.SaveConnectionString(EmbeddedDatabaseConnectionString, Constants.DbProviderNames.SqlCe); var path = Path.Combine(ioHelper.GetRootDirectorySafe(), "App_Data", "Umbraco.sdf"); if (File.Exists(path) == false) @@ -166,7 +169,7 @@ namespace Umbraco.Core.Migrations.Install { const string providerName = Constants.DbProviderNames.SqlServer; - SaveConnectionString(connectionString, providerName, _ioHelper, _logger); + _connectionStrings.SaveConnectionString(connectionString, providerName); _databaseFactory.Configure(connectionString, providerName); } @@ -182,7 +185,7 @@ namespace Umbraco.Core.Migrations.Install { var connectionString = GetDatabaseConnectionString(server, databaseName, user, password, databaseProvider, out var providerName); - SaveConnectionString(connectionString, providerName, _ioHelper, _logger); + _connectionStrings.SaveConnectionString(connectionString, providerName); _databaseFactory.Configure(connectionString, providerName); } @@ -213,7 +216,7 @@ namespace Umbraco.Core.Migrations.Install public void ConfigureIntegratedSecurityDatabaseConnection(string server, string databaseName) { var connectionString = GetIntegratedSecurityDatabaseConnectionString(server, databaseName); - SaveConnectionString(connectionString, Constants.DbProviderNames.SqlServer, _ioHelper, _logger); + _connectionStrings.SaveConnectionString(connectionString, Constants.DbProviderNames.SqlServer); _databaseFactory.Configure(connectionString, Constants.DbProviderNames.SqlServer); } @@ -282,75 +285,8 @@ namespace Umbraco.Core.Migrations.Install return server.ToLower().StartsWith("tcp:".ToLower()); } - /// - /// 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. - /// A logger. - private static void SaveConnectionString(string connectionString, string providerName, IIOHelper ioHelper, ILogger logger) - { - 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; - } #endregion diff --git a/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs b/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs index f10e966cf7..e4d0e596ae 100644 --- a/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs +++ b/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs @@ -96,7 +96,7 @@ namespace Umbraco.Tests.Runtimes private static Configs GetConfigs() { - var configs = new ConfigsFactory().Create(_ioHelper); + var configs = new ConfigsFactory().Create(_ioHelper, _logger); configs.Add(SettingsForTests.GetDefaultGlobalSettings); configs.Add(SettingsForTests.GenerateMockContentSettings); configs.Add(SettingsForTests.GetDefaultHostingSettings); diff --git a/src/Umbraco.Tests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests/TestHelpers/TestHelper.cs index 0bae38f26d..309ba9a5fc 100644 --- a/src/Umbraco.Tests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests/TestHelpers/TestHelper.cs @@ -50,7 +50,7 @@ namespace Umbraco.Tests.TestHelpers public static Configs GetConfigs() { - return GetConfigsFactory().Create(IOHelper); + return GetConfigsFactory().Create(IOHelper, Mock.Of()); } public static IRuntimeState GetRuntimeState() { diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoBackOfficeServiceCollectionExtensions.cs b/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoBackOfficeServiceCollectionExtensions.cs index 2d12ad3093..9441170ae4 100644 --- a/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoBackOfficeServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoBackOfficeServiceCollectionExtensions.cs @@ -43,9 +43,9 @@ namespace Umbraco.Web.BackOffice.AspNetCore var hostingEnvironment = new AspNetCoreHostingEnvironment(hostingSettings, webHostEnvironment, httpContextAccessor, hostApplicationLifetime); var ioHelper = new IOHelper(hostingEnvironment); - var configs = configFactory.Create(ioHelper); - var logger = SerilogLogger.CreateWithDefaultConfiguration(hostingEnvironment, new AspNetCoreSessionIdResolver(httpContextAccessor), () => services.BuildServiceProvider().GetService(), coreDebug, ioHelper, new AspNetCoreMarchal()); + var configs = configFactory.Create(ioHelper, logger); + var backOfficeInfo = new AspNetCoreBackOfficeInfo(configs.Global()); var profiler = new LogProfiler(logger); diff --git a/src/Umbraco.Web/UmbracoApplicationBase.cs b/src/Umbraco.Web/UmbracoApplicationBase.cs index cd107b179a..a4979777da 100644 --- a/src/Umbraco.Web/UmbracoApplicationBase.cs +++ b/src/Umbraco.Web/UmbracoApplicationBase.cs @@ -38,9 +38,9 @@ namespace Umbraco.Web var hostingEnvironment = new AspNetHostingEnvironment(hostingSettings); var ioHelper = new IOHelper(hostingEnvironment); - var configs = configFactory.Create(ioHelper); - var logger = SerilogLogger.CreateWithDefaultConfiguration(hostingEnvironment, new AspNetSessionManager(), () => _factory?.GetInstance(), coreDebug, ioHelper, new FrameworkMarchal()); + var configs = configFactory.Create(ioHelper, logger); + var backOfficeInfo = new AspNetBackOfficeInfo(configs.Global(), ioHelper, logger, configFactory.WebRoutingSettings); var profiler = new LogProfiler(logger); Umbraco.Composing.Current.Initialize(logger, configs, ioHelper, hostingEnvironment, backOfficeInfo, profiler);