Files
Umbraco-CMS/src/Umbraco.Core/Auditing/AuditEventHandler.cs

311 lines
16 KiB
C#
Raw Normal View History

2018-02-06 19:07:54 +01:00
using System;
using System.Linq;
using System.Threading;
2018-02-07 15:38:50 +01:00
using System.Web;
using Umbraco.Core.Events;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Membership;
2018-02-06 19:07:54 +01:00
using Umbraco.Core.Security;
using Umbraco.Core.Services;
namespace Umbraco.Core.Auditing
{
internal class AuditEventHandler : ApplicationEventHandler
{
2018-02-09 09:33:24 +01:00
private IAuditService _auditServiceInstance;
private IUserService _userServiceInstance;
private IEntityService _entityServiceInstance;
2018-02-06 19:07:54 +01:00
2018-02-07 15:38:50 +01:00
private IUser PerformingUser
2018-02-06 19:07:54 +01:00
{
2018-02-07 15:38:50 +01:00
get
{
var identity = Thread.CurrentPrincipal?.GetUmbracoIdentity();
return identity == null
? new User { Id = 0, Name = "SYSTEM", Email = "" }
2018-02-09 09:33:24 +01:00
: _userServiceInstance.GetUserById(Convert.ToInt32(identity.Id));
2018-02-07 15:38:50 +01:00
}
}
private string PerformingIp
{
get
{
var httpContext = HttpContext.Current == null ? (HttpContextBase) null : new HttpContextWrapper(HttpContext.Current);
var ip = httpContext.GetCurrentRequestIpAddress();
if (ip.ToLowerInvariant().StartsWith("unknown")) ip = "";
return ip;
}
}
2018-02-06 19:07:54 +01:00
2018-02-07 15:38:50 +01:00
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
2018-02-09 09:33:24 +01:00
_auditServiceInstance = applicationContext.Services.AuditService;
_userServiceInstance = applicationContext.Services.UserService;
_entityServiceInstance = applicationContext.Services.EntityService;
2018-02-06 19:07:54 +01:00
//BackOfficeUserManager.AccountLocked += ;
//BackOfficeUserManager.AccountUnlocked += ;
2018-02-07 15:38:50 +01:00
BackOfficeUserManager.ForgotPasswordRequested += OnForgotPasswordRequest;
BackOfficeUserManager.ForgotPasswordChangedSuccess += OnForgotPasswordChange;
BackOfficeUserManager.LoginFailed += OnLoginFailed;
2018-02-06 19:07:54 +01:00
//BackOfficeUserManager.LoginRequiresVerification += ;
BackOfficeUserManager.LoginSuccess += OnLoginSuccess;
BackOfficeUserManager.LogoutSuccess += OnLogoutSuccess;
2018-02-07 15:38:50 +01:00
BackOfficeUserManager.PasswordChanged += OnPasswordChanged;
BackOfficeUserManager.PasswordReset += OnPasswordReset;
2018-02-06 19:07:54 +01:00
//BackOfficeUserManager.ResetAccessFailedCount += ;
2018-02-07 15:38:50 +01:00
2018-02-07 15:51:18 +01:00
UserService.SavedUserGroup += OnSavedUserGroup;
2018-02-07 15:38:50 +01:00
UserService.SavedUser += OnSavedUser;
UserService.DeletedUser += OnDeletedUser;
2018-02-07 15:51:18 +01:00
UserService.UserGroupPermissionsAssigned += UserGroupPermissionAssigned;
2018-02-07 15:38:50 +01:00
MemberService.Saved += OnSavedMember;
MemberService.Deleted += OnDeletedMember;
2018-02-07 16:50:49 +01:00
MemberService.AssignedRoles += OnAssignedRoles;
MemberService.RemovedRoles += OnRemovedRoles;
}
private string FormatEmail(IMember member)
{
return member == null ? string.Empty : member.Email.IsNullOrWhiteSpace() ? "" : $"<{member.Email}>";
}
private string FormatEmail(IUser user)
{
return user == null ? string.Empty : user.Email.IsNullOrWhiteSpace() ? "" : $"<{user.Email}>";
}
2018-02-09 09:33:24 +01:00
private void OnRemovedRoles(IMemberService sender, RolesEventArgs args)
2018-02-07 16:50:49 +01:00
{
var performingUser = PerformingUser;
var roles = string.Join(", ", args.Roles);
2018-02-09 09:33:24 +01:00
var members = sender.GetAllMembers(args.MemberIds).ToDictionary(x => x.Id, x => x);
2018-02-07 16:50:49 +01:00
foreach (var id in args.MemberIds)
{
members.TryGetValue(id, out var member);
_auditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp,
2018-02-07 16:50:49 +01:00
DateTime.Now,
-1, $"Member {id} \"{member?.Name ?? "(unknown)"}\" {FormatEmail(member)}",
"umbraco/member/roles/removed", $"roles modified, removed {roles}");
2018-02-07 16:50:49 +01:00
}
}
2018-02-09 09:33:24 +01:00
private void OnAssignedRoles(IMemberService sender, RolesEventArgs args)
2018-02-07 16:50:49 +01:00
{
var performingUser = PerformingUser;
var roles = string.Join(", ", args.Roles);
2018-02-09 09:33:24 +01:00
var members = sender.GetAllMembers(args.MemberIds).ToDictionary(x => x.Id, x => x);
2018-02-07 16:50:49 +01:00
foreach (var id in args.MemberIds)
{
members.TryGetValue(id, out var member);
_auditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp,
2018-02-07 16:50:49 +01:00
DateTime.Now,
-1, $"Member {id} \"{member?.Name ?? "(unknown)"}\" {FormatEmail(member)}",
"umbraco/member/roles/assigned", $"roles modified, assigned {roles}");
2018-02-07 16:50:49 +01:00
}
2018-02-07 15:38:50 +01:00
}
2018-02-07 15:51:18 +01:00
private void OnSavedUserGroup(IUserService sender, SaveEventArgs<IUserGroup> saveEventArgs)
{
var performingUser = PerformingUser;
var groups = saveEventArgs.SavedEntities;
foreach (var group in groups)
{
var dp = string.Join(", ", ((UserGroup) group).GetPreviouslyDirtyProperties());
var sections = ((UserGroup)group).WasPropertyDirty("AllowedSections")
? string.Join(", ", group.AllowedSections)
: null;
var perms = ((UserGroup)group).WasPropertyDirty("Permissions")
? string.Join(", ", group.Permissions)
: null;
2018-02-07 15:51:18 +01:00
_auditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp,
2018-02-07 15:51:18 +01:00
DateTime.Now,
-1, $"User Group {group.Id} \"{group.Name}\" ({group.Alias})",
"umbraco/user-group/save", $"updating {(string.IsNullOrWhiteSpace(dp) ? "(nothing)" : dp)};{(sections == null ? "" : $", assigned sections: {sections}")}{(perms == null ? "" : $", assigned perms: {perms}")}");
2018-02-07 15:51:18 +01:00
}
}
2018-02-07 15:38:50 +01:00
private void UserGroupPermissionAssigned(IUserService sender, SaveEventArgs<EntityPermission> saveEventArgs)
{
var performingUser = PerformingUser;
var perms = saveEventArgs.SavedEntities;
foreach (var perm in perms)
{
var group = sender.GetUserGroupById(perm.UserGroupId);
var assigned = string.Join(", ", perm.AssignedPermissions);
2018-02-09 09:33:24 +01:00
var entity = _entityServiceInstance.Get(perm.EntityId);
2018-02-07 15:38:50 +01:00
_auditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp,
2018-02-07 15:38:50 +01:00
DateTime.Now,
-1, $"User Group {group.Id} \"{group.Name}\" ({group.Alias})",
"umbraco/user-group/permissions-change", $"assigning {(string.IsNullOrWhiteSpace(assigned) ? "(nothing)" : assigned)} on id:{perm.EntityId} \"{entity.Name}\"");
2018-02-07 15:38:50 +01:00
}
}
private void OnSavedMember(IMemberService sender, SaveEventArgs<IMember> saveEventArgs)
{
var performingUser = PerformingUser;
var members = saveEventArgs.SavedEntities;
foreach (var member in members)
{
var dp = string.Join(", ", ((Member) member).GetPreviouslyDirtyProperties());
2018-02-07 15:38:50 +01:00
_auditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp,
2018-02-07 15:38:50 +01:00
DateTime.Now,
-1, $"Member {member.Id} \"{member.Name}\" {FormatEmail(member)}",
"umbraco/member/save", $"updating {(string.IsNullOrWhiteSpace(dp) ? "(nothing)" : dp)}");
2018-02-07 15:38:50 +01:00
}
}
private void OnDeletedMember(IMemberService sender, DeleteEventArgs<IMember> deleteEventArgs)
{
var performingUser = PerformingUser;
var members = deleteEventArgs.DeletedEntities;
foreach (var member in members)
{
_auditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp,
2018-02-07 15:38:50 +01:00
DateTime.Now,
-1, $"Member {member.Id} \"{member.Name}\" {FormatEmail(member)}",
"umbraco/member/delete", $"delete member id:{member.Id} \"{member.Name}\" {FormatEmail(member)}");
2018-02-07 15:38:50 +01:00
}
}
private void OnSavedUser(IUserService sender, SaveEventArgs<IUser> saveEventArgs)
{
var performingUser = PerformingUser;
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).GetPreviouslyDirtyProperties());
_auditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp,
2018-02-07 15:38:50 +01:00
DateTime.Now,
affectedUser.Id, $"User \"{affectedUser.Name}\" {FormatEmail(affectedUser)}",
"umbraco/user/save", $"updating {(string.IsNullOrWhiteSpace(dp) ? "(nothing)" : dp)}{(groups == null ? "" : "; groups assigned: " + groups)}");
2018-02-07 15:38:50 +01:00
}
}
private void OnDeletedUser(IUserService sender, DeleteEventArgs<IUser> deleteEventArgs)
{
var performingUser = PerformingUser;
var affectedUsers = deleteEventArgs.DeletedEntities;
foreach (var affectedUser in affectedUsers)
_auditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", PerformingIp,
2018-02-07 15:38:50 +01:00
DateTime.Now,
affectedUser.Id, $"User \"{affectedUser.Name}\" {FormatEmail(affectedUser)}",
"umbraco/user/delete", "delete user");
2018-02-06 19:07:54 +01:00
}
private void OnLoginSuccess(object sender, EventArgs args)
{
if (args is IdentityAuditEventArgs identityArgs)
{
2018-02-09 09:33:24 +01:00
var performingUser = _userServiceInstance.GetUserById(identityArgs.PerformingUser);
if (performingUser == null) throw new InvalidOperationException($"No user found with id {identityArgs.PerformingUser}");
_auditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", identityArgs.IpAddress,
2018-02-07 15:38:50 +01:00
DateTime.Now,
0, null,
"umbraco/user/sign-in/login", "login success");
2018-02-06 19:07:54 +01:00
}
}
private void OnLogoutSuccess(object sender, EventArgs args)
{
if (args is IdentityAuditEventArgs identityArgs)
{
2018-02-09 09:33:24 +01:00
var performingUser = _userServiceInstance.GetUserById(identityArgs.PerformingUser);
if (performingUser == null) throw new InvalidOperationException($"No user found with id {identityArgs.PerformingUser}");
_auditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", identityArgs.IpAddress,
2018-02-07 15:38:50 +01:00
DateTime.Now,
0, null,
"umbraco/user/sign-in/logout", "logout success");
2018-02-07 15:38:50 +01:00
}
}
private void OnPasswordReset(object sender, EventArgs args)
{
if (args is IdentityAuditEventArgs identityArgs)
{
if (identityArgs.PerformingUser < 0) return;
2018-02-09 09:33:24 +01:00
var performingUser = _userServiceInstance.GetUserById(identityArgs.PerformingUser);
if (performingUser == null) throw new InvalidOperationException($"No user found with id {identityArgs.PerformingUser}");
2018-02-09 09:33:24 +01:00
var affectedUser = _userServiceInstance.GetUserById(identityArgs.AffectedUser);
if (affectedUser == null) throw new InvalidOperationException($"No user found with id {identityArgs.AffectedUser}");
_auditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", identityArgs.IpAddress,
2018-02-07 15:38:50 +01:00
DateTime.Now,
affectedUser.Id, $"User \"{affectedUser.Name}\" {FormatEmail(affectedUser)}",
"umbraco/user/password/reset", "password reset");
2018-02-07 15:38:50 +01:00
}
}
private void OnPasswordChanged(object sender, EventArgs args)
{
if (args is IdentityAuditEventArgs identityArgs)
{
if (identityArgs.PerformingUser < 0) return;
2018-02-09 09:33:24 +01:00
var performingUser = _userServiceInstance.GetUserById(identityArgs.PerformingUser);
if (performingUser == null) throw new InvalidOperationException($"No user found with id {identityArgs.PerformingUser}");
2018-02-09 09:33:24 +01:00
var affectedUser = _userServiceInstance.GetUserById(identityArgs.AffectedUser);
if (affectedUser == null) throw new InvalidOperationException($"No user found with id {identityArgs.AffectedUser}");
_auditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", identityArgs.IpAddress,
2018-02-07 15:38:50 +01:00
DateTime.Now,
affectedUser.Id, $"User \"{affectedUser.Name}\" {FormatEmail(affectedUser)}",
"umbraco/user/password/change", "password change");
2018-02-07 15:38:50 +01:00
}
}
private void OnLoginFailed(object sender, EventArgs args)
{
if (args is IdentityAuditEventArgs identityArgs)
{
if (identityArgs.PerformingUser < 0) return;
2018-02-09 09:33:24 +01:00
var performingUser = _userServiceInstance.GetUserById(identityArgs.PerformingUser);
if (performingUser == null) throw new InvalidOperationException($"No user found with id {identityArgs.PerformingUser}");
_auditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", identityArgs.IpAddress,
2018-02-07 15:38:50 +01:00
DateTime.Now,
0, null,
"umbraco/user/sign-in/failed", "login failed");
2018-02-07 15:38:50 +01:00
}
}
private void OnForgotPasswordChange(object sender, EventArgs args)
{
if (args is IdentityAuditEventArgs identityArgs)
{
2018-02-09 09:33:24 +01:00
var performingUser = _userServiceInstance.GetUserById(identityArgs.PerformingUser);
if (performingUser == null) throw new InvalidOperationException($"No user found with id {identityArgs.PerformingUser}");
2018-02-09 09:33:24 +01:00
var affectedUser = _userServiceInstance.GetUserById(identityArgs.AffectedUser);
if (affectedUser == null) throw new InvalidOperationException($"No user found with id {identityArgs.AffectedUser}");
_auditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", identityArgs.IpAddress,
2018-02-07 15:38:50 +01:00
DateTime.Now,
affectedUser.Id, $"User \"{affectedUser.Name}\" {FormatEmail(affectedUser)}",
"umbraco/user/password/forgot/change", "password forgot/change");
2018-02-07 15:38:50 +01:00
}
}
private void OnForgotPasswordRequest(object sender, EventArgs args)
{
if (args is IdentityAuditEventArgs identityArgs)
{
if (identityArgs.PerformingUser < 0) return;
2018-02-09 09:33:24 +01:00
var performingUser = _userServiceInstance.GetUserById(identityArgs.PerformingUser);
if (performingUser == null) throw new InvalidOperationException($"No user found with id {identityArgs.PerformingUser}");
2018-02-09 09:33:24 +01:00
var affectedUser = _userServiceInstance.GetUserById(identityArgs.AffectedUser);
if (affectedUser == null) throw new InvalidOperationException($"No user found with id {identityArgs.AffectedUser}");
_auditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}", identityArgs.IpAddress,
2018-02-07 15:38:50 +01:00
DateTime.Now,
affectedUser.Id, $"User \"{affectedUser.Name}\" {FormatEmail(affectedUser)}",
"umbraco/user/password/forgot/request", "password forgot/request");
2018-02-06 19:07:54 +01:00
}
}
}
}