From b581a45e053a306608b9b86ac1fe86a2a9b03835 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Thu, 17 Feb 2022 11:59:35 +0100 Subject: [PATCH 1/4] Fix for rooted UNC paths (#11982) --- .../DependencyInjection/UmbracoBuilder.FileSystems.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.FileSystems.cs b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.FileSystems.cs index ccb515182e..fbb32671a1 100644 --- a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.FileSystems.cs +++ b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.FileSystems.cs @@ -1,3 +1,4 @@ +using System.IO; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -49,7 +50,7 @@ namespace Umbraco.Cms.Infrastructure.DependencyInjection ILogger logger = factory.GetRequiredService>(); GlobalSettings globalSettings = factory.GetRequiredService>().Value; - var rootPath = hostingEnvironment.MapPathWebRoot(globalSettings.UmbracoMediaPhysicalRootPath); + var rootPath = Path.IsPathRooted(globalSettings.UmbracoMediaPhysicalRootPath) ? globalSettings.UmbracoMediaPhysicalRootPath : hostingEnvironment.MapPathWebRoot(globalSettings.UmbracoMediaPhysicalRootPath); var rootUrl = hostingEnvironment.ToAbsolute(globalSettings.UmbracoMediaPath); return new PhysicalFileSystem(ioHelper, hostingEnvironment, logger, rootPath, rootUrl); }); From 7cc495dc6525f3a471ab3119ff8ed8190355ac81 Mon Sep 17 00:00:00 2001 From: Mole Date: Thu, 17 Feb 2022 13:20:53 +0100 Subject: [PATCH 2/4] Bump version to 9.3.1 --- .../UmbracoPackage/.template.config/template.json | 2 +- .../UmbracoProject/.template.config/template.json | 2 +- src/Directory.Build.props | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build/templates/UmbracoPackage/.template.config/template.json b/build/templates/UmbracoPackage/.template.config/template.json index 32f0c924dd..f14fd9dadc 100644 --- a/build/templates/UmbracoPackage/.template.config/template.json +++ b/build/templates/UmbracoPackage/.template.config/template.json @@ -24,7 +24,7 @@ "version": { "type": "parameter", "datatype": "string", - "defaultValue": "9.3.0", + "defaultValue": "9.3.1", "description": "The version of Umbraco to load using NuGet", "replaces": "UMBRACO_VERSION_FROM_TEMPLATE" }, diff --git a/build/templates/UmbracoProject/.template.config/template.json b/build/templates/UmbracoProject/.template.config/template.json index b09050a2a4..b6091fada8 100644 --- a/build/templates/UmbracoProject/.template.config/template.json +++ b/build/templates/UmbracoProject/.template.config/template.json @@ -57,7 +57,7 @@ "version": { "type": "parameter", "datatype": "string", - "defaultValue": "9.3.0", + "defaultValue": "9.3.1", "description": "The version of Umbraco to load using NuGet", "replaces": "UMBRACO_VERSION_FROM_TEMPLATE" }, diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 55448806ef..7da936cf01 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -3,10 +3,10 @@ - 9.3.0 - 9.3.0 - 9.3.0 - 9.3.0 + 9.3.1 + 9.3.1 + 9.3.1 + 9.3.1 9.0 en-US Umbraco CMS From 7f762df952daf22a8d84918bd15aa2a7dc6ecc04 Mon Sep 17 00:00:00 2001 From: Ronald Barendse Date: Thu, 17 Feb 2022 13:33:45 +0100 Subject: [PATCH 3/4] Fix DataValueEditor incorrectly serializing JSON value (#12015) * Remove JSON serialization * Skip JSON serialization of strings --- src/Umbraco.Core/PropertyEditors/DataValueEditor.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs b/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs index 6f9e1b6611..795d75c319 100644 --- a/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs @@ -6,7 +6,6 @@ using System.Linq; using System.Runtime.Serialization; using System.Xml.Linq; using Microsoft.Extensions.Logging; -using Umbraco.Cms.Core.Hosting; using Umbraco.Cms.Core.IO; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Editors; @@ -158,17 +157,15 @@ namespace Umbraco.Cms.Core.PropertyEditors /// ValueType was out of range. internal Attempt TryConvertValueToCrlType(object value) { - // Ensure empty string values are converted to null - if (value is string s && string.IsNullOrWhiteSpace(s)) + // Ensure empty string and JSON values are converted to null + if (value is string stringValue && string.IsNullOrWhiteSpace(stringValue)) { value = null; } - - // Ensure JSON is serialized properly (without indentation or converted to null when empty) - if (value is not null && ValueType.InvariantEquals(ValueTypes.Json)) + else if (value is not string && ValueType.InvariantEquals(ValueTypes.Json)) { + // Only serialize value when it's not already a string var jsonValue = _jsonSerializer.Serialize(value); - if (jsonValue.DetectIsEmptyJson()) { value = null; From 3a269ed3293c8e22bd9a546f424402c0a491964f Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Thu, 17 Feb 2022 15:06:25 +0100 Subject: [PATCH 4/4] Fix issue with migration from 8 and added support for 8.18 migration (#12020) * Fixed issue with migration from 8, because the external login table is changed in 9.3, but added in 9.0. we need to use the legacy models when running 9.0 migrations * Support migration from 8.18 (final state) --- .../Migrations/Upgrade/UmbracoPlan.cs | 3 + .../V_9_0_0/ExternalLoginTableIndexes.cs | 22 +++++--- .../V_9_0_0/ExternalLoginTableIndexesFixup.cs | 16 +++--- .../V_9_0_0/ExternalLoginTokenTable.cs | 56 ++++++++++++++++++- 4 files changed, 79 insertions(+), 18 deletions(-) diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs index 2080034554..39d7d886b3 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs @@ -242,6 +242,9 @@ namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade // to 8.17.0 To("{153865E9-7332-4C2A-9F9D-F20AEE078EC7}"); + // Hack to support migration from 8.18 + To("{03482BB0-CF13-475C-845E-ECB8319DBE3C}"); + // This should be safe to execute again. We need it with a new name to ensure updates from all the following has executed this step. // - 8.15.0 RC - Current state: {4695D0C9-0729-4976-985B-048D503665D8} // - 8.15.0 Final - Current state: {5C424554-A32D-4852-8ED1-A13508187901} diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_9_0_0/ExternalLoginTableIndexes.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_9_0_0/ExternalLoginTableIndexes.cs index f350ed633c..db7f17eee3 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_9_0_0/ExternalLoginTableIndexes.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_9_0_0/ExternalLoginTableIndexes.cs @@ -1,6 +1,10 @@ +using System; using System.Collections.Generic; using System.Linq; +using NPoco; using Umbraco.Cms.Core; +using Umbraco.Cms.Infrastructure.Persistence.DatabaseAnnotations; +using Umbraco.Cms.Infrastructure.Persistence.DatabaseModelDefinitions; using Umbraco.Cms.Infrastructure.Persistence.Dtos; namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0 @@ -20,14 +24,14 @@ namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0 { // Before adding these indexes we need to remove duplicate data. // Get all logins by latest - var logins = Database.Fetch() + var logins = Database.Fetch() .OrderByDescending(x => x.CreateDate) .ToList(); var toDelete = new List(); // used to track duplicates so they can be removed var keys = new HashSet<(string, string)>(); - foreach(ExternalLoginDto login in logins) + foreach(ExternalLoginTokenTable.LegacyExternalLoginDto login in logins) { if (!keys.Add((login.ProviderKey, login.LoginProvider))) { @@ -37,16 +41,16 @@ namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0 } if (toDelete.Count > 0) { - Database.DeleteMany().Where(x => toDelete.Contains(x.Id)).Execute(); - } + Database.DeleteMany().Where(x => toDelete.Contains(x.Id)).Execute(); + } - var indexName1 = "IX_" + ExternalLoginDto.TableName + "_LoginProvider"; + var indexName1 = "IX_" + ExternalLoginTokenTable.LegacyExternalLoginDto.TableName + "_LoginProvider"; if (!IndexExists(indexName1)) { Create .Index(indexName1) - .OnTable(ExternalLoginDto.TableName) + .OnTable(ExternalLoginTokenTable.LegacyExternalLoginDto.TableName) .OnColumn("loginProvider") .Ascending() .WithOptions() @@ -56,13 +60,13 @@ namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0 .Do(); } - var indexName2 = "IX_" + ExternalLoginDto.TableName + "_ProviderKey"; + var indexName2 = "IX_" + ExternalLoginTokenTable.LegacyExternalLoginDto.TableName + "_ProviderKey"; if (!IndexExists(indexName2)) { Create .Index(indexName2) - .OnTable(ExternalLoginDto.TableName) + .OnTable(ExternalLoginTokenTable.LegacyExternalLoginDto.TableName) .OnColumn("loginProvider").Ascending() .OnColumn("providerKey").Ascending() .WithOptions() @@ -70,5 +74,7 @@ namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0 .Do(); } } + + } } diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_9_0_0/ExternalLoginTableIndexesFixup.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_9_0_0/ExternalLoginTableIndexesFixup.cs index 5efb914eb7..2c77b301ce 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_9_0_0/ExternalLoginTableIndexesFixup.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_9_0_0/ExternalLoginTableIndexesFixup.cs @@ -14,29 +14,29 @@ namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0 protected override void Migrate() { - var indexName1 = "IX_" + ExternalLoginDto.TableName + "_LoginProvider"; - var indexName2 = "IX_" + ExternalLoginDto.TableName + "_ProviderKey"; + var indexName1 = "IX_" + ExternalLoginTokenTable.LegacyExternalLoginDto.TableName + "_LoginProvider"; + var indexName2 = "IX_" + ExternalLoginTokenTable.LegacyExternalLoginDto.TableName + "_ProviderKey"; if (IndexExists(indexName1)) { // drop it since the previous migration index was wrong, and we // need to modify a column that belons to it - Delete.Index(indexName1).OnTable(ExternalLoginDto.TableName).Do(); + Delete.Index(indexName1).OnTable(ExternalLoginTokenTable.LegacyExternalLoginDto.TableName).Do(); } if (IndexExists(indexName2)) { // drop since it's using a column we're about to modify - Delete.Index(indexName2).OnTable(ExternalLoginDto.TableName).Do(); + Delete.Index(indexName2).OnTable(ExternalLoginTokenTable.LegacyExternalLoginDto.TableName).Do(); } // then fixup the length of the loginProvider column - AlterColumn(ExternalLoginDto.TableName, "loginProvider"); + AlterColumn(ExternalLoginTokenTable.LegacyExternalLoginDto.TableName, "loginProvider"); // create it with the correct definition Create .Index(indexName1) - .OnTable(ExternalLoginDto.TableName) + .OnTable(ExternalLoginTokenTable.LegacyExternalLoginDto.TableName) .OnColumn("loginProvider").Ascending() .OnColumn("userId").Ascending() .WithOptions() @@ -48,9 +48,9 @@ namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0 // re-create the original Create .Index(indexName2) - .OnTable(ExternalLoginDto.TableName) + .OnTable(ExternalLoginTokenTable.LegacyExternalLoginDto.TableName) .OnColumn("loginProvider").Ascending() - .OnColumn("providerKey").Ascending() + .OnColumn("providerKey").Ascending() .WithOptions() .NonClustered() .Do(); diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_9_0_0/ExternalLoginTokenTable.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_9_0_0/ExternalLoginTokenTable.cs index 8dd43f1834..851d986c7c 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_9_0_0/ExternalLoginTokenTable.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_9_0_0/ExternalLoginTokenTable.cs @@ -1,10 +1,14 @@ +using System; using System.Collections.Generic; +using NPoco; +using Umbraco.Cms.Core; +using Umbraco.Cms.Infrastructure.Persistence.DatabaseAnnotations; +using Umbraco.Cms.Infrastructure.Persistence.DatabaseModelDefinitions; using Umbraco.Cms.Infrastructure.Persistence.Dtos; using Umbraco.Extensions; namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0 { - public class ExternalLoginTokenTable : MigrationBase { public ExternalLoginTokenTable(IMigrationContext context) @@ -13,7 +17,7 @@ namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0 } /// - /// Adds new External Login token table + /// Adds new External Login token table /// protected override void Migrate() { @@ -25,5 +29,53 @@ namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0 Create.Table().Do(); } + + [TableName(TableName)] + [ExplicitColumns] + [PrimaryKey("Id")] + internal class LegacyExternalLoginDto + { + public const string TableName = Constants.DatabaseSchema.Tables.ExternalLogin; + + [Column("id")] [PrimaryKeyColumn] public int Id { get; set; } + + [Obsolete( + "This only exists to ensure you can upgrade using external logins from umbraco version where this was used to the new where it is not used")] + [Column("userId")] + public int? UserId { get; set; } + + + /// + /// Used to store the name of the provider (i.e. Facebook, Google) + /// + [Column("loginProvider")] + [Length(400)] + [NullSetting(NullSetting = NullSettings.NotNull)] + [Index(IndexTypes.UniqueNonClustered, ForColumns = "loginProvider,userOrMemberKey", + Name = "IX_" + TableName + "_LoginProvider")] + public string LoginProvider { get; set; } + + /// + /// Stores the key the provider uses to lookup the login + /// + [Column("providerKey")] + [Length(4000)] + [NullSetting(NullSetting = NullSettings.NotNull)] + [Index(IndexTypes.NonClustered, ForColumns = "loginProvider,providerKey", + Name = "IX_" + TableName + "_ProviderKey")] + public string ProviderKey { get; set; } + + [Column("createDate")] + [Constraint(Default = SystemMethods.CurrentDateTime)] + public DateTime CreateDate { get; set; } + + /// + /// Used to store any arbitrary data for the user and external provider - like user tokens returned from the provider + /// + [Column("userData")] + [NullSetting(NullSetting = NullSettings.Null)] + [SpecialDbType(SpecialDbTypes.NTEXT)] + public string UserData { get; set; } + } } }