Merge branch 'v8/dev' into v8/bugfix/AB10622-be-property-editor-caching
This commit is contained in:
@@ -16,6 +16,8 @@ namespace Umbraco.Core.Composing
|
||||
{
|
||||
protected abstract TBuilder This { get; }
|
||||
|
||||
private readonly Dictionary<Type, int> _customWeights = new Dictionary<Type, int>();
|
||||
|
||||
/// <summary>
|
||||
/// Clears all types in the collection.
|
||||
/// </summary>
|
||||
@@ -107,6 +109,18 @@ namespace Umbraco.Core.Composing
|
||||
return This;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the default weight of an item
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of item</typeparam>
|
||||
/// <param name="weight">The new weight</param>
|
||||
/// <returns></returns>
|
||||
public TBuilder SetWeight<T>(int weight) where T : TItem
|
||||
{
|
||||
_customWeights[typeof(T)] = weight;
|
||||
return This;
|
||||
}
|
||||
|
||||
protected override IEnumerable<Type> GetRegisteringTypes(IEnumerable<Type> types)
|
||||
{
|
||||
var list = types.ToList();
|
||||
@@ -118,6 +132,8 @@ namespace Umbraco.Core.Composing
|
||||
|
||||
protected virtual int GetWeight(Type type)
|
||||
{
|
||||
if (_customWeights.ContainsKey(type))
|
||||
return _customWeights[type];
|
||||
var attr = type.GetCustomAttributes(typeof(WeightAttribute), false).OfType<WeightAttribute>().SingleOrDefault();
|
||||
return attr?.Weight ?? DefaultWeight;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// The name of the 'unknown' user.
|
||||
/// </summary>
|
||||
public const string UnknownUserName = "SYTEM";
|
||||
public const string UnknownUserName = "SYSTEM";
|
||||
|
||||
public const string AdminGroupAlias = "admin";
|
||||
public const string EditorGroupAlias = "editor";
|
||||
|
||||
9
src/Umbraco.Core/Events/UnattendedInstallEventArgs.cs
Normal file
9
src/Umbraco.Core/Events/UnattendedInstallEventArgs.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to notify that an Unattended install has completed
|
||||
/// </summary>
|
||||
public class UnattendedInstallEventArgs : System.ComponentModel.CancelEventArgs
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -141,14 +141,14 @@ namespace Umbraco.Core.Migrations.Install
|
||||
//New UDI pickers with newer Ids
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1046, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1046", SortOrder = 2, UniqueId = new Guid("FD1E0DA5-5606-4862-B679-5D0CF3A52A59"), Text = "Content Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1047, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1047", SortOrder = 2, UniqueId = new Guid("1EA2E01F-EBD8-4CE1-8D71-6B1149E63548"), Text = "Member Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1048, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1048", SortOrder = 2, UniqueId = new Guid("135D60E0-64D9-49ED-AB08-893C9BA44AE5"), Text = "Media Picker (old)", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1049, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1049", SortOrder = 2, UniqueId = new Guid("9DBBCBBB-2327-434A-B355-AF1B84E5010A"), Text = "Multiple Media Picker (old)", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1048, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1048", SortOrder = 2, UniqueId = new Guid("135D60E0-64D9-49ED-AB08-893C9BA44AE5"), Text = "(Obsolete) Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1049, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1049", SortOrder = 2, UniqueId = new Guid("9DBBCBBB-2327-434A-B355-AF1B84E5010A"), Text = "(Obsolete) Multiple Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1050, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1050", SortOrder = 2, UniqueId = new Guid("B4E3535A-1753-47E2-8568-602CF8CFEE6F"), Text = "Multi URL Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1051, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1051", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3Guid, Text = "Media Picker 3", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1052, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1052", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3MultipleGuid, Text = "Multiple Media Picker 3", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1053, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1053", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3SingleImageGuid, Text = "Image Media Picker 3", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1054, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1054", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3MultipleImagesGuid, Text = "Multiple Image Media Picker 3", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1051, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1051", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3Guid, Text = "Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1052, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1052", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3MultipleGuid, Text = "Multiple Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1053, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1053", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3SingleImageGuid, Text = "Image Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1054, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1054", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.MediaPicker3MultipleImagesGuid, Text = "Multiple Image Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
|
||||
}
|
||||
|
||||
@@ -350,8 +350,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1046, EditorAlias = Constants.PropertyEditors.Aliases.ContentPicker, DbType = "Nvarchar" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1047, EditorAlias = Constants.PropertyEditors.Aliases.MemberPicker, DbType = "Nvarchar" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1048, EditorAlias = Constants.PropertyEditors.Aliases.MediaPicker, DbType = "Ntext" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1049, EditorAlias = Constants.PropertyEditors.Aliases.MediaPicker, DbType = "Ntext",
|
||||
Configuration = "{\"multiPicker\":1}" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1049, EditorAlias = Constants.PropertyEditors.Aliases.MediaPicker, DbType = "Ntext", Configuration = "{\"multiPicker\":1}" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1050, EditorAlias = Constants.PropertyEditors.Aliases.MultiUrlPicker, DbType = "Ntext" });
|
||||
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Umbraco.Core.Models.Entities
|
||||
/// <inheritdoc />
|
||||
public virtual bool IsPropertyDirty(string propertyName)
|
||||
{
|
||||
return _currentChanges != null && _currentChanges.Any(x => x.Key == propertyName);
|
||||
return _currentChanges != null && _currentChanges.ContainsKey(propertyName);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -61,7 +61,7 @@ namespace Umbraco.Core.Models.Entities
|
||||
/// <inheritdoc />
|
||||
public virtual bool WasPropertyDirty(string propertyName)
|
||||
{
|
||||
return _savedChanges != null && _savedChanges.Any(x => x.Key == propertyName);
|
||||
return _savedChanges != null && _savedChanges.ContainsKey(propertyName);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
@@ -16,6 +20,9 @@ using Umbraco.Core.Migrations.Install;
|
||||
using Umbraco.Core.Migrations.Upgrade;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Sync;
|
||||
|
||||
namespace Umbraco.Core.Runtime
|
||||
@@ -119,6 +126,9 @@ namespace Umbraco.Core.Runtime
|
||||
|
||||
try
|
||||
{
|
||||
// Setup event listener
|
||||
UnattendedInstalled += CoreRuntime_UnattendedInstalled;
|
||||
|
||||
// throws if not full-trust
|
||||
new AspNetHostingPermission(AspNetHostingPermissionLevel.Unrestricted).Demand();
|
||||
|
||||
@@ -162,8 +172,7 @@ namespace Umbraco.Core.Runtime
|
||||
// run handlers
|
||||
RuntimeOptions.DoRuntimeEssentials(composition, appCaches, typeLoader, databaseFactory);
|
||||
|
||||
// determines if unattended install is enabled and performs it if required
|
||||
DoUnattendedInstall(databaseFactory);
|
||||
|
||||
|
||||
// register runtime-level services
|
||||
// there should be none, really - this is here "just in case"
|
||||
@@ -190,6 +199,13 @@ namespace Umbraco.Core.Runtime
|
||||
// create the factory
|
||||
_factory = Current.Factory = composition.CreateFactory();
|
||||
|
||||
// determines if unattended install is enabled and performs it if required
|
||||
DoUnattendedInstall(databaseFactory);
|
||||
|
||||
// determine our runtime level (AFTER UNATTENDED INSTALL)
|
||||
// TODO: Feels kinda weird to call this again
|
||||
DetermineRuntimeLevel(databaseFactory, ProfilingLogger);
|
||||
|
||||
// if level is Run and reason is UpgradeMigrations, that means we need to perform an unattended upgrade
|
||||
if (_state.Reason == RuntimeLevelReason.UpgradeMigrations && _state.Level == RuntimeLevel.Run)
|
||||
{
|
||||
@@ -203,8 +219,6 @@ namespace Umbraco.Core.Runtime
|
||||
// create & initialize the components
|
||||
_components = _factory.GetInstance<ComponentCollection>();
|
||||
_components.Initialize();
|
||||
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -242,6 +256,93 @@ namespace Umbraco.Core.Runtime
|
||||
return _factory;
|
||||
}
|
||||
|
||||
private void CoreRuntime_UnattendedInstalled(IRuntime sender, UnattendedInstallEventArgs e)
|
||||
{
|
||||
var unattendedName = Environment.GetEnvironmentVariable("UnattendedUserName");
|
||||
var unattendedEmail = Environment.GetEnvironmentVariable("UnattendedUserEmail");
|
||||
var unattendedPassword = Environment.GetEnvironmentVariable("UnattendedUserPassword");
|
||||
|
||||
var fileExists = false;
|
||||
var filePath = IOHelper.MapPath("~/App_Data/unattended.user.json");
|
||||
|
||||
// No values store in ENV vars - try fallback file of /app_data/unattended.user.json
|
||||
if (unattendedName.IsNullOrWhiteSpace()
|
||||
|| unattendedEmail.IsNullOrWhiteSpace()
|
||||
|| unattendedPassword.IsNullOrWhiteSpace())
|
||||
{
|
||||
|
||||
fileExists = File.Exists(filePath);
|
||||
if (fileExists == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Attempt to deserialize JSON
|
||||
try
|
||||
{
|
||||
var fileContents = File.ReadAllText(filePath);
|
||||
var credentials = JsonConvert.DeserializeObject<UnattendedUserConfig>(fileContents);
|
||||
|
||||
unattendedName = credentials.Name;
|
||||
unattendedEmail = credentials.Email;
|
||||
unattendedPassword = credentials.Password;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
// ENV Variables & JSON still empty
|
||||
if (unattendedName.IsNullOrWhiteSpace()
|
||||
|| unattendedEmail.IsNullOrWhiteSpace()
|
||||
|| unattendedPassword.IsNullOrWhiteSpace())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Update user details
|
||||
var currentProvider = MembershipProviderExtensions.GetUsersMembershipProvider();
|
||||
var admin = Current.Services.UserService.GetUserById(Constants.Security.SuperUserId);
|
||||
if (admin == null)
|
||||
{
|
||||
throw new InvalidOperationException("Could not find the super user!");
|
||||
}
|
||||
|
||||
var membershipUser = currentProvider.GetUser(Constants.Security.SuperUserId, true);
|
||||
if (membershipUser == null)
|
||||
{
|
||||
throw new InvalidOperationException($"No user found in membership provider with id of {Constants.Security.SuperUserId}.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var success = membershipUser.ChangePassword("default", unattendedPassword.Trim());
|
||||
if (success == false)
|
||||
{
|
||||
throw new FormatException("Password must be at least " + currentProvider.MinRequiredPasswordLength + " characters long and contain at least " + currentProvider.MinRequiredNonAlphanumericCharacters + " symbols");
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new FormatException("Password must be at least " + currentProvider.MinRequiredPasswordLength + " characters long and contain at least " + currentProvider.MinRequiredNonAlphanumericCharacters + " symbols");
|
||||
}
|
||||
|
||||
admin.Email = unattendedEmail.Trim();
|
||||
admin.Name = unattendedName.Trim();
|
||||
admin.Username = unattendedEmail.Trim();
|
||||
|
||||
Current.Services.UserService.Save(admin);
|
||||
|
||||
// Delete JSON file if it existed to tidy
|
||||
if (fileExists)
|
||||
{
|
||||
File.Delete(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
private void DoUnattendedInstall(IUmbracoDatabaseFactory databaseFactory)
|
||||
{
|
||||
// unattended install is not enabled
|
||||
@@ -285,6 +386,11 @@ namespace Umbraco.Core.Runtime
|
||||
var creator = new DatabaseSchemaCreator(database, Logger);
|
||||
creator.InitializeDatabaseSchema();
|
||||
database.CompleteTransaction();
|
||||
|
||||
// Emit an event that unattended install completed
|
||||
// Then this event can be listened for and create an unattended user
|
||||
UnattendedInstalled?.Invoke(this, new UnattendedInstallEventArgs());
|
||||
|
||||
Logger.Info<CoreRuntime>("Unattended install completed.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -397,6 +503,7 @@ namespace Umbraco.Core.Runtime
|
||||
public virtual void Terminate()
|
||||
{
|
||||
_components?.Terminate();
|
||||
UnattendedInstalled -= CoreRuntime_UnattendedInstalled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -404,7 +511,7 @@ namespace Umbraco.Core.Runtime
|
||||
/// </summary>
|
||||
public virtual void Compose(Composition composition)
|
||||
{
|
||||
// nothing
|
||||
// Nothing
|
||||
}
|
||||
|
||||
#region Getters
|
||||
@@ -465,5 +572,23 @@ namespace Umbraco.Core.Runtime
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Event to be used to notify when the Unattended Install has finished
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IRuntime, UnattendedInstallEventArgs> UnattendedInstalled;
|
||||
|
||||
[DataContract]
|
||||
public class UnattendedUserConfig
|
||||
{
|
||||
[DataMember(Name = "name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[DataMember(Name = "email")]
|
||||
public string Email { get; set; }
|
||||
|
||||
[DataMember(Name = "password")]
|
||||
public string Password { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,6 +131,7 @@
|
||||
<Compile Include="Constants-CharArrays.cs" />
|
||||
<Compile Include="Collections\EventClearingObservableCollection.cs" />
|
||||
<Compile Include="Constants-SqlTemplates.cs" />
|
||||
<Compile Include="Events\UnattendedInstallEventArgs.cs" />
|
||||
<Compile Include="Logging\ILogger2.cs" />
|
||||
<Compile Include="Logging\Logger2Extensions.cs" />
|
||||
<Compile Include="Dashboards\ContentDashboardSettings.cs" />
|
||||
|
||||
Reference in New Issue
Block a user