mirror of
https://github.com/bitwarden/server.git
synced 2025-07-03 00:52:49 -05:00
[EC-400] Code clean up Device Verification (#2601)
* EC-400 Clean up code regarding Unknown Device Verification * EC-400 Fix formatting
This commit is contained in:

committed by
GitHub

parent
7594ca1122
commit
69511160cb
@ -100,24 +100,20 @@ public abstract class BaseRequestValidator<T> where T : class
|
||||
return;
|
||||
}
|
||||
|
||||
var (isTwoFactorRequired, requires2FABecauseNewDevice, twoFactorOrganization) = await RequiresTwoFactorAsync(user, request);
|
||||
var (isTwoFactorRequired, twoFactorOrganization) = await RequiresTwoFactorAsync(user, request);
|
||||
if (isTwoFactorRequired)
|
||||
{
|
||||
// Just defaulting it
|
||||
var twoFactorProviderType = TwoFactorProviderType.Authenticator;
|
||||
if (!twoFactorRequest || !Enum.TryParse(twoFactorProvider, out twoFactorProviderType))
|
||||
{
|
||||
await BuildTwoFactorResultAsync(user, twoFactorOrganization, context, requires2FABecauseNewDevice);
|
||||
await BuildTwoFactorResultAsync(user, twoFactorOrganization, context);
|
||||
return;
|
||||
}
|
||||
|
||||
BeforeVerifyTwoFactor(user, twoFactorProviderType, requires2FABecauseNewDevice);
|
||||
|
||||
var verified = await VerifyTwoFactor(user, twoFactorOrganization,
|
||||
twoFactorProviderType, twoFactorToken);
|
||||
|
||||
AfterVerifyTwoFactor(user, twoFactorProviderType, requires2FABecauseNewDevice);
|
||||
|
||||
if ((!verified || isBot) && twoFactorProviderType != TwoFactorProviderType.Remember)
|
||||
{
|
||||
await UpdateFailedAuthDetailsAsync(user, true, !validatorContext.KnownDevice);
|
||||
@ -128,7 +124,7 @@ public abstract class BaseRequestValidator<T> where T : class
|
||||
{
|
||||
// Delay for brute force.
|
||||
await Task.Delay(2000);
|
||||
await BuildTwoFactorResultAsync(user, twoFactorOrganization, context, requires2FABecauseNewDevice);
|
||||
await BuildTwoFactorResultAsync(user, twoFactorOrganization, context);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -201,7 +197,7 @@ public abstract class BaseRequestValidator<T> where T : class
|
||||
await SetSuccessResult(context, user, claims, customResponse);
|
||||
}
|
||||
|
||||
protected async Task BuildTwoFactorResultAsync(User user, Organization organization, T context, bool requires2FABecauseNewDevice)
|
||||
protected async Task BuildTwoFactorResultAsync(User user, Organization organization, T context)
|
||||
{
|
||||
var providerKeys = new List<byte>();
|
||||
var providers = new Dictionary<string, Dictionary<string, object>>();
|
||||
@ -226,23 +222,8 @@ public abstract class BaseRequestValidator<T> where T : class
|
||||
|
||||
if (!enabledProviders.Any())
|
||||
{
|
||||
if (!requires2FABecauseNewDevice)
|
||||
{
|
||||
await BuildErrorResultAsync("No two-step providers enabled.", false, context, user);
|
||||
return;
|
||||
}
|
||||
|
||||
var emailProvider = new TwoFactorProvider
|
||||
{
|
||||
MetaData = new Dictionary<string, object> { ["Email"] = user.Email.ToLowerInvariant() },
|
||||
Enabled = true
|
||||
};
|
||||
enabledProviders.Add(new KeyValuePair<TwoFactorProviderType, TwoFactorProvider>(
|
||||
TwoFactorProviderType.Email, emailProvider));
|
||||
user.SetTwoFactorProviders(new Dictionary<TwoFactorProviderType, TwoFactorProvider>
|
||||
{
|
||||
[TwoFactorProviderType.Email] = emailProvider
|
||||
});
|
||||
await BuildErrorResultAsync("No two-step providers enabled.", false, context, user);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var provider in enabledProviders)
|
||||
@ -262,7 +243,7 @@ public abstract class BaseRequestValidator<T> where T : class
|
||||
if (enabledProviders.Count() == 1 && enabledProviders.First().Key == TwoFactorProviderType.Email)
|
||||
{
|
||||
// Send email now if this is their only 2FA method
|
||||
await _userService.SendTwoFactorEmailAsync(user, requires2FABecauseNewDevice);
|
||||
await _userService.SendTwoFactorEmailAsync(user);
|
||||
}
|
||||
}
|
||||
|
||||
@ -298,12 +279,12 @@ public abstract class BaseRequestValidator<T> where T : class
|
||||
|
||||
protected abstract void SetErrorResult(T context, Dictionary<string, object> customResponse);
|
||||
|
||||
private async Task<Tuple<bool, bool, Organization>> RequiresTwoFactorAsync(User user, ValidatedTokenRequest request)
|
||||
private async Task<Tuple<bool, Organization>> RequiresTwoFactorAsync(User user, ValidatedTokenRequest request)
|
||||
{
|
||||
if (request.GrantType == "client_credentials")
|
||||
{
|
||||
// Do not require MFA for api key logins
|
||||
return new Tuple<bool, bool, Organization>(false, false, null);
|
||||
return new Tuple<bool, Organization>(false, null);
|
||||
}
|
||||
|
||||
var individualRequired = _userManager.SupportsUserTwoFactor &&
|
||||
@ -325,17 +306,7 @@ public abstract class BaseRequestValidator<T> where T : class
|
||||
}
|
||||
}
|
||||
|
||||
var requires2FA = individualRequired || firstEnabledOrg != null;
|
||||
var requires2FABecauseNewDevice = !requires2FA
|
||||
&&
|
||||
await _userService.Needs2FABecauseNewDeviceAsync(
|
||||
user,
|
||||
GetDeviceFromRequest(request)?.Identifier,
|
||||
request.GrantType);
|
||||
|
||||
requires2FA = requires2FA || requires2FABecauseNewDevice;
|
||||
|
||||
return new Tuple<bool, bool, Organization>(requires2FA, requires2FABecauseNewDevice, firstEnabledOrg);
|
||||
return new Tuple<bool, Organization>(individualRequired || firstEnabledOrg != null, firstEnabledOrg);
|
||||
}
|
||||
|
||||
private async Task<bool> IsValidAuthTypeAsync(User user, string grantType)
|
||||
@ -413,29 +384,6 @@ public abstract class BaseRequestValidator<T> where T : class
|
||||
};
|
||||
}
|
||||
|
||||
private void BeforeVerifyTwoFactor(User user, TwoFactorProviderType type, bool requires2FABecauseNewDevice)
|
||||
{
|
||||
if (type == TwoFactorProviderType.Email && requires2FABecauseNewDevice)
|
||||
{
|
||||
user.SetTwoFactorProviders(new Dictionary<TwoFactorProviderType, TwoFactorProvider>
|
||||
{
|
||||
[TwoFactorProviderType.Email] = new TwoFactorProvider
|
||||
{
|
||||
MetaData = new Dictionary<string, object> { ["Email"] = user.Email.ToLowerInvariant() },
|
||||
Enabled = true
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void AfterVerifyTwoFactor(User user, TwoFactorProviderType type, bool requires2FABecauseNewDevice)
|
||||
{
|
||||
if (type == TwoFactorProviderType.Email && requires2FABecauseNewDevice)
|
||||
{
|
||||
user.ClearTwoFactorProviders();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> VerifyTwoFactor(User user, Organization organization, TwoFactorProviderType type,
|
||||
string token)
|
||||
{
|
||||
|
Reference in New Issue
Block a user