diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs index 97ebd98e8c..b5a8fbc738 100644 --- a/src/SolutionInfo.cs +++ b/src/SolutionInfo.cs @@ -11,5 +11,5 @@ using System.Resources; [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("7.15.3")] -[assembly: AssemblyInformationalVersion("7.15.3")] +[assembly: AssemblyFileVersion("7.15.4")] +[assembly: AssemblyInformationalVersion("7.15.4")] diff --git a/src/Umbraco.Core/Configuration/UmbracoVersion.cs b/src/Umbraco.Core/Configuration/UmbracoVersion.cs index 8c8755577a..65bd4f8694 100644 --- a/src/Umbraco.Core/Configuration/UmbracoVersion.cs +++ b/src/Umbraco.Core/Configuration/UmbracoVersion.cs @@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration { public class UmbracoVersion { - private static readonly Version Version = new Version("7.15.3"); + private static readonly Version Version = new Version("7.15.4"); /// /// Gets the current version of Umbraco. diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFifteenFour/PopulateMissingSecurityStamps.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFifteenFour/PopulateMissingSecurityStamps.cs new file mode 100644 index 0000000000..042a003c75 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFifteenFour/PopulateMissingSecurityStamps.cs @@ -0,0 +1,24 @@ +using System; +using Umbraco.Core.Logging; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFifteenFour +{ + [Migration("7.15.4", 1, Constants.System.UmbracoMigrationName)] + public class PopulateMissingSecurityStamps : MigrationBase + { + public PopulateMissingSecurityStamps(ISqlSyntaxProvider sqlSyntax, ILogger logger) : base(sqlSyntax, logger) + { + } + + public override void Up() + { + // A user with a NULL securityStampToken can't log in after v7.8.0 + Execute.Sql($@"UPDATE umbracoUser SET securityStampToken = '{Guid.NewGuid().ToString()}' WHERE securityStampToken IS NULL"); + } + + public override void Down() + { + } + } +} diff --git a/src/Umbraco.Core/Security/UmbracoBackOfficeIdentity.cs b/src/Umbraco.Core/Security/UmbracoBackOfficeIdentity.cs index fcb5547027..7772b198c6 100644 --- a/src/Umbraco.Core/Security/UmbracoBackOfficeIdentity.cs +++ b/src/Umbraco.Core/Security/UmbracoBackOfficeIdentity.cs @@ -115,6 +115,12 @@ namespace Umbraco.Core.Security AddClaim(new Claim(ClaimTypes.CookiePath, "/", ClaimValueTypes.String, Issuer, Issuer, this)); } + // if upgrading from a pre-7.3.0 version, SecurityStamp will be null + if (userdata.SecurityStamp == null && ApplicationContext.Current.IsUpgrading) + { + userdata.SecurityStamp = Guid.NewGuid().ToString(); + } + _currentIssuer = claimsIdentity.AuthenticationType; UserData = userdata; AddExistingClaims(claimsIdentity); @@ -227,7 +233,9 @@ namespace Umbraco.Core.Security //The security stamp claim is also required... this is because this claim type is hard coded // by the SecurityStampValidator, see: https://katanaproject.codeplex.com/workitem/444 if (HasClaim(x => x.Type == Microsoft.AspNet.Identity.Constants.DefaultSecurityStampClaimType) == false) + { AddClaim(new Claim(Microsoft.AspNet.Identity.Constants.DefaultSecurityStampClaimType, SecurityStamp, ClaimValueTypes.String, Issuer, Issuer, this)); + } //Add each app as a separate claim if (HasClaim(x => x.Type == Constants.Security.AllowedApplicationsClaimType) == false) diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 3b5d0aaff6..fe822e10bc 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -576,6 +576,7 @@ + diff --git a/src/Umbraco.Tests/Security/UmbracoBackOfficeIdentityTests.cs b/src/Umbraco.Tests/Security/UmbracoBackOfficeIdentityTests.cs index d9ab9c9a3d..950c2b898f 100644 --- a/src/Umbraco.Tests/Security/UmbracoBackOfficeIdentityTests.cs +++ b/src/Umbraco.Tests/Security/UmbracoBackOfficeIdentityTests.cs @@ -4,9 +4,14 @@ using System.Security.Claims; using System.Text; using System.Threading.Tasks; using System.Web.Security; +using Moq; using Newtonsoft.Json; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Logging; +using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Core.Profiling; +using Umbraco.Core.Scoping; using Umbraco.Core.Security; using Umbraco.Core.Services; @@ -15,9 +20,24 @@ namespace Umbraco.Tests.Security [TestFixture] public class UmbracoBackOfficeIdentityTests { - public const string TestIssuer = "TestIssuer"; + [SetUp] + public void Initialize() + { + var sqlSyntax = new SqlCeSyntaxProvider(); + + //This is needed because the Migration resolver is creating migration instances with their full ctors + ApplicationContext.EnsureContext( + new ApplicationContext( + new DatabaseContext(Mock.Of(), Mock.Of(), sqlSyntax, "test"), + new ServiceContext(), + CacheHelper.CreateDisabledCacheHelper(), + new ProfilingLogger(Mock.Of(), Mock.Of())), + true); + } + + [Test] public void Create_From_Claims_Identity() { diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 76d2765672..3e0ce457e1 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -1028,9 +1028,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\" True True - 7153 + 7154 / - http://localhost:7153 + http://localhost:7154 False False