From ba97598044db85e6bdc61e16674f678c5aa9dd0c Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Wed, 26 Feb 2020 13:52:06 +0100 Subject: [PATCH] - Moved dashboards to Core - Introduced IUserAgentProvider, instead of using HttpContext directly - Introduced IUmbracoApplicationLifetime, instead of using UmbracoApplication directly - Introduced IMachineKeyConfig instead of using WebConfigurationManager directly - Move information about dbProvider to the SqlSyntax - Moved install steps --- src/Umbraco.Configuration/ConfigsFactory.cs | 3 ++ src/Umbraco.Configuration/MachineKeyConfig.cs | 20 +++++++++ .../Configuration/IMachineKeyConfig.cs | 7 +++ .../Dashboards/ContentDashboard.cs | 0 .../Dashboards/ExamineDashboard.cs | 0 .../Dashboards/FormsDashboard.cs | 0 .../Dashboards/HealthCheckDashboard.cs | 0 .../Dashboards/MediaDashboard.cs | 0 .../Dashboards/MembersDashboard.cs | 0 .../Dashboards/ProfilerDashboard.cs | 0 .../Dashboards/PublishedStatusDashboard.cs | 0 .../Dashboards/RedirectUrlDashboard.cs | 0 .../Dashboards/SettingsDashboards.cs | 0 .../Net/IUmbracoApplicationLifetime.cs | 7 +++ src/Umbraco.Core/Net/IUserAgentProvider.cs | 7 +++ .../Packaging/PackageDefinition.cs | 2 +- .../Intall}/InstallHelper.cs | 45 +++++++++---------- .../InstallSteps/ConfigureMachineKey.cs | 15 ++++--- .../InstallSteps/SetUmbracoVersionStep.cs | 23 +++------- .../InstallSteps/StarterKitDownloadStep.cs | 10 ++--- .../InstallSteps/StarterKitInstallStep.cs | 13 +++--- .../SqlSyntax/ISqlSyntaxProvider.cs | 3 +- .../SqlSyntax/SqlServerSyntaxProvider.cs | 2 + .../SqlSyntax/SqlSyntaxProviderBase.cs | 1 + .../SqlCeSyntaxProvider.cs | 1 + .../AspNetUmbracoApplicationLifetime.cs | 19 ++++++++ .../AspNet/AspNetUserAgentProvider.cs | 19 ++++++++ src/Umbraco.Web/Macros/MacroRenderer.cs | 2 +- .../Macros/PartialViewMacroEngine.cs | 41 +++++++---------- src/Umbraco.Web/Runtime/WebInitialComposer.cs | 3 ++ src/Umbraco.Web/Umbraco.Web.csproj | 7 +-- src/Umbraco.Web/UmbracoContextFactory.cs | 1 - src/Umbraco.Web/UmbracoHelper.cs | 3 +- 33 files changed, 157 insertions(+), 97 deletions(-) create mode 100644 src/Umbraco.Configuration/MachineKeyConfig.cs create mode 100644 src/Umbraco.Core/Configuration/IMachineKeyConfig.cs rename src/{Umbraco.Web.BackOffice => Umbraco.Core}/Dashboards/ContentDashboard.cs (100%) rename src/{Umbraco.Web.BackOffice => Umbraco.Core}/Dashboards/ExamineDashboard.cs (100%) rename src/{Umbraco.Web.BackOffice => Umbraco.Core}/Dashboards/FormsDashboard.cs (100%) rename src/{Umbraco.Web.BackOffice => Umbraco.Core}/Dashboards/HealthCheckDashboard.cs (100%) rename src/{Umbraco.Web.BackOffice => Umbraco.Core}/Dashboards/MediaDashboard.cs (100%) rename src/{Umbraco.Web.BackOffice => Umbraco.Core}/Dashboards/MembersDashboard.cs (100%) rename src/{Umbraco.Web.BackOffice => Umbraco.Core}/Dashboards/ProfilerDashboard.cs (100%) rename src/{Umbraco.Web.BackOffice => Umbraco.Core}/Dashboards/PublishedStatusDashboard.cs (100%) rename src/{Umbraco.Web.BackOffice => Umbraco.Core}/Dashboards/RedirectUrlDashboard.cs (100%) rename src/{Umbraco.Web.BackOffice => Umbraco.Core}/Dashboards/SettingsDashboards.cs (100%) create mode 100644 src/Umbraco.Core/Net/IUmbracoApplicationLifetime.cs create mode 100644 src/Umbraco.Core/Net/IUserAgentProvider.cs rename src/{Umbraco.Web/Install => Umbraco.Infrastructure/Intall}/InstallHelper.cs (82%) rename src/{Umbraco.Web/Install => Umbraco.Infrastructure/Intall}/InstallSteps/ConfigureMachineKey.cs (79%) rename src/{Umbraco.Web/Install => Umbraco.Infrastructure/Intall}/InstallSteps/SetUmbracoVersionStep.cs (73%) rename src/{Umbraco.Web/Install => Umbraco.Infrastructure/Intall}/InstallSteps/StarterKitDownloadStep.cs (93%) rename src/{Umbraco.Web/Install => Umbraco.Infrastructure/Intall}/InstallSteps/StarterKitInstallStep.cs (83%) create mode 100644 src/Umbraco.Web/AspNet/AspNetUmbracoApplicationLifetime.cs create mode 100644 src/Umbraco.Web/AspNet/AspNetUserAgentProvider.cs diff --git a/src/Umbraco.Configuration/ConfigsFactory.cs b/src/Umbraco.Configuration/ConfigsFactory.cs index c09dc7b9f6..3979720f9b 100644 --- a/src/Umbraco.Configuration/ConfigsFactory.cs +++ b/src/Umbraco.Configuration/ConfigsFactory.cs @@ -1,4 +1,5 @@ using System.Configuration; +using Umbraco.Configuration; using Umbraco.Core.Configuration.HealthChecks; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; @@ -10,6 +11,7 @@ namespace Umbraco.Core.Configuration public IHostingSettings HostingSettings { get; } = new HostingSettings(); public ICoreDebug CoreDebug { get; } = new CoreDebug(); + public IMachineKeyConfig MachineKeyConfig { get; } = new MachineKeyConfig(); public IUmbracoSettingsSection UmbracoSettings { get; } @@ -27,6 +29,7 @@ namespace Umbraco.Core.Configuration configs.AddPasswordConfigurations(); configs.Add(() => CoreDebug); + configs.Add(() => MachineKeyConfig); configs.Add(() => new ConnectionStrings(ioHelper)); configs.AddCoreConfigs(ioHelper); return configs; diff --git a/src/Umbraco.Configuration/MachineKeyConfig.cs b/src/Umbraco.Configuration/MachineKeyConfig.cs new file mode 100644 index 0000000000..4e3401e015 --- /dev/null +++ b/src/Umbraco.Configuration/MachineKeyConfig.cs @@ -0,0 +1,20 @@ +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.Core/Configuration/IMachineKeyConfig.cs b/src/Umbraco.Core/Configuration/IMachineKeyConfig.cs new file mode 100644 index 0000000000..35969e668a --- /dev/null +++ b/src/Umbraco.Core/Configuration/IMachineKeyConfig.cs @@ -0,0 +1,7 @@ +namespace Umbraco.Core.Configuration +{ + public interface IMachineKeyConfig + { + bool HasMachineKey { get;} + } +} diff --git a/src/Umbraco.Web.BackOffice/Dashboards/ContentDashboard.cs b/src/Umbraco.Core/Dashboards/ContentDashboard.cs similarity index 100% rename from src/Umbraco.Web.BackOffice/Dashboards/ContentDashboard.cs rename to src/Umbraco.Core/Dashboards/ContentDashboard.cs diff --git a/src/Umbraco.Web.BackOffice/Dashboards/ExamineDashboard.cs b/src/Umbraco.Core/Dashboards/ExamineDashboard.cs similarity index 100% rename from src/Umbraco.Web.BackOffice/Dashboards/ExamineDashboard.cs rename to src/Umbraco.Core/Dashboards/ExamineDashboard.cs diff --git a/src/Umbraco.Web.BackOffice/Dashboards/FormsDashboard.cs b/src/Umbraco.Core/Dashboards/FormsDashboard.cs similarity index 100% rename from src/Umbraco.Web.BackOffice/Dashboards/FormsDashboard.cs rename to src/Umbraco.Core/Dashboards/FormsDashboard.cs diff --git a/src/Umbraco.Web.BackOffice/Dashboards/HealthCheckDashboard.cs b/src/Umbraco.Core/Dashboards/HealthCheckDashboard.cs similarity index 100% rename from src/Umbraco.Web.BackOffice/Dashboards/HealthCheckDashboard.cs rename to src/Umbraco.Core/Dashboards/HealthCheckDashboard.cs diff --git a/src/Umbraco.Web.BackOffice/Dashboards/MediaDashboard.cs b/src/Umbraco.Core/Dashboards/MediaDashboard.cs similarity index 100% rename from src/Umbraco.Web.BackOffice/Dashboards/MediaDashboard.cs rename to src/Umbraco.Core/Dashboards/MediaDashboard.cs diff --git a/src/Umbraco.Web.BackOffice/Dashboards/MembersDashboard.cs b/src/Umbraco.Core/Dashboards/MembersDashboard.cs similarity index 100% rename from src/Umbraco.Web.BackOffice/Dashboards/MembersDashboard.cs rename to src/Umbraco.Core/Dashboards/MembersDashboard.cs diff --git a/src/Umbraco.Web.BackOffice/Dashboards/ProfilerDashboard.cs b/src/Umbraco.Core/Dashboards/ProfilerDashboard.cs similarity index 100% rename from src/Umbraco.Web.BackOffice/Dashboards/ProfilerDashboard.cs rename to src/Umbraco.Core/Dashboards/ProfilerDashboard.cs diff --git a/src/Umbraco.Web.BackOffice/Dashboards/PublishedStatusDashboard.cs b/src/Umbraco.Core/Dashboards/PublishedStatusDashboard.cs similarity index 100% rename from src/Umbraco.Web.BackOffice/Dashboards/PublishedStatusDashboard.cs rename to src/Umbraco.Core/Dashboards/PublishedStatusDashboard.cs diff --git a/src/Umbraco.Web.BackOffice/Dashboards/RedirectUrlDashboard.cs b/src/Umbraco.Core/Dashboards/RedirectUrlDashboard.cs similarity index 100% rename from src/Umbraco.Web.BackOffice/Dashboards/RedirectUrlDashboard.cs rename to src/Umbraco.Core/Dashboards/RedirectUrlDashboard.cs diff --git a/src/Umbraco.Web.BackOffice/Dashboards/SettingsDashboards.cs b/src/Umbraco.Core/Dashboards/SettingsDashboards.cs similarity index 100% rename from src/Umbraco.Web.BackOffice/Dashboards/SettingsDashboards.cs rename to src/Umbraco.Core/Dashboards/SettingsDashboards.cs diff --git a/src/Umbraco.Core/Net/IUmbracoApplicationLifetime.cs b/src/Umbraco.Core/Net/IUmbracoApplicationLifetime.cs new file mode 100644 index 0000000000..4e9f655414 --- /dev/null +++ b/src/Umbraco.Core/Net/IUmbracoApplicationLifetime.cs @@ -0,0 +1,7 @@ +namespace Umbraco.Net +{ + public interface IUmbracoApplicationLifetime + { + void Restart(); + } +} diff --git a/src/Umbraco.Core/Net/IUserAgentProvider.cs b/src/Umbraco.Core/Net/IUserAgentProvider.cs new file mode 100644 index 0000000000..14246ea99e --- /dev/null +++ b/src/Umbraco.Core/Net/IUserAgentProvider.cs @@ -0,0 +1,7 @@ +namespace Umbraco.Net +{ + public interface IUserAgentProvider + { + string GetUserAgent(); + } +} diff --git a/src/Umbraco.Core/Packaging/PackageDefinition.cs b/src/Umbraco.Core/Packaging/PackageDefinition.cs index 11bf26c579..29a1919a2b 100644 --- a/src/Umbraco.Core/Packaging/PackageDefinition.cs +++ b/src/Umbraco.Core/Packaging/PackageDefinition.cs @@ -19,7 +19,7 @@ namespace Umbraco.Core.Models.Packaging /// /// This is used only for conversions and will not 'get' a PackageDefinition from the repository with a valid ID /// - internal static PackageDefinition FromCompiledPackage(CompiledPackage compiled) + public static PackageDefinition FromCompiledPackage(CompiledPackage compiled) { return new PackageDefinition { diff --git a/src/Umbraco.Web/Install/InstallHelper.cs b/src/Umbraco.Infrastructure/Intall/InstallHelper.cs similarity index 82% rename from src/Umbraco.Web/Install/InstallHelper.cs rename to src/Umbraco.Infrastructure/Intall/InstallHelper.cs index f7344d0b0b..704459429e 100644 --- a/src/Umbraco.Web/Install/InstallHelper.cs +++ b/src/Umbraco.Infrastructure/Intall/InstallHelper.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Threading.Tasks; -using System.Web; using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Cookie; @@ -12,8 +11,9 @@ using Umbraco.Core.Migrations.Install; using Umbraco.Core.Models; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Core.Serialization; using Umbraco.Core.Services; -using Umbraco.Web.Composing; +using Umbraco.Net; using Umbraco.Web.Install.Models; namespace Umbraco.Web.Install @@ -22,25 +22,28 @@ namespace Umbraco.Web.Install { private static HttpClient _httpClient; private readonly DatabaseBuilder _databaseBuilder; - private readonly IHttpContextAccessor _httpContextAccessor; private readonly ILogger _logger; private readonly IGlobalSettings _globalSettings; private readonly IUmbracoVersion _umbracoVersion; private readonly IConnectionStrings _connectionStrings; private readonly IInstallationService _installationService; private readonly ICookieManager _cookieManager; + private readonly IUserAgentProvider _userAgentProvider; + private readonly Lazy _sqlContext; + private readonly IJsonSerializer _jsonSerializer; private InstallationType? _installationType; - public InstallHelper(IHttpContextAccessor httpContextAccessor, - DatabaseBuilder databaseBuilder, + public InstallHelper(DatabaseBuilder databaseBuilder, ILogger logger, IGlobalSettings globalSettings, IUmbracoVersion umbracoVersion, IConnectionStrings connectionStrings, IInstallationService installationService, - ICookieManager cookieManager) + ICookieManager cookieManager, + IUserAgentProvider userAgentProvider, + Lazy sqlContext, + IJsonSerializer jsonSerializer) { - _httpContextAccessor = httpContextAccessor; _logger = logger; _globalSettings = globalSettings; _umbracoVersion = umbracoVersion; @@ -48,6 +51,9 @@ namespace Umbraco.Web.Install _connectionStrings = connectionStrings ?? throw new ArgumentNullException(nameof(connectionStrings)); _installationService = installationService; _cookieManager = cookieManager; + _userAgentProvider = userAgentProvider; + _sqlContext = sqlContext; + _jsonSerializer = jsonSerializer; } public InstallationType GetInstallationType() @@ -57,11 +63,9 @@ namespace Umbraco.Web.Install public async Task InstallStatus(bool isCompleted, string errorMsg) { - - var httpContext = _httpContextAccessor.GetRequiredHttpContext(); try { - var userAgent = httpContext.Request.UserAgent; + var userAgent = _userAgentProvider.GetUserAgent(); // Check for current install Id var installId = Guid.NewGuid(); @@ -88,7 +92,7 @@ namespace Umbraco.Web.Install { // we don't have DatabaseProvider anymore... doing it differently //dbProvider = ApplicationContext.Current.DatabaseContext.DatabaseProvider.ToString(); - dbProvider = GetDbProviderString(Current.SqlContext); + dbProvider = GetDbProviderString(_sqlContext.Value); } var installLog = new InstallLog(installId: installId, isUpgrade: IsBrandNewInstall == false, @@ -107,19 +111,7 @@ namespace Umbraco.Web.Install internal static string GetDbProviderString(ISqlContext sqlContext) { - var dbProvider = string.Empty; - - // we don't have DatabaseProvider anymore... - //dbProvider = ApplicationContext.Current.DatabaseContext.DatabaseProvider.ToString(); - // - // doing it differently - var syntax = sqlContext.SqlSyntax; - if (syntax is SqlCeSyntaxProvider) - dbProvider = "SqlServerCE"; - else if (syntax is SqlServerSyntaxProvider) - dbProvider = (syntax as SqlServerSyntaxProvider).ServerVersion.IsAzure ? "SqlAzure" : "SqlServer"; - - return dbProvider; + return sqlContext.SqlSyntax.DbProvider; } /// @@ -162,7 +154,10 @@ namespace Umbraco.Web.Install using (var request = new HttpRequestMessage(HttpMethod.Get, requestUri)) { var response = _httpClient.SendAsync(request).Result; - packages = response.Content.ReadAsAsync>().Result.ToList(); + + + var json = response.Content.ReadAsStringAsync().Result; + packages = _jsonSerializer.Deserialize>(json).ToList(); } } catch (AggregateException ex) diff --git a/src/Umbraco.Web/Install/InstallSteps/ConfigureMachineKey.cs b/src/Umbraco.Infrastructure/Intall/InstallSteps/ConfigureMachineKey.cs similarity index 79% rename from src/Umbraco.Web/Install/InstallSteps/ConfigureMachineKey.cs rename to src/Umbraco.Infrastructure/Intall/InstallSteps/ConfigureMachineKey.cs index 164c142e0c..b64f66edc6 100644 --- a/src/Umbraco.Web/Install/InstallSteps/ConfigureMachineKey.cs +++ b/src/Umbraco.Infrastructure/Intall/InstallSteps/ConfigureMachineKey.cs @@ -1,7 +1,7 @@ using System.Linq; using System.Threading.Tasks; -using System.Web.Configuration; using System.Xml.Linq; +using Umbraco.Core.Configuration; using Umbraco.Core.IO; using Umbraco.Core.Security; using Umbraco.Web.Install.Models; @@ -12,13 +12,15 @@ namespace Umbraco.Web.Install.InstallSteps "ConfigureMachineKey", "machinekey", 2, "Updating some security settings...", PerformsAppRestart = true)] - internal class ConfigureMachineKey : InstallSetupStep + public class ConfigureMachineKey : InstallSetupStep { private readonly IIOHelper _ioHelper; + private readonly IMachineKeyConfig _machineKeyConfig; - public ConfigureMachineKey(IIOHelper ioHelper) + public ConfigureMachineKey(IIOHelper ioHelper, IMachineKeyConfig machineKeyConfig) { _ioHelper = ioHelper; + _machineKeyConfig = machineKeyConfig; } public override string View => HasMachineKey() == false ? base.View : ""; @@ -27,10 +29,11 @@ namespace Umbraco.Web.Install.InstallSteps /// Don't display the view or execute if a machine key already exists /// /// - private static bool HasMachineKey() + private bool HasMachineKey() { - var section = (MachineKeySection) WebConfigurationManager.GetSection("system.web/machineKey"); - return section.ElementInformation.Source != null; + return _machineKeyConfig.HasMachineKey; + // var section = (MachineKeySection) WebConfigurationManager.GetSection("system.web/machineKey"); + // return section.ElementInformation.Source != null; } /// diff --git a/src/Umbraco.Web/Install/InstallSteps/SetUmbracoVersionStep.cs b/src/Umbraco.Infrastructure/Intall/InstallSteps/SetUmbracoVersionStep.cs similarity index 73% rename from src/Umbraco.Web/Install/InstallSteps/SetUmbracoVersionStep.cs rename to src/Umbraco.Infrastructure/Intall/InstallSteps/SetUmbracoVersionStep.cs index dcf115082f..949435449f 100644 --- a/src/Umbraco.Web/Install/InstallSteps/SetUmbracoVersionStep.cs +++ b/src/Umbraco.Infrastructure/Intall/InstallSteps/SetUmbracoVersionStep.cs @@ -1,44 +1,31 @@ using System.Threading.Tasks; -using System.Web; using Umbraco.Core; using Umbraco.Core.Configuration; -using Umbraco.Core.IO; -using Umbraco.Core.Logging; -using Umbraco.Core.Services; -using Umbraco.Web.Cache; -using Umbraco.Web.Composing; using Umbraco.Web.Install.Models; -using Umbraco.Web.Security; - namespace Umbraco.Web.Install.InstallSteps { [InstallSetupStep(InstallationType.NewInstall | InstallationType.Upgrade, "UmbracoVersion", 50, "Installation is complete!, get ready to be redirected to your new CMS.", PerformsAppRestart = true)] - internal class SetUmbracoVersionStep : InstallSetupStep + public class SetUmbracoVersionStep : InstallSetupStep { - private readonly IHttpContextAccessor _httpContextAccessor; + private readonly IUmbracoContextAccessor _umbracoContextAccessor; private readonly InstallHelper _installHelper; private readonly IGlobalSettings _globalSettings; - private readonly IUserService _userService; private readonly IUmbracoVersion _umbracoVersion; - private readonly IIOHelper _ioHelper; - public SetUmbracoVersionStep(IHttpContextAccessor httpContextAccessor, InstallHelper installHelper, IGlobalSettings globalSettings, IUserService userService, IUmbracoVersion umbracoVersion, IIOHelper ioHelper) + public SetUmbracoVersionStep(IUmbracoContextAccessor umbracoContextAccessor, InstallHelper installHelper, IGlobalSettings globalSettings, IUmbracoVersion umbracoVersion) { - _httpContextAccessor = httpContextAccessor; + _umbracoContextAccessor = umbracoContextAccessor; _installHelper = installHelper; _globalSettings = globalSettings; - _userService = userService; _umbracoVersion = umbracoVersion; - _ioHelper = ioHelper; } public override Task ExecuteAsync(object model) { - var security = new WebSecurity(_httpContextAccessor, _userService, _globalSettings, _ioHelper); - + var security = _umbracoContextAccessor.UmbracoContext.Security; if (security.IsAuthenticated() == false && _globalSettings.ConfigurationStatus.IsNullOrWhiteSpace()) { security.PerformLogin(-1); diff --git a/src/Umbraco.Web/Install/InstallSteps/StarterKitDownloadStep.cs b/src/Umbraco.Infrastructure/Intall/InstallSteps/StarterKitDownloadStep.cs similarity index 93% rename from src/Umbraco.Web/Install/InstallSteps/StarterKitDownloadStep.cs rename to src/Umbraco.Infrastructure/Intall/InstallSteps/StarterKitDownloadStep.cs index 624f5897c7..d8986cacb7 100644 --- a/src/Umbraco.Web/Install/InstallSteps/StarterKitDownloadStep.cs +++ b/src/Umbraco.Infrastructure/Intall/InstallSteps/StarterKitDownloadStep.cs @@ -1,13 +1,11 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Threading.Tasks; -using System.Web; using Umbraco.Core.Services; using Umbraco.Core.Configuration; using Umbraco.Core.Models.Packaging; -using Umbraco.Web.Composing; +using Umbraco.Net; using Umbraco.Web.Install.Models; namespace Umbraco.Web.Install.InstallSteps @@ -20,14 +18,16 @@ namespace Umbraco.Web.Install.InstallSteps private readonly InstallHelper _installHelper; private readonly IUmbracoContextAccessor _umbracoContextAccessor; private readonly IUmbracoVersion _umbracoVersion; + private readonly IUmbracoApplicationLifetime _umbracoApplicationLifetime; private readonly IContentService _contentService; private readonly IPackagingService _packageService; - public StarterKitDownloadStep(IContentService contentService, IPackagingService packageService, InstallHelper installHelper, IUmbracoContextAccessor umbracoContextAccessor, IUmbracoVersion umbracoVersion) + public StarterKitDownloadStep(IContentService contentService, IPackagingService packageService, InstallHelper installHelper, IUmbracoContextAccessor umbracoContextAccessor, IUmbracoVersion umbracoVersion, IUmbracoApplicationLifetime umbracoApplicationLifetime) { _installHelper = installHelper; _umbracoContextAccessor = umbracoContextAccessor; _umbracoVersion = umbracoVersion; + _umbracoApplicationLifetime = umbracoApplicationLifetime; _contentService = contentService; _packageService = packageService; } @@ -54,7 +54,7 @@ namespace Umbraco.Web.Install.InstallSteps var (packageFile, packageId) = await DownloadPackageFilesAsync(starterKitId.Value); - UmbracoApplication.Restart(); + _umbracoApplicationLifetime.Restart(); return new InstallSetupResult(new Dictionary { diff --git a/src/Umbraco.Web/Install/InstallSteps/StarterKitInstallStep.cs b/src/Umbraco.Infrastructure/Intall/InstallSteps/StarterKitInstallStep.cs similarity index 83% rename from src/Umbraco.Web/Install/InstallSteps/StarterKitInstallStep.cs rename to src/Umbraco.Infrastructure/Intall/InstallSteps/StarterKitInstallStep.cs index c9688fed4c..cc269408f4 100644 --- a/src/Umbraco.Web/Install/InstallSteps/StarterKitInstallStep.cs +++ b/src/Umbraco.Infrastructure/Intall/InstallSteps/StarterKitInstallStep.cs @@ -2,9 +2,8 @@ using System.IO; using System.Linq; using System.Threading.Tasks; -using System.Web; using Umbraco.Core.Services; -using Umbraco.Web.Composing; +using Umbraco.Net; using Umbraco.Web.Install.Models; namespace Umbraco.Web.Install.InstallSteps @@ -14,13 +13,13 @@ namespace Umbraco.Web.Install.InstallSteps PerformsAppRestart = true)] internal class StarterKitInstallStep : InstallSetupStep { - private readonly IHttpContextAccessor _httContextAccessor; + private readonly IUmbracoApplicationLifetime _umbracoApplicationLifetime; private readonly IUmbracoContextAccessor _umbracoContextAccessor; private readonly IPackagingService _packagingService; - public StarterKitInstallStep(IHttpContextAccessor httContextAccessor, IUmbracoContextAccessor umbracoContextAccessor, IPackagingService packagingService) + public StarterKitInstallStep(IUmbracoApplicationLifetime umbracoApplicationLifetime, IUmbracoContextAccessor umbracoContextAccessor, IPackagingService packagingService) { - _httContextAccessor = httContextAccessor; + _umbracoApplicationLifetime = umbracoApplicationLifetime; _umbracoContextAccessor = umbracoContextAccessor; _packagingService = packagingService; } @@ -34,7 +33,9 @@ namespace Umbraco.Web.Install.InstallSteps InstallBusinessLogic(packageId); - UmbracoApplication.Restart(_httContextAccessor.GetRequiredHttpContext()); + _umbracoApplicationLifetime.Restart(); + + return Task.FromResult(null); } diff --git a/src/Umbraco.Infrastructure/Persistence/SqlSyntax/ISqlSyntaxProvider.cs b/src/Umbraco.Infrastructure/Persistence/SqlSyntax/ISqlSyntaxProvider.cs index 7ae001bf24..58f9a4b68a 100644 --- a/src/Umbraco.Infrastructure/Persistence/SqlSyntax/ISqlSyntaxProvider.cs +++ b/src/Umbraco.Infrastructure/Persistence/SqlSyntax/ISqlSyntaxProvider.cs @@ -77,12 +77,13 @@ namespace Umbraco.Core.Persistence.SqlSyntax string ConvertIntegerToOrderableString { get; } string ConvertDateToOrderableString { get; } string ConvertDecimalToOrderableString { get; } - + /// /// Returns the default isolation level for the database /// IsolationLevel DefaultIsolationLevel { get; } + string DbProvider { get; } IEnumerable GetTablesInSchema(IDatabase db); IEnumerable GetColumnsInSchema(IDatabase db); diff --git a/src/Umbraco.Infrastructure/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs b/src/Umbraco.Infrastructure/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs index a478c88412..8d3a41e5bf 100644 --- a/src/Umbraco.Infrastructure/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs +++ b/src/Umbraco.Infrastructure/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs @@ -175,6 +175,8 @@ namespace Umbraco.Core.Persistence.SqlSyntax return items.Select(x => new Tuple(x.TableName, x.ColumnName, x.Name, x.Definition)); } + public override string DbProvider => ServerVersion.IsAzure ? "SqlAzure" : "SqlServer"; + public override IEnumerable GetTablesInSchema(IDatabase db) { var items = db.Fetch("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = (SELECT SCHEMA_NAME())"); diff --git a/src/Umbraco.Infrastructure/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs b/src/Umbraco.Infrastructure/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs index b2e03df96e..3df97c0b4f 100644 --- a/src/Umbraco.Infrastructure/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs +++ b/src/Umbraco.Infrastructure/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs @@ -202,6 +202,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax } public abstract IsolationLevel DefaultIsolationLevel { get; } + public abstract string DbProvider { get; } public virtual IEnumerable GetTablesInSchema(IDatabase db) { diff --git a/src/Umbraco.Persistance.SqlCe/SqlCeSyntaxProvider.cs b/src/Umbraco.Persistance.SqlCe/SqlCeSyntaxProvider.cs index 2ed0fb878c..7abcc60c86 100644 --- a/src/Umbraco.Persistance.SqlCe/SqlCeSyntaxProvider.cs +++ b/src/Umbraco.Persistance.SqlCe/SqlCeSyntaxProvider.cs @@ -55,6 +55,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax } public override System.Data.IsolationLevel DefaultIsolationLevel => System.Data.IsolationLevel.RepeatableRead; + public override string DbProvider => "SqlServerCE"; public override string FormatColumnRename(string tableName, string oldName, string newName) { diff --git a/src/Umbraco.Web/AspNet/AspNetUmbracoApplicationLifetime.cs b/src/Umbraco.Web/AspNet/AspNetUmbracoApplicationLifetime.cs new file mode 100644 index 0000000000..7651365c74 --- /dev/null +++ b/src/Umbraco.Web/AspNet/AspNetUmbracoApplicationLifetime.cs @@ -0,0 +1,19 @@ +using Umbraco.Net; + +namespace Umbraco.Web.AspNet +{ + public class AspNetUmbracoApplicationLifetime : IUmbracoApplicationLifetime + { + private readonly IHttpContextAccessor _httpContextAccessor; + + public AspNetUmbracoApplicationLifetime(IHttpContextAccessor httpContextAccessor) + { + _httpContextAccessor = httpContextAccessor; + } + + public void Restart() + { + UmbracoApplication.Restart(_httpContextAccessor.HttpContext); + } + } +} diff --git a/src/Umbraco.Web/AspNet/AspNetUserAgentProvider.cs b/src/Umbraco.Web/AspNet/AspNetUserAgentProvider.cs new file mode 100644 index 0000000000..bd37b62531 --- /dev/null +++ b/src/Umbraco.Web/AspNet/AspNetUserAgentProvider.cs @@ -0,0 +1,19 @@ +using Umbraco.Net; + +namespace Umbraco.Web.AspNet +{ + public class AspNetUserAgentProvider : IUserAgentProvider + { + private readonly IHttpContextAccessor _httpContextAccessor; + + public AspNetUserAgentProvider(IHttpContextAccessor httpContextAccessor) + { + _httpContextAccessor = httpContextAccessor; + } + + public string GetUserAgent() + { + return _httpContextAccessor.GetRequiredHttpContext().Request.UserAgent; + } + } +} diff --git a/src/Umbraco.Web/Macros/MacroRenderer.cs b/src/Umbraco.Web/Macros/MacroRenderer.cs index 85861a1496..9990644db8 100755 --- a/src/Umbraco.Web/Macros/MacroRenderer.cs +++ b/src/Umbraco.Web/Macros/MacroRenderer.cs @@ -331,7 +331,7 @@ namespace Umbraco.Web.Macros /// The text output of the macro execution. private MacroContent ExecutePartialView(MacroModel macro, IPublishedContent content) { - var engine = new PartialViewMacroEngine(); + var engine = new PartialViewMacroEngine(_umbracoContextAccessor, _httpContextAccessor, _ioHelper); return engine.Execute(macro, content); } diff --git a/src/Umbraco.Web/Macros/PartialViewMacroEngine.cs b/src/Umbraco.Web/Macros/PartialViewMacroEngine.cs index ecfda80399..0099ff220a 100644 --- a/src/Umbraco.Web/Macros/PartialViewMacroEngine.cs +++ b/src/Umbraco.Web/Macros/PartialViewMacroEngine.cs @@ -5,6 +5,7 @@ using System.Web.Routing; using System.Web.WebPages; using Umbraco.Web.Mvc; using Umbraco.Core; +using Umbraco.Core.IO; using Umbraco.Core.Models.PublishedContent; using Umbraco.Web.Composing; @@ -15,37 +16,24 @@ namespace Umbraco.Web.Macros /// public class PartialViewMacroEngine { - private readonly Func _getHttpContext; + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly IIOHelper _ioHelper; private readonly Func _getUmbracoContext; - public PartialViewMacroEngine() + public PartialViewMacroEngine(IUmbracoContextAccessor umbracoContextAccessor, IHttpContextAccessor httpContextAccessor, IIOHelper ioHelper) { - _getHttpContext = () => - { - if (HttpContext.Current == null) - throw new InvalidOperationException($"The {GetType()} cannot execute with a null HttpContext.Current reference."); - return new HttpContextWrapper(HttpContext.Current); - }; + _httpContextAccessor = httpContextAccessor; + _ioHelper = ioHelper; _getUmbracoContext = () => { - if (Current.UmbracoContext == null) + var context = umbracoContextAccessor.UmbracoContext; + if (context == null) throw new InvalidOperationException($"The {GetType()} cannot execute with a null UmbracoContext.Current reference."); - return Current.UmbracoContext; + return context; }; } - /// - /// Constructor generally used for unit testing - /// - /// - /// - internal PartialViewMacroEngine(HttpContextBase httpContext, IUmbracoContext umbracoContext) - { - _getHttpContext = () => httpContext; - _getUmbracoContext = () => umbracoContext; - } - public bool Validate(string code, string tempFileName, IPublishedContent currentPage, out string errorMessage) { var temp = GetVirtualPathFromPhysicalPath(tempFileName); @@ -68,7 +56,7 @@ namespace Umbraco.Web.Macros if (content == null) throw new ArgumentNullException(nameof(content)); if (macro.MacroSource.IsNullOrWhiteSpace()) throw new ArgumentException("The MacroSource property of the macro object cannot be null or empty"); - var http = _getHttpContext(); + var httpContext = _httpContextAccessor.GetRequiredHttpContext(); var umbCtx = _getUmbracoContext(); var routeVals = new RouteData(); routeVals.Values.Add("controller", "PartialViewMacro"); @@ -79,13 +67,14 @@ namespace Umbraco.Web.Macros var viewContext = new ViewContext { ViewData = new ViewDataDictionary() }; //try and extract the current view context from the route values, this would be set in the UmbracoViewPage or in // the UmbracoPageResult if POSTing to an MVC controller but rendering in Webforms - if (http.Request.RequestContext.RouteData.DataTokens.ContainsKey(Mvc.Constants.DataTokenCurrentViewContext)) + if (httpContext.Request.RequestContext.RouteData.DataTokens.ContainsKey(Mvc.Constants.DataTokenCurrentViewContext)) { - viewContext = (ViewContext)http.Request.RequestContext.RouteData.DataTokens[Mvc.Constants.DataTokenCurrentViewContext]; + viewContext = (ViewContext)httpContext.Request.RequestContext.RouteData.DataTokens[Mvc.Constants.DataTokenCurrentViewContext]; } routeVals.DataTokens.Add("ParentActionViewContext", viewContext); - var request = new RequestContext(http, routeVals); + var request = new RequestContext(httpContext, routeVals); + string output; using (var controller = new PartialViewMacroController(macro, content)) { @@ -103,7 +92,7 @@ namespace Umbraco.Web.Macros private string GetVirtualPathFromPhysicalPath(string physicalPath) { - var rootpath = _getHttpContext().Server.MapPath("~/"); + var rootpath = _ioHelper.MapPath("~/"); physicalPath = physicalPath.Replace(rootpath, ""); physicalPath = physicalPath.Replace("\\", "/"); return "~/" + physicalPath; diff --git a/src/Umbraco.Web/Runtime/WebInitialComposer.cs b/src/Umbraco.Web/Runtime/WebInitialComposer.cs index df5d6756ae..fe18dae5f3 100644 --- a/src/Umbraco.Web/Runtime/WebInitialComposer.cs +++ b/src/Umbraco.Web/Runtime/WebInitialComposer.cs @@ -49,6 +49,7 @@ using Current = Umbraco.Web.Composing.Current; using Umbraco.Web.PropertyEditors; using Umbraco.Examine; using Umbraco.Core.Models; +using Umbraco.Web.AspNet; using Umbraco.Web.Models; namespace Umbraco.Web.Runtime @@ -64,9 +65,11 @@ namespace Umbraco.Web.Runtime composition.Register(); composition.Register(); + composition.Register(); composition.Register(); composition.Register(); composition.Register(); + composition.Register(); composition.Register(); composition.Register(Lifetime.Singleton); diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 27f372753a..fb96847eb4 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -134,7 +134,9 @@ + + @@ -158,8 +160,6 @@ - - @@ -270,7 +270,6 @@ - @@ -359,7 +358,6 @@ - @@ -455,7 +453,6 @@ - diff --git a/src/Umbraco.Web/UmbracoContextFactory.cs b/src/Umbraco.Web/UmbracoContextFactory.cs index 466bf68576..4090da5a6d 100644 --- a/src/Umbraco.Web/UmbracoContextFactory.cs +++ b/src/Umbraco.Web/UmbracoContextFactory.cs @@ -70,7 +70,6 @@ namespace Umbraco.Web _variationContextAccessor.VariationContext = new VariationContext(_defaultCultureAccessor.DefaultCulture); } - var webSecurity = new WebSecurity(_httpContextAccessor, _userService, _globalSettings, _ioHelper); return new UmbracoContext(_httpContextAccessor, _publishedSnapshotService, webSecurity, _globalSettings, _variationContextAccessor, _ioHelper, _uriUtility, _cookieManager); diff --git a/src/Umbraco.Web/UmbracoHelper.cs b/src/Umbraco.Web/UmbracoHelper.cs index 241c079ab4..c50e3790d1 100644 --- a/src/Umbraco.Web/UmbracoHelper.cs +++ b/src/Umbraco.Web/UmbracoHelper.cs @@ -3,13 +3,12 @@ using System.Collections.Generic; using System.Linq; using System.Web; using System.Xml.XPath; +using Umbraco.Composing; using Umbraco.Core; using Umbraco.Core.Dictionary; -using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Xml; -using Umbraco.Web.Composing; using Umbraco.Web.Mvc; using Umbraco.Web.Security;