Got more of the install checker working and inspecting package assemblies for report.
This commit is contained in:
@@ -3,46 +3,48 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
|
||||
namespace Umbraco.Core.Packaging
|
||||
{
|
||||
internal class PackageBinaryInspector
|
||||
internal class PackageBinaryInspector : MarshalByRefObject
|
||||
{
|
||||
|
||||
public static IEnumerable<string> BinariesContainInstanceOf<T>(string dllPath)
|
||||
public IEnumerable<string> PerformScan<T>(string dllPath, out string[] errorReport)
|
||||
{
|
||||
var result = new List<string>();
|
||||
|
||||
if (Directory.Exists(dllPath) == false)
|
||||
{
|
||||
throw new DirectoryNotFoundException("Could not find directory " + dllPath);
|
||||
}
|
||||
|
||||
var files = Directory.GetFiles(dllPath, "*.dll");
|
||||
|
||||
var dllsWithReference = new List<string>();
|
||||
var errors = new List<string>();
|
||||
var assembliesWithErrors = new List<string>();
|
||||
|
||||
//we need this handler to resolve assembly dependencies below
|
||||
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += (s, e) =>
|
||||
{
|
||||
var ass = Assembly.ReflectionOnlyLoad(e.Name);
|
||||
if (ass == null)
|
||||
{
|
||||
throw new TypeLoadException("Could not load assembly " + e.Name);
|
||||
}
|
||||
return ass;
|
||||
var a = Assembly.ReflectionOnlyLoad(e.Name);
|
||||
if (a == null) throw new TypeLoadException("Could not load assembly " + e.Name);
|
||||
return a;
|
||||
};
|
||||
|
||||
//First load each dll file into the context
|
||||
foreach (var f in files)
|
||||
{
|
||||
if (File.Exists(f) == false)
|
||||
{
|
||||
throw new FileNotFoundException("Could not find file " + f);
|
||||
}
|
||||
Assembly.ReflectionOnlyLoadFrom(f);
|
||||
}
|
||||
//First load each dll file into the context
|
||||
foreach (var f in files) Assembly.ReflectionOnlyLoadFrom(f);
|
||||
|
||||
var toIgnore = new List<string>();
|
||||
////before we try to load these assemblies into context, ensure we haven't done that already
|
||||
//var alreadyLoaded = AppDomain.CurrentDomain.ReflectionOnlyGetAssemblies();
|
||||
////First load each dll file into the context
|
||||
//foreach (var f in files.Where(a => !IsAlreadyLoaded(a, alreadyLoaded)))
|
||||
//{
|
||||
// //NOTE: if you're loading an already loaded assembly from a new location
|
||||
// // you will get a FileLoadException here.
|
||||
// Assembly.ReflectionOnlyLoadFrom(f);
|
||||
//}
|
||||
|
||||
//Then load each referenced assembly into the context
|
||||
foreach (var f in files)
|
||||
@@ -54,27 +56,81 @@ namespace Umbraco.Core.Packaging
|
||||
{
|
||||
Assembly.ReflectionOnlyLoad(assemblyName.FullName);
|
||||
}
|
||||
catch (Exception)
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
//if an exception occurs it means that a referenced assembly could not be found - unless something else strange is going on.
|
||||
//we'll log an error for this to return in our report
|
||||
result.Add("This package references an assembly that was not found (" + assemblyName.FullName + "), this package may have problems running");
|
||||
toIgnore.Add(f);
|
||||
//if an exception occurs it means that a referenced assembly could not be found
|
||||
errors.Add(
|
||||
string.Concat("This package references the assembly '",
|
||||
assemblyName.Name,
|
||||
"' which was not found, this package may have problems running"));
|
||||
assembliesWithErrors.Add(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//now that we have all referenced types into the context we can look up stuff
|
||||
foreach (var f in files.Except(toIgnore))
|
||||
foreach (var f in files.Except(assembliesWithErrors))
|
||||
{
|
||||
//now we need to see if they contain any type 'T'
|
||||
var reflectedAssembly = Assembly.ReflectionOnlyLoadFrom(f);
|
||||
var found = reflectedAssembly.GetExportedTypes().Where(TypeHelper.IsTypeAssignableFrom<T>).ToArray();
|
||||
result.AddRange(found.Select(x => x.FullName));
|
||||
var found = reflectedAssembly.GetExportedTypes().Where(TypeHelper.IsTypeAssignableFrom<T>);
|
||||
if (found.Any())
|
||||
{
|
||||
dllsWithReference.Add(reflectedAssembly.FullName);
|
||||
}
|
||||
}
|
||||
|
||||
errorReport = errors.ToArray();
|
||||
return dllsWithReference;
|
||||
}
|
||||
|
||||
public static IEnumerable<string> ScanAssembliesForTypeReference<T>(string dllPath, out string[] errorReport)
|
||||
{
|
||||
var appDomain = GetTempAppDomain();
|
||||
var type = typeof(PackageBinaryInspector);
|
||||
var value = (PackageBinaryInspector) appDomain.CreateInstanceAndUnwrap(
|
||||
type.Assembly.FullName,
|
||||
type.FullName);
|
||||
var result = value.PerformScan<T>(dllPath, out errorReport);
|
||||
AppDomain.Unload(appDomain);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static AppDomain GetTempAppDomain()
|
||||
{
|
||||
//copy the current app domain setup but don't shadow copy files
|
||||
var appName = "TempDomain" + Guid.NewGuid();
|
||||
var domainSetup = new AppDomainSetup
|
||||
{
|
||||
ApplicationName = appName,
|
||||
ShadowCopyFiles = "false",
|
||||
ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase,
|
||||
ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile,
|
||||
DynamicBase = AppDomain.CurrentDomain.SetupInformation.DynamicBase,
|
||||
LicenseFile = AppDomain.CurrentDomain.SetupInformation.LicenseFile,
|
||||
LoaderOptimization = AppDomain.CurrentDomain.SetupInformation.LoaderOptimization,
|
||||
PrivateBinPath = AppDomain.CurrentDomain.SetupInformation.PrivateBinPath,
|
||||
PrivateBinPathProbe = AppDomain.CurrentDomain.SetupInformation.PrivateBinPathProbe
|
||||
};
|
||||
|
||||
//create new domain with full trust
|
||||
return AppDomain.CreateDomain(
|
||||
appName,
|
||||
AppDomain.CurrentDomain.Evidence,
|
||||
domainSetup,
|
||||
new PermissionSet(PermissionState.Unrestricted));
|
||||
}
|
||||
|
||||
//private static bool IsAlreadyLoaded(string assemblyFile, IEnumerable<Assembly> alreadyLoaded)
|
||||
//{
|
||||
// return alreadyLoaded.Any(assembly => GetAssemblyLocation(assembly) == assemblyFile);
|
||||
//}
|
||||
|
||||
//private static string GetAssemblyLocation(Assembly assembly)
|
||||
//{
|
||||
// var uri = new Uri(assembly.CodeBase);
|
||||
// return uri.LocalPath;
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Web;
|
||||
using System.Web.Security;
|
||||
using Newtonsoft.Json;
|
||||
@@ -11,6 +12,7 @@ namespace Umbraco.Core.Security
|
||||
/// <remarks>
|
||||
/// All values are lazy loaded for performance reasons as the constructor is called for every single request
|
||||
/// </remarks>
|
||||
[Serializable]
|
||||
public class UmbracoBackOfficeIdentity : FormsIdentity
|
||||
{
|
||||
public UmbracoBackOfficeIdentity(FormsAuthenticationTicket ticket)
|
||||
@@ -104,5 +106,6 @@ namespace Umbraco.Core.Security
|
||||
HttpContext.Current.Items[typeof (UmbracoBackOfficeIdentity)] = DeserializedData;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Runtime.Serialization;
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
@@ -6,6 +7,7 @@ namespace Umbraco.Core.Security
|
||||
/// Data structure used to store information in the authentication cookie
|
||||
/// </summary>
|
||||
[DataContract(Name = "userData", Namespace = "")]
|
||||
[Serializable]
|
||||
internal class UserData
|
||||
{
|
||||
public UserData()
|
||||
|
||||
@@ -157,6 +157,11 @@ namespace umbraco.presentation.developer.packages
|
||||
}
|
||||
}
|
||||
|
||||
if (_installer.ContainsLegacyPropertyEditors)
|
||||
{
|
||||
LegacyPropertyEditorPanel.Visible = true;
|
||||
}
|
||||
|
||||
if (_installer.ContainsBinaryFileErrors)
|
||||
{
|
||||
BinaryFileErrorsPanel.Visible = true;
|
||||
|
||||
@@ -301,6 +301,7 @@ namespace umbraco.presentation.developer.packages {
|
||||
protected global::umbraco.uicontrols.PropertyPanel pp_templateConflicts;
|
||||
|
||||
protected global::umbraco.uicontrols.PropertyPanel BinaryFileErrorsPanel;
|
||||
protected global::umbraco.uicontrols.PropertyPanel LegacyPropertyEditorPanel;
|
||||
protected global::System.Web.UI.WebControls.Literal BinaryFileErrorReport;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -63,15 +63,20 @@ namespace umbraco.cms.businesslogic.packager
|
||||
public IDictionary<string, string> ConflictingTemplateAliases { get { return _conflictingTemplateAliases; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the package contains legacy property editors that are not compatible with this version (v7)
|
||||
/// Indicates that the package contains assembly reference errors
|
||||
/// </summary>
|
||||
public bool ContainsBinaryFileErrors { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// List each property editor that is not compatible
|
||||
/// List each assembly reference error
|
||||
/// </summary>
|
||||
public List<string> BinaryFileErrors { get { return _binaryFileErrors; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the package contains legacy property editors
|
||||
/// </summary>
|
||||
public bool ContainsLegacyPropertyEditors { get; private set; }
|
||||
|
||||
public bool ContainsStyleSheeConflicts { get; private set; }
|
||||
public IDictionary<string, string> ConflictingStyleSheetNames { get { return _conflictingStyleSheetNames; } }
|
||||
|
||||
@@ -597,11 +602,16 @@ namespace umbraco.cms.businesslogic.packager
|
||||
if (ContainsUnsecureFiles)
|
||||
{
|
||||
//Now we want to see if the DLLs contain any legacy data types since we want to warn people about that
|
||||
var binaryFileErrors = PackageBinaryInspector.BinariesContainInstanceOf<IDataType>(tempDir).ToArray();
|
||||
if (binaryFileErrors.Any())
|
||||
string[] assemblyErrors;
|
||||
var assembliesWithReferences = PackageBinaryInspector.ScanAssembliesForTypeReference<IDataType>(tempDir, out assemblyErrors).ToArray();
|
||||
if (assemblyErrors.Any())
|
||||
{
|
||||
ContainsBinaryFileErrors = true;
|
||||
BinaryFileErrors.AddRange(binaryFileErrors);
|
||||
BinaryFileErrors.AddRange(assemblyErrors);
|
||||
}
|
||||
if (assembliesWithReferences.Any())
|
||||
{
|
||||
ContainsLegacyPropertyEditors = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -741,8 +751,18 @@ namespace umbraco.cms.businesslogic.packager
|
||||
private static string UnPack(string zipName)
|
||||
{
|
||||
// Unzip
|
||||
string tempDir = IOHelper.MapPath(SystemDirectories.Data) + Path.DirectorySeparatorChar + Guid.NewGuid().ToString();
|
||||
Directory.CreateDirectory(tempDir);
|
||||
|
||||
//the temp directory will be the package GUID - this keeps it consistent!
|
||||
//the zipName is always the package Guid.umb
|
||||
|
||||
var packageFileName = Path.GetFileNameWithoutExtension(zipName);
|
||||
var packageId = Guid.NewGuid();
|
||||
Guid.TryParse(packageFileName, out packageId);
|
||||
|
||||
string tempDir = IOHelper.MapPath(SystemDirectories.Data) + Path.DirectorySeparatorChar + packageId.ToString();
|
||||
//clear the directory if it exists
|
||||
if (Directory.Exists(tempDir)) Directory.Delete(tempDir, true);
|
||||
Directory.CreateDirectory(tempDir);
|
||||
|
||||
var s = new ZipInputStream(File.OpenRead(zipName));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user