Files
Umbraco-CMS/src/Umbraco.Core/Configuration/ModelsBuilderConfigExtensions.cs
2021-12-16 13:44:20 +01:00

58 lines
2.1 KiB
C#

using System.IO;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Exceptions;
using Umbraco.Cms.Core.Hosting;
namespace Umbraco.Extensions
{
public static class ModelsBuilderConfigExtensions
{
private static string? _modelsDirectoryAbsolute = null;
public static string ModelsDirectoryAbsolute(this ModelsBuilderSettings modelsBuilderConfig, IHostingEnvironment hostingEnvironment)
{
if (_modelsDirectoryAbsolute is null)
{
var modelsDirectory = modelsBuilderConfig.ModelsDirectory;
var root = hostingEnvironment.MapPathContentRoot("~/");
_modelsDirectoryAbsolute = GetModelsDirectory(root, modelsDirectory,
modelsBuilderConfig.AcceptUnsafeModelsDirectory);
}
return _modelsDirectoryAbsolute;
}
// internal for tests
internal static string GetModelsDirectory(string root, string config, bool acceptUnsafe)
{
// making sure it is safe, ie under the website root,
// unless AcceptUnsafeModelsDirectory and then everything is OK.
if (!Path.IsPathRooted(root))
throw new ConfigurationException($"Root is not rooted \"{root}\".");
if (config.StartsWith("~/"))
{
var dir = Path.Combine(root, config.TrimStart("~/"));
// sanitize - GetFullPath will take care of any relative
// segments in path, eg '../../foo.tmp' - it may throw a SecurityException
// if the combined path reaches illegal parts of the filesystem
dir = Path.GetFullPath(dir);
root = Path.GetFullPath(root);
if (!dir.StartsWith(root) && !acceptUnsafe)
throw new ConfigurationException($"Invalid models directory \"{config}\".");
return dir;
}
if (acceptUnsafe)
return Path.GetFullPath(config);
throw new ConfigurationException($"Invalid models directory \"{config}\".");
}
}
}