From caa3a3319fe8a608855714fe9d69215a462bd0ca Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 13 Feb 2018 18:54:13 +1100 Subject: [PATCH] Fixes issue with user groups being dirty and resetting dirty events --- src/Umbraco.Core/Auditing/AuditEventHandler.cs | 14 +++++++++++++- src/Umbraco.Core/Models/Membership/IUserGroup.cs | 4 ++-- .../Persistence/Repositories/RepositoryBase.cs | 7 ++++++- .../Repositories/UserGroupRepository.cs | 8 ++++++-- src/Umbraco.Web/Models/Mapping/UserModelMapper.cs | 2 ++ 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Core/Auditing/AuditEventHandler.cs b/src/Umbraco.Core/Auditing/AuditEventHandler.cs index 0d69888f8e..cc63f68f9d 100644 --- a/src/Umbraco.Core/Auditing/AuditEventHandler.cs +++ b/src/Umbraco.Core/Auditing/AuditEventHandler.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Text; using System.Threading; using System.Web; using Umbraco.Core.Events; @@ -128,10 +129,21 @@ namespace Umbraco.Core.Auditing ? string.Join(", ", group.Permissions) : null; + var sb = new StringBuilder(); + sb.Append($"updating {(string.IsNullOrWhiteSpace(dp) ? "(nothing)" : dp)};"); + if (sections != null) + sb.Append($", assigned sections: {sections}"); + if (perms != null) + { + if (sections != null) + sb.Append(", "); + sb.Append($"default perms: {perms}"); + } + _auditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp, DateTime.Now, -1, $"User Group {group.Id} \"{group.Name}\" ({group.Alias})", - "umbraco/user-group/save", $"updating {(string.IsNullOrWhiteSpace(dp) ? "(nothing)" : dp)};{(sections == null ? "" : $", assigned sections: {sections}")}{(perms == null ? "" : $", assigned perms: {perms}")}"); + "umbraco/user-group/save", $"{sb}"); } } diff --git a/src/Umbraco.Core/Models/Membership/IUserGroup.cs b/src/Umbraco.Core/Models/Membership/IUserGroup.cs index 0282073a2e..2c11119d76 100644 --- a/src/Umbraco.Core/Models/Membership/IUserGroup.cs +++ b/src/Umbraco.Core/Models/Membership/IUserGroup.cs @@ -3,7 +3,7 @@ using Umbraco.Core.Models.EntityBase; namespace Umbraco.Core.Models.Membership { - public interface IUserGroup : IAggregateRoot + public interface IUserGroup : IAggregateRoot, IRememberBeingDirty, ICanBeDirty { string Alias { get; set; } @@ -41,4 +41,4 @@ namespace Umbraco.Core.Models.Membership /// int UserCount { get; } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs index 7a9f854679..5b1737564a 100644 --- a/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs +++ b/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs @@ -308,6 +308,9 @@ namespace Umbraco.Core.Persistence.Repositories public virtual void PersistNewItem(IEntity entity) { CachePolicy.Create((TEntity) entity, PersistNewItem); + + //TODO: In v8 we should automatically reset dirty properties so they don't have to be manually reset in all of the implemented repositories + //if (entity is ICanBeDirty dirty) dirty.ResetDirtyProperties(); } /// @@ -317,6 +320,8 @@ namespace Umbraco.Core.Persistence.Repositories public virtual void PersistUpdatedItem(IEntity entity) { CachePolicy.Update((TEntity) entity, PersistUpdatedItem); + //TODO: In v8 we should automatically reset dirty properties so they don't have to be manually reset in all of the implemented repositories + //if (entity is ICanBeDirty dirty) dirty.ResetDirtyProperties(); } /// @@ -343,4 +348,4 @@ namespace Umbraco.Core.Persistence.Repositories UnitOfWork.DisposeIfDisposable(); } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/Persistence/Repositories/UserGroupRepository.cs b/src/Umbraco.Core/Persistence/Repositories/UserGroupRepository.cs index be7a31e298..b6e9e38741 100644 --- a/src/Umbraco.Core/Persistence/Repositories/UserGroupRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/UserGroupRepository.cs @@ -285,7 +285,7 @@ umbracoUserGroup.userGroupName, umbracoUserGroup2App.app, umbracoUserGroup2App.u protected override void PersistNewItem(IUserGroup entity) { - ((UserGroup)entity).AddingEntity(); + ((UserGroup)entity).AddingEntity(); var userGroupDto = UserGroupFactory.BuildDto(entity); @@ -293,6 +293,8 @@ umbracoUserGroup.userGroupName, umbracoUserGroup2App.app, umbracoUserGroup2App.u entity.Id = id; PersistAllowedSections(entity); + + entity.ResetDirtyProperties(); } protected override void PersistUpdatedItem(IUserGroup entity) @@ -304,6 +306,8 @@ umbracoUserGroup.userGroupName, umbracoUserGroup2App.app, umbracoUserGroup2App.u Database.Update(userGroupDto); PersistAllowedSections(entity); + + entity.ResetDirtyProperties(); } private void PersistAllowedSections(IUserGroup entity) @@ -456,4 +460,4 @@ umbracoUserGroup.userGroupName, umbracoUserGroup2App.app, umbracoUserGroup2App.u } } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs b/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs index 737a66b7ce..9a14f9a487 100644 --- a/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs @@ -29,10 +29,12 @@ namespace Umbraco.Web.Models.Mapping .IgnoreDeletableEntityCommonProperties() .ForMember(dest => dest.Id, map => map.Condition(source => GetIntId(source.Id) > 0)) .ForMember(dest => dest.Id, map => map.MapFrom(source => GetIntId(source.Id))) + //TODO: This is insane - but with our current version of AutoMapper when mapping from an existing object to another existing object, it will map the private fields which means the public setter is not used! wtf. So zpqrtbnk will laugh and say how crappy AutoMapper is... well he'll win this battle this time, so we need to do this in AfterMap to make sure the public setter is used so the property is dirty //.ForMember(dest => dest.Permissions, map => map.MapFrom(source => source.DefaultPermissions)) .ForMember(dest => dest.Permissions, map => map.Ignore()) .AfterMap((save, userGroup) => { + //TODO: See above comment userGroup.Permissions = save.DefaultPermissions; userGroup.ClearAllowedSections();