Attempt to raise events from parts of code that don't hit the BackOfficeUserManager directly

This commit is contained in:
Sebastiaan Janssen
2017-04-29 12:49:56 +02:00
parent ecca480334
commit ae17172126
5 changed files with 111 additions and 8 deletions

View File

@@ -1,7 +1,5 @@
using System;
using System.Web;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Umbraco.Core.Security;
namespace Umbraco.Core.Auditing
@@ -61,11 +59,12 @@ namespace Umbraco.Core.Auditing
AccountLocked,
AccountUnlocked,
LoginSucces,
Logout,
LogoutSuccess,
AccessFailed,
PasswordChanged,
AccountCreated,
AccountCreated, //not yet being called
ResetAccessFailedCount,
AccountUpdated
AccountUpdated,
PasswordReset
}
}

View File

@@ -238,7 +238,6 @@ namespace Umbraco.Core.Security
/// </summary>
public IBackOfficeUserPasswordChecker BackOfficeUserPasswordChecker { get; set; }
//TODO: Call this method (?)
public override Task<IdentityResult> SetLockoutEnabledAsync(int userId, bool enabled)
{
var result = base.SetLockoutEnabledAsync(userId, enabled);
@@ -265,7 +264,6 @@ namespace Umbraco.Core.Security
return result;
}
//TODO: Call this method (?)
public override Task<IdentityResult> ChangePasswordAsync(int userId, string currentPassword, string newPassword)
{
var result = base.ChangePasswordAsync(userId, currentPassword, newPassword);
@@ -315,6 +313,54 @@ namespace Umbraco.Core.Security
return await Task.FromResult(IdentityResult.Success);
}
internal void RaisePasswordChangedEvent(int userId)
{
OnAuthResetAccessFailedCount(new IdentityAuditEventArgs(AuditEvent.PasswordChanged)
{
AffectedUser = userId
});
}
internal void RaisePasswordResetEvent(int userId)
{
OnAuthResetAccessFailedCount(new IdentityAuditEventArgs(AuditEvent.PasswordReset)
{
AffectedUser = userId
});
}
internal void RaiseAccountLockedEvent(int userId)
{
OnAuthResetAccessFailedCount(new IdentityAuditEventArgs(AuditEvent.AccountLocked)
{
AffectedUser = userId
});
}
internal void RaiseResetAccessFailedCountEvent(int userId)
{
OnAuthResetAccessFailedCount(new IdentityAuditEventArgs(AuditEvent.ResetAccessFailedCount)
{
AffectedUser = userId
});
}
internal void RaiseLoginSuccessEvent(int userId)
{
OnAuthResetAccessFailedCount(new IdentityAuditEventArgs(AuditEvent.LoginSucces)
{
AffectedUser = userId
});
}
internal void RaiseLogoutSuccessEvent(int userId)
{
OnAuthResetAccessFailedCount(new IdentityAuditEventArgs(AuditEvent.LogoutSuccess)
{
AffectedUser = userId
});
}
public override Task<IdentityResult> UpdateAsync(T user)
{
var result = base.UpdateAsync(user);

View File

@@ -327,9 +327,27 @@ namespace Umbraco.Web.Editors
() => User.Identity == null ? "UNKNOWN" : User.Identity.Name,
() => TryGetOwinContext().Result.Request.RemoteIpAddress);
var backofficeUserManager = GetBackofficeUserManager();
if (backofficeUserManager != null)
{
var userId = -1;
int.TryParse(User.Identity.GetUserId(), out userId);
backofficeUserManager.RaiseLogoutSuccessEvent(userId);
}
return Request.CreateResponse(HttpStatusCode.OK);
}
internal BackOfficeUserManager<BackOfficeIdentityUser> GetBackofficeUserManager()
{
if (HttpContext.Current == null) return null;
var owinContext = HttpContext.Current.GetOwinContext();
if (owinContext == null) return null;
var userManager = owinContext.GetBackOfficeUserManager();
if (userManager == null) return null;
return userManager;
}
/// <summary>
/// This is used when the user is auth'd successfully and we need to return an OK with user details along with setting the current Principal in the request

View File

@@ -13,6 +13,7 @@ using Umbraco.Core.Security;
using Umbraco.Web.Models;
using Umbraco.Web.PublishedCache;
using Umbraco.Core.Cache;
using Umbraco.Core.Models.Identity;
using Umbraco.Web.Security.Providers;
using MPE = global::Umbraco.Core.Security.MembershipProviderExtensions;
@@ -660,6 +661,15 @@ namespace Umbraco.Web.Security
if (passwordModel == null) throw new ArgumentNullException("passwordModel");
if (membershipProvider == null) throw new ArgumentNullException("membershipProvider");
int userId = -1;
var backofficeUserManager = GetBackofficeUserManager();
if (backofficeUserManager != null)
{
var profile = _applicationContext.Services.UserService.GetProfileByUserName(username);
if (profile != null)
int.TryParse(profile.Id.ToString(), out userId);
}
//Are we resetting the password??
if (passwordModel.Reset.HasValue && passwordModel.Reset.Value)
{
@@ -679,6 +689,9 @@ namespace Umbraco.Web.Security
username,
membershipProvider.RequiresQuestionAndAnswer ? passwordModel.Answer : null);
if (backofficeUserManager != null && userId >= 0)
backofficeUserManager.RaisePasswordResetEvent(userId);
//return the generated pword
return Attempt.Succeed(new PasswordChangedModel { ResetPassword = newPass });
}
@@ -729,6 +742,10 @@ namespace Umbraco.Web.Security
try
{
var result = membershipProvider.ChangePassword(username, passwordModel.OldPassword, passwordModel.NewPassword);
if (result && backofficeUserManager != null && userId >= 0)
backofficeUserManager.RaisePasswordChangedEvent(userId);
return result == false
? Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Could not change password, invalid username or password", new[] { "value" }) })
: Attempt.Succeed(new PasswordChangedModel());
@@ -870,5 +887,15 @@ namespace Umbraco.Web.Security
return sb.ToString();
}
internal BackOfficeUserManager<BackOfficeIdentityUser> GetBackofficeUserManager()
{
if (HttpContext.Current == null) return null;
var owinContext = HttpContext.Current.GetOwinContext();
if (owinContext == null) return null;
var userManager = owinContext.GetBackOfficeUserManager();
if (userManager == null) return null;
return userManager;
}
}
}

View File

@@ -551,6 +551,7 @@ namespace Umbraco.Web.Security.Providers
}
var authenticated = CheckPassword(password, member.RawPasswordValue);
var backofficeUserManager = GetBackofficeUserManager();
if (authenticated == false)
{
@@ -570,6 +571,9 @@ namespace Umbraco.Web.Security.Providers
"Login attempt failed for username {0} from IP address {1}, the user is now locked out, max invalid password attempts exceeded",
username,
GetCurrentRequestIpAddress()));
if(backofficeUserManager != null)
backofficeUserManager.RaiseAccountLockedEvent(member.Id);
}
else
{
@@ -582,7 +586,13 @@ namespace Umbraco.Web.Security.Providers
}
else
{
member.FailedPasswordAttempts = 0;
if (member.FailedPasswordAttempts > 0)
{
member.FailedPasswordAttempts = 0;
if (backofficeUserManager != null)
backofficeUserManager.RaiseResetAccessFailedCountEvent(member.Id);
}
member.LastLoginDate = DateTime.Now;
LogHelper.Info<UmbracoMembershipProviderBase>(
@@ -590,6 +600,9 @@ namespace Umbraco.Web.Security.Providers
"Login attempt succeeded for username {0} from IP address {1}",
username,
GetCurrentRequestIpAddress()));
if (backofficeUserManager != null)
backofficeUserManager.RaiseLoginSuccessEvent(member.Id);
}
//don't raise events for this! It just sets the member dates, if we do raise events this will