Port 7.7 - WIP

This commit is contained in:
Stephan
2017-09-19 15:51:47 +02:00
parent d54658009c
commit 9ed6576908
126 changed files with 3447 additions and 596 deletions

View File

@@ -40,6 +40,8 @@ namespace Umbraco.Web.Install.Controllers
// Update ClientDependency version
var clientDependencyConfig = new ClientDependencyConfiguration(_logger);
var clientDependencyUpdated = clientDependencyConfig.IncreaseVersionNumber();
// Delete ClientDependency temp directories to make sure we get fresh caches
var clientDependencyTempFilesDeleted = clientDependencyConfig.ClearTempFiles(HttpContext);
var result = _umbracoContext.Security.ValidateCurrentUser(false);

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Security.AccessControl;
using Umbraco.Core.IO;
using Umbraco.Web.Composing;
using Umbraco.Web.PublishedCache;
@@ -41,7 +42,18 @@ namespace Umbraco.Web.Install
return report.Count == 0;
}
public static bool EnsureDirectories(string[] dirs, out IEnumerable<string> errors)
/// <summary>
/// This will test the directories for write access
/// </summary>
/// <param name="directories"></param>
/// <param name="errorReport"></param>
/// <param name="writeCausesRestart">
/// If this is false, the easiest way to test for write access is to write a temp file, however some folder will cause
/// an App Domain restart if a file is written to the folder, so in that case we need to use the ACL APIs which aren't as
/// reliable but we cannot write a file since it will cause an app domain restart.
/// </param>
/// <returns></returns>
public static bool EnsureDirectories(string[] dirs, out IEnumerable<string> errors, bool writeCausesRestart = false)
{
List<string> temp = null;
var success = true;
@@ -49,7 +61,7 @@ namespace Umbraco.Web.Install
{
// we don't want to create/ship unnecessary directories, so
// here we just ensure we can access the directory, not create it
var tryAccess = TryAccessDirectory(dir);
var tryAccess = TryAccessDirectory(dir, !writeCausesRestart);
if (tryAccess) continue;
if (temp == null) temp = new List<string>();
@@ -151,8 +163,13 @@ namespace Umbraco.Web.Install
// tries to create a file
// if successful, the file is deleted
//
// or
//
// use the ACL APIs to avoid creating files
//
// if the directory does not exist, do nothing & success
public static bool TryAccessDirectory(string dir)
public static bool TryAccessDirectory(string dir, bool canWrite)
{
try
{
@@ -161,10 +178,17 @@ namespace Umbraco.Web.Install
if (Directory.Exists(dirPath) == false)
return true;
var filePath = dirPath + "/" + CreateRandomName() + ".tmp";
File.WriteAllText(filePath, "This is an Umbraco internal test file. It is safe to delete it.");
File.Delete(filePath);
return true;
if (canWrite)
{
var filePath = dirPath + "/" + CreateRandomName() + ".tmp";
File.WriteAllText(filePath, "This is an Umbraco internal test file. It is safe to delete it.");
File.Delete(filePath);
return true;
}
else
{
return HasWritePermission(dirPath);
}
}
catch
{
@@ -172,6 +196,42 @@ namespace Umbraco.Web.Install
}
}
private static bool HasWritePermission(string path)
{
var writeAllow = false;
var writeDeny = false;
var accessControlList = Directory.GetAccessControl(path);
if (accessControlList == null)
return false;
AuthorizationRuleCollection accessRules;
try
{
accessRules = accessControlList.GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));
if (accessRules == null)
return false;
}
catch (Exception e)
{
//This is not 100% accurate btw because it could turn out that the current user doesn't
//have access to read the current permissions but does have write access.
//I think this is an edge case however
return false;
}
foreach (FileSystemAccessRule rule in accessRules)
{
if ((FileSystemRights.Write & rule.FileSystemRights) != FileSystemRights.Write)
continue;
if (rule.AccessControlType == AccessControlType.Allow)
writeAllow = true;
else if (rule.AccessControlType == AccessControlType.Deny)
writeDeny = true;
}
return writeAllow && writeDeny == false;
}
// tries to write into a file
// fails if the directory does not exist
private static bool TryWriteFile(string file)