Skip to content

Commit b414456

Browse files
authored
Merge commit from fork
1 parent f6dbe0f commit b414456

File tree

3 files changed

+31
-4
lines changed

3 files changed

+31
-4
lines changed

src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,17 @@ public AuthenticationController(
131131
AuthorizationPolicies.BackOfficeAccess)] // Needed to enforce the principle set on the request, if one exists.
132132
public IDictionary<string, object> GetPasswordConfig(int userId)
133133
{
134+
if (HttpContext.HasActivePasswordResetFlowSession(userId))
135+
{
136+
return _passwordConfiguration.GetConfiguration();
137+
}
138+
134139
Attempt<int> currentUserId =
135140
_backofficeSecurityAccessor.BackOfficeSecurity?.GetUserId() ?? Attempt<int>.Fail();
136-
return _passwordConfiguration.GetConfiguration(
137-
currentUserId.Success
138-
? currentUserId.Result != userId
139-
: true);
141+
142+
return currentUserId.Success
143+
? _passwordConfiguration.GetConfiguration(currentUserId.Result != userId)
144+
: new Dictionary<string, object>();
140145
}
141146

142147
/// <summary>
@@ -417,6 +422,8 @@ public async Task<bool> IsAuthenticated()
417422
[Authorize(Policy = AuthorizationPolicies.DenyLocalLoginIfConfigured)]
418423
public async Task<ActionResult<UserDetail?>> PostLogin(LoginModel loginModel)
419424
{
425+
HttpContext.EndPasswordResetFlowSession();
426+
420427
// Start a timed scope to ensure failed responses return is a consistent time
421428
var loginDuration = Math.Max(_loginDurationAverage ?? _securitySettings.UserDefaultFailedLoginDurationInMilliseconds, _securitySettings.UserMinimumFailedLoginDurationInMilliseconds);
422429
await using var timedScope = new TimedScope(loginDuration, HttpContext.RequestAborted);
@@ -490,6 +497,8 @@ public async Task<IActionResult> PostRequestPasswordReset(RequestPasswordResetMo
490497
return BadRequest();
491498
}
492499

500+
HttpContext.EndPasswordResetFlowSession();
501+
493502
BackOfficeIdentityUser? identityUser = await _userManager.FindByEmailAsync(model.Email);
494503

495504
await Task.Delay(RandomNumberGenerator.GetInt32(400, 2500)); // To randomize response time preventing user enumeration
@@ -646,6 +655,8 @@ public async Task<IActionResult> PostSend2FACode([FromBody] string provider)
646655
[AllowAnonymous]
647656
public async Task<IActionResult> PostSetPassword(SetPasswordModel model)
648657
{
658+
HttpContext.EndPasswordResetFlowSession();
659+
649660
BackOfficeIdentityUser? identityUser =
650661
await _userManager.FindByIdAsync(model.UserId.ToString(CultureInfo.InvariantCulture));
651662
if (identityUser is null)

src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,11 @@ public async Task<IActionResult> ValidatePasswordResetCode([Bind(Prefix = "u")]
402402

403403
var result = await _userManager.VerifyUserTokenAsync(user, "Default", "ResetPassword", resetCode);
404404

405+
if (result)
406+
{
407+
HttpContext.StartPasswordResetFlowSession(userId);
408+
}
409+
405410
return result ?
406411

407412
// Redirect to login with userId and resetCode

src/Umbraco.Web.BackOffice/Extensions/HttpContextExtensions.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,20 @@ namespace Umbraco.Extensions;
55

66
public static class HttpContextExtensions
77
{
8+
private const string PasswordResetFlowSessionKey = nameof(PasswordResetFlowSessionKey);
9+
810
public static void SetExternalLoginProviderErrors(this HttpContext httpContext, BackOfficeExternalLoginProviderErrors errors)
911
=> httpContext.Items[nameof(BackOfficeExternalLoginProviderErrors)] = errors;
1012

1113
public static BackOfficeExternalLoginProviderErrors? GetExternalLoginProviderErrors(this HttpContext httpContext)
1214
=> httpContext.Items[nameof(BackOfficeExternalLoginProviderErrors)] as BackOfficeExternalLoginProviderErrors;
15+
16+
internal static void StartPasswordResetFlowSession(this HttpContext httpContext, int userId)
17+
=> httpContext.Session.SetInt32(PasswordResetFlowSessionKey, userId);
18+
19+
internal static void EndPasswordResetFlowSession(this HttpContext httpContext)
20+
=> httpContext.Session.Remove(PasswordResetFlowSessionKey);
21+
22+
internal static bool HasActivePasswordResetFlowSession(this HttpContext httpContext, int userId)
23+
=> httpContext.Session.GetInt32(PasswordResetFlowSessionKey) == userId;
1324
}

0 commit comments

Comments
 (0)