bitwarden-mobile/src/Core/Services/UserVerificationService.cs

96 lines
3.6 KiB
C#

using System.Threading.Tasks;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Models.Request;
namespace Bit.Core.Services
{
public class UserVerificationService : IUserVerificationService
{
private readonly IApiService _apiService;
private readonly IPlatformUtilsService _platformUtilsService;
private readonly II18nService _i18nService;
private readonly ICryptoService _cryptoService;
private readonly IStateService _stateService;
private readonly IKeyConnectorService _keyConnectorService;
public UserVerificationService(IApiService apiService, IPlatformUtilsService platformUtilsService,
II18nService i18nService, ICryptoService cryptoService, IStateService stateService, IKeyConnectorService keyConnectorService)
{
_apiService = apiService;
_platformUtilsService = platformUtilsService;
_i18nService = i18nService;
_cryptoService = cryptoService;
_stateService = stateService;
_keyConnectorService = keyConnectorService;
}
public async Task<bool> VerifyUser(string secret, VerificationType verificationType)
{
if (string.IsNullOrEmpty(secret))
{
await InvalidSecretErrorAsync(verificationType);
return false;
}
if (verificationType == VerificationType.OTP)
{
var request = new VerifyOTPRequest(secret);
try
{
await _apiService.PostAccountVerifyOTPAsync(request);
}
catch
{
await InvalidSecretErrorAsync(verificationType);
return false;
}
}
else
{
var masterKey = await _cryptoService.GetOrDeriveMasterKeyAsync(secret);
var passwordValid = await _cryptoService.CompareAndUpdateKeyHashAsync(secret, masterKey);
if (!passwordValid)
{
await InvalidSecretErrorAsync(verificationType);
return false;
}
await _cryptoService.UpdateMasterKeyAndUserKeyAsync(masterKey);
}
return true;
}
public async Task<bool> VerifyMasterPasswordAsync(string masterPassword)
{
var masterKey = await _cryptoService.GetOrDeriveMasterKeyAsync(masterPassword);
return await _cryptoService.CompareAndUpdateKeyHashAsync(masterPassword, masterKey);
}
async private Task InvalidSecretErrorAsync(VerificationType verificationType)
{
var errorMessage = verificationType == VerificationType.OTP
? _i18nService.T("InvalidVerificationCode")
: _i18nService.T("InvalidMasterPassword");
await _platformUtilsService.ShowDialogAsync(errorMessage);
}
public async Task<bool> HasMasterPasswordAsync(bool checkMasterKeyHash = false)
{
async Task<bool> CheckMasterKeyHashAsync()
{
return !checkMasterKeyHash || await _cryptoService.GetMasterKeyHashAsync() != null;
};
var decryptOptions = await _stateService.GetAccountDecryptionOptions();
if (decryptOptions != null)
{
return decryptOptions.HasMasterPassword && await CheckMasterKeyHashAsync();
}
return !await _keyConnectorService.GetUsesKeyConnectorAsync() && await CheckMasterKeyHashAsync();
}
}
}