From ea55d2662ec48e72f09fe799b20603dcc53a85de Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 8 Dec 2020 10:42:26 +1100 Subject: [PATCH] no app_data paths, changing to constants, some linting updates --- .../Configuration/LocalTempStorage.cs | 1 - .../Constants-SystemDirectories.cs | 7 +-- .../FolderAndFilePermissionsCheck.cs | 3 +- .../Hosting/IHostingEnvironment.cs | 6 +- .../Diagnostics/MiniDump.cs | 22 +++++--- .../Migrations/Install/DatabaseBuilder.cs | 4 +- src/Umbraco.Tests.Common/TestHelperBase.cs | 4 +- .../Umbraco.Core/Components/ComponentTests.cs | 4 +- .../Composing/ComposingTestBase.cs | 5 +- .../Umbraco.Core/Composing/TypeLoaderTests.cs | 4 +- .../TestHelpers/BaseUsingSqlCeSyntax.cs | 4 +- .../Controllers/ContentTypeController.cs | 4 +- .../AspNetCoreHostingEnvironment.cs | 56 ++++++++++++------- .../AspNet/AspNetHostingEnvironment.cs | 8 +-- 14 files changed, 72 insertions(+), 60 deletions(-) diff --git a/src/Umbraco.Core/Configuration/LocalTempStorage.cs b/src/Umbraco.Core/Configuration/LocalTempStorage.cs index 0013fb68e4..50eab639d0 100644 --- a/src/Umbraco.Core/Configuration/LocalTempStorage.cs +++ b/src/Umbraco.Core/Configuration/LocalTempStorage.cs @@ -4,7 +4,6 @@ namespace Umbraco.Core.Configuration { Unknown = 0, Default, - AspNetTemp, EnvironmentTemp } } diff --git a/src/Umbraco.Core/Constants-SystemDirectories.cs b/src/Umbraco.Core/Constants-SystemDirectories.cs index d4ca2a3c57..a86e4171d6 100644 --- a/src/Umbraco.Core/Constants-SystemDirectories.cs +++ b/src/Umbraco.Core/Constants-SystemDirectories.cs @@ -1,4 +1,4 @@ -namespace Umbraco.Core +namespace Umbraco.Core { public static partial class Constants { @@ -8,7 +8,7 @@ public const string Config = "~/config"; - public const string Data = "~/App_Data"; + public const string Data = "~/Umbraco/Data"; public const string TempData = Data + "/TEMP"; @@ -18,8 +18,6 @@ public const string Install = "~/install"; - public const string AppCode = "~/App_Code"; - public const string AppPlugins = "/App_Plugins"; public const string MvcViews = "~/Views"; @@ -32,6 +30,7 @@ public const string Preview = Data + "/preview"; + // TODO: This doesn't seem right? public const string LogFiles= "~/Logs"; } } diff --git a/src/Umbraco.Core/HealthCheck/Checks/Permissions/FolderAndFilePermissionsCheck.cs b/src/Umbraco.Core/HealthCheck/Checks/Permissions/FolderAndFilePermissionsCheck.cs index 9e279c98e2..a22748094a 100644 --- a/src/Umbraco.Core/HealthCheck/Checks/Permissions/FolderAndFilePermissionsCheck.cs +++ b/src/Umbraco.Core/HealthCheck/Checks/Permissions/FolderAndFilePermissionsCheck.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.Options; @@ -71,7 +71,6 @@ namespace Umbraco.Core.HealthCheck.Checks.Permissions //so these need to be tested differently var pathsToCheckWithRestarts = new Dictionary { - { Constants.SystemDirectories.AppCode, PermissionCheckRequirement.Optional }, { Constants.SystemDirectories.Bin, PermissionCheckRequirement.Optional } }; diff --git a/src/Umbraco.Core/Hosting/IHostingEnvironment.cs b/src/Umbraco.Core/Hosting/IHostingEnvironment.cs index 188fb87b55..60d582c6c9 100644 --- a/src/Umbraco.Core/Hosting/IHostingEnvironment.cs +++ b/src/Umbraco.Core/Hosting/IHostingEnvironment.cs @@ -5,6 +5,7 @@ namespace Umbraco.Core.Hosting public interface IHostingEnvironment { string SiteName { get; } + string ApplicationId { get; } /// @@ -35,8 +36,6 @@ namespace Umbraco.Core.Hosting /// /// Maps a virtual path to a physical path to the application's web root /// - /// - /// /// /// Depending on the runtime 'web root', this result can vary. For example in Net Framework the web root and the content root are the same, however /// in netcore the web root is /www therefore this will Map to a physical path within www. @@ -46,8 +45,6 @@ namespace Umbraco.Core.Hosting /// /// Maps a virtual path to a physical path to the application's root (not always equal to the web root) /// - /// - /// /// /// Depending on the runtime 'web root', this result can vary. For example in Net Framework the web root and the content root are the same, however /// in netcore the web root is /www therefore this will Map to a physical path within www. @@ -58,7 +55,6 @@ namespace Umbraco.Core.Hosting /// Converts a virtual path to an absolute URL path based on the application's web root /// /// The virtual path. Must start with either ~/ or / else an exception is thrown. - /// /// /// This maps the virtual path syntax to the web root. For example when hosting in a virtual directory called "site" and the value "~/pages/test" is passed in, it will /// map to "/site/pages/test" where "/site" is the value of . diff --git a/src/Umbraco.Infrastructure/Diagnostics/MiniDump.cs b/src/Umbraco.Infrastructure/Diagnostics/MiniDump.cs index 57e9b5204b..f2f730078f 100644 --- a/src/Umbraco.Infrastructure/Diagnostics/MiniDump.cs +++ b/src/Umbraco.Infrastructure/Diagnostics/MiniDump.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; @@ -111,11 +111,14 @@ namespace Umbraco.Core.Diagnostics // filter everywhere in our code = not! var stacktrace = withException ? Environment.StackTrace : string.Empty; - var filepath = Path.Combine(hostingEnvironment.ApplicationPhysicalPath, "App_Data/MiniDump"); - if (Directory.Exists(filepath) == false) - Directory.CreateDirectory(filepath); + var directory = hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.Data + "/MiniDump"); - var filename = Path.Combine(filepath, $"{DateTime.UtcNow:yyyyMMddTHHmmss}.{Guid.NewGuid().ToString("N").Substring(0, 4)}.dmp"); + if (Directory.Exists(directory) == false) + { + Directory.CreateDirectory(directory); + } + + var filename = Path.Combine(directory, $"{DateTime.UtcNow:yyyyMMddTHHmmss}.{Guid.NewGuid().ToString("N").Substring(0, 4)}.dmp"); using (var stream = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.Write)) { return Write(marchal, stream.SafeFileHandle, options, withException); @@ -127,9 +130,12 @@ namespace Umbraco.Core.Diagnostics { lock (LockO) { - var filepath = Path.Combine(hostingEnvironment.ApplicationPhysicalPath, "App_Data/MiniDump"); - if (Directory.Exists(filepath) == false) return true; - var count = Directory.GetFiles(filepath, "*.dmp").Length; + var directory = hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.Data + "/MiniDump"); + if (Directory.Exists(directory) == false) + { + return true; + } + var count = Directory.GetFiles(directory, "*.dmp").Length; return count < 8; } } diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs index b27bc48c8e..98e9bcb4bb 100644 --- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs +++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Linq; using System.Xml.Linq; @@ -462,7 +462,7 @@ namespace Umbraco.Core.Migrations.Install { Message = "The database configuration failed with the following message: " + ex.Message + - "\n Please check log file for additional information (can be found in '/App_Data/Logs/')", + $"\n Please check log file for additional information (can be found in '{Constants.SystemDirectories.LogFiles}')", Success = false, Percentage = "90" }; diff --git a/src/Umbraco.Tests.Common/TestHelperBase.cs b/src/Umbraco.Tests.Common/TestHelperBase.cs index 24759f9ffb..ed3e28ee21 100644 --- a/src/Umbraco.Tests.Common/TestHelperBase.cs +++ b/src/Umbraco.Tests.Common/TestHelperBase.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Reflection; using Microsoft.Extensions.DependencyInjection; @@ -48,7 +48,7 @@ namespace Umbraco.Tests.Common public TypeLoader GetMockedTypeLoader() { - return new TypeLoader(Mock.Of(), Mock.Of(), new DirectoryInfo(GetHostingEnvironment().MapPathContentRoot("~/App_Data/TEMP")), Mock.Of>(), Mock.Of()); + return new TypeLoader(Mock.Of(), Mock.Of(), new DirectoryInfo(GetHostingEnvironment().MapPathContentRoot(Constants.SystemDirectories.TempData)), Mock.Of>(), Mock.Of()); } // public Configs GetConfigs() => GetConfigsFactory().Create(); diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Components/ComponentTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Components/ComponentTests.cs index 44aacab944..6d51603502 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Components/ComponentTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Components/ComponentTests.cs @@ -68,7 +68,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Components private static TypeLoader MockTypeLoader() { var ioHelper = IOHelper; - return new TypeLoader(Mock.Of(), Mock.Of(), new DirectoryInfo(TestHelper.GetHostingEnvironment().MapPathContentRoot("~/App_Data/TEMP")), Mock.Of>(), Mock.Of()); + return new TypeLoader(Mock.Of(), Mock.Of(), new DirectoryInfo(TestHelper.GetHostingEnvironment().MapPathContentRoot(Constants.SystemDirectories.TempData)), Mock.Of>(), Mock.Of()); } @@ -390,7 +390,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Components public void AllComposers() { var typeFinder = TestHelper.GetTypeFinder(); - var typeLoader = new TypeLoader(typeFinder, AppCaches.Disabled.RuntimeCache, new DirectoryInfo(TestHelper.GetHostingEnvironment().MapPathContentRoot("~/App_Data/TEMP")), Mock.Of>(), Mock.Of()); + var typeLoader = new TypeLoader(typeFinder, AppCaches.Disabled.RuntimeCache, new DirectoryInfo(TestHelper.GetHostingEnvironment().MapPathContentRoot(Constants.SystemDirectories.TempData)), Mock.Of>(), Mock.Of()); var register = MockRegister(); var builder = new UmbracoBuilder(register, Mock.Of(), TestHelper.GetMockedTypeLoader()); diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/ComposingTestBase.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/ComposingTestBase.cs index 43760d1c6c..1c8bf139ac 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/ComposingTestBase.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/ComposingTestBase.cs @@ -1,9 +1,10 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Reflection; using Microsoft.Extensions.Logging; using Moq; using NUnit.Framework; +using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Logging; @@ -23,7 +24,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing ProfilingLogger = new ProfilingLogger(Mock.Of>(), Mock.Of()); var typeFinder = TestHelper.GetTypeFinder(); - TypeLoader = new TypeLoader(typeFinder, NoAppCache.Instance, new DirectoryInfo(TestHelper.GetHostingEnvironment().MapPathContentRoot("~/App_Data/TEMP")), Mock.Of>(), ProfilingLogger, false, AssembliesToScan); + TypeLoader = new TypeLoader(typeFinder, NoAppCache.Instance, new DirectoryInfo(TestHelper.GetHostingEnvironment().MapPathContentRoot(Constants.SystemDirectories.TempData)), Mock.Of>(), ProfilingLogger, false, AssembliesToScan); } protected virtual IEnumerable AssembliesToScan diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeLoaderTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeLoaderTests.cs index 20e9f8feef..36843ad1cc 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeLoaderTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeLoaderTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -28,7 +28,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing // this ensures it's reset var typeFinder = TestHelper.GetTypeFinder(); _typeLoader = new TypeLoader(typeFinder, NoAppCache.Instance, - new DirectoryInfo(TestHelper.GetHostingEnvironment().MapPathContentRoot("~/App_Data/TEMP")), + new DirectoryInfo(TestHelper.GetHostingEnvironment().MapPathContentRoot(Constants.SystemDirectories.TempData)), Mock.Of>(), new ProfilingLogger(Mock.Of>(), Mock.Of()), false, // for testing, we'll specify which assemblies are scanned for the PluginTypeResolver diff --git a/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs b/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs index 6e27bdd07c..adc076caec 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -43,7 +43,7 @@ namespace Umbraco.Tests.TestHelpers var logger = new ProfilingLogger(Mock.Of>(), Mock.Of()); var typeFinder = TestHelper.GetTypeFinder(); var typeLoader = new TypeLoader(typeFinder, NoAppCache.Instance, - new DirectoryInfo(ioHelper.MapPath("~/App_Data/TEMP")), + new DirectoryInfo(ioHelper.MapPath(Constants.SystemDirectories.TempData)), Mock.Of>(), logger, false); diff --git a/src/Umbraco.Web.BackOffice/Controllers/ContentTypeController.cs b/src/Umbraco.Web.BackOffice/Controllers/ContentTypeController.cs index 8d6adee475..f11ed373cd 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/ContentTypeController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/ContentTypeController.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -643,7 +643,7 @@ namespace Umbraco.Web.BackOffice.Controllers } catch (Exception ex) { - _logger.LogError(ex, "Error cleaning up temporary udt file in App_Data: {File}", filePath); + _logger.LogError(ex, "Error cleaning up temporary udt file in {File}", filePath); } return Ok(); diff --git a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreHostingEnvironment.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreHostingEnvironment.cs index f67e062847..6b06db315c 100644 --- a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreHostingEnvironment.cs +++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreHostingEnvironment.cs @@ -10,7 +10,7 @@ namespace Umbraco.Web.Common.AspNetCore { public class AspNetCoreHostingEnvironment : Core.Hosting.IHostingEnvironment { - private IOptionsMonitor _hostingSettings; + private IOptionsMonitor _hostingSettings; private readonly IWebHostEnvironment _webHostEnvironment; private string _localTempPath; @@ -27,59 +27,67 @@ namespace Umbraco.Web.Common.AspNetCore IISVersion = new Version(0, 0); // TODO not necessary IIS } + /// public bool IsHosted { get; } = true; + + /// public string SiteName { get; } + + /// public string ApplicationId { get; } + + /// public string ApplicationPhysicalPath { get; } + public string ApplicationServerAddress { get; } - //TODO how to find this, This is a server thing, not application thing. + // TODO how to find this, This is a server thing, not application thing. public string ApplicationVirtualPath => _hostingSettings.CurrentValue.ApplicationVirtualPath?.EnsureStartsWith('/') ?? "/"; + + /// public bool IsDebugMode => _hostingSettings.CurrentValue.Debug; public Version IISVersion { get; } + public string LocalTempPath { get { if (_localTempPath != null) + { return _localTempPath; + } switch (_hostingSettings.CurrentValue.LocalTempStorageLocation) { - case LocalTempStorage.AspNetTemp: - - // TODO: I don't think this is correct? but also we probably can remove AspNetTemp as an option entirely - // since this is legacy and we shouldn't use it - return _localTempPath = System.IO.Path.Combine(Path.GetTempPath(), ApplicationId, "UmbracoData"); - case LocalTempStorage.EnvironmentTemp: // environment temp is unique, we need a folder per site // use a hash // combine site name and application id - // site name is a Guid on Cloud - // application id is eg /LM/W3SVC/123456/ROOT + // site name is a Guid on Cloud + // application id is eg /LM/W3SVC/123456/ROOT // the combination is unique on one server // and, if a site moves from worker A to B and then back to A... - // hopefully it gets a new Guid or new application id? - - var hashString = SiteName + "::" + ApplicationId; - var hash = hashString.GenerateHash(); - var siteTemp = System.IO.Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData", hash); + // hopefully it gets a new Guid or new application id? + string hashString = SiteName + "::" + ApplicationId; + string hash = hashString.GenerateHash(); + string siteTemp = Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData", hash); return _localTempPath = siteTemp; - //case LocalTempStorage.Default: - //case LocalTempStorage.Unknown: default: - return _localTempPath = MapPathContentRoot("~/App_Data/TEMP"); + + return _localTempPath = MapPathContentRoot(Core.Constants.SystemDirectories.TempData); } } } + /// public string MapPathWebRoot(string path) => MapPath(_webHostEnvironment.WebRootPath, path); + + /// public string MapPathContentRoot(string path) => MapPath(_webHostEnvironment.ContentRootPath, path); private string MapPath(string root, string path) @@ -91,21 +99,29 @@ namespace Umbraco.Web.Common.AspNetCore // however if you are requesting a path be mapped, it should always assume the path is relative to the root, not // absolute in the file system. This error will help us find and fix improper uses, and should be removed once // all those uses have been found and fixed - if (newPath.StartsWith(root)) throw new ArgumentException("The path appears to already be fully qualified. Please remove the call to MapPath"); + if (newPath.StartsWith(root)) + { + throw new ArgumentException("The path appears to already be fully qualified. Please remove the call to MapPath"); + } return Path.Combine(root, newPath.TrimStart('~', '/', '\\')); } + /// public string ToAbsolute(string virtualPath) { if (!virtualPath.StartsWith("~/") && !virtualPath.StartsWith("/")) + { throw new InvalidOperationException($"The value {virtualPath} for parameter {nameof(virtualPath)} must start with ~/ or /"); + } // will occur if it starts with "/" if (Uri.IsWellFormedUriString(virtualPath, UriKind.Absolute)) + { return virtualPath; + } - var fullPath = ApplicationVirtualPath.EnsureEndsWith('/') + virtualPath.TrimStart('~', '/'); + string fullPath = ApplicationVirtualPath.EnsureEndsWith('/') + virtualPath.TrimStart('~', '/'); return fullPath; } diff --git a/src/Umbraco.Web/AspNet/AspNetHostingEnvironment.cs b/src/Umbraco.Web/AspNet/AspNetHostingEnvironment.cs index cc8fc975d2..ec9d66859e 100644 --- a/src/Umbraco.Web/AspNet/AspNetHostingEnvironment.cs +++ b/src/Umbraco.Web/AspNet/AspNetHostingEnvironment.cs @@ -11,6 +11,7 @@ using Umbraco.Core.Hosting; namespace Umbraco.Web.Hosting { + // TODO: This has been migrated to netcore public class AspNetHostingEnvironment : IHostingEnvironment { @@ -67,9 +68,6 @@ namespace Umbraco.Web.Hosting switch (_hostingSettings.LocalTempStorageLocation) { - case LocalTempStorage.AspNetTemp: - return _localTempPath = System.IO.Path.Combine(HttpRuntime.CodegenDir, "UmbracoData"); - case LocalTempStorage.EnvironmentTemp: // environment temp is unique, we need a folder per site @@ -88,10 +86,8 @@ namespace Umbraco.Web.Hosting return _localTempPath = siteTemp; - //case LocalTempStorage.Default: - //case LocalTempStorage.Unknown: default: - return _localTempPath = MapPathContentRoot("~/App_Data/TEMP"); + return _localTempPath = MapPathContentRoot(Constants.SystemDirectories.TempData); } } }