BITAU-108 Add unlockWithAuthenticatorSyncKey to VaultRepository (#3909)

This commit is contained in:
Andrew Haisting 2024-09-18 16:41:57 -05:00 committed by GitHub
parent 84f92f1b13
commit cdf8b49d61
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 116 additions and 0 deletions

View file

@ -167,6 +167,18 @@ interface VaultRepository : CipherManager, VaultLockManager {
*/
fun emitTotpCodeResult(totpCodeResult: TotpCodeResult)
/**
* Attempt to unlock the vault using a user unlock key.
*
* @param userId ID of the user's vault to unlock.
* @param decryptedUserKey A decrypted unlock key for the user (ex: their authenticator
* sync unlock key)
*/
suspend fun unlockVaultWithDecryptedUserKey(
userId: String,
decryptedUserKey: String,
): VaultUnlockResult
/**
* Attempt to unlock the vault using the stored biometric key for the currently active user.
*/

View file

@ -553,6 +553,16 @@ class VaultRepositoryImpl(
mutableTotpCodeResultFlow.tryEmit(totpCodeResult)
}
override suspend fun unlockVaultWithDecryptedUserKey(
userId: String,
decryptedUserKey: String,
): VaultUnlockResult = unlockVaultForUser(
userId = userId,
initUserCryptoMethod = InitUserCryptoMethod.DecryptedKey(
decryptedUserKey = decryptedUserKey,
),
)
override suspend fun unlockVaultWithBiometrics(): VaultUnlockResult {
val userId = activeUserId ?: return VaultUnlockResult.InvalidStateError
val biometricsKey = authDiskSource

View file

@ -1243,6 +1243,100 @@ class VaultRepositoryTest {
}
}
@Test
@Suppress("MaxLineLength")
fun `unlockVaultWithDecryptedUserKey with VaultLockManager Success should return Success`() =
runTest {
val userId = MOCK_USER_STATE.activeUserId
val authenticatorSyncUnlockKey = "asdf1234"
val privateKey = "mockPrivateKey-1"
fakeAuthDiskSource.userState = MOCK_USER_STATE
coEvery {
vaultLockManager.unlockVault(
userId = userId,
kdf = MOCK_PROFILE.toSdkParams(),
email = "email",
privateKey = privateKey,
initUserCryptoMethod = InitUserCryptoMethod.DecryptedKey(
decryptedUserKey = authenticatorSyncUnlockKey,
),
organizationKeys = null,
)
} returns VaultUnlockResult.Success
fakeAuthDiskSource.apply {
storeAuthenticatorSyncUnlockKey(
userId = userId,
authenticatorSyncUnlockKey = authenticatorSyncUnlockKey,
)
storePrivateKey(userId = userId, privateKey = privateKey)
}
val result = vaultRepository.unlockVaultWithDecryptedUserKey(
userId = userId,
decryptedUserKey = authenticatorSyncUnlockKey,
)
assertEquals(VaultUnlockResult.Success, result)
coVerify {
vaultLockManager.unlockVault(
userId = userId,
kdf = MOCK_PROFILE.toSdkParams(),
email = "email",
privateKey = "mockPrivateKey-1",
initUserCryptoMethod = InitUserCryptoMethod.DecryptedKey(
decryptedUserKey = authenticatorSyncUnlockKey,
),
organizationKeys = null,
)
}
}
@Test
@Suppress("MaxLineLength")
fun `unlockVaultWithDecryptedUserKey with VaultLockManager InvalidStateError should return InvalidStateError`() =
runTest {
val userId = MOCK_USER_STATE.activeUserId
val authenticatorSyncUnlockKey = "asdf1234"
val privateKey = "mockPrivateKey-1"
fakeAuthDiskSource.userState = MOCK_USER_STATE
coEvery {
vaultLockManager.unlockVault(
userId = userId,
kdf = MOCK_PROFILE.toSdkParams(),
email = "email",
privateKey = privateKey,
initUserCryptoMethod = InitUserCryptoMethod.DecryptedKey(
decryptedUserKey = authenticatorSyncUnlockKey,
),
organizationKeys = null,
)
} returns VaultUnlockResult.InvalidStateError
fakeAuthDiskSource.apply {
storeAuthenticatorSyncUnlockKey(
userId = userId,
authenticatorSyncUnlockKey = authenticatorSyncUnlockKey,
)
storePrivateKey(userId = userId, privateKey = privateKey)
}
val result = vaultRepository.unlockVaultWithDecryptedUserKey(
userId = userId,
decryptedUserKey = authenticatorSyncUnlockKey,
)
assertEquals(VaultUnlockResult.InvalidStateError, result)
coVerify {
vaultLockManager.unlockVault(
userId = userId,
kdf = MOCK_PROFILE.toSdkParams(),
email = "email",
privateKey = "mockPrivateKey-1",
initUserCryptoMethod = InitUserCryptoMethod.DecryptedKey(
decryptedUserKey = authenticatorSyncUnlockKey,
),
organizationKeys = null,
)
}
}
@Test
fun `unlockVaultWithMasterPassword with missing user state should return InvalidStateError`() =
runTest {