diff --git a/src/Umbraco.Core/Security/BackOfficeSignInManager.cs b/src/Umbraco.Core/Security/BackOfficeSignInManager.cs index fd1d828369..073fbc87a2 100644 --- a/src/Umbraco.Core/Security/BackOfficeSignInManager.cs +++ b/src/Umbraco.Core/Security/BackOfficeSignInManager.cs @@ -49,7 +49,7 @@ namespace Umbraco.Core.Security public override async Task PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout) { var result = await PasswordSignInAsyncImpl(userName, password, isPersistent, shouldLockout); - + switch (result) { case SignInStatus.Success: @@ -121,6 +121,11 @@ namespace Umbraco.Core.Security await UserManager.AccessFailedAsync(user.Id); if (await UserManager.IsLockedOutAsync(user.Id)) { + //at this point we've just locked the user out after too many failed login attempts + var backofficeUserManager = _request.Context.GetBackOfficeUserManager(); + if(backofficeUserManager != null) + backofficeUserManager.RaiseAccountLockedEvent(user.Id); + return SignInStatus.LockedOut; } } @@ -176,7 +181,7 @@ namespace Umbraco.Core.Security AllowRefresh = true, IssuedUtc = nowUtc, ExpiresUtc = nowUtc.AddMinutes(GlobalSettings.TimeOutInMinutes) - }, userIdentity, rememberBrowserIdentity); + }, userIdentity, rememberBrowserIdentity); } else { diff --git a/src/Umbraco.Core/Security/BackOfficeUserManager.cs b/src/Umbraco.Core/Security/BackOfficeUserManager.cs index e1788cd46e..9d456be458 100644 --- a/src/Umbraco.Core/Security/BackOfficeUserManager.cs +++ b/src/Umbraco.Core/Security/BackOfficeUserManager.cs @@ -238,15 +238,21 @@ namespace Umbraco.Core.Security /// public IBackOfficeUserPasswordChecker BackOfficeUserPasswordChecker { get; set; } - public override Task SetLockoutEnabledAsync(int userId, bool enabled) + public override Task SetLockoutEndDateAsync(int userId, DateTimeOffset lockoutEnd) { - var result = base.SetLockoutEnabledAsync(userId, enabled); + var result = base.SetLockoutEndDateAsync(userId, lockoutEnd); - if (result.Result.Succeeded) + // The way we unlock is by setting the lockoutEnd date to the current datetime + if (result.Result.Succeeded && lockoutEnd >= DateTimeOffset.UtcNow) OnAccountLocked(new IdentityAuditEventArgs(AuditEvent.AccountLocked) { AffectedUser = userId }); + else + OnAccountUnlocked(new IdentityAuditEventArgs(AuditEvent.AccountUnlocked) + { + AffectedUser = userId + }); return result; } @@ -414,7 +420,7 @@ namespace Umbraco.Core.Security ApplicationContext.Current.Services.UserService.Save(user); - OnAccounthUnlocked(new IdentityAuditEventArgs(AuditEvent.AccountUnlocked) + OnAccountUnlocked(new IdentityAuditEventArgs(AuditEvent.AccountUnlocked) { AffectedUser = user.Id }); @@ -444,7 +450,7 @@ namespace Umbraco.Core.Security if (AccountLocked != null) AccountLocked(this, e); } - protected virtual void OnAccounthUnlocked(IdentityAuditEventArgs e) + protected virtual void OnAccountUnlocked(IdentityAuditEventArgs e) { if (AccountUnlocked != null) AccountUnlocked(this, e); }