mirror of
https://github.com/bitwarden/server.git
synced 2025-06-30 07:36:14 -05:00
feat(2FA): [PM-17129] Login with 2FA Recovery Code
* feat(2FA): [PM-17129] Login with 2FA Recovery Code - Login with Recovery Code working. * feat(2FA): [PM-17129] Login with 2FA Recovery Code - Feature flagged implementation. * style(2FA): [PM-17129] Login with 2FA Recovery Code - Code cleanup. * test(2FA): [PM-17129] Login with 2FA Recovery Code - Tests.
This commit is contained in:

committed by
GitHub

parent
465549b812
commit
ac6bc40d85
@ -1,4 +1,5 @@
|
||||
using System.Text.Json;
|
||||
using Bit.Core;
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.Auth.Enums;
|
||||
using Bit.Core.Auth.Identity.TokenProviders;
|
||||
@ -44,7 +45,7 @@ public interface ITwoFactorAuthenticationValidator
|
||||
/// <param name="twoFactorProviderType">Two Factor Provider to use to verify the token</param>
|
||||
/// <param name="token">secret passed from the user and consumed by the two-factor provider's verify method</param>
|
||||
/// <returns>boolean</returns>
|
||||
Task<bool> VerifyTwoFactor(User user, Organization organization, TwoFactorProviderType twoFactorProviderType, string token);
|
||||
Task<bool> VerifyTwoFactorAsync(User user, Organization organization, TwoFactorProviderType twoFactorProviderType, string token);
|
||||
}
|
||||
|
||||
public class TwoFactorAuthenticationValidator(
|
||||
@ -139,7 +140,7 @@ public class TwoFactorAuthenticationValidator(
|
||||
return twoFactorResultDict;
|
||||
}
|
||||
|
||||
public async Task<bool> VerifyTwoFactor(
|
||||
public async Task<bool> VerifyTwoFactorAsync(
|
||||
User user,
|
||||
Organization organization,
|
||||
TwoFactorProviderType type,
|
||||
@ -154,24 +155,39 @@ public class TwoFactorAuthenticationValidator(
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
if (_featureService.IsEnabled(FeatureFlagKeys.RecoveryCodeLogin))
|
||||
{
|
||||
case TwoFactorProviderType.Authenticator:
|
||||
case TwoFactorProviderType.Email:
|
||||
case TwoFactorProviderType.Duo:
|
||||
case TwoFactorProviderType.YubiKey:
|
||||
case TwoFactorProviderType.WebAuthn:
|
||||
case TwoFactorProviderType.Remember:
|
||||
if (type != TwoFactorProviderType.Remember &&
|
||||
!await _userService.TwoFactorProviderIsEnabledAsync(type, user))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return await _userManager.VerifyTwoFactorTokenAsync(user,
|
||||
CoreHelpers.CustomProviderName(type), token);
|
||||
default:
|
||||
return false;
|
||||
if (type is TwoFactorProviderType.RecoveryCode)
|
||||
{
|
||||
return await _userService.RecoverTwoFactorAsync(user, token);
|
||||
}
|
||||
}
|
||||
|
||||
// These cases we want to always return false, U2f is deprecated and OrganizationDuo
|
||||
// uses a different flow than the other two factor providers, it follows the same
|
||||
// structure of a UserTokenProvider but has it's logic ran outside the usual token
|
||||
// provider flow. See IOrganizationDuoUniversalTokenProvider.cs
|
||||
if (type is TwoFactorProviderType.U2f or TwoFactorProviderType.OrganizationDuo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now we are concerning the rest of the Two Factor Provider Types
|
||||
|
||||
// The intent of this check is to make sure that the user is using a 2FA provider that
|
||||
// is enabled and allowed by their premium status. The exception for Remember
|
||||
// is because it is a "special" 2FA type that isn't ever explicitly
|
||||
// enabled by a user, so we can't check the user's 2FA providers to see if they're
|
||||
// enabled. We just have to check if the token is valid.
|
||||
if (type != TwoFactorProviderType.Remember &&
|
||||
!await _userService.TwoFactorProviderIsEnabledAsync(type, user))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Finally, verify the token based on the provider type.
|
||||
return await _userManager.VerifyTwoFactorTokenAsync(
|
||||
user, CoreHelpers.CustomProviderName(type), token);
|
||||
}
|
||||
|
||||
private async Task<List<KeyValuePair<TwoFactorProviderType, TwoFactorProvider>>> GetEnabledTwoFactorProvidersAsync(
|
||||
|
Reference in New Issue
Block a user