From eb74f74c91ba147dfa1decce0501be6c53a99e9b Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Tue, 9 Mar 2021 07:52:32 +0100 Subject: [PATCH 1/7] Replace static events with notifications in MemberService, PublicAccessService and UserService, and clean up unused components etc. --- .../Cache/DistributedCacheBinder_Handlers.cs | 90 ------ .../Cache/DistributedCacheHandler.cs | 64 +++++ .../Compose/AuditEventsComposer.cs | 7 - ...ponent.cs => AuditNotificationsHandler.cs} | 258 +++++++----------- .../Compose/NotificationsComponent.cs | 181 ------------ .../Compose/NotificationsComposer.cs | 41 ++- .../Events/UserNotificationsHandler.cs | 25 +- .../FileUploadPropertyEditor.cs | 10 +- .../ImageCropperPropertyEditor.cs | 10 +- .../PropertyEditorsComponent.cs | 56 ---- .../PropertyEditorsComposer.cs | 10 - .../Services/Implement/MemberService.cs | 89 ++---- .../Services/Implement/PublicAccessService.cs | 53 +--- .../Services/Implement/UserService.cs | 124 ++++----- .../AssignedMemberRolesNotification.cs | 10 + ...ssignedUserGroupPermissionsNotification.cs | 15 + .../ExportedMemberNotification.cs | 19 ++ .../Notifications/MemberRolesNotification.cs | 17 ++ .../RemovedMemberRolesNotification.cs | 10 + 19 files changed, 390 insertions(+), 699 deletions(-) create mode 100644 src/Umbraco.Infrastructure/Cache/DistributedCacheHandler.cs delete mode 100644 src/Umbraco.Infrastructure/Compose/AuditEventsComposer.cs rename src/Umbraco.Infrastructure/Compose/{AuditEventsComponent.cs => AuditNotificationsHandler.cs} (61%) delete mode 100644 src/Umbraco.Infrastructure/Compose/NotificationsComponent.cs delete mode 100644 src/Umbraco.Infrastructure/PropertyEditors/PropertyEditorsComponent.cs delete mode 100644 src/Umbraco.Infrastructure/PropertyEditors/PropertyEditorsComposer.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/AssignedMemberRolesNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/AssignedUserGroupPermissionsNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/ExportedMemberNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/MemberRolesNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/RemovedMemberRolesNotification.cs diff --git a/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs b/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs index 1aa4906029..ae6b6f135b 100644 --- a/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs +++ b/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs @@ -49,18 +49,6 @@ namespace Umbraco.Cms.Core.Cache _logger.LogInformation("Initializing Umbraco internal event handlers for cache refreshing."); - // bind to user and user group events - Bind(() => UserService.SavedUserGroup += UserService_SavedUserGroup, - () => UserService.SavedUserGroup -= UserService_SavedUserGroup); - Bind(() => UserService.DeletedUserGroup += UserService_DeletedUserGroup, - () => UserService.DeletedUserGroup -= UserService_DeletedUserGroup); - Bind(() => UserService.SavedUser += UserService_SavedUser, - () => UserService.SavedUser -= UserService_SavedUser); - Bind(() => UserService.DeletedUser += UserService_DeletedUser, - () => UserService.DeletedUser -= UserService_DeletedUser); - Bind(() => UserService.UserGroupPermissionsAssigned += UserService_UserGroupPermissionsAssigned, - () => UserService.UserGroupPermissionsAssigned -= UserService_UserGroupPermissionsAssigned); - // bind to dictionary events Bind(() => LocalizationService.DeletedDictionaryItem += LocalizationService_DeletedDictionaryItem, () => LocalizationService.DeletedDictionaryItem -= LocalizationService_DeletedDictionaryItem); @@ -112,10 +100,6 @@ namespace Umbraco.Cms.Core.Cache () => MacroService.Deleted -= MacroService_Deleted); // bind to member events - Bind(() => MemberService.Saved += MemberService_Saved, - () => MemberService.Saved -= MemberService_Saved); - Bind(() => MemberService.Deleted += MemberService_Deleted, - () => MemberService.Deleted -= MemberService_Deleted); Bind(() => MemberGroupService.Saved += MemberGroupService_Saved, () => MemberGroupService.Saved -= MemberGroupService_Saved); Bind(() => MemberGroupService.Deleted += MemberGroupService_Deleted, @@ -135,12 +119,6 @@ namespace Umbraco.Cms.Core.Cache //Bind(() => ContentService.DeletedBlueprint += ContentService_DeletedBlueprint, // () => ContentService.DeletedBlueprint -= ContentService_DeletedBlueprint); - // bind to public access events - Bind(() => PublicAccessService.Saved += PublicAccessService_Saved, - () => PublicAccessService.Saved -= PublicAccessService_Saved); - Bind(() => PublicAccessService.Deleted += PublicAccessService_Deleted, - () => PublicAccessService.Deleted -= PublicAccessService_Deleted); - // bind to relation type events Bind(() => RelationService.SavedRelationType += RelationService_SavedRelationType, () => RelationService.SavedRelationType -= RelationService_SavedRelationType); @@ -148,21 +126,6 @@ namespace Umbraco.Cms.Core.Cache () => RelationService.DeletedRelationType -= RelationService_DeletedRelationType); } - #region PublicAccessService - - private void PublicAccessService_Saved(IPublicAccessService sender, SaveEventArgs e) - { - - _distributedCache.RefreshPublicAccess(); - } - - private void PublicAccessService_Deleted(IPublicAccessService sender, DeleteEventArgs e) - { - _distributedCache.RefreshPublicAccess(); - } - - #endregion - #region ContentService /// @@ -296,45 +259,6 @@ namespace Umbraco.Cms.Core.Cache #endregion - #region UserService - - private void UserService_UserGroupPermissionsAssigned(IUserService sender, SaveEventArgs e) - { - // TODO: Not sure if we need this yet depends if we start caching permissions - //var groupIds = e.SavedEntities.Select(x => x.UserGroupId).Distinct(); - //foreach (var groupId in groupIds) - //{ - // DistributedCache.Instance.RefreshUserGroupPermissionsCache(groupId); - //} - } - - private void UserService_SavedUser(IUserService sender, SaveEventArgs e) - { - foreach (var entity in e.SavedEntities) - _distributedCache.RefreshUserCache(entity.Id); - } - - private void UserService_DeletedUser(IUserService sender, DeleteEventArgs e) - { - foreach (var entity in e.DeletedEntities) - _distributedCache.RemoveUserCache(entity.Id); - } - - private void UserService_SavedUserGroup(IUserService sender, SaveEventArgs e) - { - foreach (var entity in e.SavedEntities) - _distributedCache.RefreshUserGroupCache(entity.UserGroup.Id); - } - - private void UserService_DeletedUserGroup(IUserService sender, DeleteEventArgs e) - { - - foreach (var entity in e.DeletedEntities) - _distributedCache.RemoveUserGroupCache(entity.Id); - } - - #endregion - #region FileService /// @@ -390,20 +314,6 @@ namespace Umbraco.Cms.Core.Cache #endregion - #region MemberService - - private void MemberService_Deleted(IMemberService sender, DeleteEventArgs e) - { - _distributedCache.RemoveMemberCache(e.DeletedEntities.ToArray()); - } - - private void MemberService_Saved(IMemberService sender, SaveEventArgs e) - { - _distributedCache.RefreshMemberCache(e.SavedEntities.ToArray()); - } - - #endregion - #region MemberGroupService private void MemberGroupService_Deleted(IMemberGroupService sender, DeleteEventArgs e) diff --git a/src/Umbraco.Infrastructure/Cache/DistributedCacheHandler.cs b/src/Umbraco.Infrastructure/Cache/DistributedCacheHandler.cs new file mode 100644 index 0000000000..648edaca68 --- /dev/null +++ b/src/Umbraco.Infrastructure/Cache/DistributedCacheHandler.cs @@ -0,0 +1,64 @@ +using System.Linq; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.Membership; +using Umbraco.Cms.Infrastructure.Services.Notifications; +using Umbraco.Extensions; + +namespace Umbraco.Cms.Core.Cache +{ + internal class DistributedCacheHandler : + INotificationHandler>, + INotificationHandler>, + INotificationHandler>, + INotificationHandler>, + INotificationHandler>, + INotificationHandler>, + INotificationHandler>, + INotificationHandler> + { + private readonly DistributedCache _distributedCache; + + public DistributedCacheHandler(DistributedCache distributedCache) => _distributedCache = distributedCache; + + public void Handle(SavedNotification notification) => _distributedCache.RefreshMemberCache(notification.SavedEntities.ToArray()); + + public void Handle(DeletedNotification notification) => _distributedCache.RemoveMemberCache(notification.DeletedEntities.ToArray()); + + public void Handle(SavedNotification notification) + { + foreach (var entity in notification.SavedEntities) + { + _distributedCache.RefreshUserCache(entity.Id); + } + } + + public void Handle(DeletedNotification notification) + { + foreach (var entity in notification.DeletedEntities) + { + _distributedCache.RemoveUserCache(entity.Id); + } + } + + public void Handle(SavedNotification notification) + { + foreach (var entity in notification.SavedEntities) + { + _distributedCache.RefreshUserGroupCache(entity.Id); + } + } + + public void Handle(DeletedNotification notification) + { + foreach (var entity in notification.DeletedEntities) + { + _distributedCache.RemoveUserGroupCache(entity.Id); + } + } + + public void Handle(SavedNotification notification) => _distributedCache.RefreshPublicAccess(); + + public void Handle(DeletedNotification notification) => _distributedCache.RefreshPublicAccess(); + } +} diff --git a/src/Umbraco.Infrastructure/Compose/AuditEventsComposer.cs b/src/Umbraco.Infrastructure/Compose/AuditEventsComposer.cs deleted file mode 100644 index b6d5f60765..0000000000 --- a/src/Umbraco.Infrastructure/Compose/AuditEventsComposer.cs +++ /dev/null @@ -1,7 +0,0 @@ -using Umbraco.Cms.Core.Composing; - -namespace Umbraco.Cms.Core.Compose -{ - public sealed class AuditEventsComposer : ComponentComposer, ICoreComposer - { } -} diff --git a/src/Umbraco.Infrastructure/Compose/AuditEventsComponent.cs b/src/Umbraco.Infrastructure/Compose/AuditNotificationsHandler.cs similarity index 61% rename from src/Umbraco.Infrastructure/Compose/AuditEventsComponent.cs rename to src/Umbraco.Infrastructure/Compose/AuditNotificationsHandler.cs index 7c526d330c..f152dd16cf 100644 --- a/src/Umbraco.Infrastructure/Compose/AuditEventsComponent.cs +++ b/src/Umbraco.Infrastructure/Compose/AuditNotificationsHandler.cs @@ -2,7 +2,6 @@ using System; using System.Linq; using System.Text; using Microsoft.Extensions.Options; -using Umbraco.Cms.Core.Composing; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; @@ -10,12 +9,21 @@ using Umbraco.Cms.Core.Models.Membership; using Umbraco.Cms.Core.Net; using Umbraco.Cms.Core.Security; using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Core.Services.Implement; +using Umbraco.Cms.Infrastructure.Services.Notifications; using Umbraco.Extensions; namespace Umbraco.Cms.Core.Compose { - public sealed class AuditEventsComponent : IComponent + public sealed class AuditNotificationsHandler : + INotificationHandler>, + INotificationHandler>, + INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler>, + INotificationHandler>, + INotificationHandler>, + INotificationHandler { private readonly IAuditService _auditService; private readonly IUserService _userService; @@ -23,55 +31,26 @@ namespace Umbraco.Cms.Core.Compose private readonly IIpResolver _ipResolver; private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor; private readonly GlobalSettings _globalSettings; + private readonly IMemberService _memberService; - public AuditEventsComponent( + public AuditNotificationsHandler( IAuditService auditService, IUserService userService, IEntityService entityService, IIpResolver ipResolver, IOptions globalSettings, - IBackOfficeSecurityAccessor backOfficeSecurityAccessor) + IBackOfficeSecurityAccessor backOfficeSecurityAccessor, + IMemberService memberService) { _auditService = auditService; _userService = userService; _entityService = entityService; _ipResolver = ipResolver; _backOfficeSecurityAccessor = backOfficeSecurityAccessor; + _memberService = memberService; _globalSettings = globalSettings.Value; } - public void Initialize() - { - UserService.SavedUserGroup += OnSavedUserGroupWithUsers; - - UserService.SavedUser += OnSavedUser; - UserService.DeletedUser += OnDeletedUser; - UserService.UserGroupPermissionsAssigned += UserGroupPermissionAssigned; - - MemberService.Saved += OnSavedMember; - MemberService.Deleted += OnDeletedMember; - MemberService.AssignedRoles += OnAssignedRoles; - MemberService.RemovedRoles += OnRemovedRoles; - MemberService.Exported += OnMemberExported; - } - - public void Terminate() - { - UserService.SavedUserGroup -= OnSavedUserGroupWithUsers; - - UserService.SavedUser -= OnSavedUser; - UserService.DeletedUser -= OnDeletedUser; - UserService.UserGroupPermissionsAssigned -= UserGroupPermissionAssigned; - - MemberService.Saved -= OnSavedMember; - MemberService.Deleted -= OnDeletedMember; - MemberService.AssignedRoles -= OnAssignedRoles; - MemberService.RemovedRoles -= OnRemovedRoles; - MemberService.Exported -= OnMemberExported; - } - - public static IUser UnknownUser(GlobalSettings globalSettings) => new User(globalSettings) { Id = Cms.Core.Constants.Security.UnknownUserId, Name = Cms.Core.Constants.Security.UnknownUserName, Email = "" }; - private IUser CurrentPerformingUser { get @@ -82,45 +61,48 @@ namespace Umbraco.Cms.Core.Compose } } - private IUser GetPerformingUser(int userId) - { - var found = userId >= 0 ? _userService.GetUserById(userId) : null; - return found ?? UnknownUser(_globalSettings); - } + public static IUser UnknownUser(GlobalSettings globalSettings) => new User(globalSettings) { Id = Cms.Core.Constants.Security.UnknownUserId, Name = Cms.Core.Constants.Security.UnknownUserName, Email = "" }; private string PerformingIp => _ipResolver.GetCurrentRequestIpAddress(); - private string FormatEmail(IMember member) - { - return member == null ? string.Empty : member.Email.IsNullOrWhiteSpace() ? "" : $"<{member.Email}>"; - } + private string FormatEmail(IMember member) => member == null ? string.Empty : member.Email.IsNullOrWhiteSpace() ? "" : $"<{member.Email}>"; - private string FormatEmail(IUser user) - { - return user == null ? string.Empty : user.Email.IsNullOrWhiteSpace() ? "" : $"<{user.Email}>"; - } + private string FormatEmail(IUser user) => user == null ? string.Empty : user.Email.IsNullOrWhiteSpace() ? "" : $"<{user.Email}>"; - private void OnRemovedRoles(IMemberService sender, RolesEventArgs args) + public void Handle(SavedNotification notification) { var performingUser = CurrentPerformingUser; - var roles = string.Join(", ", args.Roles); - var members = sender.GetAllMembers(args.MemberIds).ToDictionary(x => x.Id, x => x); - foreach (var id in args.MemberIds) + var members = notification.SavedEntities; + foreach (var member in members) { - members.TryGetValue(id, out var member); + var dp = string.Join(", ", ((Member)member).GetWereDirtyProperties()); + _auditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp, DateTime.UtcNow, - -1, $"Member {id} \"{member?.Name ?? "(unknown)"}\" {FormatEmail(member)}", - "umbraco/member/roles/removed", $"roles modified, removed {roles}"); + -1, $"Member {member.Id} \"{member.Name}\" {FormatEmail(member)}", + "umbraco/member/save", $"updating {(string.IsNullOrWhiteSpace(dp) ? "(nothing)" : dp)}"); } } - private void OnAssignedRoles(IMemberService sender, RolesEventArgs args) + public void Handle(DeletedNotification notification) { var performingUser = CurrentPerformingUser; - var roles = string.Join(", ", args.Roles); - var members = sender.GetAllMembers(args.MemberIds).ToDictionary(x => x.Id, x => x); - foreach (var id in args.MemberIds) + var members = notification.DeletedEntities; + foreach (var member in members) + { + _auditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp, + DateTime.UtcNow, + -1, $"Member {member.Id} \"{member.Name}\" {FormatEmail(member)}", + "umbraco/member/delete", $"delete member id:{member.Id} \"{member.Name}\" {FormatEmail(member)}"); + } + } + + public void Handle(AssignedMemberRolesNotification notification) + { + var performingUser = CurrentPerformingUser; + var roles = string.Join(", ", notification.Roles); + var members = _memberService.GetAllMembers(notification.MemberIds).ToDictionary(x => x.Id, x => x); + foreach (var id in notification.MemberIds) { members.TryGetValue(id, out var member); _auditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp, @@ -130,10 +112,25 @@ namespace Umbraco.Cms.Core.Compose } } - private void OnMemberExported(IMemberService sender, ExportedMemberEventArgs exportedMemberEventArgs) + public void Handle(RemovedMemberRolesNotification notification) { var performingUser = CurrentPerformingUser; - var member = exportedMemberEventArgs.Member; + var roles = string.Join(", ", notification.Roles); + var members = _memberService.GetAllMembers(notification.MemberIds).ToDictionary(x => x.Id, x => x); + foreach (var id in notification.MemberIds) + { + members.TryGetValue(id, out var member); + _auditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp, + DateTime.UtcNow, + -1, $"Member {id} \"{member?.Name ?? "(unknown)"}\" {FormatEmail(member)}", + "umbraco/member/roles/removed", $"roles modified, removed {roles}"); + } + } + + public void Handle(ExportedMemberNotification notification) + { + var performingUser = CurrentPerformingUser; + var member = notification.Member; _auditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp, DateTime.UtcNow, @@ -141,10 +138,40 @@ namespace Umbraco.Cms.Core.Compose "umbraco/member/exported", "exported member data"); } - private void OnSavedUserGroupWithUsers(IUserService sender, SaveEventArgs saveEventArgs) + public void Handle(SavedNotification notification) { var performingUser = CurrentPerformingUser; - foreach (var groupWithUser in saveEventArgs.SavedEntities) + var affectedUsers = notification.SavedEntities; + foreach (var affectedUser in affectedUsers) + { + var groups = affectedUser.WasPropertyDirty("Groups") + ? string.Join(", ", affectedUser.Groups.Select(x => x.Alias)) + : null; + + var dp = string.Join(", ", ((User)affectedUser).GetWereDirtyProperties()); + + _auditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp, + DateTime.UtcNow, + affectedUser.Id, $"User \"{affectedUser.Name}\" {FormatEmail(affectedUser)}", + "umbraco/user/save", $"updating {(string.IsNullOrWhiteSpace(dp) ? "(nothing)" : dp)}{(groups == null ? "" : "; groups assigned: " + groups)}"); + } + } + + public void Handle(DeletedNotification notification) + { + var performingUser = CurrentPerformingUser; + var affectedUsers = notification.DeletedEntities; + foreach (var affectedUser in affectedUsers) + _auditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp, + DateTime.UtcNow, + affectedUser.Id, $"User \"{affectedUser.Name}\" {FormatEmail(affectedUser)}", + "umbraco/user/delete", "delete user"); + } + + public void Handle(SavedNotification notification) + { + var performingUser = CurrentPerformingUser; + foreach (var groupWithUser in notification.SavedEntities) { var group = groupWithUser.UserGroup; @@ -192,13 +219,13 @@ namespace Umbraco.Cms.Core.Compose } } - private void UserGroupPermissionAssigned(IUserService sender, SaveEventArgs saveEventArgs) + public void Handle(AssignedUserGroupPermissionsNotification notification) { var performingUser = CurrentPerformingUser; - var perms = saveEventArgs.SavedEntities; + var perms = notification.EntityPermissions; foreach (var perm in perms) { - var group = sender.GetUserGroupById(perm.UserGroupId); + var group = _userService.GetUserGroupById(perm.UserGroupId); var assigned = string.Join(", ", perm.AssignedPermissions); var entity = _entityService.Get(perm.EntityId); @@ -208,100 +235,5 @@ namespace Umbraco.Cms.Core.Compose "umbraco/user-group/permissions-change", $"assigning {(string.IsNullOrWhiteSpace(assigned) ? "(nothing)" : assigned)} on id:{perm.EntityId} \"{entity.Name}\""); } } - - private void OnSavedMember(IMemberService sender, SaveEventArgs saveEventArgs) - { - var performingUser = CurrentPerformingUser; - var members = saveEventArgs.SavedEntities; - foreach (var member in members) - { - var dp = string.Join(", ", ((Member) member).GetWereDirtyProperties()); - - _auditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp, - DateTime.UtcNow, - -1, $"Member {member.Id} \"{member.Name}\" {FormatEmail(member)}", - "umbraco/member/save", $"updating {(string.IsNullOrWhiteSpace(dp) ? "(nothing)" : dp)}"); - } - } - - private void OnDeletedMember(IMemberService sender, DeleteEventArgs deleteEventArgs) - { - var performingUser = CurrentPerformingUser; - var members = deleteEventArgs.DeletedEntities; - foreach (var member in members) - { - _auditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp, - DateTime.UtcNow, - -1, $"Member {member.Id} \"{member.Name}\" {FormatEmail(member)}", - "umbraco/member/delete", $"delete member id:{member.Id} \"{member.Name}\" {FormatEmail(member)}"); - } - } - - private void OnSavedUser(IUserService sender, SaveEventArgs saveEventArgs) - { - var performingUser = CurrentPerformingUser; - var affectedUsers = saveEventArgs.SavedEntities; - foreach (var affectedUser in affectedUsers) - { - var groups = affectedUser.WasPropertyDirty("Groups") - ? string.Join(", ", affectedUser.Groups.Select(x => x.Alias)) - : null; - - var dp = string.Join(", ", ((User)affectedUser).GetWereDirtyProperties()); - - _auditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp, - DateTime.UtcNow, - affectedUser.Id, $"User \"{affectedUser.Name}\" {FormatEmail(affectedUser)}", - "umbraco/user/save", $"updating {(string.IsNullOrWhiteSpace(dp) ? "(nothing)" : dp)}{(groups == null ? "" : "; groups assigned: " + groups)}"); - } - } - - private void OnDeletedUser(IUserService sender, DeleteEventArgs deleteEventArgs) - { - var performingUser = CurrentPerformingUser; - var affectedUsers = deleteEventArgs.DeletedEntities; - foreach (var affectedUser in affectedUsers) - _auditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp, - DateTime.UtcNow, - affectedUser.Id, $"User \"{affectedUser.Name}\" {FormatEmail(affectedUser)}", - "umbraco/user/delete", "delete user"); - } - - private void WriteAudit(int performingId, int affectedId, string ipAddress, string eventType, string eventDetails, string affectedDetails = null) - { - var performingUser = _userService.GetUserById(performingId); - - var performingDetails = performingUser == null - ? $"User UNKNOWN:{performingId}" - : $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}"; - - WriteAudit(performingId, performingDetails, affectedId, ipAddress, eventType, eventDetails, affectedDetails); - } - - private void WriteAudit(IUser performingUser, int affectedId, string ipAddress, string eventType, string eventDetails) - { - var performingDetails = performingUser == null - ? $"User UNKNOWN" - : $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}"; - - WriteAudit(performingUser?.Id ?? 0, performingDetails, affectedId, ipAddress, eventType, eventDetails); - } - - private void WriteAudit(int performingId, string performingDetails, int affectedId, string ipAddress, string eventType, string eventDetails, string affectedDetails = null) - { - if (affectedDetails == null) - { - var affectedUser = _userService.GetUserById(affectedId); - affectedDetails = affectedUser == null - ? $"User UNKNOWN:{affectedId}" - : $"User \"{affectedUser.Name}\" {FormatEmail(affectedUser)}"; - } - - _auditService.Write(performingId, performingDetails, - ipAddress, - DateTime.UtcNow, - affectedId, affectedDetails, - eventType, eventDetails); - } } } diff --git a/src/Umbraco.Infrastructure/Compose/NotificationsComponent.cs b/src/Umbraco.Infrastructure/Compose/NotificationsComponent.cs deleted file mode 100644 index 687fdbf294..0000000000 --- a/src/Umbraco.Infrastructure/Compose/NotificationsComponent.cs +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright (c) Umbraco. -// See LICENSE for more details. - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using Umbraco.Cms.Core.Actions; -using Umbraco.Cms.Core.Composing; -using Umbraco.Cms.Core.Configuration.Models; -using Umbraco.Cms.Core.Events; -using Umbraco.Cms.Core.Hosting; -using Umbraco.Cms.Core.Models; -using Umbraco.Cms.Core.Models.Membership; -using Umbraco.Cms.Core.Security; -using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Core.Services.Implement; -using Umbraco.Extensions; - -namespace Umbraco.Cms.Core.Compose -{ - /// - /// TODO: this component must be removed entirely - there is some code duplication in in anticipation of this component being deleted - /// - public sealed class NotificationsComponent : IComponent - { - private readonly Notifier _notifier; - private readonly ActionCollection _actions; - private readonly IContentService _contentService; - - public NotificationsComponent(Notifier notifier, ActionCollection actions, IContentService contentService) - { - _notifier = notifier; - _actions = actions; - _contentService = contentService; - } - - public void Initialize() - { - //Send notifications for the public access changed action - PublicAccessService.Saved += PublicAccessService_Saved; - - UserService.UserGroupPermissionsAssigned += UserService_UserGroupPermissionsAssigned; - } - - public void Terminate() - { - PublicAccessService.Saved -= PublicAccessService_Saved; - UserService.UserGroupPermissionsAssigned -= UserService_UserGroupPermissionsAssigned; - } - - private void UserService_UserGroupPermissionsAssigned(IUserService sender, SaveEventArgs args) - => UserServiceUserGroupPermissionsAssigned(args, _contentService); - - private void PublicAccessService_Saved(IPublicAccessService sender, SaveEventArgs args) - => PublicAccessServiceSaved(args, _contentService); - - private void UserServiceUserGroupPermissionsAssigned(SaveEventArgs args, IContentService contentService) - { - var entities = contentService.GetByIds(args.SavedEntities.Select(e => e.EntityId)).ToArray(); - if (entities.Any() == false) - { - return; - } - _notifier.Notify(_actions.GetAction(), entities); - } - - private void PublicAccessServiceSaved(SaveEventArgs args, IContentService contentService) - { - var entities = contentService.GetByIds(args.SavedEntities.Select(e => e.ProtectedNodeId)).ToArray(); - if (entities.Any() == false) - { - return; - } - _notifier.Notify(_actions.GetAction(), entities); - } - - /// - /// This class is used to send the notifications - /// - public sealed class Notifier - { - private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor; - private readonly IHostingEnvironment _hostingEnvironment; - private readonly INotificationService _notificationService; - private readonly IUserService _userService; - private readonly ILocalizedTextService _textService; - private readonly GlobalSettings _globalSettings; - private readonly ILogger _logger; - - /// - /// Initializes a new instance of the class. - /// - public Notifier( - IBackOfficeSecurityAccessor backOfficeSecurityAccessor, - IHostingEnvironment hostingEnvironment, - INotificationService notificationService, - IUserService userService, - ILocalizedTextService textService, - IOptions globalSettings, - ILogger logger) - { - _backOfficeSecurityAccessor = backOfficeSecurityAccessor; - _hostingEnvironment = hostingEnvironment; - _notificationService = notificationService; - _userService = userService; - _textService = textService; - _globalSettings = globalSettings.Value; - _logger = logger; - } - - public void Notify(IAction action, params IContent[] entities) - { - var user = _backOfficeSecurityAccessor?.BackOfficeSecurity?.CurrentUser; - - //if there is no current user, then use the admin - if (user == null) - { - _logger.LogDebug("There is no current Umbraco user logged in, the notifications will be sent from the administrator"); - user = _userService.GetUserById(Constants.Security.SuperUserId); - if (user == null) - { - _logger.LogWarning("Notifications can not be sent, no admin user with id {SuperUserId} could be resolved", Constants.Security.SuperUserId); - return; - } - } - - SendNotification(user, entities, action, _hostingEnvironment.ApplicationMainUrl); - } - - private void SendNotification(IUser sender, IEnumerable entities, IAction action, Uri siteUri) - { - if (sender == null) throw new ArgumentNullException(nameof(sender)); - if (siteUri == null) - { - _logger.LogWarning("Notifications can not be sent, no site URL is set (might be during boot process?)"); - return; - } - - //group by the content type variation since the emails will be different - foreach(var contentVariantGroup in entities.GroupBy(x => x.ContentType.Variations)) - { - _notificationService.SendNotifications( - sender, - contentVariantGroup, - action.Letter.ToString(CultureInfo.InvariantCulture), - _textService.Localize("actions", action.Alias), - siteUri, - ((IUser user, NotificationEmailSubjectParams subject) x) - => _textService.Localize( - "notifications/mailSubject", - x.user.GetUserCulture(_textService, _globalSettings), - new[] { x.subject.SiteUrl, x.subject.Action, x.subject.ItemName }), - ((IUser user, NotificationEmailBodyParams body, bool isHtml) x) - => _textService.Localize( - x.isHtml ? "notifications/mailBodyHtml" : "notifications/mailBody", - x.user.GetUserCulture(_textService, _globalSettings), - new[] - { - x.body.RecipientName, - x.body.Action, - x.body.ItemName, - x.body.EditedUser, - x.body.SiteUrl, - x.body.ItemId, - //format the summary depending on if it's variant or not - contentVariantGroup.Key == ContentVariation.Culture - ? (x.isHtml ? _textService.Localize("notifications/mailBodyVariantHtmlSummary", new[]{ x.body.Summary }) : _textService.Localize("notifications/mailBodyVariantSummary", new []{ x.body.Summary })) - : x.body.Summary, - x.body.ItemUrl - })); - } - } - - } - } - - -} diff --git a/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs b/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs index 906f10c524..9b9253cfbf 100644 --- a/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs +++ b/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs @@ -1,10 +1,12 @@ // Copyright (c) Umbraco. // See LICENSE for more details. +using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Composing; using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.Membership; using Umbraco.Cms.Core.PropertyEditors; using Umbraco.Cms.Core.Routing; using Umbraco.Cms.Infrastructure.Services.Notifications; @@ -12,14 +14,10 @@ using Umbraco.Extensions; namespace Umbraco.Cms.Core.Compose { - public sealed class NotificationsComposer : ComponentComposer, ICoreComposer + public sealed class NotificationsComposer : ICoreComposer { - public override void Compose(IUmbracoBuilder builder) + public void Compose(IUmbracoBuilder builder) { - base.Compose(builder); - - builder.Services.AddUnique(); - // add handlers for sending user notifications (i.e. emails) builder.Services.AddUnique(); builder @@ -31,7 +29,9 @@ namespace Umbraco.Cms.Core.Compose .AddNotificationHandler, UserNotificationsHandler>() .AddNotificationHandler, UserNotificationsHandler>() .AddNotificationHandler, UserNotificationsHandler>() - .AddNotificationHandler, UserNotificationsHandler>(); + .AddNotificationHandler, UserNotificationsHandler>() + .AddNotificationHandler() + .AddNotificationHandler, UserNotificationsHandler>(); // add handlers for building content relations builder @@ -51,10 +51,12 @@ namespace Umbraco.Cms.Core.Compose .AddNotificationHandler, FileUploadPropertyEditor>() .AddNotificationHandler, FileUploadPropertyEditor>() .AddNotificationHandler, FileUploadPropertyEditor>() + .AddNotificationHandler, FileUploadPropertyEditor>() .AddNotificationHandler, ImageCropperPropertyEditor>() .AddNotificationHandler, ImageCropperPropertyEditor>() .AddNotificationHandler, ImageCropperPropertyEditor>() - .AddNotificationHandler, ImageCropperPropertyEditor>(); + .AddNotificationHandler, ImageCropperPropertyEditor>() + .AddNotificationHandler, ImageCropperPropertyEditor>(); // add notification handlers for redirect tracking builder @@ -62,6 +64,29 @@ namespace Umbraco.Cms.Core.Compose .AddNotificationHandler, RedirectTrackingHandler>() .AddNotificationHandler, RedirectTrackingHandler>() .AddNotificationHandler, RedirectTrackingHandler>(); + + // add notification handlers for auditing + builder + .AddNotificationHandler, AuditNotificationsHandler>() + .AddNotificationHandler, AuditNotificationsHandler>() + .AddNotificationHandler() + .AddNotificationHandler() + .AddNotificationHandler() + .AddNotificationHandler, AuditNotificationsHandler>() + .AddNotificationHandler, AuditNotificationsHandler>() + .AddNotificationHandler, AuditNotificationsHandler>() + .AddNotificationHandler(); + + // add notifications handlers for distributed cache + builder + .AddNotificationHandler, DistributedCacheHandler>() + .AddNotificationHandler, DistributedCacheHandler>() + .AddNotificationHandler, DistributedCacheHandler>() + .AddNotificationHandler, DistributedCacheHandler>() + .AddNotificationHandler, DistributedCacheHandler>() + .AddNotificationHandler, DistributedCacheHandler>() + .AddNotificationHandler, DistributedCacheHandler>() + .AddNotificationHandler, DistributedCacheHandler>(); } } } diff --git a/src/Umbraco.Infrastructure/Events/UserNotificationsHandler.cs b/src/Umbraco.Infrastructure/Events/UserNotificationsHandler.cs index a099a66d8e..ef5d9b660b 100644 --- a/src/Umbraco.Infrastructure/Events/UserNotificationsHandler.cs +++ b/src/Umbraco.Infrastructure/Events/UserNotificationsHandler.cs @@ -29,7 +29,9 @@ namespace Umbraco.Cms.Core.Events INotificationHandler>, INotificationHandler>, INotificationHandler>, - INotificationHandler> + INotificationHandler>, + INotificationHandler, + INotificationHandler> { private readonly Notifier _notifier; private readonly ActionCollection _actions; @@ -211,5 +213,26 @@ namespace Umbraco.Cms.Core.Events } } + + public void Handle(AssignedUserGroupPermissionsNotification notification) + { + var entities = _contentService.GetByIds(notification.EntityPermissions.Select(e => e.EntityId)).ToArray(); + if (entities.Any() == false) + { + return; + } + _notifier.Notify(_actions.GetAction(), entities); + + } + + public void Handle(SavedNotification notification) + { + var entities = _contentService.GetByIds(notification.SavedEntities.Select(e => e.ProtectedNodeId)).ToArray(); + if (entities.Any() == false) + { + return; + } + _notifier.Notify(_actions.GetAction(), entities); + } } } diff --git a/src/Umbraco.Infrastructure/PropertyEditors/FileUploadPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/FileUploadPropertyEditor.cs index a43531bb83..6b75c54a12 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/FileUploadPropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/FileUploadPropertyEditor.cs @@ -27,7 +27,8 @@ namespace Umbraco.Cms.Core.PropertyEditors Icon = "icon-download-alt")] public class FileUploadPropertyEditor : DataEditor, IMediaUrlGenerator, INotificationHandler>, INotificationHandler>, - INotificationHandler>, INotificationHandler> + INotificationHandler>, INotificationHandler>, + INotificationHandler> { private readonly IMediaFileSystem _mediaFileSystem; private readonly ContentSettings _contentSettings; @@ -95,10 +96,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// The paths to all file upload property files contained within a collection of content entities /// /// - /// - /// This method must be made private once MemberService events have been replaced by notifications - /// - internal IEnumerable ContainedFilePaths(IEnumerable entities) => entities + private IEnumerable ContainedFilePaths(IEnumerable entities) => entities .SelectMany(x => x.Properties) .Where(IsUploadField) .SelectMany(GetFilePathsFromPropertyValues) @@ -162,6 +160,8 @@ namespace Umbraco.Cms.Core.PropertyEditors public void Handle(DeletedNotification notification) => DeleteContainedFiles(notification.DeletedEntities); + public void Handle(DeletedNotification notification) => DeleteContainedFiles(notification.DeletedEntities); + private void DeleteContainedFiles(IEnumerable deletedEntities) { var filePathsToDelete = ContainedFilePaths(deletedEntities); diff --git a/src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyEditor.cs index d4c0c94054..886812d5a2 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyEditor.cs @@ -34,7 +34,8 @@ namespace Umbraco.Cms.Core.PropertyEditors Icon = "icon-crop")] public class ImageCropperPropertyEditor : DataEditor, IMediaUrlGenerator, INotificationHandler>, INotificationHandler>, - INotificationHandler>, INotificationHandler> + INotificationHandler>, INotificationHandler>, + INotificationHandler> { private readonly IMediaFileSystem _mediaFileSystem; private readonly ContentSettings _contentSettings; @@ -131,10 +132,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// The paths to all image cropper property files contained within a collection of content entities /// /// - /// - /// This method must be made private once MemberService events have been replaced by notifications - /// - internal IEnumerable ContainedFilePaths(IEnumerable entities) => entities + private IEnumerable ContainedFilePaths(IEnumerable entities) => entities .SelectMany(x => x.Properties) .Where(IsCropperField) .SelectMany(GetFilePathsFromPropertyValues) @@ -218,6 +216,8 @@ namespace Umbraco.Cms.Core.PropertyEditors public void Handle(DeletedNotification notification) => DeleteContainedFiles(notification.DeletedEntities); + public void Handle(DeletedNotification notification) => DeleteContainedFiles(notification.DeletedEntities); + private void DeleteContainedFiles(IEnumerable deletedEntities) { var filePathsToDelete = ContainedFilePaths(deletedEntities); diff --git a/src/Umbraco.Infrastructure/PropertyEditors/PropertyEditorsComponent.cs b/src/Umbraco.Infrastructure/PropertyEditors/PropertyEditorsComponent.cs deleted file mode 100644 index b9e9e33889..0000000000 --- a/src/Umbraco.Infrastructure/PropertyEditors/PropertyEditorsComponent.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) Umbraco. -// See LICENSE for more details. - -using System; -using System.Collections.Generic; -using System.Linq; -using Umbraco.Cms.Core.Composing; -using Umbraco.Cms.Core.Events; -using Umbraco.Cms.Core.Models; -using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Core.Services.Implement; - -namespace Umbraco.Cms.Core.PropertyEditors -{ - // TODO: delete this component and make the "ContainedFilePaths" methods on FileUploadPropertyEditor and ImageCropperPropertyEditor private once MemberService uses notifications instead of static events - public sealed class PropertyEditorsComponent : IComponent - { - private readonly PropertyEditorCollection _propertyEditors; - private readonly List _terminate = new List(); - - public PropertyEditorsComponent(PropertyEditorCollection propertyEditors) - { - _propertyEditors = propertyEditors; - } - - public void Initialize() - { - var fileUpload = _propertyEditors.OfType().FirstOrDefault(); - if (fileUpload != null) Initialize(fileUpload); - - var imageCropper = _propertyEditors.OfType().FirstOrDefault(); - if (imageCropper != null) Initialize(imageCropper); - - // grid/examine moved to ExamineComponent - } - - public void Terminate() - { - foreach (var t in _terminate) t(); - } - - private void Initialize(FileUploadPropertyEditor fileUpload) - { - void memberServiceDeleted(IMemberService sender, DeleteEventArgs args) => args.MediaFilesToDelete.AddRange(fileUpload.ContainedFilePaths(args.DeletedEntities.Cast())); - MemberService.Deleted += memberServiceDeleted; - _terminate.Add(() => MemberService.Deleted -= memberServiceDeleted); - } - - private void Initialize(ImageCropperPropertyEditor imageCropper) - { - void memberServiceDeleted(IMemberService sender, DeleteEventArgs args) => args.MediaFilesToDelete.AddRange(imageCropper.ContainedFilePaths(args.DeletedEntities.Cast())); - MemberService.Deleted += memberServiceDeleted; - _terminate.Add(() => MemberService.Deleted -= memberServiceDeleted); - } - } -} diff --git a/src/Umbraco.Infrastructure/PropertyEditors/PropertyEditorsComposer.cs b/src/Umbraco.Infrastructure/PropertyEditors/PropertyEditorsComposer.cs deleted file mode 100644 index 4e876ad554..0000000000 --- a/src/Umbraco.Infrastructure/PropertyEditors/PropertyEditorsComposer.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) Umbraco. -// See LICENSE for more details. - -using Umbraco.Cms.Core.Composing; - -namespace Umbraco.Cms.Core.PropertyEditors -{ - public sealed class PropertyEditorsComposer : ComponentComposer, ICoreComposer - { } -} diff --git a/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs b/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs index 96ba494790..026052fa67 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.Logging; @@ -9,6 +9,7 @@ using Umbraco.Cms.Core.Persistence.Querying; using Umbraco.Cms.Core.Persistence.Repositories; using Umbraco.Cms.Core.Scoping; using Umbraco.Cms.Infrastructure.Persistence.Querying; +using Umbraco.Cms.Infrastructure.Services.Notifications; using Umbraco.Extensions; namespace Umbraco.Cms.Core.Services.Implement @@ -22,7 +23,6 @@ namespace Umbraco.Cms.Core.Services.Implement private readonly IMemberTypeRepository _memberTypeRepository; private readonly IMemberGroupRepository _memberGroupRepository; private readonly IAuditRepository _auditRepository; - private readonly IMemberTypeService _memberTypeService; private readonly IMemberGroupService _memberGroupService; @@ -773,10 +773,12 @@ namespace Umbraco.Cms.Core.Services.Implement member.Username = member.Username.Trim(); member.Email = member.Email.Trim(); + var evtMsgs = EventMessagesFactory.Get(); + using (IScope scope = ScopeProvider.CreateScope()) { - var saveEventArgs = new SaveEventArgs(member); - if (raiseEvents && scope.Events.DispatchCancelable(Saving, this, saveEventArgs)) + var savingNotification = new SavingNotification(member, evtMsgs); + if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); return; @@ -793,8 +795,7 @@ namespace Umbraco.Cms.Core.Services.Implement if (raiseEvents) { - saveEventArgs.CanCancel = false; - scope.Events.Dispatch(Saved, this, saveEventArgs); + scope.Notifications.Publish(new SavedNotification(member, evtMsgs).WithStateFrom(savingNotification)); } Audit(AuditType.Save, 0, member.Id); @@ -808,10 +809,12 @@ namespace Umbraco.Cms.Core.Services.Implement { var membersA = members.ToArray(); + var evtMsgs = EventMessagesFactory.Get(); + using (var scope = ScopeProvider.CreateScope()) { - var saveEventArgs = new SaveEventArgs(membersA); - if (raiseEvents && scope.Events.DispatchCancelable(Saving, this, saveEventArgs)) + var savingNotification = new SavingNotification(membersA, evtMsgs); + if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); return; @@ -830,8 +833,7 @@ namespace Umbraco.Cms.Core.Services.Implement if (raiseEvents) { - saveEventArgs.CanCancel = false; - scope.Events.Dispatch(Saved, this, saveEventArgs); + scope.Notifications.Publish(new SavedNotification(membersA, evtMsgs).WithStateFrom(savingNotification)); } Audit(AuditType.Save, 0, -1, "Save multiple Members"); @@ -849,32 +851,30 @@ namespace Umbraco.Cms.Core.Services.Implement /// to Delete public void Delete(IMember member) { + var evtMsgs = EventMessagesFactory.Get(); + using (var scope = ScopeProvider.CreateScope()) { - var deleteEventArgs = new DeleteEventArgs(member); - if (scope.Events.DispatchCancelable(Deleting, this, deleteEventArgs)) + var deletingNotification = new DeletingNotification(member, evtMsgs); + if (scope.Notifications.PublishCancelable(deletingNotification)) { scope.Complete(); return; } scope.WriteLock(Constants.Locks.MemberTree); - DeleteLocked(scope, member, deleteEventArgs); + DeleteLocked(scope, member, evtMsgs, deletingNotification.State); Audit(AuditType.Delete, 0, member.Id); scope.Complete(); } } - private void DeleteLocked(IScope scope, IMember member, DeleteEventArgs args = null) + private void DeleteLocked(IScope scope, IMember member, EventMessages evtMsgs, IDictionary notificationState = null) { // a member has no descendants _memberRepository.Delete(member); - if (args == null) - args = new DeleteEventArgs(member, false); // raise event & get flagged files - else - args.CanCancel = false; - scope.Events.Dispatch(Deleted, this, args); + scope.Notifications.Publish(new DeletedNotification(member, evtMsgs).WithState(notificationState)); // media files deleted by QueuingEventDispatcher } @@ -1017,8 +1017,7 @@ namespace Umbraco.Cms.Core.Services.Implement scope.WriteLock(Constants.Locks.MemberTree); int[] ids = _memberGroupRepository.GetMemberIds(usernames); _memberGroupRepository.AssignRoles(ids, roleNames); - scope.Events.Dispatch(AssignedRoles, this, new RolesEventArgs(ids, roleNames), nameof(AssignedRoles)); - scope.Complete(); + scope.Notifications.Publish(new AssignedMemberRolesNotification(ids, roleNames)); } } @@ -1031,8 +1030,7 @@ namespace Umbraco.Cms.Core.Services.Implement scope.WriteLock(Constants.Locks.MemberTree); int[] ids = _memberGroupRepository.GetMemberIds(usernames); _memberGroupRepository.DissociateRoles(ids, roleNames); - scope.Events.Dispatch(RemovedRoles, this, new RolesEventArgs(ids, roleNames), nameof(RemovedRoles)); - scope.Complete(); + scope.Notifications.Publish(new RemovedMemberRolesNotification(ids, roleNames)); } } @@ -1044,8 +1042,7 @@ namespace Umbraco.Cms.Core.Services.Implement { scope.WriteLock(Constants.Locks.MemberTree); _memberGroupRepository.AssignRoles(memberIds, roleNames); - scope.Events.Dispatch(AssignedRoles, this, new RolesEventArgs(memberIds, roleNames), nameof(AssignedRoles)); - scope.Complete(); + scope.Notifications.Publish(new AssignedMemberRolesNotification(memberIds, roleNames)); } } @@ -1057,8 +1054,7 @@ namespace Umbraco.Cms.Core.Services.Implement { scope.WriteLock(Constants.Locks.MemberTree); _memberGroupRepository.DissociateRoles(memberIds, roleNames); - scope.Events.Dispatch(RemovedRoles, this, new RolesEventArgs(memberIds, roleNames), nameof(RemovedRoles)); - scope.Complete(); + scope.Notifications.Publish(new RemovedMemberRolesNotification(memberIds, roleNames)); } } @@ -1072,36 +1068,6 @@ namespace Umbraco.Cms.Core.Services.Implement #region Event Handlers - /// - /// Occurs before Delete - /// - public static event TypedEventHandler> Deleting; - - /// - /// Occurs after Delete - /// - public static event TypedEventHandler> Deleted; - - /// - /// Occurs before Save - /// - public static event TypedEventHandler> Saving; - - /// - /// Occurs after Save - /// - public static event TypedEventHandler> Saved; - - /// - /// Occurs after roles have been assigned. - /// - public static event TypedEventHandler AssignedRoles; - - /// - /// Occurs after roles have been removed. - /// - public static event TypedEventHandler RemovedRoles; - /// /// Occurs after members have been exported. /// @@ -1145,7 +1111,7 @@ namespace Umbraco.Cms.Core.Services.Implement Properties = new List(GetPropertyExportItems(member)) }; - scope.Events.Dispatch(Exported, this, new ExportedMemberEventArgs(member, model)); + scope.Notifications.Publish(new ExportedMemberNotification(member, model)); return model; } @@ -1187,6 +1153,8 @@ namespace Umbraco.Cms.Core.Services.Implement /// Id of the MemberType public void DeleteMembersOfType(int memberTypeId) { + var evtMsgs = EventMessagesFactory.Get(); + // note: no tree to manage here using (IScope scope = ScopeProvider.CreateScope()) { @@ -1196,9 +1164,8 @@ namespace Umbraco.Cms.Core.Services.Implement IQuery query = Query().Where(x => x.ContentTypeId == memberTypeId); IMember[] members = _memberRepository.Get(query).ToArray(); - var deleteEventArgs = new DeleteEventArgs(members); - if (scope.Events.DispatchCancelable(Deleting, this, deleteEventArgs)) + if (scope.Notifications.PublishCancelable(new DeletingNotification(members, evtMsgs))) { scope.Complete(); return; @@ -1208,7 +1175,7 @@ namespace Umbraco.Cms.Core.Services.Implement { // delete media // triggers the deleted event (and handles the files) - DeleteLocked(scope, member); + DeleteLocked(scope, member, evtMsgs); } scope.Complete(); diff --git a/src/Umbraco.Infrastructure/Services/Implement/PublicAccessService.cs b/src/Umbraco.Infrastructure/Services/Implement/PublicAccessService.cs index 4c8615f442..b82f09d1b1 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/PublicAccessService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/PublicAccessService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.Logging; @@ -6,6 +6,7 @@ using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Persistence.Repositories; using Umbraco.Cms.Core.Scoping; +using Umbraco.Cms.Infrastructure.Services.Notifications; using Umbraco.Extensions; namespace Umbraco.Cms.Core.Services.Implement @@ -129,8 +130,8 @@ namespace Umbraco.Cms.Core.Services.Implement return OperationResult.Attempt.Succeed(evtMsgs, entry); } - var saveEventArgs = new SaveEventArgs(entry, evtMsgs); - if (scope.Events.DispatchCancelable(Saving, this, saveEventArgs)) + var savingNotifiation = new SavingNotification(entry, evtMsgs); + if (scope.Notifications.PublishCancelable(savingNotifiation)) { scope.Complete(); return OperationResult.Attempt.Cancel(evtMsgs, entry); @@ -140,8 +141,7 @@ namespace Umbraco.Cms.Core.Services.Implement scope.Complete(); - saveEventArgs.CanCancel = false; - scope.Events.Dispatch(Saved, this, saveEventArgs); + scope.Notifications.Publish(new SavedNotification(entry, evtMsgs).WithStateFrom(savingNotifiation)); } return OperationResult.Attempt.Succeed(evtMsgs, entry); @@ -167,8 +167,8 @@ namespace Umbraco.Cms.Core.Services.Implement entry.RemoveRule(existingRule); - var saveEventArgs = new SaveEventArgs(entry, evtMsgs); - if (scope.Events.DispatchCancelable(Saving, this, saveEventArgs)) + var savingNotifiation = new SavingNotification(entry, evtMsgs); + if (scope.Notifications.PublishCancelable(savingNotifiation)) { scope.Complete(); return OperationResult.Attempt.Cancel(evtMsgs); @@ -177,8 +177,7 @@ namespace Umbraco.Cms.Core.Services.Implement _publicAccessRepository.Save(entry); scope.Complete(); - saveEventArgs.CanCancel = false; - scope.Events.Dispatch(Saved, this, saveEventArgs); + scope.Notifications.Publish(new SavedNotification(entry, evtMsgs).WithStateFrom(savingNotifiation)); } return OperationResult.Attempt.Succeed(evtMsgs); @@ -194,8 +193,8 @@ namespace Umbraco.Cms.Core.Services.Implement using (var scope = ScopeProvider.CreateScope()) { - var saveEventArgs = new SaveEventArgs(entry, evtMsgs); - if (scope.Events.DispatchCancelable(Saving, this, saveEventArgs)) + var savingNotifiation = new SavingNotification(entry, evtMsgs); + if (scope.Notifications.PublishCancelable(savingNotifiation)) { scope.Complete(); return OperationResult.Attempt.Cancel(evtMsgs); @@ -204,8 +203,7 @@ namespace Umbraco.Cms.Core.Services.Implement _publicAccessRepository.Save(entry); scope.Complete(); - saveEventArgs.CanCancel = false; - scope.Events.Dispatch(Saved, this, saveEventArgs); + scope.Notifications.Publish(new SavedNotification(entry, evtMsgs).WithStateFrom(savingNotifiation)); } return OperationResult.Attempt.Succeed(evtMsgs); @@ -221,8 +219,8 @@ namespace Umbraco.Cms.Core.Services.Implement using (var scope = ScopeProvider.CreateScope()) { - var deleteEventArgs = new DeleteEventArgs(entry, evtMsgs); - if (scope.Events.DispatchCancelable(Deleting, this, deleteEventArgs)) + var deletingNotification = new DeletingNotification(entry, evtMsgs); + if (scope.Notifications.PublishCancelable(deletingNotification)) { scope.Complete(); return OperationResult.Attempt.Cancel(evtMsgs); @@ -231,33 +229,10 @@ namespace Umbraco.Cms.Core.Services.Implement _publicAccessRepository.Delete(entry); scope.Complete(); - deleteEventArgs.CanCancel = false; - scope.Events.Dispatch(Deleted, this, deleteEventArgs); + scope.Notifications.Publish(new DeletedNotification(entry, evtMsgs).WithStateFrom(deletingNotification)); } return OperationResult.Attempt.Succeed(evtMsgs); } - - /// - /// Occurs before Save - /// - public static event TypedEventHandler> Saving; - - /// - /// Occurs after Save - /// - public static event TypedEventHandler> Saved; - - /// - /// Occurs before Delete - /// - public static event TypedEventHandler> Deleting; - - /// - /// Occurs after Delete - /// - public static event TypedEventHandler> Deleted; - - } } diff --git a/src/Umbraco.Infrastructure/Services/Implement/UserService.cs b/src/Umbraco.Infrastructure/Services/Implement/UserService.cs index 751581e068..3336ba37a3 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/UserService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/UserService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Data.Common; using System.Globalization; @@ -14,6 +14,7 @@ using Umbraco.Cms.Core.Persistence.Repositories; using Umbraco.Cms.Core.Scoping; using Umbraco.Cms.Infrastructure.Persistence.Querying; using Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement; +using Umbraco.Cms.Infrastructure.Services.Notifications; using Umbraco.Extensions; namespace Umbraco.Cms.Core.Services.Implement @@ -109,6 +110,8 @@ namespace Umbraco.Cms.Core.Services.Implement if (username == null) throw new ArgumentNullException(nameof(username)); if (string.IsNullOrWhiteSpace(username)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(username)); + var evtMsgs = EventMessagesFactory.Get(); + // TODO: PUT lock here!! User user; @@ -129,8 +132,8 @@ namespace Umbraco.Cms.Core.Services.Implement IsApproved = isApproved }; - var saveEventArgs = new SaveEventArgs(user); - if (scope.Events.DispatchCancelable(SavingUser, this, saveEventArgs)) + var savingNotification = new SavingNotification(user, evtMsgs); + if (scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); return user; @@ -138,8 +141,7 @@ namespace Umbraco.Cms.Core.Services.Implement _userRepository.Save(user); - saveEventArgs.CanCancel = false; - scope.Events.Dispatch(SavedUser, this, saveEventArgs); + scope.Notifications.Publish(new SavedNotification(user, evtMsgs).WithStateFrom(savingNotification)); scope.Complete(); } @@ -239,10 +241,12 @@ namespace Umbraco.Cms.Core.Services.Implement } else { + var evtMsgs = EventMessagesFactory.Get(); + using (var scope = ScopeProvider.CreateScope()) { - var deleteEventArgs = new DeleteEventArgs(user); - if (scope.Events.DispatchCancelable(DeletingUser, this, deleteEventArgs)) + var deletingNotification = new DeletingNotification(user, evtMsgs); + if (scope.Notifications.PublishCancelable(deletingNotification)) { scope.Complete(); return; @@ -250,8 +254,7 @@ namespace Umbraco.Cms.Core.Services.Implement _userRepository.Delete(user); - deleteEventArgs.CanCancel = false; - scope.Events.Dispatch(DeletedUser, this, deleteEventArgs); + scope.Notifications.Publish(new DeletedNotification(user, evtMsgs).WithStateFrom(deletingNotification)); scope.Complete(); } } @@ -272,10 +275,12 @@ namespace Umbraco.Cms.Core.Services.Implement /// Default is True otherwise set to False to not raise events public void Save(IUser entity, bool raiseEvents = true) { + var evtMsgs = EventMessagesFactory.Get(); + using (var scope = ScopeProvider.CreateScope()) { - var saveEventArgs = new SaveEventArgs(entity); - if (raiseEvents && scope.Events.DispatchCancelable(SavingUser, this, saveEventArgs)) + var savingNotification = new SavingNotification(entity, evtMsgs); + if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); return; @@ -292,8 +297,7 @@ namespace Umbraco.Cms.Core.Services.Implement _userRepository.Save(entity); if (raiseEvents) { - saveEventArgs.CanCancel = false; - scope.Events.Dispatch(SavedUser, this, saveEventArgs); + scope.Notifications.Publish(new SavedNotification(entity, evtMsgs).WithStateFrom(savingNotification)); } scope.Complete(); @@ -319,12 +323,14 @@ namespace Umbraco.Cms.Core.Services.Implement /// Default is True otherwise set to False to not raise events public void Save(IEnumerable entities, bool raiseEvents = true) { + var evtMsgs = EventMessagesFactory.Get(); + var entitiesA = entities.ToArray(); using (var scope = ScopeProvider.CreateScope()) { - var saveEventArgs = new SaveEventArgs(entitiesA); - if (raiseEvents && scope.Events.DispatchCancelable(SavingUser, this, saveEventArgs)) + var savingNotification = new SavingNotification(entitiesA, evtMsgs); + if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); return; @@ -344,8 +350,7 @@ namespace Umbraco.Cms.Core.Services.Implement if (raiseEvents) { - saveEventArgs.CanCancel = false; - scope.Events.Dispatch(SavedUser, this, saveEventArgs); + scope.Notifications.Publish(new SavedNotification(entitiesA, evtMsgs).WithStateFrom(savingNotification)); } //commit the whole lot in one go @@ -709,14 +714,16 @@ namespace Umbraco.Cms.Core.Services.Implement if (entityIds.Length == 0) return; + var evtMsgs = EventMessagesFactory.Get(); + using (var scope = ScopeProvider.CreateScope()) { _userGroupRepository.ReplaceGroupPermissions(groupId, permissions, entityIds); scope.Complete(); var assigned = permissions.Select(p => p.ToString(CultureInfo.InvariantCulture)).ToArray(); - scope.Events.Dispatch(UserGroupPermissionsAssigned, this, - new SaveEventArgs(entityIds.Select(x => new EntityPermission(groupId, x, assigned)).ToArray(), false)); + var entityPermissions = entityIds.Select(x => new EntityPermission(groupId, x, assigned)).ToArray(); + scope.Notifications.Publish(new AssignedUserGroupPermissionsNotification(entityPermissions, evtMsgs)); } } @@ -731,14 +738,16 @@ namespace Umbraco.Cms.Core.Services.Implement if (entityIds.Length == 0) return; + var evtMsgs = EventMessagesFactory.Get(); + using (var scope = ScopeProvider.CreateScope()) { _userGroupRepository.AssignGroupPermission(groupId, permission, entityIds); scope.Complete(); var assigned = new[] { permission.ToString(CultureInfo.InvariantCulture) }; - scope.Events.Dispatch(UserGroupPermissionsAssigned, this, - new SaveEventArgs(entityIds.Select(x => new EntityPermission(groupId, x, assigned)).ToArray(), false)); + var entityPermissions = entityIds.Select(x => new EntityPermission(groupId, x, assigned)).ToArray(); + scope.Notifications.Publish(new AssignedUserGroupPermissionsNotification(entityPermissions, evtMsgs)); } } @@ -809,6 +818,8 @@ namespace Umbraco.Cms.Core.Services.Implement /// Default is True otherwise set to False to not raise events public void Save(IUserGroup userGroup, int[] userIds = null, bool raiseEvents = true) { + var evtMsgs = EventMessagesFactory.Get(); + using (var scope = ScopeProvider.CreateScope()) { // we need to figure out which users have been added / removed, for audit purposes @@ -826,9 +837,19 @@ namespace Umbraco.Cms.Core.Services.Implement removedUsers = groupIds.Except(userIds).Select(x => xGroupUsers[x]).Where(x => x.Id != 0).ToArray(); } - var saveEventArgs = new SaveEventArgs(new UserGroupWithUsers(userGroup, addedUsers, removedUsers)); + var userGroupWithUsers = new UserGroupWithUsers(userGroup, addedUsers, removedUsers); - if (raiseEvents && scope.Events.DispatchCancelable(SavingUserGroup, this, saveEventArgs)) + // this is the default/expected notification for the IUserGroup entity being saved + var savingNotification = new SavingNotification(userGroup, evtMsgs); + if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification)) + { + scope.Complete(); + return; + } + + // this is an additional notification for special auditing + var savingUserGroupWithUsersNotification = new SavingNotification(userGroupWithUsers, evtMsgs); + if (raiseEvents && scope.Notifications.PublishCancelable(savingUserGroupWithUsersNotification)) { scope.Complete(); return; @@ -838,8 +859,8 @@ namespace Umbraco.Cms.Core.Services.Implement if (raiseEvents) { - saveEventArgs.CanCancel = false; - scope.Events.Dispatch(SavedUserGroup, this, saveEventArgs); + scope.Notifications.Publish(new SavedNotification(userGroup, evtMsgs).WithStateFrom(savingNotification)); + scope.Notifications.Publish(new SavedNotification(userGroupWithUsers, evtMsgs).WithStateFrom(savingUserGroupWithUsersNotification)); } scope.Complete(); @@ -852,10 +873,12 @@ namespace Umbraco.Cms.Core.Services.Implement /// UserGroup to delete public void DeleteUserGroup(IUserGroup userGroup) { + var evtMsgs = EventMessagesFactory.Get(); + using (var scope = ScopeProvider.CreateScope()) { - var deleteEventArgs = new DeleteEventArgs(userGroup); - if (scope.Events.DispatchCancelable(DeletingUserGroup, this, deleteEventArgs)) + var deletingNotification = new DeletingNotification(userGroup, evtMsgs); + if (scope.Notifications.PublishCancelable(deletingNotification)) { scope.Complete(); return; @@ -863,8 +886,7 @@ namespace Umbraco.Cms.Core.Services.Implement _userGroupRepository.Delete(userGroup); - deleteEventArgs.CanCancel = false; - scope.Events.Dispatch(DeletedUserGroup, this, deleteEventArgs); + scope.Notifications.Publish(new DeletedNotification(userGroup, evtMsgs).WithStateFrom(deletingNotification)); scope.Complete(); } @@ -1144,49 +1166,5 @@ namespace Umbraco.Cms.Core.Services.Implement } #endregion - - /// - /// Occurs before Save - /// - public static event TypedEventHandler> SavingUser; - - /// - /// Occurs after Save - /// - public static event TypedEventHandler> SavedUser; - - /// - /// Occurs before Delete - /// - public static event TypedEventHandler> DeletingUser; - - /// - /// Occurs after Delete - /// - public static event TypedEventHandler> DeletedUser; - - /// - /// Occurs before Save - /// - public static event TypedEventHandler> SavingUserGroup; - - /// - /// Occurs after Save - /// - public static event TypedEventHandler> SavedUserGroup; - - /// - /// Occurs before Delete - /// - public static event TypedEventHandler> DeletingUserGroup; - - /// - /// Occurs after Delete - /// - public static event TypedEventHandler> DeletedUserGroup; - - // TODO: still don't know if we need this yet unless we start caching permissions, but that also means we'll need another - // event on the ContentService since there's a method there to modify node permissions too, or we can proxy events if needed. - public static event TypedEventHandler> UserGroupPermissionsAssigned; } } diff --git a/src/Umbraco.Infrastructure/Services/Notifications/AssignedMemberRolesNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/AssignedMemberRolesNotification.cs new file mode 100644 index 0000000000..9d5d707f64 --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/AssignedMemberRolesNotification.cs @@ -0,0 +1,10 @@ +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public class AssignedMemberRolesNotification : MemberRolesNotification + { + public AssignedMemberRolesNotification(int[] memberIds, string[] roles) : base(memberIds, roles) + { + + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/AssignedUserGroupPermissionsNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/AssignedUserGroupPermissionsNotification.cs new file mode 100644 index 0000000000..e0838f8c33 --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/AssignedUserGroupPermissionsNotification.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models.Membership; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public class AssignedUserGroupPermissionsNotification : EnumerableObjectNotification + { + public AssignedUserGroupPermissionsNotification(IEnumerable target, EventMessages messages) : base(target, messages) + { + } + + public IEnumerable EntityPermissions => Target; + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/ExportedMemberNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/ExportedMemberNotification.cs new file mode 100644 index 0000000000..449244242f --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/ExportedMemberNotification.cs @@ -0,0 +1,19 @@ +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.Membership; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public class ExportedMemberNotification : INotification + { + public ExportedMemberNotification(IMember member, MemberExportModel exported) + { + Member = member; + Exported = exported; + } + + public IMember Member { get; } + + public MemberExportModel Exported { get; } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/MemberRolesNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/MemberRolesNotification.cs new file mode 100644 index 0000000000..2b7c9bd828 --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/MemberRolesNotification.cs @@ -0,0 +1,17 @@ +using Umbraco.Cms.Core.Events; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public abstract class MemberRolesNotification : INotification + { + protected MemberRolesNotification(int[] memberIds, string[] roles) + { + MemberIds = memberIds; + Roles = roles; + } + + public int[] MemberIds { get; } + + public string[] Roles { get; } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/RemovedMemberRolesNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/RemovedMemberRolesNotification.cs new file mode 100644 index 0000000000..bd902cb078 --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/RemovedMemberRolesNotification.cs @@ -0,0 +1,10 @@ +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public class RemovedMemberRolesNotification : MemberRolesNotification + { + public RemovedMemberRolesNotification(int[] memberIds, string[] roles) : base(memberIds, roles) + { + + } + } +} From 239edaa9523993a2529ebf7ac7c6704a95d875f6 Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Tue, 9 Mar 2021 08:01:19 +0100 Subject: [PATCH 2/7] Missing file commit --- .../Security/BackOfficeUserManagerAuditer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.BackOffice/Security/BackOfficeUserManagerAuditer.cs b/src/Umbraco.Web.BackOffice/Security/BackOfficeUserManagerAuditer.cs index 6e67ee84ba..5af34d3b52 100644 --- a/src/Umbraco.Web.BackOffice/Security/BackOfficeUserManagerAuditer.cs +++ b/src/Umbraco.Web.BackOffice/Security/BackOfficeUserManagerAuditer.cs @@ -47,11 +47,11 @@ namespace Umbraco.Cms.Web.BackOffice.Security { if (!int.TryParse(userId, out int asInt)) { - return AuditEventsComponent.UnknownUser(_globalSettings); + return AuditNotificationsHandler.UnknownUser(_globalSettings); } IUser found = asInt >= 0 ? _userService.GetUserById(asInt) : null; - return found ?? AuditEventsComponent.UnknownUser(_globalSettings); + return found ?? AuditNotificationsHandler.UnknownUser(_globalSettings); } private static string FormatEmail(IMembershipUser user) => user == null ? string.Empty : user.Email.IsNullOrWhiteSpace() ? "" : $"<{user.Email}>"; From ef178c560671c2a2da284d45798c6b8d88435e1a Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Tue, 16 Mar 2021 09:21:27 +0100 Subject: [PATCH 3/7] Use explicitly typed notifications instead of generic ones --- .../Cache/DistributedCacheHandler.cs | 32 +++++++++---------- .../Compose/AuditNotificationsHandler.cs | 20 ++++++------ .../Compose/NotificationsComposer.cs | 32 +++++++++---------- .../Events/UserNotificationsHandler.cs | 4 +-- .../FileUploadPropertyEditor.cs | 4 +-- .../ImageCropperPropertyEditor.cs | 4 +-- .../Services/Implement/MemberService.cs | 14 ++++---- .../Services/Implement/PublicAccessService.cs | 16 +++++----- .../Services/Implement/UserService.cs | 28 ++++++++-------- .../MemberDeletedNotification.cs | 15 +++++++++ .../MemberDeletingNotification.cs | 20 ++++++++++++ .../Notifications/MemberSavedNotification.cs | 20 ++++++++++++ .../Notifications/MemberSavingNotification.cs | 20 ++++++++++++ .../PublicAccessEntryDeletedNotification.cs | 15 +++++++++ .../PublicAccessEntryDeletingNotification.cs | 20 ++++++++++++ .../PublicAccessEntrySavedNotification.cs | 20 ++++++++++++ .../PublicAccessEntrySavingNotification.cs | 20 ++++++++++++ .../Notifications/UserDeletedNotification.cs | 15 +++++++++ .../Notifications/UserDeletingNotification.cs | 20 ++++++++++++ .../UserGroupDeletedNotification.cs | 15 +++++++++ .../UserGroupDeletingNotification.cs | 20 ++++++++++++ .../UserGroupSavedNotification.cs | 20 ++++++++++++ .../UserGroupSavingNotification.cs | 20 ++++++++++++ .../UserGroupWithUsersSavedNotification.cs | 19 +++++++++++ .../UserGroupWithUsersSavingNotification.cs | 19 +++++++++++ .../Notifications/UserSavedNotification.cs | 20 ++++++++++++ .../Notifications/UserSavingNotification.cs | 20 ++++++++++++ 27 files changed, 415 insertions(+), 77 deletions(-) create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/MemberDeletedNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/MemberDeletingNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/MemberSavedNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/MemberSavingNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/PublicAccessEntryDeletedNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/PublicAccessEntryDeletingNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/PublicAccessEntrySavedNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/PublicAccessEntrySavingNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/UserDeletedNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/UserDeletingNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/UserGroupDeletedNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/UserGroupDeletingNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/UserGroupSavedNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/UserGroupSavingNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/UserGroupWithUsersSavedNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/UserGroupWithUsersSavingNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/UserSavedNotification.cs create mode 100644 src/Umbraco.Infrastructure/Services/Notifications/UserSavingNotification.cs diff --git a/src/Umbraco.Infrastructure/Cache/DistributedCacheHandler.cs b/src/Umbraco.Infrastructure/Cache/DistributedCacheHandler.cs index 648edaca68..793c78f68b 100644 --- a/src/Umbraco.Infrastructure/Cache/DistributedCacheHandler.cs +++ b/src/Umbraco.Infrastructure/Cache/DistributedCacheHandler.cs @@ -8,24 +8,24 @@ using Umbraco.Extensions; namespace Umbraco.Cms.Core.Cache { internal class DistributedCacheHandler : - INotificationHandler>, - INotificationHandler>, - INotificationHandler>, - INotificationHandler>, - INotificationHandler>, - INotificationHandler>, - INotificationHandler>, - INotificationHandler> + INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler { private readonly DistributedCache _distributedCache; public DistributedCacheHandler(DistributedCache distributedCache) => _distributedCache = distributedCache; - public void Handle(SavedNotification notification) => _distributedCache.RefreshMemberCache(notification.SavedEntities.ToArray()); + public void Handle(MemberSavedNotification notification) => _distributedCache.RefreshMemberCache(notification.SavedEntities.ToArray()); - public void Handle(DeletedNotification notification) => _distributedCache.RemoveMemberCache(notification.DeletedEntities.ToArray()); + public void Handle(MemberDeletedNotification notification) => _distributedCache.RemoveMemberCache(notification.DeletedEntities.ToArray()); - public void Handle(SavedNotification notification) + public void Handle(UserSavedNotification notification) { foreach (var entity in notification.SavedEntities) { @@ -33,7 +33,7 @@ namespace Umbraco.Cms.Core.Cache } } - public void Handle(DeletedNotification notification) + public void Handle(UserDeletedNotification notification) { foreach (var entity in notification.DeletedEntities) { @@ -41,7 +41,7 @@ namespace Umbraco.Cms.Core.Cache } } - public void Handle(SavedNotification notification) + public void Handle(UserGroupSavedNotification notification) { foreach (var entity in notification.SavedEntities) { @@ -49,7 +49,7 @@ namespace Umbraco.Cms.Core.Cache } } - public void Handle(DeletedNotification notification) + public void Handle(UserGroupDeletedNotification notification) { foreach (var entity in notification.DeletedEntities) { @@ -57,8 +57,8 @@ namespace Umbraco.Cms.Core.Cache } } - public void Handle(SavedNotification notification) => _distributedCache.RefreshPublicAccess(); + public void Handle(PublicAccessEntrySavedNotification notification) => _distributedCache.RefreshPublicAccess(); - public void Handle(DeletedNotification notification) => _distributedCache.RefreshPublicAccess(); + public void Handle(PublicAccessEntryDeletedNotification notification) => _distributedCache.RefreshPublicAccess(); } } diff --git a/src/Umbraco.Infrastructure/Compose/AuditNotificationsHandler.cs b/src/Umbraco.Infrastructure/Compose/AuditNotificationsHandler.cs index f152dd16cf..e2da324b56 100644 --- a/src/Umbraco.Infrastructure/Compose/AuditNotificationsHandler.cs +++ b/src/Umbraco.Infrastructure/Compose/AuditNotificationsHandler.cs @@ -15,14 +15,14 @@ using Umbraco.Extensions; namespace Umbraco.Cms.Core.Compose { public sealed class AuditNotificationsHandler : - INotificationHandler>, - INotificationHandler>, + INotificationHandler, + INotificationHandler, INotificationHandler, INotificationHandler, INotificationHandler, - INotificationHandler>, - INotificationHandler>, - INotificationHandler>, + INotificationHandler, + INotificationHandler, + INotificationHandler, INotificationHandler { private readonly IAuditService _auditService; @@ -69,7 +69,7 @@ namespace Umbraco.Cms.Core.Compose private string FormatEmail(IUser user) => user == null ? string.Empty : user.Email.IsNullOrWhiteSpace() ? "" : $"<{user.Email}>"; - public void Handle(SavedNotification notification) + public void Handle(MemberSavedNotification notification) { var performingUser = CurrentPerformingUser; var members = notification.SavedEntities; @@ -84,7 +84,7 @@ namespace Umbraco.Cms.Core.Compose } } - public void Handle(DeletedNotification notification) + public void Handle(MemberDeletedNotification notification) { var performingUser = CurrentPerformingUser; var members = notification.DeletedEntities; @@ -138,7 +138,7 @@ namespace Umbraco.Cms.Core.Compose "umbraco/member/exported", "exported member data"); } - public void Handle(SavedNotification notification) + public void Handle(UserSavedNotification notification) { var performingUser = CurrentPerformingUser; var affectedUsers = notification.SavedEntities; @@ -157,7 +157,7 @@ namespace Umbraco.Cms.Core.Compose } } - public void Handle(DeletedNotification notification) + public void Handle(UserDeletedNotification notification) { var performingUser = CurrentPerformingUser; var affectedUsers = notification.DeletedEntities; @@ -168,7 +168,7 @@ namespace Umbraco.Cms.Core.Compose "umbraco/user/delete", "delete user"); } - public void Handle(SavedNotification notification) + public void Handle(UserGroupWithUsersSavedNotification notification) { var performingUser = CurrentPerformingUser; foreach (var groupWithUser in notification.SavedEntities) diff --git a/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs b/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs index e79cef4cb1..d973254659 100644 --- a/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs +++ b/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs @@ -31,7 +31,7 @@ namespace Umbraco.Cms.Core.Compose .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() - .AddNotificationHandler, UserNotificationsHandler>(); + .AddNotificationHandler(); // add handlers for building content relations builder @@ -51,12 +51,12 @@ namespace Umbraco.Cms.Core.Compose .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() - .AddNotificationHandler, FileUploadPropertyEditor>() + .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() - .AddNotificationHandler, ImageCropperPropertyEditor>(); + .AddNotificationHandler(); // add notification handlers for redirect tracking builder @@ -67,26 +67,26 @@ namespace Umbraco.Cms.Core.Compose // add notification handlers for auditing builder - .AddNotificationHandler, AuditNotificationsHandler>() - .AddNotificationHandler, AuditNotificationsHandler>() + .AddNotificationHandler() + .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() - .AddNotificationHandler, AuditNotificationsHandler>() - .AddNotificationHandler, AuditNotificationsHandler>() - .AddNotificationHandler, AuditNotificationsHandler>() + .AddNotificationHandler() + .AddNotificationHandler() + .AddNotificationHandler() .AddNotificationHandler(); // add notifications handlers for distributed cache builder - .AddNotificationHandler, DistributedCacheHandler>() - .AddNotificationHandler, DistributedCacheHandler>() - .AddNotificationHandler, DistributedCacheHandler>() - .AddNotificationHandler, DistributedCacheHandler>() - .AddNotificationHandler, DistributedCacheHandler>() - .AddNotificationHandler, DistributedCacheHandler>() - .AddNotificationHandler, DistributedCacheHandler>() - .AddNotificationHandler, DistributedCacheHandler>(); + .AddNotificationHandler() + .AddNotificationHandler() + .AddNotificationHandler() + .AddNotificationHandler() + .AddNotificationHandler() + .AddNotificationHandler() + .AddNotificationHandler() + .AddNotificationHandler(); } } } diff --git a/src/Umbraco.Infrastructure/Events/UserNotificationsHandler.cs b/src/Umbraco.Infrastructure/Events/UserNotificationsHandler.cs index 719692e38d..933a0fc890 100644 --- a/src/Umbraco.Infrastructure/Events/UserNotificationsHandler.cs +++ b/src/Umbraco.Infrastructure/Events/UserNotificationsHandler.cs @@ -31,7 +31,7 @@ namespace Umbraco.Cms.Core.Events INotificationHandler, INotificationHandler, INotificationHandler, - INotificationHandler> + INotificationHandler { private readonly Notifier _notifier; private readonly ActionCollection _actions; @@ -225,7 +225,7 @@ namespace Umbraco.Cms.Core.Events } - public void Handle(SavedNotification notification) + public void Handle(PublicAccessEntrySavedNotification notification) { var entities = _contentService.GetByIds(notification.SavedEntities.Select(e => e.ProtectedNodeId)).ToArray(); if (entities.Any() == false) diff --git a/src/Umbraco.Infrastructure/PropertyEditors/FileUploadPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/FileUploadPropertyEditor.cs index 33c31b6ee4..a794d62ce2 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/FileUploadPropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/FileUploadPropertyEditor.cs @@ -28,7 +28,7 @@ namespace Umbraco.Cms.Core.PropertyEditors public class FileUploadPropertyEditor : DataEditor, IMediaUrlGenerator, INotificationHandler, INotificationHandler, INotificationHandler, INotificationHandler, - INotificationHandler> + INotificationHandler { private readonly IMediaFileSystem _mediaFileSystem; private readonly ContentSettings _contentSettings; @@ -160,7 +160,7 @@ namespace Umbraco.Cms.Core.PropertyEditors public void Handle(MediaDeletedNotification notification) => DeleteContainedFiles(notification.DeletedEntities); - public void Handle(DeletedNotification notification) => DeleteContainedFiles(notification.DeletedEntities); + public void Handle(MemberDeletedNotification notification) => DeleteContainedFiles(notification.DeletedEntities); private void DeleteContainedFiles(IEnumerable deletedEntities) { diff --git a/src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyEditor.cs index e96e8582a9..902cb32f08 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyEditor.cs @@ -35,7 +35,7 @@ namespace Umbraco.Cms.Core.PropertyEditors public class ImageCropperPropertyEditor : DataEditor, IMediaUrlGenerator, INotificationHandler, INotificationHandler, INotificationHandler, INotificationHandler, - INotificationHandler> + INotificationHandler { private readonly IMediaFileSystem _mediaFileSystem; private readonly ContentSettings _contentSettings; @@ -216,7 +216,7 @@ namespace Umbraco.Cms.Core.PropertyEditors public void Handle(MediaDeletedNotification notification) => DeleteContainedFiles(notification.DeletedEntities); - public void Handle(DeletedNotification notification) => DeleteContainedFiles(notification.DeletedEntities); + public void Handle(MemberDeletedNotification notification) => DeleteContainedFiles(notification.DeletedEntities); private void DeleteContainedFiles(IEnumerable deletedEntities) { diff --git a/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs b/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs index 026052fa67..fd5c9480a7 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs @@ -777,7 +777,7 @@ namespace Umbraco.Cms.Core.Services.Implement using (IScope scope = ScopeProvider.CreateScope()) { - var savingNotification = new SavingNotification(member, evtMsgs); + var savingNotification = new MemberSavingNotification(member, evtMsgs); if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); @@ -795,7 +795,7 @@ namespace Umbraco.Cms.Core.Services.Implement if (raiseEvents) { - scope.Notifications.Publish(new SavedNotification(member, evtMsgs).WithStateFrom(savingNotification)); + scope.Notifications.Publish(new MemberSavedNotification(member, evtMsgs).WithStateFrom(savingNotification)); } Audit(AuditType.Save, 0, member.Id); @@ -813,7 +813,7 @@ namespace Umbraco.Cms.Core.Services.Implement using (var scope = ScopeProvider.CreateScope()) { - var savingNotification = new SavingNotification(membersA, evtMsgs); + var savingNotification = new MemberSavingNotification(membersA, evtMsgs); if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); @@ -833,7 +833,7 @@ namespace Umbraco.Cms.Core.Services.Implement if (raiseEvents) { - scope.Notifications.Publish(new SavedNotification(membersA, evtMsgs).WithStateFrom(savingNotification)); + scope.Notifications.Publish(new MemberSavedNotification(membersA, evtMsgs).WithStateFrom(savingNotification)); } Audit(AuditType.Save, 0, -1, "Save multiple Members"); @@ -855,7 +855,7 @@ namespace Umbraco.Cms.Core.Services.Implement using (var scope = ScopeProvider.CreateScope()) { - var deletingNotification = new DeletingNotification(member, evtMsgs); + var deletingNotification = new MemberDeletingNotification(member, evtMsgs); if (scope.Notifications.PublishCancelable(deletingNotification)) { scope.Complete(); @@ -874,7 +874,7 @@ namespace Umbraco.Cms.Core.Services.Implement { // a member has no descendants _memberRepository.Delete(member); - scope.Notifications.Publish(new DeletedNotification(member, evtMsgs).WithState(notificationState)); + scope.Notifications.Publish(new MemberDeletedNotification(member, evtMsgs).WithState(notificationState)); // media files deleted by QueuingEventDispatcher } @@ -1165,7 +1165,7 @@ namespace Umbraco.Cms.Core.Services.Implement IMember[] members = _memberRepository.Get(query).ToArray(); - if (scope.Notifications.PublishCancelable(new DeletingNotification(members, evtMsgs))) + if (scope.Notifications.PublishCancelable(new MemberDeletingNotification(members, evtMsgs))) { scope.Complete(); return; diff --git a/src/Umbraco.Infrastructure/Services/Implement/PublicAccessService.cs b/src/Umbraco.Infrastructure/Services/Implement/PublicAccessService.cs index 57df102620..b79b0ec0ab 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/PublicAccessService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/PublicAccessService.cs @@ -128,7 +128,7 @@ namespace Umbraco.Cms.Core.Services.Implement return OperationResult.Attempt.Succeed(evtMsgs, entry); } - var savingNotifiation = new SavingNotification(entry, evtMsgs); + var savingNotifiation = new PublicAccessEntrySavingNotification(entry, evtMsgs); if (scope.Notifications.PublishCancelable(savingNotifiation)) { scope.Complete(); @@ -139,7 +139,7 @@ namespace Umbraco.Cms.Core.Services.Implement scope.Complete(); - scope.Notifications.Publish(new SavedNotification(entry, evtMsgs).WithStateFrom(savingNotifiation)); + scope.Notifications.Publish(new PublicAccessEntrySavedNotification(entry, evtMsgs).WithStateFrom(savingNotifiation)); } return OperationResult.Attempt.Succeed(evtMsgs, entry); @@ -165,7 +165,7 @@ namespace Umbraco.Cms.Core.Services.Implement entry.RemoveRule(existingRule); - var savingNotifiation = new SavingNotification(entry, evtMsgs); + var savingNotifiation = new PublicAccessEntrySavingNotification(entry, evtMsgs); if (scope.Notifications.PublishCancelable(savingNotifiation)) { scope.Complete(); @@ -175,7 +175,7 @@ namespace Umbraco.Cms.Core.Services.Implement _publicAccessRepository.Save(entry); scope.Complete(); - scope.Notifications.Publish(new SavedNotification(entry, evtMsgs).WithStateFrom(savingNotifiation)); + scope.Notifications.Publish(new PublicAccessEntrySavedNotification(entry, evtMsgs).WithStateFrom(savingNotifiation)); } return OperationResult.Attempt.Succeed(evtMsgs); @@ -191,7 +191,7 @@ namespace Umbraco.Cms.Core.Services.Implement using (var scope = ScopeProvider.CreateScope()) { - var savingNotifiation = new SavingNotification(entry, evtMsgs); + var savingNotifiation = new PublicAccessEntrySavingNotification(entry, evtMsgs); if (scope.Notifications.PublishCancelable(savingNotifiation)) { scope.Complete(); @@ -201,7 +201,7 @@ namespace Umbraco.Cms.Core.Services.Implement _publicAccessRepository.Save(entry); scope.Complete(); - scope.Notifications.Publish(new SavedNotification(entry, evtMsgs).WithStateFrom(savingNotifiation)); + scope.Notifications.Publish(new PublicAccessEntrySavedNotification(entry, evtMsgs).WithStateFrom(savingNotifiation)); } return OperationResult.Attempt.Succeed(evtMsgs); @@ -217,7 +217,7 @@ namespace Umbraco.Cms.Core.Services.Implement using (var scope = ScopeProvider.CreateScope()) { - var deletingNotification = new DeletingNotification(entry, evtMsgs); + var deletingNotification = new PublicAccessEntryDeletingNotification(entry, evtMsgs); if (scope.Notifications.PublishCancelable(deletingNotification)) { scope.Complete(); @@ -227,7 +227,7 @@ namespace Umbraco.Cms.Core.Services.Implement _publicAccessRepository.Delete(entry); scope.Complete(); - scope.Notifications.Publish(new DeletedNotification(entry, evtMsgs).WithStateFrom(deletingNotification)); + scope.Notifications.Publish(new PublicAccessEntryDeletedNotification(entry, evtMsgs).WithStateFrom(deletingNotification)); } return OperationResult.Attempt.Succeed(evtMsgs); diff --git a/src/Umbraco.Infrastructure/Services/Implement/UserService.cs b/src/Umbraco.Infrastructure/Services/Implement/UserService.cs index 3336ba37a3..4fbe579ca3 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/UserService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/UserService.cs @@ -132,7 +132,7 @@ namespace Umbraco.Cms.Core.Services.Implement IsApproved = isApproved }; - var savingNotification = new SavingNotification(user, evtMsgs); + var savingNotification = new UserSavingNotification(user, evtMsgs); if (scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); @@ -141,7 +141,7 @@ namespace Umbraco.Cms.Core.Services.Implement _userRepository.Save(user); - scope.Notifications.Publish(new SavedNotification(user, evtMsgs).WithStateFrom(savingNotification)); + scope.Notifications.Publish(new UserSavedNotification(user, evtMsgs).WithStateFrom(savingNotification)); scope.Complete(); } @@ -245,7 +245,7 @@ namespace Umbraco.Cms.Core.Services.Implement using (var scope = ScopeProvider.CreateScope()) { - var deletingNotification = new DeletingNotification(user, evtMsgs); + var deletingNotification = new UserDeletingNotification(user, evtMsgs); if (scope.Notifications.PublishCancelable(deletingNotification)) { scope.Complete(); @@ -254,7 +254,7 @@ namespace Umbraco.Cms.Core.Services.Implement _userRepository.Delete(user); - scope.Notifications.Publish(new DeletedNotification(user, evtMsgs).WithStateFrom(deletingNotification)); + scope.Notifications.Publish(new UserDeletedNotification(user, evtMsgs).WithStateFrom(deletingNotification)); scope.Complete(); } } @@ -279,7 +279,7 @@ namespace Umbraco.Cms.Core.Services.Implement using (var scope = ScopeProvider.CreateScope()) { - var savingNotification = new SavingNotification(entity, evtMsgs); + var savingNotification = new UserSavingNotification(entity, evtMsgs); if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); @@ -297,7 +297,7 @@ namespace Umbraco.Cms.Core.Services.Implement _userRepository.Save(entity); if (raiseEvents) { - scope.Notifications.Publish(new SavedNotification(entity, evtMsgs).WithStateFrom(savingNotification)); + scope.Notifications.Publish(new UserSavedNotification(entity, evtMsgs).WithStateFrom(savingNotification)); } scope.Complete(); @@ -329,7 +329,7 @@ namespace Umbraco.Cms.Core.Services.Implement using (var scope = ScopeProvider.CreateScope()) { - var savingNotification = new SavingNotification(entitiesA, evtMsgs); + var savingNotification = new UserSavingNotification(entitiesA, evtMsgs); if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); @@ -350,7 +350,7 @@ namespace Umbraco.Cms.Core.Services.Implement if (raiseEvents) { - scope.Notifications.Publish(new SavedNotification(entitiesA, evtMsgs).WithStateFrom(savingNotification)); + scope.Notifications.Publish(new UserSavedNotification(entitiesA, evtMsgs).WithStateFrom(savingNotification)); } //commit the whole lot in one go @@ -840,7 +840,7 @@ namespace Umbraco.Cms.Core.Services.Implement var userGroupWithUsers = new UserGroupWithUsers(userGroup, addedUsers, removedUsers); // this is the default/expected notification for the IUserGroup entity being saved - var savingNotification = new SavingNotification(userGroup, evtMsgs); + var savingNotification = new UserGroupSavingNotification(userGroup, evtMsgs); if (raiseEvents && scope.Notifications.PublishCancelable(savingNotification)) { scope.Complete(); @@ -848,7 +848,7 @@ namespace Umbraco.Cms.Core.Services.Implement } // this is an additional notification for special auditing - var savingUserGroupWithUsersNotification = new SavingNotification(userGroupWithUsers, evtMsgs); + var savingUserGroupWithUsersNotification = new UserGroupWithUsersSavingNotification(userGroupWithUsers, evtMsgs); if (raiseEvents && scope.Notifications.PublishCancelable(savingUserGroupWithUsersNotification)) { scope.Complete(); @@ -859,8 +859,8 @@ namespace Umbraco.Cms.Core.Services.Implement if (raiseEvents) { - scope.Notifications.Publish(new SavedNotification(userGroup, evtMsgs).WithStateFrom(savingNotification)); - scope.Notifications.Publish(new SavedNotification(userGroupWithUsers, evtMsgs).WithStateFrom(savingUserGroupWithUsersNotification)); + scope.Notifications.Publish(new UserGroupSavedNotification(userGroup, evtMsgs).WithStateFrom(savingNotification)); + scope.Notifications.Publish(new UserGroupWithUsersSavedNotification(userGroupWithUsers, evtMsgs).WithStateFrom(savingUserGroupWithUsersNotification)); } scope.Complete(); @@ -877,7 +877,7 @@ namespace Umbraco.Cms.Core.Services.Implement using (var scope = ScopeProvider.CreateScope()) { - var deletingNotification = new DeletingNotification(userGroup, evtMsgs); + var deletingNotification = new UserGroupDeletingNotification(userGroup, evtMsgs); if (scope.Notifications.PublishCancelable(deletingNotification)) { scope.Complete(); @@ -886,7 +886,7 @@ namespace Umbraco.Cms.Core.Services.Implement _userGroupRepository.Delete(userGroup); - scope.Notifications.Publish(new DeletedNotification(userGroup, evtMsgs).WithStateFrom(deletingNotification)); + scope.Notifications.Publish(new UserGroupDeletedNotification(userGroup, evtMsgs).WithStateFrom(deletingNotification)); scope.Complete(); } diff --git a/src/Umbraco.Infrastructure/Services/Notifications/MemberDeletedNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/MemberDeletedNotification.cs new file mode 100644 index 0000000000..41edd5371e --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/MemberDeletedNotification.cs @@ -0,0 +1,15 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public sealed class MemberDeletedNotification : DeletedNotification + { + public MemberDeletedNotification(IMember target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/MemberDeletingNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/MemberDeletingNotification.cs new file mode 100644 index 0000000000..4a4cd585c5 --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/MemberDeletingNotification.cs @@ -0,0 +1,20 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using System.Collections.Generic; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public sealed class MemberDeletingNotification : DeletingNotification + { + public MemberDeletingNotification(IMember target, EventMessages messages) : base(target, messages) + { + } + + public MemberDeletingNotification(IEnumerable target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/MemberSavedNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/MemberSavedNotification.cs new file mode 100644 index 0000000000..6ea4e38870 --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/MemberSavedNotification.cs @@ -0,0 +1,20 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using System.Collections.Generic; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public sealed class MemberSavedNotification : SavedNotification + { + public MemberSavedNotification(IMember target, EventMessages messages) : base(target, messages) + { + } + + public MemberSavedNotification(IEnumerable target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/MemberSavingNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/MemberSavingNotification.cs new file mode 100644 index 0000000000..8496731304 --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/MemberSavingNotification.cs @@ -0,0 +1,20 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using System.Collections.Generic; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public sealed class MemberSavingNotification : SavingNotification + { + public MemberSavingNotification(IMember target, EventMessages messages) : base(target, messages) + { + } + + public MemberSavingNotification(IEnumerable target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/PublicAccessEntryDeletedNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/PublicAccessEntryDeletedNotification.cs new file mode 100644 index 0000000000..03f48dff5c --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/PublicAccessEntryDeletedNotification.cs @@ -0,0 +1,15 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public sealed class PublicAccessEntryDeletedNotification : DeletedNotification + { + public PublicAccessEntryDeletedNotification(PublicAccessEntry target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/PublicAccessEntryDeletingNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/PublicAccessEntryDeletingNotification.cs new file mode 100644 index 0000000000..521a86caff --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/PublicAccessEntryDeletingNotification.cs @@ -0,0 +1,20 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using System.Collections.Generic; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public sealed class PublicAccessEntryDeletingNotification : DeletingNotification + { + public PublicAccessEntryDeletingNotification(PublicAccessEntry target, EventMessages messages) : base(target, messages) + { + } + + public PublicAccessEntryDeletingNotification(IEnumerable target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/PublicAccessEntrySavedNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/PublicAccessEntrySavedNotification.cs new file mode 100644 index 0000000000..ec1781a3d4 --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/PublicAccessEntrySavedNotification.cs @@ -0,0 +1,20 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using System.Collections.Generic; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public sealed class PublicAccessEntrySavedNotification : SavedNotification + { + public PublicAccessEntrySavedNotification(PublicAccessEntry target, EventMessages messages) : base(target, messages) + { + } + + public PublicAccessEntrySavedNotification(IEnumerable target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/PublicAccessEntrySavingNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/PublicAccessEntrySavingNotification.cs new file mode 100644 index 0000000000..63f4a490a3 --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/PublicAccessEntrySavingNotification.cs @@ -0,0 +1,20 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using System.Collections.Generic; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public sealed class PublicAccessEntrySavingNotification : SavingNotification + { + public PublicAccessEntrySavingNotification(PublicAccessEntry target, EventMessages messages) : base(target, messages) + { + } + + public PublicAccessEntrySavingNotification(IEnumerable target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/UserDeletedNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/UserDeletedNotification.cs new file mode 100644 index 0000000000..3173647652 --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/UserDeletedNotification.cs @@ -0,0 +1,15 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models.Membership; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public sealed class UserDeletedNotification : DeletedNotification + { + public UserDeletedNotification(IUser target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/UserDeletingNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/UserDeletingNotification.cs new file mode 100644 index 0000000000..1f57755a5a --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/UserDeletingNotification.cs @@ -0,0 +1,20 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using System.Collections.Generic; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models.Membership; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public sealed class UserDeletingNotification : DeletingNotification + { + public UserDeletingNotification(IUser target, EventMessages messages) : base(target, messages) + { + } + + public UserDeletingNotification(IEnumerable target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/UserGroupDeletedNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/UserGroupDeletedNotification.cs new file mode 100644 index 0000000000..a9c51dc72d --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/UserGroupDeletedNotification.cs @@ -0,0 +1,15 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models.Membership; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public sealed class UserGroupDeletedNotification : DeletedNotification + { + public UserGroupDeletedNotification(IUserGroup target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/UserGroupDeletingNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/UserGroupDeletingNotification.cs new file mode 100644 index 0000000000..c176e55456 --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/UserGroupDeletingNotification.cs @@ -0,0 +1,20 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using System.Collections.Generic; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models.Membership; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public sealed class UserGroupDeletingNotification : DeletingNotification + { + public UserGroupDeletingNotification(IUserGroup target, EventMessages messages) : base(target, messages) + { + } + + public UserGroupDeletingNotification(IEnumerable target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/UserGroupSavedNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/UserGroupSavedNotification.cs new file mode 100644 index 0000000000..b542b35b26 --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/UserGroupSavedNotification.cs @@ -0,0 +1,20 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using System.Collections.Generic; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models.Membership; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public sealed class UserGroupSavedNotification : SavedNotification + { + public UserGroupSavedNotification(IUserGroup target, EventMessages messages) : base(target, messages) + { + } + + public UserGroupSavedNotification(IEnumerable target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/UserGroupSavingNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/UserGroupSavingNotification.cs new file mode 100644 index 0000000000..136b2da6a5 --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/UserGroupSavingNotification.cs @@ -0,0 +1,20 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using System.Collections.Generic; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models.Membership; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public sealed class UserGroupSavingNotification : SavingNotification + { + public UserGroupSavingNotification(IUserGroup target, EventMessages messages) : base(target, messages) + { + } + + public UserGroupSavingNotification(IEnumerable target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/UserGroupWithUsersSavedNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/UserGroupWithUsersSavedNotification.cs new file mode 100644 index 0000000000..22e0d67d06 --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/UserGroupWithUsersSavedNotification.cs @@ -0,0 +1,19 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using System.Collections.Generic; +using Umbraco.Cms.Core.Events; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public sealed class UserGroupWithUsersSavedNotification : SavedNotification + { + public UserGroupWithUsersSavedNotification(UserGroupWithUsers target, EventMessages messages) : base(target, messages) + { + } + + public UserGroupWithUsersSavedNotification(IEnumerable target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/UserGroupWithUsersSavingNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/UserGroupWithUsersSavingNotification.cs new file mode 100644 index 0000000000..c61087038a --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/UserGroupWithUsersSavingNotification.cs @@ -0,0 +1,19 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using System.Collections.Generic; +using Umbraco.Cms.Core.Events; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public sealed class UserGroupWithUsersSavingNotification : SavingNotification + { + public UserGroupWithUsersSavingNotification(UserGroupWithUsers target, EventMessages messages) : base(target, messages) + { + } + + public UserGroupWithUsersSavingNotification(IEnumerable target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/UserSavedNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/UserSavedNotification.cs new file mode 100644 index 0000000000..850085ae90 --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/UserSavedNotification.cs @@ -0,0 +1,20 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using System.Collections.Generic; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models.Membership; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public sealed class UserSavedNotification : SavedNotification + { + public UserSavedNotification(IUser target, EventMessages messages) : base(target, messages) + { + } + + public UserSavedNotification(IEnumerable target, EventMessages messages) : base(target, messages) + { + } + } +} diff --git a/src/Umbraco.Infrastructure/Services/Notifications/UserSavingNotification.cs b/src/Umbraco.Infrastructure/Services/Notifications/UserSavingNotification.cs new file mode 100644 index 0000000000..0b062c33f1 --- /dev/null +++ b/src/Umbraco.Infrastructure/Services/Notifications/UserSavingNotification.cs @@ -0,0 +1,20 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using System.Collections.Generic; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models.Membership; + +namespace Umbraco.Cms.Infrastructure.Services.Notifications +{ + public sealed class UserSavingNotification : SavingNotification + { + public UserSavingNotification(IUser target, EventMessages messages) : base(target, messages) + { + } + + public UserSavingNotification(IEnumerable target, EventMessages messages) : base(target, messages) + { + } + } +} From 152dc7a5b9d6d80911e50cdb570249997d25d5d8 Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Tue, 16 Mar 2021 09:59:44 +0100 Subject: [PATCH 4/7] A little reformatting and removal of unused usings --- src/Umbraco.Infrastructure/Cache/DistributedCacheHandler.cs | 2 -- src/Umbraco.Infrastructure/Events/UserNotificationsHandler.cs | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/Umbraco.Infrastructure/Cache/DistributedCacheHandler.cs b/src/Umbraco.Infrastructure/Cache/DistributedCacheHandler.cs index 793c78f68b..a72b37c189 100644 --- a/src/Umbraco.Infrastructure/Cache/DistributedCacheHandler.cs +++ b/src/Umbraco.Infrastructure/Cache/DistributedCacheHandler.cs @@ -1,7 +1,5 @@ using System.Linq; using Umbraco.Cms.Core.Events; -using Umbraco.Cms.Core.Models; -using Umbraco.Cms.Core.Models.Membership; using Umbraco.Cms.Infrastructure.Services.Notifications; using Umbraco.Extensions; diff --git a/src/Umbraco.Infrastructure/Events/UserNotificationsHandler.cs b/src/Umbraco.Infrastructure/Events/UserNotificationsHandler.cs index 933a0fc890..3df16dda25 100644 --- a/src/Umbraco.Infrastructure/Events/UserNotificationsHandler.cs +++ b/src/Umbraco.Infrastructure/Events/UserNotificationsHandler.cs @@ -211,7 +211,6 @@ namespace Umbraco.Cms.Core.Events })); } } - } public void Handle(AssignedUserGroupPermissionsNotification notification) @@ -222,7 +221,6 @@ namespace Umbraco.Cms.Core.Events return; } _notifier.Notify(_actions.GetAction(), entities); - } public void Handle(PublicAccessEntrySavedNotification notification) From 3018e1ba894da6b9523f5b3cb94a2c399b1207f3 Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Tue, 16 Mar 2021 16:45:26 +0100 Subject: [PATCH 5/7] Removed events from integration test --- .../Cache/DistributedCacheBinderTests.cs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/Umbraco.Tests.Integration/Cache/DistributedCacheBinderTests.cs b/src/Umbraco.Tests.Integration/Cache/DistributedCacheBinderTests.cs index 9b8a1e9c98..8fbe858294 100644 --- a/src/Umbraco.Tests.Integration/Cache/DistributedCacheBinderTests.cs +++ b/src/Umbraco.Tests.Integration/Cache/DistributedCacheBinderTests.cs @@ -5,7 +5,6 @@ using NUnit.Framework; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; -using Umbraco.Cms.Core.Models.Membership; using Umbraco.Cms.Core.Routing; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Web; @@ -18,7 +17,6 @@ namespace Umbraco.Cms.Tests.Integration.Cache [UmbracoTest(Boot = true)] public class DistributedCacheBinderTests : UmbracoIntegrationTest { - private IUserService UserService => GetRequiredService(); private ILocalizationService LocalizationService => GetRequiredService(); private IDataTypeService DataTypeService => GetRequiredService(); private IFileService FileService => GetRequiredService(); @@ -27,11 +25,7 @@ namespace Umbraco.Cms.Tests.Integration.Cache private IDomainService DomainService => GetRequiredService(); private IMemberTypeService MemberTypeService => GetRequiredService(); private IMacroService MacroService => GetRequiredService(); - private IMemberService MemberService => GetRequiredService(); private IMemberGroupService MemberGroupService => GetRequiredService(); - private IMediaService MediaService => GetRequiredService(); - private IContentService ContentService => GetRequiredService(); - private IPublicAccessService PublicAccessService => GetRequiredService(); private IRelationService RelationService => GetRequiredService(); private UriUtility UriUtility => GetRequiredService(); private IUmbracoContextFactory UmbracoContextFactory => GetRequiredService(); @@ -42,11 +36,6 @@ namespace Umbraco.Cms.Tests.Integration.Cache var definitions = new IEventDefinition[] { - new EventDefinition>(null, UserService, new SaveEventArgs(Enumerable.Empty())), - new EventDefinition>(null, UserService, new DeleteEventArgs(Enumerable.Empty())), - new EventDefinition>(null, UserService, new SaveEventArgs(Enumerable.Empty())), - new EventDefinition>(null, UserService, new DeleteEventArgs(Enumerable.Empty())), - new EventDefinition>(null, LocalizationService, new SaveEventArgs(Enumerable.Empty())), new EventDefinition>(null, LocalizationService, new DeleteEventArgs(Enumerable.Empty())), @@ -76,9 +65,6 @@ namespace Umbraco.Cms.Tests.Integration.Cache new EventDefinition>(null, MacroService, new SaveEventArgs(Enumerable.Empty())), new EventDefinition>(null, MacroService, new DeleteEventArgs(Enumerable.Empty())), - new EventDefinition>(null, MemberService, new SaveEventArgs(Enumerable.Empty())), - new EventDefinition>(null, MemberService, new DeleteEventArgs(Enumerable.Empty())), - new EventDefinition>(null, MemberGroupService, new SaveEventArgs(Enumerable.Empty())), new EventDefinition>(null, MemberGroupService, new DeleteEventArgs(Enumerable.Empty())), @@ -86,9 +72,6 @@ namespace Umbraco.Cms.Tests.Integration.Cache //new EventDefinition>(null, ContentService, new SaveEventArgs(Enumerable.Empty()), "SavedBlueprint"), //new EventDefinition>(null, ContentService, new DeleteEventArgs(Enumerable.Empty()), "DeletedBlueprint"), - new EventDefinition>(null, PublicAccessService, new SaveEventArgs(Enumerable.Empty())), - new EventDefinition>(null, PublicAccessService, new DeleteEventArgs(Enumerable.Empty())), - new EventDefinition>(null, RelationService, new SaveEventArgs(Enumerable.Empty())), new EventDefinition>(null, RelationService, new DeleteEventArgs(Enumerable.Empty())), From 7a5af55cac938e28ea2ff7c7ad970f7c241bbbd3 Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Wed, 17 Mar 2021 12:47:16 +0100 Subject: [PATCH 6/7] Reintroduce and obsolete static events for use in the distributed cache + added some accidentally removed scope completions --- .../Cache/DistributedCacheBinder_Handlers.cs | 77 +++++++++++++++++++ .../Cache/DistributedCacheHandler.cs | 62 --------------- .../Compose/NotificationsComposer.cs | 11 --- .../Services/Implement/MemberService.cs | 16 +++- .../Services/Implement/PublicAccessService.cs | 10 +++ .../Services/Implement/UserService.cs | 18 +++++ .../Cache/DistributedCacheBinderTests.cs | 17 ++++ 7 files changed, 134 insertions(+), 77 deletions(-) delete mode 100644 src/Umbraco.Infrastructure/Cache/DistributedCacheHandler.cs diff --git a/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs b/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs index ae6b6f135b..d6fff0f99d 100644 --- a/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs +++ b/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs @@ -49,6 +49,16 @@ namespace Umbraco.Cms.Core.Cache _logger.LogInformation("Initializing Umbraco internal event handlers for cache refreshing."); + // bind to user and user group events + Bind(() => UserService.SavedUserGroup += UserService_SavedUserGroup, + () => UserService.SavedUserGroup -= UserService_SavedUserGroup); + Bind(() => UserService.DeletedUserGroup += UserService_DeletedUserGroup, + () => UserService.DeletedUserGroup -= UserService_DeletedUserGroup); + Bind(() => UserService.SavedUser += UserService_SavedUser, + () => UserService.SavedUser -= UserService_SavedUser); + Bind(() => UserService.DeletedUser += UserService_DeletedUser, + () => UserService.DeletedUser -= UserService_DeletedUser); + // bind to dictionary events Bind(() => LocalizationService.DeletedDictionaryItem += LocalizationService_DeletedDictionaryItem, () => LocalizationService.DeletedDictionaryItem -= LocalizationService_DeletedDictionaryItem); @@ -100,6 +110,10 @@ namespace Umbraco.Cms.Core.Cache () => MacroService.Deleted -= MacroService_Deleted); // bind to member events + Bind(() => MemberService.Saved += MemberService_Saved, + () => MemberService.Saved -= MemberService_Saved); + Bind(() => MemberService.Deleted += MemberService_Deleted, + () => MemberService.Deleted -= MemberService_Deleted); Bind(() => MemberGroupService.Saved += MemberGroupService_Saved, () => MemberGroupService.Saved -= MemberGroupService_Saved); Bind(() => MemberGroupService.Deleted += MemberGroupService_Deleted, @@ -119,6 +133,12 @@ namespace Umbraco.Cms.Core.Cache //Bind(() => ContentService.DeletedBlueprint += ContentService_DeletedBlueprint, // () => ContentService.DeletedBlueprint -= ContentService_DeletedBlueprint); + // bind to public access events + Bind(() => PublicAccessService.Saved += PublicAccessService_Saved, + () => PublicAccessService.Saved -= PublicAccessService_Saved); + Bind(() => PublicAccessService.Deleted += PublicAccessService_Deleted, + () => PublicAccessService.Deleted -= PublicAccessService_Deleted); + // bind to relation type events Bind(() => RelationService.SavedRelationType += RelationService_SavedRelationType, () => RelationService.SavedRelationType -= RelationService_SavedRelationType); @@ -126,6 +146,20 @@ namespace Umbraco.Cms.Core.Cache () => RelationService.DeletedRelationType -= RelationService_DeletedRelationType); } + #region PublicAccessService + + private void PublicAccessService_Saved(IPublicAccessService sender, SaveEventArgs e) + { + _distributedCache.RefreshPublicAccess(); + } + + private void PublicAccessService_Deleted(IPublicAccessService sender, DeleteEventArgs e) + { + _distributedCache.RefreshPublicAccess(); + } + + #endregion + #region ContentService /// @@ -259,6 +293,35 @@ namespace Umbraco.Cms.Core.Cache #endregion + #region UserService + + private void UserService_SavedUser(IUserService sender, SaveEventArgs e) + { + foreach (var entity in e.SavedEntities) + _distributedCache.RefreshUserCache(entity.Id); + } + + private void UserService_DeletedUser(IUserService sender, DeleteEventArgs e) + { + foreach (var entity in e.DeletedEntities) + _distributedCache.RemoveUserCache(entity.Id); + } + + private void UserService_SavedUserGroup(IUserService sender, SaveEventArgs e) + { + foreach (var entity in e.SavedEntities) + _distributedCache.RefreshUserGroupCache(entity.UserGroup.Id); + } + + private void UserService_DeletedUserGroup(IUserService sender, DeleteEventArgs e) + { + + foreach (var entity in e.DeletedEntities) + _distributedCache.RemoveUserGroupCache(entity.Id); + } + + #endregion + #region FileService /// @@ -314,6 +377,20 @@ namespace Umbraco.Cms.Core.Cache #endregion + #region MemberService + + private void MemberService_Deleted(IMemberService sender, DeleteEventArgs e) + { + _distributedCache.RemoveMemberCache(e.DeletedEntities.ToArray()); + } + + private void MemberService_Saved(IMemberService sender, SaveEventArgs e) + { + _distributedCache.RefreshMemberCache(e.SavedEntities.ToArray()); + } + + #endregion + #region MemberGroupService private void MemberGroupService_Deleted(IMemberGroupService sender, DeleteEventArgs e) diff --git a/src/Umbraco.Infrastructure/Cache/DistributedCacheHandler.cs b/src/Umbraco.Infrastructure/Cache/DistributedCacheHandler.cs deleted file mode 100644 index a72b37c189..0000000000 --- a/src/Umbraco.Infrastructure/Cache/DistributedCacheHandler.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System.Linq; -using Umbraco.Cms.Core.Events; -using Umbraco.Cms.Infrastructure.Services.Notifications; -using Umbraco.Extensions; - -namespace Umbraco.Cms.Core.Cache -{ - internal class DistributedCacheHandler : - INotificationHandler, - INotificationHandler, - INotificationHandler, - INotificationHandler, - INotificationHandler, - INotificationHandler, - INotificationHandler, - INotificationHandler - { - private readonly DistributedCache _distributedCache; - - public DistributedCacheHandler(DistributedCache distributedCache) => _distributedCache = distributedCache; - - public void Handle(MemberSavedNotification notification) => _distributedCache.RefreshMemberCache(notification.SavedEntities.ToArray()); - - public void Handle(MemberDeletedNotification notification) => _distributedCache.RemoveMemberCache(notification.DeletedEntities.ToArray()); - - public void Handle(UserSavedNotification notification) - { - foreach (var entity in notification.SavedEntities) - { - _distributedCache.RefreshUserCache(entity.Id); - } - } - - public void Handle(UserDeletedNotification notification) - { - foreach (var entity in notification.DeletedEntities) - { - _distributedCache.RemoveUserCache(entity.Id); - } - } - - public void Handle(UserGroupSavedNotification notification) - { - foreach (var entity in notification.SavedEntities) - { - _distributedCache.RefreshUserGroupCache(entity.Id); - } - } - - public void Handle(UserGroupDeletedNotification notification) - { - foreach (var entity in notification.DeletedEntities) - { - _distributedCache.RemoveUserGroupCache(entity.Id); - } - } - - public void Handle(PublicAccessEntrySavedNotification notification) => _distributedCache.RefreshPublicAccess(); - - public void Handle(PublicAccessEntryDeletedNotification notification) => _distributedCache.RefreshPublicAccess(); - } -} diff --git a/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs b/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs index d973254659..2e5c587f64 100644 --- a/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs +++ b/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs @@ -76,17 +76,6 @@ namespace Umbraco.Cms.Core.Compose .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler(); - - // add notifications handlers for distributed cache - builder - .AddNotificationHandler() - .AddNotificationHandler() - .AddNotificationHandler() - .AddNotificationHandler() - .AddNotificationHandler() - .AddNotificationHandler() - .AddNotificationHandler() - .AddNotificationHandler(); } } } diff --git a/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs b/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs index fd5c9480a7..32fc6955cf 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs @@ -796,6 +796,7 @@ namespace Umbraco.Cms.Core.Services.Implement if (raiseEvents) { scope.Notifications.Publish(new MemberSavedNotification(member, evtMsgs).WithStateFrom(savingNotification)); + scope.Events.Dispatch(Saved, this, new SaveEventArgs(member, false)); } Audit(AuditType.Save, 0, member.Id); @@ -834,6 +835,7 @@ namespace Umbraco.Cms.Core.Services.Implement if (raiseEvents) { scope.Notifications.Publish(new MemberSavedNotification(membersA, evtMsgs).WithStateFrom(savingNotification)); + scope.Events.Dispatch(Saved, this, new SaveEventArgs(membersA, false)); } Audit(AuditType.Save, 0, -1, "Save multiple Members"); @@ -875,6 +877,7 @@ namespace Umbraco.Cms.Core.Services.Implement // a member has no descendants _memberRepository.Delete(member); scope.Notifications.Publish(new MemberDeletedNotification(member, evtMsgs).WithState(notificationState)); + scope.Events.Dispatch(Deleted, this, new DeleteEventArgs(member, false)); // media files deleted by QueuingEventDispatcher } @@ -1018,6 +1021,7 @@ namespace Umbraco.Cms.Core.Services.Implement int[] ids = _memberGroupRepository.GetMemberIds(usernames); _memberGroupRepository.AssignRoles(ids, roleNames); scope.Notifications.Publish(new AssignedMemberRolesNotification(ids, roleNames)); + scope.Complete(); } } @@ -1031,6 +1035,7 @@ namespace Umbraco.Cms.Core.Services.Implement int[] ids = _memberGroupRepository.GetMemberIds(usernames); _memberGroupRepository.DissociateRoles(ids, roleNames); scope.Notifications.Publish(new RemovedMemberRolesNotification(ids, roleNames)); + scope.Complete(); } } @@ -1043,6 +1048,7 @@ namespace Umbraco.Cms.Core.Services.Implement scope.WriteLock(Constants.Locks.MemberTree); _memberGroupRepository.AssignRoles(memberIds, roleNames); scope.Notifications.Publish(new AssignedMemberRolesNotification(memberIds, roleNames)); + scope.Complete(); } } @@ -1055,6 +1061,7 @@ namespace Umbraco.Cms.Core.Services.Implement scope.WriteLock(Constants.Locks.MemberTree); _memberGroupRepository.DissociateRoles(memberIds, roleNames); scope.Notifications.Publish(new RemovedMemberRolesNotification(memberIds, roleNames)); + scope.Complete(); } } @@ -1068,10 +1075,11 @@ namespace Umbraco.Cms.Core.Services.Implement #region Event Handlers - /// - /// Occurs after members have been exported. - /// - public static event TypedEventHandler Exported; + [Obsolete("Will be removed in an upcoming version. Implement an INotificationHandler for MemberDeletedNotification instead.")] + public static event TypedEventHandler> Deleted; + + [Obsolete("Will be removed in an upcoming version. Implement an INotificationHandler for MemberSavedNotification instead.")] + public static event TypedEventHandler> Saved; #endregion diff --git a/src/Umbraco.Infrastructure/Services/Implement/PublicAccessService.cs b/src/Umbraco.Infrastructure/Services/Implement/PublicAccessService.cs index b79b0ec0ab..afe309e8b4 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/PublicAccessService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/PublicAccessService.cs @@ -140,6 +140,7 @@ namespace Umbraco.Cms.Core.Services.Implement scope.Complete(); scope.Notifications.Publish(new PublicAccessEntrySavedNotification(entry, evtMsgs).WithStateFrom(savingNotifiation)); + scope.Events.Dispatch(Saved, this, new SaveEventArgs(entry, false)); } return OperationResult.Attempt.Succeed(evtMsgs, entry); @@ -176,6 +177,7 @@ namespace Umbraco.Cms.Core.Services.Implement scope.Complete(); scope.Notifications.Publish(new PublicAccessEntrySavedNotification(entry, evtMsgs).WithStateFrom(savingNotifiation)); + scope.Events.Dispatch(Saved, this, new SaveEventArgs(entry, false)); } return OperationResult.Attempt.Succeed(evtMsgs); @@ -202,6 +204,7 @@ namespace Umbraco.Cms.Core.Services.Implement scope.Complete(); scope.Notifications.Publish(new PublicAccessEntrySavedNotification(entry, evtMsgs).WithStateFrom(savingNotifiation)); + scope.Events.Dispatch(Saved, this, new SaveEventArgs(entry, false)); } return OperationResult.Attempt.Succeed(evtMsgs); @@ -228,9 +231,16 @@ namespace Umbraco.Cms.Core.Services.Implement scope.Complete(); scope.Notifications.Publish(new PublicAccessEntryDeletedNotification(entry, evtMsgs).WithStateFrom(deletingNotification)); + scope.Events.Dispatch(Deleted, this, new DeleteEventArgs(entry, false)); } return OperationResult.Attempt.Succeed(evtMsgs); } + + [Obsolete("Will be removed in an upcoming version. Implement an INotificationHandler for PublicAccessEntrySavedNotification instead.")] + public static event TypedEventHandler> Saved; + + [Obsolete("Will be removed in an upcoming version. Implement an INotificationHandler for PublicAccessEntryDeletedNotification instead.")] + public static event TypedEventHandler> Deleted; } } diff --git a/src/Umbraco.Infrastructure/Services/Implement/UserService.cs b/src/Umbraco.Infrastructure/Services/Implement/UserService.cs index 4fbe579ca3..07694ffb1a 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/UserService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/UserService.cs @@ -142,6 +142,7 @@ namespace Umbraco.Cms.Core.Services.Implement _userRepository.Save(user); scope.Notifications.Publish(new UserSavedNotification(user, evtMsgs).WithStateFrom(savingNotification)); + scope.Events.Dispatch(SavedUser, this, new SaveEventArgs(user, false)); scope.Complete(); } @@ -255,6 +256,7 @@ namespace Umbraco.Cms.Core.Services.Implement _userRepository.Delete(user); scope.Notifications.Publish(new UserDeletedNotification(user, evtMsgs).WithStateFrom(deletingNotification)); + scope.Events.Dispatch(DeletedUser, this, new DeleteEventArgs(user, false)); scope.Complete(); } } @@ -298,6 +300,7 @@ namespace Umbraco.Cms.Core.Services.Implement if (raiseEvents) { scope.Notifications.Publish(new UserSavedNotification(entity, evtMsgs).WithStateFrom(savingNotification)); + scope.Events.Dispatch(SavedUser, this, new SaveEventArgs(entity, false)); } scope.Complete(); @@ -351,6 +354,7 @@ namespace Umbraco.Cms.Core.Services.Implement if (raiseEvents) { scope.Notifications.Publish(new UserSavedNotification(entitiesA, evtMsgs).WithStateFrom(savingNotification)); + scope.Events.Dispatch(SavedUser, this, new SaveEventArgs(entitiesA, false)); } //commit the whole lot in one go @@ -861,6 +865,7 @@ namespace Umbraco.Cms.Core.Services.Implement { scope.Notifications.Publish(new UserGroupSavedNotification(userGroup, evtMsgs).WithStateFrom(savingNotification)); scope.Notifications.Publish(new UserGroupWithUsersSavedNotification(userGroupWithUsers, evtMsgs).WithStateFrom(savingUserGroupWithUsersNotification)); + scope.Events.Dispatch(SavedUserGroup, this, new SaveEventArgs(new UserGroupWithUsers(userGroup, addedUsers, removedUsers), false)); } scope.Complete(); @@ -887,6 +892,7 @@ namespace Umbraco.Cms.Core.Services.Implement _userGroupRepository.Delete(userGroup); scope.Notifications.Publish(new UserGroupDeletedNotification(userGroup, evtMsgs).WithStateFrom(deletingNotification)); + scope.Events.Dispatch(DeletedUserGroup, this, new DeleteEventArgs(userGroup, false)); scope.Complete(); } @@ -1166,5 +1172,17 @@ namespace Umbraco.Cms.Core.Services.Implement } #endregion + + [Obsolete("Will be removed in an upcoming version. Implement an INotificationHandler for UserSavedNotification instead.")] + public static event TypedEventHandler> SavedUser; + + [Obsolete("Will be removed in an upcoming version. Implement an INotificationHandler for UserDeletedNotification instead.")] + public static event TypedEventHandler> DeletedUser; + + [Obsolete("Will be removed in an upcoming version. Implement an INotificationHandler for UserGroupSavedNotification instead.")] + public static event TypedEventHandler> SavedUserGroup; + + [Obsolete("Will be removed in an upcoming version. Implement an INotificationHandler for UserGroupDeletedNotification instead.")] + public static event TypedEventHandler> DeletedUserGroup; } } diff --git a/src/Umbraco.Tests.Integration/Cache/DistributedCacheBinderTests.cs b/src/Umbraco.Tests.Integration/Cache/DistributedCacheBinderTests.cs index 8fbe858294..9b8a1e9c98 100644 --- a/src/Umbraco.Tests.Integration/Cache/DistributedCacheBinderTests.cs +++ b/src/Umbraco.Tests.Integration/Cache/DistributedCacheBinderTests.cs @@ -5,6 +5,7 @@ using NUnit.Framework; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.Membership; using Umbraco.Cms.Core.Routing; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Web; @@ -17,6 +18,7 @@ namespace Umbraco.Cms.Tests.Integration.Cache [UmbracoTest(Boot = true)] public class DistributedCacheBinderTests : UmbracoIntegrationTest { + private IUserService UserService => GetRequiredService(); private ILocalizationService LocalizationService => GetRequiredService(); private IDataTypeService DataTypeService => GetRequiredService(); private IFileService FileService => GetRequiredService(); @@ -25,7 +27,11 @@ namespace Umbraco.Cms.Tests.Integration.Cache private IDomainService DomainService => GetRequiredService(); private IMemberTypeService MemberTypeService => GetRequiredService(); private IMacroService MacroService => GetRequiredService(); + private IMemberService MemberService => GetRequiredService(); private IMemberGroupService MemberGroupService => GetRequiredService(); + private IMediaService MediaService => GetRequiredService(); + private IContentService ContentService => GetRequiredService(); + private IPublicAccessService PublicAccessService => GetRequiredService(); private IRelationService RelationService => GetRequiredService(); private UriUtility UriUtility => GetRequiredService(); private IUmbracoContextFactory UmbracoContextFactory => GetRequiredService(); @@ -36,6 +42,11 @@ namespace Umbraco.Cms.Tests.Integration.Cache var definitions = new IEventDefinition[] { + new EventDefinition>(null, UserService, new SaveEventArgs(Enumerable.Empty())), + new EventDefinition>(null, UserService, new DeleteEventArgs(Enumerable.Empty())), + new EventDefinition>(null, UserService, new SaveEventArgs(Enumerable.Empty())), + new EventDefinition>(null, UserService, new DeleteEventArgs(Enumerable.Empty())), + new EventDefinition>(null, LocalizationService, new SaveEventArgs(Enumerable.Empty())), new EventDefinition>(null, LocalizationService, new DeleteEventArgs(Enumerable.Empty())), @@ -65,6 +76,9 @@ namespace Umbraco.Cms.Tests.Integration.Cache new EventDefinition>(null, MacroService, new SaveEventArgs(Enumerable.Empty())), new EventDefinition>(null, MacroService, new DeleteEventArgs(Enumerable.Empty())), + new EventDefinition>(null, MemberService, new SaveEventArgs(Enumerable.Empty())), + new EventDefinition>(null, MemberService, new DeleteEventArgs(Enumerable.Empty())), + new EventDefinition>(null, MemberGroupService, new SaveEventArgs(Enumerable.Empty())), new EventDefinition>(null, MemberGroupService, new DeleteEventArgs(Enumerable.Empty())), @@ -72,6 +86,9 @@ namespace Umbraco.Cms.Tests.Integration.Cache //new EventDefinition>(null, ContentService, new SaveEventArgs(Enumerable.Empty()), "SavedBlueprint"), //new EventDefinition>(null, ContentService, new DeleteEventArgs(Enumerable.Empty()), "DeletedBlueprint"), + new EventDefinition>(null, PublicAccessService, new SaveEventArgs(Enumerable.Empty())), + new EventDefinition>(null, PublicAccessService, new DeleteEventArgs(Enumerable.Empty())), + new EventDefinition>(null, RelationService, new SaveEventArgs(Enumerable.Empty())), new EventDefinition>(null, RelationService, new DeleteEventArgs(Enumerable.Empty())), From b4cbf0cf5dbeede1c55f793d243996c94b5f5cfc Mon Sep 17 00:00:00 2001 From: Mole Date: Mon, 29 Mar 2021 10:42:42 +0200 Subject: [PATCH 7/7] Remove obsolete static events --- .../Cache/DistributedCacheBinder_Handlers.cs | 68 +++++++++---------- .../Compose/NotificationsComposer.cs | 10 ++- .../Services/Implement/MemberService.cs | 15 +--- .../Services/Implement/PublicAccessService.cs | 14 +--- .../Services/Implement/UserService.cs | 22 +----- .../Cache/DistributedCacheBinderTests.cs | 11 --- .../Scoping/ScopedRepositoryTests.cs | 19 +++--- 7 files changed, 55 insertions(+), 104 deletions(-) diff --git a/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs b/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs index e8479de307..a1071b71f0 100644 --- a/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs +++ b/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs @@ -23,7 +23,15 @@ namespace Umbraco.Cms.Core.Cache INotificationHandler, INotificationHandler, INotificationHandler, - INotificationHandler + INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler { private List _unbinders; @@ -54,16 +62,6 @@ namespace Umbraco.Cms.Core.Cache _logger.LogInformation("Initializing Umbraco internal event handlers for cache refreshing."); - // bind to user and user group events - Bind(() => UserService.SavedUserGroup += UserService_SavedUserGroup, - () => UserService.SavedUserGroup -= UserService_SavedUserGroup); - Bind(() => UserService.DeletedUserGroup += UserService_DeletedUserGroup, - () => UserService.DeletedUserGroup -= UserService_DeletedUserGroup); - Bind(() => UserService.SavedUser += UserService_SavedUser, - () => UserService.SavedUser -= UserService_SavedUser); - Bind(() => UserService.DeletedUser += UserService_DeletedUser, - () => UserService.DeletedUser -= UserService_DeletedUser); - // bind to data type events Bind(() => DataTypeService.Deleted += DataTypeService_Deleted, () => DataTypeService.Deleted -= DataTypeService_Deleted); @@ -103,10 +101,6 @@ namespace Umbraco.Cms.Core.Cache () => MacroService.Deleted -= MacroService_Deleted); // bind to member events - Bind(() => MemberService.Saved += MemberService_Saved, - () => MemberService.Saved -= MemberService_Saved); - Bind(() => MemberService.Deleted += MemberService_Deleted, - () => MemberService.Deleted -= MemberService_Deleted); Bind(() => MemberGroupService.Saved += MemberGroupService_Saved, () => MemberGroupService.Saved -= MemberGroupService_Saved); Bind(() => MemberGroupService.Deleted += MemberGroupService_Deleted, @@ -126,12 +120,6 @@ namespace Umbraco.Cms.Core.Cache //Bind(() => ContentService.DeletedBlueprint += ContentService_DeletedBlueprint, // () => ContentService.DeletedBlueprint -= ContentService_DeletedBlueprint); - // bind to public access events - Bind(() => PublicAccessService.Saved += PublicAccessService_Saved, - () => PublicAccessService.Saved -= PublicAccessService_Saved); - Bind(() => PublicAccessService.Deleted += PublicAccessService_Deleted, - () => PublicAccessService.Deleted -= PublicAccessService_Deleted); - // bind to relation type events Bind(() => RelationService.SavedRelationType += RelationService_SavedRelationType, () => RelationService.SavedRelationType -= RelationService_SavedRelationType); @@ -141,14 +129,15 @@ namespace Umbraco.Cms.Core.Cache #region PublicAccessService - private void PublicAccessService_Saved(IPublicAccessService sender, SaveEventArgs e) + public void Handle(PublicAccessEntrySavedNotification notification) { _distributedCache.RefreshPublicAccess(); } - private void PublicAccessService_Deleted(IPublicAccessService sender, DeleteEventArgs e) + public void Handle(PublicAccessEntryDeletedNotification notification) { _distributedCache.RefreshPublicAccess(); + } #endregion @@ -293,29 +282,36 @@ namespace Umbraco.Cms.Core.Cache #region UserService - private void UserService_SavedUser(IUserService sender, SaveEventArgs e) + public void Handle(UserSavedNotification notification) { - foreach (var entity in e.SavedEntities) + foreach (IUser entity in notification.SavedEntities) + { _distributedCache.RefreshUserCache(entity.Id); + } } - private void UserService_DeletedUser(IUserService sender, DeleteEventArgs e) + public void Handle(UserDeletedNotification notification) { - foreach (var entity in e.DeletedEntities) + foreach (IUser entity in notification.DeletedEntities) + { _distributedCache.RemoveUserCache(entity.Id); + } } - private void UserService_SavedUserGroup(IUserService sender, SaveEventArgs e) + public void Handle(UserGroupWithUsersSavedNotification notification) { - foreach (var entity in e.SavedEntities) + foreach (UserGroupWithUsers entity in notification.SavedEntities) + { _distributedCache.RefreshUserGroupCache(entity.UserGroup.Id); + } } - private void UserService_DeletedUserGroup(IUserService sender, DeleteEventArgs e) + public void Handle(UserGroupDeletedNotification notification) { - - foreach (var entity in e.DeletedEntities) + foreach (IUserGroup entity in notification.DeletedEntities) + { _distributedCache.RemoveUserGroupCache(entity.Id); + } } #endregion @@ -377,14 +373,14 @@ namespace Umbraco.Cms.Core.Cache #region MemberService - private void MemberService_Deleted(IMemberService sender, DeleteEventArgs e) + public void Handle(MemberDeletedNotification notification) { - _distributedCache.RemoveMemberCache(e.DeletedEntities.ToArray()); + _distributedCache.RemoveMemberCache(notification.DeletedEntities.ToArray()); } - private void MemberService_Saved(IMemberService sender, SaveEventArgs e) + public void Handle(MemberSavedNotification notification) { - _distributedCache.RefreshMemberCache(e.SavedEntities.ToArray()); + _distributedCache.RefreshMemberCache(notification.SavedEntities.ToArray()); } #endregion diff --git a/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs b/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs index fd35a5111f..be6539ac55 100644 --- a/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs +++ b/src/Umbraco.Infrastructure/Compose/NotificationsComposer.cs @@ -70,7 +70,15 @@ namespace Umbraco.Cms.Core.Compose .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() - .AddNotificationHandler(); + .AddNotificationHandler() + .AddNotificationHandler() + .AddNotificationHandler() + .AddNotificationHandler() + .AddNotificationHandler() + .AddNotificationHandler() + .AddNotificationHandler() + .AddNotificationHandler() + .AddNotificationHandler(); // add notification handlers for auditing builder diff --git a/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs b/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs index 794fd09934..aba40333b0 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/MemberService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.Logging; @@ -796,7 +796,6 @@ namespace Umbraco.Cms.Core.Services.Implement if (raiseEvents) { scope.Notifications.Publish(new MemberSavedNotification(member, evtMsgs).WithStateFrom(savingNotification)); - scope.Events.Dispatch(Saved, this, new SaveEventArgs(member, false)); } Audit(AuditType.Save, 0, member.Id); @@ -835,7 +834,6 @@ namespace Umbraco.Cms.Core.Services.Implement if (raiseEvents) { scope.Notifications.Publish(new MemberSavedNotification(membersA, evtMsgs).WithStateFrom(savingNotification)); - scope.Events.Dispatch(Saved, this, new SaveEventArgs(membersA, false)); } Audit(AuditType.Save, 0, -1, "Save multiple Members"); @@ -877,7 +875,6 @@ namespace Umbraco.Cms.Core.Services.Implement // a member has no descendants _memberRepository.Delete(member); scope.Notifications.Publish(new MemberDeletedNotification(member, evtMsgs).WithState(notificationState)); - scope.Events.Dispatch(Deleted, this, new DeleteEventArgs(member, false)); // media files deleted by QueuingEventDispatcher } @@ -1073,16 +1070,6 @@ namespace Umbraco.Cms.Core.Services.Implement #endregion - #region Event Handlers - - [Obsolete("Will be removed in an upcoming version. Implement an INotificationHandler for MemberDeletedNotification instead.")] - public static event TypedEventHandler> Deleted; - - [Obsolete("Will be removed in an upcoming version. Implement an INotificationHandler for MemberSavedNotification instead.")] - public static event TypedEventHandler> Saved; - - #endregion - #region Membership diff --git a/src/Umbraco.Infrastructure/Services/Implement/PublicAccessService.cs b/src/Umbraco.Infrastructure/Services/Implement/PublicAccessService.cs index 3d44ed2cf8..b6d12784c6 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/PublicAccessService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/PublicAccessService.cs @@ -11,7 +11,7 @@ using Umbraco.Extensions; namespace Umbraco.Cms.Core.Services.Implement { - public class PublicAccessService : RepositoryService, IPublicAccessService + internal class PublicAccessService : RepositoryService, IPublicAccessService { private readonly IPublicAccessRepository _publicAccessRepository; @@ -115,7 +115,7 @@ namespace Umbraco.Cms.Core.Services.Implement { entry = _publicAccessRepository.GetMany().FirstOrDefault(x => x.ProtectedNodeId == content.Id); if (entry == null) - return OperationResult.Attempt.Cannot(evtMsgs); // causes rollback // causes rollback + return OperationResult.Attempt.Cannot(evtMsgs); // causes rollback var existingRule = entry.Rules.FirstOrDefault(x => x.RuleType == ruleType && x.RuleValue == ruleValue); if (existingRule == null) @@ -140,7 +140,6 @@ namespace Umbraco.Cms.Core.Services.Implement scope.Complete(); scope.Notifications.Publish(new PublicAccessEntrySavedNotification(entry, evtMsgs).WithStateFrom(savingNotifiation)); - scope.Events.Dispatch(Saved, this, new SaveEventArgs(entry, false)); } return OperationResult.Attempt.Succeed(evtMsgs, entry); @@ -177,7 +176,6 @@ namespace Umbraco.Cms.Core.Services.Implement scope.Complete(); scope.Notifications.Publish(new PublicAccessEntrySavedNotification(entry, evtMsgs).WithStateFrom(savingNotifiation)); - scope.Events.Dispatch(Saved, this, new SaveEventArgs(entry, false)); } return OperationResult.Attempt.Succeed(evtMsgs); @@ -204,7 +202,6 @@ namespace Umbraco.Cms.Core.Services.Implement scope.Complete(); scope.Notifications.Publish(new PublicAccessEntrySavedNotification(entry, evtMsgs).WithStateFrom(savingNotifiation)); - scope.Events.Dispatch(Saved, this, new SaveEventArgs(entry, false)); } return OperationResult.Attempt.Succeed(evtMsgs); @@ -231,16 +228,9 @@ namespace Umbraco.Cms.Core.Services.Implement scope.Complete(); scope.Notifications.Publish(new PublicAccessEntryDeletedNotification(entry, evtMsgs).WithStateFrom(deletingNotification)); - scope.Events.Dispatch(Deleted, this, new DeleteEventArgs(entry, false)); } return OperationResult.Attempt.Succeed(evtMsgs); } - - [Obsolete("Will be removed in an upcoming version. Implement an INotificationHandler for PublicAccessEntrySavedNotification instead.")] - public static event TypedEventHandler> Saved; - - [Obsolete("Will be removed in an upcoming version. Implement an INotificationHandler for PublicAccessEntryDeletedNotification instead.")] - public static event TypedEventHandler> Deleted; } } diff --git a/src/Umbraco.Infrastructure/Services/Implement/UserService.cs b/src/Umbraco.Infrastructure/Services/Implement/UserService.cs index e29eeefc01..b7b52ae616 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/UserService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/UserService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Data.Common; using System.Globalization; @@ -22,7 +22,7 @@ namespace Umbraco.Cms.Core.Services.Implement /// /// Represents the UserService, which is an easy access to operations involving , and eventually Backoffice Users. /// - public class UserService : RepositoryService, IUserService + internal class UserService : RepositoryService, IUserService { private readonly IUserRepository _userRepository; private readonly IUserGroupRepository _userGroupRepository; @@ -142,7 +142,6 @@ namespace Umbraco.Cms.Core.Services.Implement _userRepository.Save(user); scope.Notifications.Publish(new UserSavedNotification(user, evtMsgs).WithStateFrom(savingNotification)); - scope.Events.Dispatch(SavedUser, this, new SaveEventArgs(user, false)); scope.Complete(); } @@ -256,7 +255,6 @@ namespace Umbraco.Cms.Core.Services.Implement _userRepository.Delete(user); scope.Notifications.Publish(new UserDeletedNotification(user, evtMsgs).WithStateFrom(deletingNotification)); - scope.Events.Dispatch(DeletedUser, this, new DeleteEventArgs(user, false)); scope.Complete(); } } @@ -300,7 +298,6 @@ namespace Umbraco.Cms.Core.Services.Implement if (raiseEvents) { scope.Notifications.Publish(new UserSavedNotification(entity, evtMsgs).WithStateFrom(savingNotification)); - scope.Events.Dispatch(SavedUser, this, new SaveEventArgs(entity, false)); } scope.Complete(); @@ -354,7 +351,6 @@ namespace Umbraco.Cms.Core.Services.Implement if (raiseEvents) { scope.Notifications.Publish(new UserSavedNotification(entitiesA, evtMsgs).WithStateFrom(savingNotification)); - scope.Events.Dispatch(SavedUser, this, new SaveEventArgs(entitiesA, false)); } //commit the whole lot in one go @@ -865,7 +861,6 @@ namespace Umbraco.Cms.Core.Services.Implement { scope.Notifications.Publish(new UserGroupSavedNotification(userGroup, evtMsgs).WithStateFrom(savingNotification)); scope.Notifications.Publish(new UserGroupWithUsersSavedNotification(userGroupWithUsers, evtMsgs).WithStateFrom(savingUserGroupWithUsersNotification)); - scope.Events.Dispatch(SavedUserGroup, this, new SaveEventArgs(new UserGroupWithUsers(userGroup, addedUsers, removedUsers), false)); } scope.Complete(); @@ -892,7 +887,6 @@ namespace Umbraco.Cms.Core.Services.Implement _userGroupRepository.Delete(userGroup); scope.Notifications.Publish(new UserGroupDeletedNotification(userGroup, evtMsgs).WithStateFrom(deletingNotification)); - scope.Events.Dispatch(DeletedUserGroup, this, new DeleteEventArgs(userGroup, false)); scope.Complete(); } @@ -1172,17 +1166,5 @@ namespace Umbraco.Cms.Core.Services.Implement } #endregion - - [Obsolete("Will be removed in an upcoming version. Implement an INotificationHandler for UserSavedNotification instead.")] - public static event TypedEventHandler> SavedUser; - - [Obsolete("Will be removed in an upcoming version. Implement an INotificationHandler for UserDeletedNotification instead.")] - public static event TypedEventHandler> DeletedUser; - - [Obsolete("Will be removed in an upcoming version. Implement an INotificationHandler for UserGroupSavedNotification instead.")] - public static event TypedEventHandler> SavedUserGroup; - - [Obsolete("Will be removed in an upcoming version. Implement an INotificationHandler for UserGroupDeletedNotification instead.")] - public static event TypedEventHandler> DeletedUserGroup; } } diff --git a/src/Umbraco.Tests.Integration/Cache/DistributedCacheBinderTests.cs b/src/Umbraco.Tests.Integration/Cache/DistributedCacheBinderTests.cs index 6a263cb6ae..b0d62778cf 100644 --- a/src/Umbraco.Tests.Integration/Cache/DistributedCacheBinderTests.cs +++ b/src/Umbraco.Tests.Integration/Cache/DistributedCacheBinderTests.cs @@ -42,11 +42,6 @@ namespace Umbraco.Cms.Tests.Integration.Cache var definitions = new IEventDefinition[] { - new EventDefinition>(null, UserService, new SaveEventArgs(Enumerable.Empty())), - new EventDefinition>(null, UserService, new DeleteEventArgs(Enumerable.Empty())), - new EventDefinition>(null, UserService, new SaveEventArgs(Enumerable.Empty())), - new EventDefinition>(null, UserService, new DeleteEventArgs(Enumerable.Empty())), - new EventDefinition>(null, DataTypeService, new SaveEventArgs(Enumerable.Empty())), new EventDefinition>(null, DataTypeService, new DeleteEventArgs(Enumerable.Empty())), @@ -70,9 +65,6 @@ namespace Umbraco.Cms.Tests.Integration.Cache new EventDefinition>(null, MacroService, new SaveEventArgs(Enumerable.Empty())), new EventDefinition>(null, MacroService, new DeleteEventArgs(Enumerable.Empty())), - new EventDefinition>(null, MemberService, new SaveEventArgs(Enumerable.Empty())), - new EventDefinition>(null, MemberService, new DeleteEventArgs(Enumerable.Empty())), - new EventDefinition>(null, MemberGroupService, new SaveEventArgs(Enumerable.Empty())), new EventDefinition>(null, MemberGroupService, new DeleteEventArgs(Enumerable.Empty())), @@ -80,9 +72,6 @@ namespace Umbraco.Cms.Tests.Integration.Cache //new EventDefinition>(null, ContentService, new SaveEventArgs(Enumerable.Empty()), "SavedBlueprint"), //new EventDefinition>(null, ContentService, new DeleteEventArgs(Enumerable.Empty()), "DeletedBlueprint"), - new EventDefinition>(null, PublicAccessService, new SaveEventArgs(Enumerable.Empty())), - new EventDefinition>(null, PublicAccessService, new DeleteEventArgs(Enumerable.Empty())), - new EventDefinition>(null, RelationService, new SaveEventArgs(Enumerable.Empty())), new EventDefinition>(null, RelationService, new DeleteEventArgs(Enumerable.Empty())), diff --git a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs index 61334940e1..695a281d0a 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedRepositoryTests.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; -using Microsoft.Extensions.Logging; using NUnit.Framework; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.DependencyInjection; @@ -14,7 +13,6 @@ using Umbraco.Cms.Core.Scoping; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Services.Implement; using Umbraco.Cms.Core.Sync; -using Umbraco.Cms.Core.Web; using Umbraco.Cms.Infrastructure.PublishedCache; using Umbraco.Cms.Infrastructure.Services.Notifications; using Umbraco.Cms.Infrastructure.Sync; @@ -55,7 +53,8 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Scoping .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() - .AddNotificationHandler(); + .AddNotificationHandler() + .AddNotificationHandler(); builder.AddNotificationHandler(); } @@ -76,18 +75,18 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Scoping var user = (IUser)new User(GlobalSettings, "name", "email", "username", "rawPassword"); service.Save(user); - // global cache contains the entity + // User has been saved so the cache has been cleared of it var globalCached = (IUser)globalCache.Get(GetCacheIdKey(user.Id), () => null); + Assert.IsNull(globalCached); + // Get user again to load it into the cache again, this also ensure we don't modify the one that's in the cache. + user = service.GetUserById(user.Id); + + // global cache contains the entity + globalCached = (IUser)globalCache.Get(GetCacheIdKey(user.Id), () => null); Assert.IsNotNull(globalCached); Assert.AreEqual(user.Id, globalCached.Id); Assert.AreEqual("name", globalCached.Name); - // get user again - else we'd modify the one that's in the cache - user = service.GetUserById(user.Id); - - _distributedCacheBinder = new DistributedCacheBinder(new DistributedCache(ServerMessenger, CacheRefresherCollection), GetRequiredService(), GetRequiredService>()); - _distributedCacheBinder.BindEvents(true); - Assert.IsNull(scopeProvider.AmbientScope); using (IScope scope = scopeProvider.CreateScope(repositoryCacheMode: RepositoryCacheMode.Scoped)) {