From 836297df583340724563350656fb0ac18909de26 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 15 May 2014 13:35:52 +1000 Subject: [PATCH 01/13] Fixes error message on publishing when it fails due to any of these statuses: FailedHasExpired, FailedAwaitingRelease, FailedIsTrashed --- src/Umbraco.Web/WebServices/BulkPublishController.cs | 2 +- .../umbraco.presentation/umbraco/actions/publish.aspx.cs | 1 + .../umbraco.presentation/umbraco/editContent.aspx.cs | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/WebServices/BulkPublishController.cs b/src/Umbraco.Web/WebServices/BulkPublishController.cs index 2c18a6df2c..30a609f6ff 100644 --- a/src/Umbraco.Web/WebServices/BulkPublishController.cs +++ b/src/Umbraco.Web/WebServices/BulkPublishController.cs @@ -87,7 +87,7 @@ namespace Umbraco.Web.WebServices case PublishStatusType.FailedHasExpired: case PublishStatusType.FailedAwaitingRelease: case PublishStatusType.FailedIsTrashed: - return ""; //we will not notify about this type of failure... or should we ? + return "Cannot publish document with a status of " + status.StatusType; case PublishStatusType.FailedCancelledByEvent: return ui.Text("publish", "contentPublishedFailedByEvent", string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id), UmbracoUser); diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.cs index 928ac680a6..a505f3cb69 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.cs @@ -70,6 +70,7 @@ namespace umbraco.presentation.actions case PublishStatusType.FailedHasExpired: case PublishStatusType.FailedAwaitingRelease: case PublishStatusType.FailedIsTrashed: + return "Cannot publish document with a status of " + status.StatusType; case PublishStatusType.FailedContentInvalid: return ui.Text("publish", "contentPublishedFailedInvalid", new[] diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs index 3af648c142..bf12e4d931 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs @@ -341,6 +341,11 @@ namespace umbraco.cms.presentation case PublishStatusType.FailedHasExpired: case PublishStatusType.FailedAwaitingRelease: case PublishStatusType.FailedIsTrashed: + ClientTools.ShowSpeechBubble( + speechBubbleIcon.warning, + ui.Text("publish"), + "Cannot publish document with a status of " + status.StatusType); + break; case PublishStatusType.FailedContentInvalid: ClientTools.ShowSpeechBubble( speechBubbleIcon.warning, From 5f9dddafd80c8fa72b2b7d5637ec5078c2c2b5a1 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 15 May 2014 14:11:43 +1000 Subject: [PATCH 02/13] fixed an upgrade script when upgrading from old 4.x versions --- .../RemoveUmbracoAppConstraints.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourNineZero/RemoveUmbracoAppConstraints.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourNineZero/RemoveUmbracoAppConstraints.cs index 244884017c..9ecb530578 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourNineZero/RemoveUmbracoAppConstraints.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourNineZero/RemoveUmbracoAppConstraints.cs @@ -1,5 +1,7 @@ using System.Data; +using System.Linq; using Umbraco.Core.Configuration; +using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionFourNineZero { @@ -18,9 +20,18 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionFourNineZero } else { - //These are the old aliases - Delete.ForeignKey("FK_umbracoUser2app_umbracoApp").OnTable("umbracoUser2app"); - Delete.ForeignKey("FK_umbracoUser2app_umbracoUser").OnTable("umbracoUser2app"); + //These are the old aliases, before removing them, check they exist + var constraints = SqlSyntaxContext.SqlSyntaxProvider.GetConstraintsPerColumn(Context.Database).Distinct().ToArray(); + + if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser2app") && x.Item3.InvariantEquals("FK_umbracoUser2app_umbracoApp"))) + { + Delete.ForeignKey("FK_umbracoUser2app_umbracoApp").OnTable("umbracoUser2app"); + } + if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser2app") && x.Item3.InvariantEquals("FK_umbracoUser2app_umbracoUser"))) + { + Delete.ForeignKey("FK_umbracoUser2app_umbracoUser").OnTable("umbracoUser2app"); + } + } } From 365a8e85e9884a0b98ebed95c60449b5aaa55e2a Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 15 May 2014 16:13:54 +1000 Subject: [PATCH 03/13] Fixes: U4-2356 --- .../Repositories/TemplateRepository.cs | 2 +- .../Repositories/TemplateRepositoryTest.cs | 272 +++++++++++------- 2 files changed, 169 insertions(+), 105 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs b/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs index e3b69a786e..767f59087a 100644 --- a/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs @@ -158,7 +158,7 @@ namespace Umbraco.Core.Persistence.Repositories { "DELETE FROM umbracoUser2NodeNotify WHERE nodeId = @Id", "DELETE FROM umbracoUser2NodePermission WHERE nodeId = @Id", - "UPDATE cmsDocument SET templateId = NULL WHERE nodeId = @Id", + "UPDATE cmsDocument SET templateId = NULL WHERE templateId = @Id", "DELETE FROM cmsDocumentType WHERE templateNodeId = @Id", "DELETE FROM cmsTemplate WHERE nodeId = @Id", "DELETE FROM umbracoNode WHERE id = @Id" diff --git a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs index db7d553a58..a8c31b60d5 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; using System.Text; using NUnit.Framework; +using Umbraco.Core; using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Persistence; @@ -10,6 +11,7 @@ using Umbraco.Core.Persistence.Caching; using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.UnitOfWork; using Umbraco.Tests.TestHelpers; +using Umbraco.Tests.TestHelpers.Entities; namespace Umbraco.Tests.Persistence.Repositories { @@ -37,10 +39,13 @@ namespace Umbraco.Tests.Persistence.Repositories var unitOfWork = provider.GetUnitOfWork(); // Act - var repository = RepositoryResolver.Current.ResolveByType(unitOfWork); + using (var repository = RepositoryResolver.Current.ResolveByType(unitOfWork)) + { + + // Assert + Assert.That(repository, Is.Not.Null); + } - // Assert - Assert.That(repository, Is.Not.Null); } [Test] @@ -51,10 +56,13 @@ namespace Umbraco.Tests.Persistence.Repositories var unitOfWork = provider.GetUnitOfWork(); // Act - var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem); + using (var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem)) + { + + // Assert + Assert.That(repository, Is.Not.Null); + } - // Assert - Assert.That(repository, Is.Not.Null); } [Test] @@ -63,16 +71,18 @@ namespace Umbraco.Tests.Persistence.Repositories // Arrange var provider = new PetaPocoUnitOfWorkProvider(); var unitOfWork = provider.GetUnitOfWork(); - var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem); + using (var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem)) + { + // Act + var template = new Template("test-add-masterpage.master", "test", "test") { Content = @"<%@ Master Language=""C#"" %>" }; + repository.AddOrUpdate(template); + unitOfWork.Commit(); - // Act - var template = new Template("test-add-masterpage.master", "test", "test") { Content = @"<%@ Master Language=""C#"" %>" }; - repository.AddOrUpdate(template); - unitOfWork.Commit(); - - //Assert - Assert.That(repository.Get("test"), Is.Not.Null); - Assert.That(_masterPageFileSystem.FileExists("test.master"), Is.True); + //Assert + Assert.That(repository.Get("test"), Is.Not.Null); + Assert.That(_masterPageFileSystem.FileExists("test.master"), Is.True); + } + } [Test] @@ -81,22 +91,25 @@ namespace Umbraco.Tests.Persistence.Repositories // Arrange var provider = new PetaPocoUnitOfWorkProvider(); var unitOfWork = provider.GetUnitOfWork(); - var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem); + using (var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem)) + { + // Act + var template = new Template("test-updated-masterpage.master", "test", "test") { Content = @"<%@ Master Language=""C#"" %>" }; + repository.AddOrUpdate(template); + unitOfWork.Commit(); - // Act - var template = new Template("test-updated-masterpage.master", "test", "test") { Content = @"<%@ Master Language=""C#"" %>" }; - repository.AddOrUpdate(template); - unitOfWork.Commit(); + template.Content = @"<%@ Master Language=""VB"" %>"; + repository.AddOrUpdate(template); + unitOfWork.Commit(); - template.Content = @"<%@ Master Language=""VB"" %>"; - repository.AddOrUpdate(template); - unitOfWork.Commit(); + var updated = repository.Get("test"); - var updated = repository.Get("test"); + // Assert + Assert.That(_masterPageFileSystem.FileExists("test.master"), Is.True); + Assert.That(updated.Content, Is.EqualTo(@"<%@ Master Language=""VB"" %>")); + } - // Assert - Assert.That(_masterPageFileSystem.FileExists("test.master"), Is.True); - Assert.That(updated.Content, Is.EqualTo(@"<%@ Master Language=""VB"" %>")); + } [Test] @@ -105,19 +118,64 @@ namespace Umbraco.Tests.Persistence.Repositories // Arrange var provider = new PetaPocoUnitOfWorkProvider(); var unitOfWork = provider.GetUnitOfWork(); - var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem); + using (var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem)) + { + var template = new Template("test-add-masterpage.master", "test", "test") { Content = @"<%@ Master Language=""C#"" %>" }; + repository.AddOrUpdate(template); + unitOfWork.Commit(); - var template = new Template("test-add-masterpage.master", "test", "test") { Content = @"<%@ Master Language=""C#"" %>" }; - repository.AddOrUpdate(template); - unitOfWork.Commit(); + // Act + var templates = repository.Get("test"); + repository.Delete(templates); + unitOfWork.Commit(); - // Act - var templates = repository.Get("test"); - repository.Delete(templates); - unitOfWork.Commit(); + // Assert + Assert.IsNull(repository.Get("test")); + } - // Assert - Assert.IsNull(repository.Get("test")); + + } + + [Test] + public void Can_Perform_Delete_When_Assigned_To_Doc() + { + // Arrange + var provider = new PetaPocoUnitOfWorkProvider(); + var unitOfWork = provider.GetUnitOfWork(); + + var templateRepository = new TemplateRepository(unitOfWork, NullCacheProvider.Current); + var tagRepository = new TagsRepository(unitOfWork, NullCacheProvider.Current); + var contentTypeRepository = new ContentTypeRepository(unitOfWork, NullCacheProvider.Current, templateRepository); + var contentRepo = new ContentRepository(unitOfWork, NullCacheProvider.Current, contentTypeRepository, templateRepository, tagRepository, CacheHelper.CreateDisabledCacheHelper()); + + using (contentRepo) + { + var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage2", "Textpage"); + var textpage = MockedContent.CreateSimpleContent(contentType); + contentTypeRepository.AddOrUpdate(contentType); + contentRepo.AddOrUpdate(textpage); + unitOfWork.Commit(); + + using (var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem)) + { + var template = new Template("test-add-masterpage.master", "test", "test") { Content = @"<%@ Master Language=""C#"" %>" }; + repository.AddOrUpdate(template); + unitOfWork.Commit(); + + textpage.Template = template; + contentRepo.AddOrUpdate(textpage); + unitOfWork.Commit(); + + // Act + var templates = repository.Get("test"); + repository.Delete(templates); + unitOfWork.Commit(); + + // Assert + Assert.IsNull(repository.Get("test")); + } + } + } [Test] @@ -126,27 +184,30 @@ namespace Umbraco.Tests.Persistence.Repositories // Arrange var provider = new PetaPocoUnitOfWorkProvider(); var unitOfWork = provider.GetUnitOfWork(); - var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem); - - var parent = new Template("test-parent-masterpage.master", "parent", "parent") { Content = @"<%@ Master Language=""C#"" %>" }; - var child = new Template("test-child-masterpage.master", "child", "child") { Content = @"<%@ Master Language=""C#"" %>" }; + using (var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem)) + { + var parent = new Template("test-parent-masterpage.master", "parent", "parent") { Content = @"<%@ Master Language=""C#"" %>" }; + var child = new Template("test-child-masterpage.master", "child", "child") { Content = @"<%@ Master Language=""C#"" %>" }; var baby = new Template("test-baby-masterpage.master", "baby", "baby") { Content = @"<%@ Master Language=""C#"" %>" }; - child.MasterTemplateAlias = parent.Alias; - child.MasterTemplateId = new Lazy(() => parent.Id); - baby.MasterTemplateAlias = child.Alias; - baby.MasterTemplateId = new Lazy(() => child.Id); - repository.AddOrUpdate(parent); - repository.AddOrUpdate(child); - repository.AddOrUpdate(baby); - unitOfWork.Commit(); + child.MasterTemplateAlias = parent.Alias; + child.MasterTemplateId = new Lazy(() => parent.Id); + baby.MasterTemplateAlias = child.Alias; + baby.MasterTemplateId = new Lazy(() => child.Id); + repository.AddOrUpdate(parent); + repository.AddOrUpdate(child); + repository.AddOrUpdate(baby); + unitOfWork.Commit(); - // Act - var templates = repository.Get("parent"); - repository.Delete(templates); - unitOfWork.Commit(); + // Act + var templates = repository.Get("parent"); + repository.Delete(templates); + unitOfWork.Commit(); - // Assert - Assert.IsNull(repository.Get("test")); + // Assert + Assert.IsNull(repository.Get("test")); + } + + } [Test] @@ -155,66 +216,69 @@ namespace Umbraco.Tests.Persistence.Repositories // Arrange var provider = new PetaPocoUnitOfWorkProvider(); var unitOfWork = provider.GetUnitOfWork(); - var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem); + using (var repository = new TemplateRepository(unitOfWork, NullCacheProvider.Current, _masterPageFileSystem, _viewsFileSystem)) + { + var parent = new Template("test-parent-masterpage.master", "parent", "parent") { Content = @"<%@ Master Language=""C#"" %>" }; - var parent = new Template("test-parent-masterpage.master", "parent", "parent") { Content = @"<%@ Master Language=""C#"" %>" }; + var child1 = new Template("test-child1-masterpage.master", "child1", "child1") { Content = @"<%@ Master Language=""C#"" %>" }; + var toddler1 = new Template("test-toddler1-masterpage.master", "toddler1", "toddler1") { Content = @"<%@ Master Language=""C#"" %>" }; + var toddler2 = new Template("test-toddler2-masterpage.master", "toddler2", "toddler2") { Content = @"<%@ Master Language=""C#"" %>" }; + var baby1 = new Template("test-baby1-masterpage.master", "baby1", "baby1") { Content = @"<%@ Master Language=""C#"" %>" }; - var child1 = new Template("test-child1-masterpage.master", "child1", "child1") { Content = @"<%@ Master Language=""C#"" %>" }; - var toddler1 = new Template("test-toddler1-masterpage.master", "toddler1", "toddler1") { Content = @"<%@ Master Language=""C#"" %>" }; - var toddler2 = new Template("test-toddler2-masterpage.master", "toddler2", "toddler2") { Content = @"<%@ Master Language=""C#"" %>" }; - var baby1 = new Template("test-baby1-masterpage.master", "baby1", "baby1") { Content = @"<%@ Master Language=""C#"" %>" }; - - var child2 = new Template("test-child2-masterpage.master", "child2", "child2") { Content = @"<%@ Master Language=""C#"" %>" }; - var toddler3 = new Template("test-toddler3-masterpage.master", "toddler3", "toddler3") { Content = @"<%@ Master Language=""C#"" %>" }; - var toddler4 = new Template("test-toddler4-masterpage.master", "toddler4", "toddler4") { Content = @"<%@ Master Language=""C#"" %>" }; - var baby2 = new Template("test-baby2-masterpage.master", "baby2", "baby2") { Content = @"<%@ Master Language=""C#"" %>" }; + var child2 = new Template("test-child2-masterpage.master", "child2", "child2") { Content = @"<%@ Master Language=""C#"" %>" }; + var toddler3 = new Template("test-toddler3-masterpage.master", "toddler3", "toddler3") { Content = @"<%@ Master Language=""C#"" %>" }; + var toddler4 = new Template("test-toddler4-masterpage.master", "toddler4", "toddler4") { Content = @"<%@ Master Language=""C#"" %>" }; + var baby2 = new Template("test-baby2-masterpage.master", "baby2", "baby2") { Content = @"<%@ Master Language=""C#"" %>" }; - child1.MasterTemplateAlias = parent.Alias; - child1.MasterTemplateId = new Lazy(() => parent.Id); - child2.MasterTemplateAlias = parent.Alias; - child2.MasterTemplateId = new Lazy(() => parent.Id); + child1.MasterTemplateAlias = parent.Alias; + child1.MasterTemplateId = new Lazy(() => parent.Id); + child2.MasterTemplateAlias = parent.Alias; + child2.MasterTemplateId = new Lazy(() => parent.Id); - toddler1.MasterTemplateAlias = child1.Alias; - toddler1.MasterTemplateId = new Lazy(() => child1.Id); - toddler2.MasterTemplateAlias = child1.Alias; - toddler2.MasterTemplateId = new Lazy(() => child1.Id); + toddler1.MasterTemplateAlias = child1.Alias; + toddler1.MasterTemplateId = new Lazy(() => child1.Id); + toddler2.MasterTemplateAlias = child1.Alias; + toddler2.MasterTemplateId = new Lazy(() => child1.Id); - toddler3.MasterTemplateAlias = child2.Alias; - toddler3.MasterTemplateId = new Lazy(() => child2.Id); - toddler4.MasterTemplateAlias = child2.Alias; - toddler4.MasterTemplateId = new Lazy(() => child2.Id); + toddler3.MasterTemplateAlias = child2.Alias; + toddler3.MasterTemplateId = new Lazy(() => child2.Id); + toddler4.MasterTemplateAlias = child2.Alias; + toddler4.MasterTemplateId = new Lazy(() => child2.Id); - baby1.MasterTemplateAlias = toddler2.Alias; - baby1.MasterTemplateId = new Lazy(() => toddler2.Id); + baby1.MasterTemplateAlias = toddler2.Alias; + baby1.MasterTemplateId = new Lazy(() => toddler2.Id); - baby2.MasterTemplateAlias = toddler4.Alias; - baby2.MasterTemplateId = new Lazy(() => toddler4.Id); + baby2.MasterTemplateAlias = toddler4.Alias; + baby2.MasterTemplateId = new Lazy(() => toddler4.Id); - repository.AddOrUpdate(parent); - repository.AddOrUpdate(child1); - repository.AddOrUpdate(child2); - repository.AddOrUpdate(toddler1); - repository.AddOrUpdate(toddler2); - repository.AddOrUpdate(toddler3); - repository.AddOrUpdate(toddler4); - repository.AddOrUpdate(baby1); - repository.AddOrUpdate(baby2); - unitOfWork.Commit(); + repository.AddOrUpdate(parent); + repository.AddOrUpdate(child1); + repository.AddOrUpdate(child2); + repository.AddOrUpdate(toddler1); + repository.AddOrUpdate(toddler2); + repository.AddOrUpdate(toddler3); + repository.AddOrUpdate(toddler4); + repository.AddOrUpdate(baby1); + repository.AddOrUpdate(baby2); + unitOfWork.Commit(); - // Act - var rootNode = repository.GetTemplateNode("parent"); + // Act + var rootNode = repository.GetTemplateNode("parent"); - // Assert - Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "parent")); - Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "child1")); - Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "child2")); - Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "toddler1")); - Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "toddler2")); - Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "toddler3")); - Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "toddler4")); - Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "baby1")); - Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "baby2")); + // Assert + Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "parent")); + Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "child1")); + Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "child2")); + Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "toddler1")); + Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "toddler2")); + Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "toddler3")); + Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "toddler4")); + Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "baby1")); + Assert.IsNotNull(repository.FindTemplateInTree(rootNode, "baby2")); + } + + } //[Test] From d8edf67b828cfdf1905ec964a5d130b411b8b8ff Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 16 May 2014 12:09:08 +1000 Subject: [PATCH 04/13] Fixes: U4-4842 Unable to edit "name" and "alias" to MediaType property --- src/Umbraco.Core/Models/ContentType.cs | 23 ------------- src/Umbraco.Core/Models/ContentTypeBase.cs | 32 ++++++++++++++++++- src/Umbraco.Core/Models/DeepCloneHelper.cs | 24 +++++++++++++- .../Caching/RuntimeCacheProvider.cs | 8 ++--- src/Umbraco.Tests/Models/ContentTypeTests.cs | 1 + 5 files changed, 59 insertions(+), 29 deletions(-) diff --git a/src/Umbraco.Core/Models/ContentType.cs b/src/Umbraco.Core/Models/ContentType.cs index 1cf7fc9684..ec763d07fa 100644 --- a/src/Umbraco.Core/Models/ContentType.cs +++ b/src/Umbraco.Core/Models/ContentType.cs @@ -133,29 +133,6 @@ namespace Umbraco.Core.Models Key = Guid.NewGuid(); } - /// - /// Method to call when Entity is being updated - /// - /// Modified Date is set and a new Version guid is set - internal override void UpdatingEntity() - { - base.UpdatingEntity(); - } - - public override object DeepClone() - { - var clone = (ContentType)base.DeepClone(); - var propertyGroups = PropertyGroups.Select(x => (PropertyGroup)x.DeepClone()).ToList(); - clone.PropertyGroups = new PropertyGroupCollection(propertyGroups); - //set the property types that are not part of a group - clone.PropertyTypes = PropertyTypeCollection - .Where(x => x.PropertyGroupId == null) - .Select(x => (PropertyType)x.DeepClone()).ToList(); - - clone.ResetDirtyProperties(false); - - return clone; - } /// /// Creates a deep clone of the current entity with its identity/alias and it's property identities reset diff --git a/src/Umbraco.Core/Models/ContentTypeBase.cs b/src/Umbraco.Core/Models/ContentTypeBase.cs index da4cdcfd19..5c09deadb8 100644 --- a/src/Umbraco.Core/Models/ContentTypeBase.cs +++ b/src/Umbraco.Core/Models/ContentTypeBase.cs @@ -351,7 +351,9 @@ namespace Umbraco.Core.Models /// /// List of PropertyGroups available on this ContentType /// - /// A PropertyGroup corresponds to a Tab in the UI + /// + /// A PropertyGroup corresponds to a Tab in the UI + /// [DataMember] public virtual PropertyGroupCollection PropertyGroups { @@ -367,7 +369,13 @@ namespace Umbraco.Core.Models /// List of PropertyTypes available on this ContentType. /// This list aggregates PropertyTypes across the PropertyGroups. /// + /// + /// Marked as DoNotClone because the result of this property is not the natural result of the data, it is + /// a union of data so when auto-cloning if the setter is used it will be setting the unnatural result of the + /// data. We manually clone this instead. + /// [IgnoreDataMember] + [DoNotClone] public virtual IEnumerable PropertyTypes { get @@ -383,6 +391,14 @@ namespace Umbraco.Core.Models } /// + /// Returns the property type collection containing types that are non-groups - used for tests + /// + internal IEnumerable NonGroupedPropertyTypes + { + get { return _propertyTypes; } + } + + /// /// A boolean flag indicating if a property type has been removed from this instance. /// /// @@ -579,5 +595,19 @@ namespace Umbraco.Core.Models propertyType.ResetDirtyProperties(); } } + + public override object DeepClone() + { + var clone = (ContentTypeBase)base.DeepClone(); + + //need to manually wire up the event handlers for the property type collections - we've ensured + // its ignored from the auto-clone process because its return values are unions, not raw and + // we end up with duplicates, see: http://issues.umbraco.org/issue/U4-4842 + + clone._propertyTypes = (PropertyTypeCollection)_propertyTypes.DeepClone(); + clone._propertyTypes.CollectionChanged += clone.PropertyTypesChanged; + + return clone; + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/DeepCloneHelper.cs b/src/Umbraco.Core/Models/DeepCloneHelper.cs index aaee03f963..d8ef10751b 100644 --- a/src/Umbraco.Core/Models/DeepCloneHelper.cs +++ b/src/Umbraco.Core/Models/DeepCloneHelper.cs @@ -2,9 +2,29 @@ using System; using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Reflection; namespace Umbraco.Core.Models { + /// + /// Used to attribute properties that have a setter and are a reference type + /// that should be ignored for cloning when using the DeepCloneHelper + /// + /// + /// + /// This attribute must be used: + /// * when the property is backed by a field but the result of the property is the un-natural data stored in the field + /// + /// This attribute should not be used: + /// * when the property is virtual + /// * when the setter performs additional required logic other than just setting the underlying field + /// + /// + internal class DoNotCloneAttribute : Attribute + { + + } + public static class DeepCloneHelper { /// @@ -25,8 +45,10 @@ namespace Umbraco.Core.Models var refProperties = inputType.GetProperties() .Where(x => + //is not attributed with the ignore clone attribute + x.GetCustomAttribute() == null //reference type but not string - x.PropertyType.IsValueType == false && x.PropertyType != typeof (string) + && x.PropertyType.IsValueType == false && x.PropertyType != typeof (string) //settable && x.CanWrite //non-indexed diff --git a/src/Umbraco.Core/Persistence/Caching/RuntimeCacheProvider.cs b/src/Umbraco.Core/Persistence/Caching/RuntimeCacheProvider.cs index c2ca53a240..acacadb0cc 100644 --- a/src/Umbraco.Core/Persistence/Caching/RuntimeCacheProvider.cs +++ b/src/Umbraco.Core/Persistence/Caching/RuntimeCacheProvider.cs @@ -128,9 +128,9 @@ namespace Umbraco.Core.Persistence.Caching public void Save(Type type, IEntity entity) { //IMPORTANT: we must clone to store, see: http://issues.umbraco.org/issue/U4-4259 - entity = (IEntity)entity.DeepClone(); + var clone = (IEntity)entity.DeepClone(); - var key = GetCompositeId(type, entity.Id); + var key = GetCompositeId(type, clone.Id); _keyTracker.TryAdd(key); @@ -139,11 +139,11 @@ namespace Umbraco.Core.Persistence.Caching if (_memoryCache != null) { - _memoryCache.Set(key, entity, new CacheItemPolicy { SlidingExpiration = TimeSpan.FromMinutes(5) }); + _memoryCache.Set(key, clone, new CacheItemPolicy { SlidingExpiration = TimeSpan.FromMinutes(5) }); } else { - HttpRuntime.Cache.Insert(key, entity, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(5)); + HttpRuntime.Cache.Insert(key, clone, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(5)); } } diff --git a/src/Umbraco.Tests/Models/ContentTypeTests.cs b/src/Umbraco.Tests/Models/ContentTypeTests.cs index dc2de0d6bb..43b90c424e 100644 --- a/src/Umbraco.Tests/Models/ContentTypeTests.cs +++ b/src/Umbraco.Tests/Models/ContentTypeTests.cs @@ -162,6 +162,7 @@ namespace Umbraco.Tests.Models } Assert.AreNotSame(clone.PropertyTypes, contentType.PropertyTypes); Assert.AreEqual(clone.PropertyTypes.Count(), contentType.PropertyTypes.Count()); + Assert.AreEqual(0, ((ContentTypeBase)clone).NonGroupedPropertyTypes.Count()); for (var index = 0; index < contentType.PropertyTypes.Count(); index++) { Assert.AreNotSame(clone.PropertyTypes.ElementAt(index), contentType.PropertyTypes.ElementAt(index)); From 1f88960b3fbc44f55bdfbb1a37258c2a5ab8591a Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 16 May 2014 12:09:47 +1000 Subject: [PATCH 05/13] Fixes: U4-4926 Pre-values need to be cloned in/out of the cache Conflicts: src/Umbraco.Core/Models/PreValue.cs src/Umbraco.Core/Models/PreValueCollection.cs --- src/Umbraco.Core/Models/PreValue.cs | 9 +++- src/Umbraco.Core/Models/PreValueCollection.cs | 18 ++++++- .../DataTypeDefinitionRepository.cs | 4 +- .../Models/PreValueCollectionTests.cs | 51 +++++++++++++++++++ src/Umbraco.Tests/Umbraco.Tests.csproj | 1 + 5 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 src/Umbraco.Tests/Models/PreValueCollectionTests.cs diff --git a/src/Umbraco.Core/Models/PreValue.cs b/src/Umbraco.Core/Models/PreValue.cs index 92cada007a..c33f642744 100644 --- a/src/Umbraco.Core/Models/PreValue.cs +++ b/src/Umbraco.Core/Models/PreValue.cs @@ -3,7 +3,7 @@ /// /// Represents a stored pre-value field value /// - public class PreValue + public class PreValue : IDeepCloneable { public PreValue(int id, string value) { @@ -25,5 +25,12 @@ /// The database id for the pre-value field value /// public int Id { get; private set; } + + public virtual object DeepClone() + { + //Memberwise clone on PreValue will work since it doesn't have any deep elements + var clone = (PreValue)MemberwiseClone(); + return clone; + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/PreValueCollection.cs b/src/Umbraco.Core/Models/PreValueCollection.cs index c6e07d6e34..e91aed8457 100644 --- a/src/Umbraco.Core/Models/PreValueCollection.cs +++ b/src/Umbraco.Core/Models/PreValueCollection.cs @@ -14,7 +14,7 @@ namespace Umbraco.Core.Models /// Most legacy property editors won't support the dictionary format but new property editors should always use the dictionary format. /// In order to get overrideable pre-values working we need a dictionary since we'll have to reference a pre-value by a key. /// - public class PreValueCollection + public class PreValueCollection : IDeepCloneable { private IDictionary _preValuesAsDictionary; private IEnumerable _preValuesAsArray; @@ -82,5 +82,21 @@ namespace Umbraco.Core.Models } return result; } + + public object DeepClone() + { + var clone = (PreValueCollection) MemberwiseClone(); + if (_preValuesAsArray != null) + { + clone._preValuesAsArray = _preValuesAsArray.Select(x => (PreValue)x.DeepClone()).ToArray(); + } + if (_preValuesAsDictionary != null) + { + clone._preValuesAsDictionary = _preValuesAsDictionary.ToDictionary(x => x.Key, x => (PreValue)x.Value.DeepClone()); + } + + + return clone; + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs b/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs index 9484121ad7..0e8ae8c3bc 100644 --- a/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs @@ -295,8 +295,8 @@ AND umbracoNode.id <> @id", var cached = _cacheHelper.RuntimeCache.GetCacheItemsByKeySearch(GetPrefixedCacheKey(dataTypeId)); if (cached != null && cached.Any()) { - //return from the cache - return cached.First(); + //return from the cache, ensure it's a cloned result + return (PreValueCollection)cached.First().DeepClone(); } l.UpgradeToWriteLock(); diff --git a/src/Umbraco.Tests/Models/PreValueCollectionTests.cs b/src/Umbraco.Tests/Models/PreValueCollectionTests.cs new file mode 100644 index 0000000000..49c9ab16bb --- /dev/null +++ b/src/Umbraco.Tests/Models/PreValueCollectionTests.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using Umbraco.Core.Models; + +namespace Umbraco.Tests.Models +{ + [TestFixture] + public class PreValueCollectionTests + { + [Test] + public void Can_Deep_Clone() + { + var d = new PreValueCollection(new Dictionary + { + {"blah1", new PreValue(1, "test1", 1)}, + {"blah2", new PreValue(2, "test1", 3)}, + {"blah3", new PreValue(3, "test1", 2)} + }); + + var a = new PreValueCollection(new[] + { + new PreValue(1, "test1", 1), + new PreValue(2, "test1", 3), + new PreValue(3, "test1", 2) + }); + + var clone1 = (PreValueCollection)d.DeepClone(); + var clone2 = (PreValueCollection)a.DeepClone(); + + Action assert = (orig, clone) => + { + Assert.AreNotSame(orig, clone); + var oDic = orig.FormatAsDictionary(); + var cDic = clone.FormatAsDictionary(); + Assert.AreEqual(oDic.Keys.Count(), cDic.Keys.Count()); + foreach (var k in oDic.Keys) + { + Assert.AreNotSame(oDic[k], cDic[k]); + Assert.AreEqual(oDic[k].Id, cDic[k].Id); + Assert.AreEqual(oDic[k].SortOrder, cDic[k].SortOrder); + Assert.AreEqual(oDic[k].Value, cDic[k].Value); + } + }; + + assert(d, clone1); + assert(a, clone2); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index a40f1a4688..6e56759ca5 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -173,6 +173,7 @@ + From e07f5736839c374e9c1d8a78a71aa2fd522a279c Mon Sep 17 00:00:00 2001 From: Stephan Date: Fri, 16 May 2014 09:57:21 +0200 Subject: [PATCH 06/13] Fix the build --- src/Umbraco.Core/Models/DeepCloneHelper.cs | 2 +- src/Umbraco.Core/Models/PreValue.cs | 12 ++++++++++++ .../Repositories/TemplateRepositoryTest.cs | 3 +-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Core/Models/DeepCloneHelper.cs b/src/Umbraco.Core/Models/DeepCloneHelper.cs index d8ef10751b..ed7a0e802d 100644 --- a/src/Umbraco.Core/Models/DeepCloneHelper.cs +++ b/src/Umbraco.Core/Models/DeepCloneHelper.cs @@ -46,7 +46,7 @@ namespace Umbraco.Core.Models var refProperties = inputType.GetProperties() .Where(x => //is not attributed with the ignore clone attribute - x.GetCustomAttribute() == null + Attribute.GetCustomAttribute(x, typeof(DoNotCloneAttribute)) == null //reference type but not string && x.PropertyType.IsValueType == false && x.PropertyType != typeof (string) //settable diff --git a/src/Umbraco.Core/Models/PreValue.cs b/src/Umbraco.Core/Models/PreValue.cs index c33f642744..e39f5caf1f 100644 --- a/src/Umbraco.Core/Models/PreValue.cs +++ b/src/Umbraco.Core/Models/PreValue.cs @@ -5,6 +5,13 @@ /// public class PreValue : IDeepCloneable { + public PreValue(int id, string value, int sortOrder) + { + Id = id; + Value = value; + SortOrder = sortOrder; + } + public PreValue(int id, string value) { Value = value; @@ -26,6 +33,11 @@ /// public int Id { get; private set; } + /// + /// The sort order stored for the pre-value field value + /// + public int SortOrder { get; private set; } + public virtual object DeepClone() { //Memberwise clone on PreValue will work since it doesn't have any deep elements diff --git a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs index a8c31b60d5..2ccc0410e4 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs @@ -144,9 +144,8 @@ namespace Umbraco.Tests.Persistence.Repositories var unitOfWork = provider.GetUnitOfWork(); var templateRepository = new TemplateRepository(unitOfWork, NullCacheProvider.Current); - var tagRepository = new TagsRepository(unitOfWork, NullCacheProvider.Current); var contentTypeRepository = new ContentTypeRepository(unitOfWork, NullCacheProvider.Current, templateRepository); - var contentRepo = new ContentRepository(unitOfWork, NullCacheProvider.Current, contentTypeRepository, templateRepository, tagRepository, CacheHelper.CreateDisabledCacheHelper()); + var contentRepo = new ContentRepository(unitOfWork, NullCacheProvider.Current, contentTypeRepository, templateRepository, CacheHelper.CreateDisabledCacheHelper()); using (contentRepo) { From ddd0e8abb50ddb4b9fb14ab4590151e8f65b2ec6 Mon Sep 17 00:00:00 2001 From: Stephan Date: Fri, 16 May 2014 10:10:55 +0200 Subject: [PATCH 07/13] Bugfix media cache property alias case sensitivity --- .../PublishedCache/XmlPublishedCache/PublishedMediaCache.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs index 1f23ea88de..06da0c807d 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs @@ -328,7 +328,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache //lets check if the alias does not exist on the document. //NOTE: Examine will not index empty values and we do not output empty XML Elements to the cache - either of these situations // would mean that the property is missing from the collection whether we are getting the value from Examine or from the library media cache. - if (dd.Properties.All(x => x.PropertyTypeAlias != alias)) + if (dd.Properties.All(x => x.PropertyTypeAlias.InvariantEquals(alias) == false)) { return null; } From afa81be102ba9adb2afacc727284a87627af9ccc Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Fri, 16 May 2014 14:23:40 +0200 Subject: [PATCH 08/13] Fixes U4-4650 Pluralization of document type aliases doesn't always work --- src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs index 6a752cdb7a..9ac76ba464 100644 --- a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs +++ b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs @@ -875,7 +875,7 @@ namespace umbraco.MacroEngines //this is from SqlMetal and just makes it a bit of fun to allow pluralisation private static string MakePluralName(string name) { - if ((name.EndsWith("x", StringComparison.OrdinalIgnoreCase) || name.EndsWith("ch", StringComparison.OrdinalIgnoreCase)) || (name.EndsWith("ss", StringComparison.OrdinalIgnoreCase) || name.EndsWith("sh", StringComparison.OrdinalIgnoreCase))) + if ((name.EndsWith("x", StringComparison.OrdinalIgnoreCase) || name.EndsWith("ch", StringComparison.OrdinalIgnoreCase)) || (name.EndsWith("s", StringComparison.OrdinalIgnoreCase) || name.EndsWith("sh", StringComparison.OrdinalIgnoreCase))) { name = name + "es"; return name; From a55cd67fd63d789d197e7fc81b2b3df2e198e745 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Fri, 16 May 2014 14:33:03 +0200 Subject: [PATCH 09/13] U4-4650 Pluralization of document type aliases doesn't always work --- src/Umbraco.Core/StringExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Core/StringExtensions.cs b/src/Umbraco.Core/StringExtensions.cs index 48bc18a398..c714afa061 100644 --- a/src/Umbraco.Core/StringExtensions.cs +++ b/src/Umbraco.Core/StringExtensions.cs @@ -135,7 +135,7 @@ namespace Umbraco.Core //this is from SqlMetal and just makes it a bit of fun to allow pluralisation public static string MakePluralName(this string name) { - if ((name.EndsWith("x", StringComparison.OrdinalIgnoreCase) || name.EndsWith("ch", StringComparison.OrdinalIgnoreCase)) || (name.EndsWith("ss", StringComparison.OrdinalIgnoreCase) || name.EndsWith("sh", StringComparison.OrdinalIgnoreCase))) + if ((name.EndsWith("x", StringComparison.OrdinalIgnoreCase) || name.EndsWith("ch", StringComparison.OrdinalIgnoreCase)) || (name.EndsWith("s", StringComparison.OrdinalIgnoreCase) || name.EndsWith("sh", StringComparison.OrdinalIgnoreCase))) { name = name + "es"; return name; From d697c590e7e763d3e1f74ae1f50d74c3587882dc Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Fri, 16 May 2014 18:54:49 +0200 Subject: [PATCH 10/13] U4-4930 NuGet update fails to copy new Umbraco binaries --- build/NuSpecs/UmbracoCms.Core.nuspec | 1 + build/NuSpecs/tools/install.core.ps1 | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 build/NuSpecs/tools/install.core.ps1 diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index 48c82d445c..83408646a1 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -69,5 +69,6 @@ + \ No newline at end of file diff --git a/build/NuSpecs/tools/install.core.ps1 b/build/NuSpecs/tools/install.core.ps1 new file mode 100644 index 0000000000..c712b363bc --- /dev/null +++ b/build/NuSpecs/tools/install.core.ps1 @@ -0,0 +1,24 @@ +param($rootPath, $toolsPath, $package, $project) + +if ($project) { + $dateTime = Get-Date -Format yyyyMMdd-HHmmss + $backupPath = Join-Path (Split-Path $project.FullName -Parent) "\App_Data\NuGetBackup\$dateTime" + $copyLogsPath = Join-Path $backupPath "CopyLogs" + $projectDestinationPath = Split-Path $project.FullName -Parent + + # Create backup folder and logs folder if it doesn't exist yet + New-Item -ItemType Directory -Force -Path $backupPath + New-Item -ItemType Directory -Force -Path $copyLogsPath + + # After backing up, remove all dlls from bin folder in case dll files are included in the VS project + # See: http://issues.umbraco.org/issue/U4-4930 + $umbracoBinFolder = Join-Path $projectDestinationPath "bin" + if(Test-Path $umbracoBinFolder) { + $umbracoBinBackupPath = Join-Path $backupPath "bin" + + New-Item -ItemType Directory -Force -Path $umbracoBinBackupPath + + robocopy $umbracoBinFolder $umbracoBinBackupPath /e /LOG:$copyLogsPath\UmbracoBinBackup.log + Remove-Item $umbracoBinFolder\*.dll -Force -Confirm:$false + } +} \ No newline at end of file From 3ec6d2b82f4718f1f069191ea07727a174bce3bc Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 19 May 2014 10:08:26 +0200 Subject: [PATCH 11/13] U4-4861 6.2.0 Nuget package copies wrong files --- build/NuSpecs/tools/install.ps1 | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/build/NuSpecs/tools/install.ps1 b/build/NuSpecs/tools/install.ps1 index 94f4feafc1..c602671e18 100644 --- a/build/NuSpecs/tools/install.ps1 +++ b/build/NuSpecs/tools/install.ps1 @@ -3,9 +3,11 @@ param($rootPath, $toolsPath, $package, $project) if ($project) { $dateTime = Get-Date -Format yyyyMMdd-HHmmss $backupPath = Join-Path (Split-Path $project.FullName -Parent) "\App_Data\NuGetBackup\$dateTime" + $copyLogsPath = Join-Path $backupPath "CopyLogs" - # Create backup folder if it doesn't exist yet + # Create backup folder and logs folder if it doesn't exist yet New-Item -ItemType Directory -Force -Path $backupPath + New-Item -ItemType Directory -Force -Path $copyLogsPath # Create a backup of original web.config $projectDestinationPath = Split-Path $project.FullName -Parent @@ -19,18 +21,26 @@ if ($project) { # Copy umbraco and umbraco_files from package to project folder # This is only done when these folders already exist because we # only want to do this for upgrades - $umbracoFolder = Join-Path $projectDestinationPath "Umbraco\" + $umbracoFolder = Join-Path $projectDestinationPath "Umbraco" if(Test-Path $umbracoFolder) { $umbracoFolderSource = Join-Path $rootPath "UmbracoFiles\Umbraco" - Copy-Item $umbracoFolder $backupPath -Force - robocopy $umbracoFolderSource $umbracoFolder /e /xf UI.xml + + $umbracoBackupPath = Join-Path $backupPath "Umbraco" + New-Item -ItemType Directory -Force -Path $umbracoBackupPath + + robocopy $umbracoFolder $umbracoBackupPath /e /LOG:$copyLogsPath\UmbracoBackup.log + robocopy $umbracoFolderSource $umbracoFolder /is /it /e /xf UI.xml /LOG:$copyLogsPath\UmbracoCopy.log } $umbracoClientFolder = Join-Path $projectDestinationPath "Umbraco_Client" if(Test-Path $umbracoClientFolder) { $umbracoClientFolderSource = Join-Path $rootPath "UmbracoFiles\Umbraco_Client" - Copy-Item $umbracoClientFolder $backupPath -Force - robocopy $umbracoFolderSource $umbracoClientFolder /e + + $umbracoClientBackupPath = Join-Path $backupPath "Umbraco_Client" + New-Item -ItemType Directory -Force -Path $umbracoClientBackupPath + + robocopy $umbracoClientFolder $umbracoClientBackupPath /e /LOG:$copyLogsPath\UmbracoClientBackup.log + robocopy $umbracoClientFolderSource $umbracoClientFolder /is /it /e /LOG:$copyLogsPath\UmbracoClientCopy.log } # Open readme.txt file $DTE.ItemOperations.OpenFile($toolsPath + '\Readme.txt') From f325794523d03200e2a4d378327710546318795d Mon Sep 17 00:00:00 2001 From: Stephan Date: Tue, 20 May 2014 09:32:26 +0200 Subject: [PATCH 12/13] U4-4949 - fix issue with domains --- src/Umbraco.Web/Routing/DomainHelper.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Umbraco.Web/Routing/DomainHelper.cs b/src/Umbraco.Web/Routing/DomainHelper.cs index 9f64b51e04..1efe0eed0d 100644 --- a/src/Umbraco.Web/Routing/DomainHelper.cs +++ b/src/Umbraco.Web/Routing/DomainHelper.cs @@ -159,12 +159,6 @@ namespace Umbraco.Web.Routing .FirstOrDefault(d => d.Uri.EndPathWithSlash().IsBaseOf(currentWithSlash)); if (domainAndUri != null) return domainAndUri; - // look for the first domain that the current url would be the base of - // ie current is www.example.com, look for domain www.example.com/foo/bar - domainAndUri = domainsAndUris - .FirstOrDefault(d => currentWithSlash.IsBaseOf(d.Uri.EndPathWithSlash())); - if (domainAndUri != null) return domainAndUri; - // if none matches, then try to run the filter to pick a domain if (filter != null) { From 62887607ffbe150cf1e35816dd9084c21c517e8a Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 22 May 2014 12:44:04 +1000 Subject: [PATCH 13/13] fixes csrf with mediauploader.ashx --- .../FolderBrowser/Js/folderbrowser.js | 1 + src/Umbraco.Web/UI/Controls/FolderBrowser.cs | 6 +++-- .../umbraco/webservices/MediaUploader.ashx.cs | 26 +++++++++++++++++-- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI/umbraco_client/FolderBrowser/Js/folderbrowser.js b/src/Umbraco.Web.UI/umbraco_client/FolderBrowser/Js/folderbrowser.js index 497c1843b0..253c2e0edf 100644 --- a/src/Umbraco.Web.UI/umbraco_client/FolderBrowser/Js/folderbrowser.js +++ b/src/Umbraco.Web.UI/umbraco_client/FolderBrowser/Js/folderbrowser.js @@ -180,6 +180,7 @@ Umbraco.Sys.registerNamespace("Umbraco.Controls"); instructions + "
" + "" + + "" + "" + "" + "
" + diff --git a/src/Umbraco.Web/UI/Controls/FolderBrowser.cs b/src/Umbraco.Web/UI/Controls/FolderBrowser.cs index f662bd507e..b56033fb80 100644 --- a/src/Umbraco.Web/UI/Controls/FolderBrowser.cs +++ b/src/Umbraco.Web/UI/Controls/FolderBrowser.cs @@ -4,6 +4,7 @@ using System.Text; using System.Web.UI; using System.Web.UI.WebControls; using ClientDependency.Core; +using Umbraco.Core; using Umbraco.Web.UI.Bundles; using umbraco.BasePages; using Umbraco.Core.IO; @@ -138,10 +139,11 @@ namespace Umbraco.Web.UI.Controls Page.ClientScript.RegisterStartupScript(typeof(FolderBrowser), "RegisterFolderBrowsers", - string.Format("$(function () {{ $(\".umbFolderBrowser\").folderBrowser({{ umbracoPath : '{0}', basePath : '{1}' }}); " + + string.Format("$(function () {{ $(\".umbFolderBrowser\").folderBrowser({{ umbracoPath : '{0}', basePath : '{1}', reqver : '{2}' }}); " + "$(\".umbFolderBrowser #filterTerm\").keypress(function(event) {{ return event.keyCode != 13; }});}});", IOHelper.ResolveUrl(SystemDirectories.Umbraco), - IOHelper.ResolveUrl(SystemDirectories.Base)), + IOHelper.ResolveUrl(SystemDirectories.Base), + UmbracoEnsuredPage.umbracoUserContextID.EncryptWithMachineKey() ), true); } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/MediaUploader.ashx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/MediaUploader.ashx.cs index f6212fac9c..cf9a575954 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/MediaUploader.ashx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/MediaUploader.ashx.cs @@ -256,10 +256,32 @@ namespace umbraco.presentation.umbraco.webservices else { var usr = User.GetCurrent(); + if (BasePage.ValidateUserContextID(BasePage.umbracoUserContextID) && usr != null) { - isValid = true; - AuthenticatedUser = usr; + //The user is valid based on their cookies, but is the request valid? We need to validate + // against CSRF here. We'll do this by ensuring that the request contains a token which will + // be equal to the decrypted version of the current user's user context id. + var token = context.Request["__reqver"]; + if (token.IsNullOrWhiteSpace() == false) + { + //try decrypting it + try + { + var decrypted = token.DecryptWithMachineKey(); + //now check if it matches + if (decrypted == BasePage.umbracoUserContextID) + { + isValid = true; + AuthenticatedUser = usr; + } + } + catch + { + //couldn't decrypt, so it's invalid + } + + } } }