From 0a44ad3ab69377dccfcb02e91b060d718045fb6d Mon Sep 17 00:00:00 2001 From: Stephan Date: Wed, 7 Feb 2018 16:50:49 +0100 Subject: [PATCH] U4-10795 - granular logging - roles --- .../Auditing/AuditEventHandler.cs | 32 +++++++++++++++++++ .../Interfaces/IMemberGroupRepository.cs | 4 ++- .../Repositories/MemberGroupRepository.cs | 31 +++++++----------- src/Umbraco.Core/Services/MemberService.cs | 31 ++++++++++++++++-- 4 files changed, 76 insertions(+), 22 deletions(-) diff --git a/src/Umbraco.Core/Auditing/AuditEventHandler.cs b/src/Umbraco.Core/Auditing/AuditEventHandler.cs index 85a673e76e..ff8c1b7b7d 100644 --- a/src/Umbraco.Core/Auditing/AuditEventHandler.cs +++ b/src/Umbraco.Core/Auditing/AuditEventHandler.cs @@ -60,6 +60,38 @@ namespace Umbraco.Core.Auditing MemberService.Saved += OnSavedMember; MemberService.Deleted += OnDeletedMember; + MemberService.AssignedRoles += OnAssignedRoles; + MemberService.RemovedRoles += OnRemovedRoles; + } + + private void OnRemovedRoles(IMemberService sender, MemberService.RolesEventArgs args) + { + var performingUser = PerformingUser; + var roles = string.Join(", ", args.Roles); + var members = ApplicationContext.Current.Services.MemberService.GetAllMembers(args.MemberIds).ToDictionary(x => x.Id, x => x); + foreach (var id in args.MemberIds) + { + members.TryGetValue(id, out var member); + AuditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", PerformingIp, + DateTime.Now, + 0, null, + "umbraco/member", $"modified roles for member id:{id} \"{member?.Name ?? "(unknown)"}\" <{member?.Email ?? ""}>, removed {roles}"); + } + } + + private void OnAssignedRoles(IMemberService sender, MemberService.RolesEventArgs args) + { + var performingUser = PerformingUser; + var roles = string.Join(", ", args.Roles); + var members = ApplicationContext.Current.Services.MemberService.GetAllMembers(args.MemberIds).ToDictionary(x => x.Id, x => x); + foreach (var id in args.MemberIds) + { + members.TryGetValue(id, out var member); + AuditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", PerformingIp, + DateTime.Now, + 0, null, + "umbraco/member", $"modified roles for member id:{id} \"{member?.Name ?? "(unknown)"}\" <{member?.Email ?? ""}>, assigned {roles}"); + } } private void OnSavedUserGroup(IUserService sender, SaveEventArgs saveEventArgs) diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMemberGroupRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMemberGroupRepository.cs index 2750457271..49b8e41d11 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMemberGroupRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMemberGroupRepository.cs @@ -39,5 +39,7 @@ namespace Umbraco.Core.Persistence.Repositories void AssignRoles(int[] memberIds, string[] roleNames); void DissociateRoles(int[] memberIds, string[] roleNames); + + int[] GetMemberIds(string[] names); } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs index c7e8a5c328..4006ea26c9 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs @@ -183,7 +183,7 @@ namespace Umbraco.Core.Persistence.Repositories } public IEnumerable GetMemberGroupsForMember(string username) - { + { var sql = new Sql() .Select("un.*") .From("umbracoNode AS un") @@ -192,16 +192,15 @@ namespace Umbraco.Core.Persistence.Repositories .InnerJoin("cmsMember") .On("cmsMember.nodeId = cmsMember2MemberGroup.Member") .Where("un.nodeObjectType=@objectType", new { objectType = NodeObjectTypeId }) - .Where("cmsMember.LoginName=@loginName", new { loginName = username }); - + .Where("cmsMember.LoginName=@loginName", new { loginName = username }); + return Database.Fetch(sql) .DistinctBy(dto => dto.NodeId) .Select(x => _modelFactory.BuildEntity(x)); } - public void AssignRoles(string[] usernames, string[] roleNames) + public int[] GetMemberIds(string[] names) { - //first get the member ids based on the usernames var memberSql = new Sql(); var memberObjectType = new Guid(Constants.ObjectTypes.Member); memberSql.Select("umbracoNode.id") @@ -209,25 +208,19 @@ namespace Umbraco.Core.Persistence.Repositories .InnerJoin() .On(dto => dto.NodeId, dto => dto.NodeId) .Where(x => x.NodeObjectType == memberObjectType) - .Where("cmsMember.LoginName in (@usernames)", new { usernames = usernames }); - var memberIds = Database.Fetch(memberSql).ToArray(); + .Where("cmsMember.LoginName in (@names)", new { names }); + return Database.Fetch(memberSql).ToArray(); + } + public void AssignRoles(string[] usernames, string[] roleNames) + { + var memberIds = GetMemberIds(usernames); AssignRolesInternal(memberIds, roleNames); } public void DissociateRoles(string[] usernames, string[] roleNames) { - //first get the member ids based on the usernames - var memberSql = new Sql(); - var memberObjectType = new Guid(Constants.ObjectTypes.Member); - memberSql.Select("umbracoNode.id") - .From() - .InnerJoin() - .On(dto => dto.NodeId, dto => dto.NodeId) - .Where(x => x.NodeObjectType == memberObjectType) - .Where("cmsMember.LoginName in (@usernames)", new { usernames = usernames }); - var memberIds = Database.Fetch(memberSql).ToArray(); - + var memberIds = GetMemberIds(usernames); DissociateRolesInternal(memberIds, roleNames); } @@ -337,4 +330,4 @@ namespace Umbraco.Core.Persistence.Repositories /// internal static event TypedEventHandler> SavedMemberGroup; } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/Services/MemberService.cs b/src/Umbraco.Core/Services/MemberService.cs index 41fe0b2e31..ce97ec9629 100644 --- a/src/Umbraco.Core/Services/MemberService.cs +++ b/src/Umbraco.Core/Services/MemberService.cs @@ -1173,12 +1173,16 @@ namespace Umbraco.Core.Services public void AssignRoles(string[] usernames, string[] roleNames) { + int[] memberIds; using (var uow = UowProvider.GetUnitOfWork()) { var repository = RepositoryFactory.CreateMemberGroupRepository(uow); - repository.AssignRoles(usernames, roleNames); + memberIds = repository.GetMemberIds(usernames); + repository.AssignRoles(memberIds, roleNames); uow.Commit(); } + + AssignedRoles?.Invoke(this, new RolesEventArgs(memberIds, roleNames)); } public void DissociateRole(string username, string roleName) @@ -1188,12 +1192,16 @@ namespace Umbraco.Core.Services public void DissociateRoles(string[] usernames, string[] roleNames) { + int[] memberIds; using (var uow = UowProvider.GetUnitOfWork()) { var repository = RepositoryFactory.CreateMemberGroupRepository(uow); - repository.DissociateRoles(usernames, roleNames); + memberIds = repository.GetMemberIds(usernames); + repository.DissociateRoles(memberIds, roleNames); uow.Commit(); } + + RemovedRoles?.Invoke(this, new RolesEventArgs(memberIds, roleNames)); } public void AssignRole(int memberId, string roleName) @@ -1209,6 +1217,8 @@ namespace Umbraco.Core.Services repository.AssignRoles(memberIds, roleNames); uow.Commit(); } + + AssignedRoles?.Invoke(this, new RolesEventArgs(memberIds, roleNames)); } public void DissociateRole(int memberId, string roleName) @@ -1224,6 +1234,8 @@ namespace Umbraco.Core.Services repository.DissociateRoles(memberIds, roleNames); uow.Commit(); } + + RemovedRoles?.Invoke(this, new RolesEventArgs(memberIds, roleNames)); } @@ -1289,6 +1301,21 @@ namespace Umbraco.Core.Services /// public static event TypedEventHandler> Saved; + public static event TypedEventHandler AssignedRoles; + public static event TypedEventHandler RemovedRoles; + + public class RolesEventArgs : EventArgs + { + public RolesEventArgs(int[] memberIds, string[] roles) + { + MemberIds = memberIds; + Roles = roles; + } + + public int[] MemberIds { get; set; } + public string[] Roles { get; set; } + } + #endregion ///