mirror of
https://github.com/bitwarden/android.git
synced 2025-03-15 10:48:47 +03:00
Add unlockVaultWithPinAndSync to VaultRepository (#613)
This commit is contained in:
parent
18af449e1f
commit
3e28e5cc9b
5 changed files with 375 additions and 202 deletions
|
@ -108,9 +108,20 @@ interface VaultRepository : VaultLockManager {
|
|||
fun emitTotpCodeResult(totpCodeResult: TotpCodeResult)
|
||||
|
||||
/**
|
||||
* Attempt to unlock the vault and sync the vault data for the currently active user.
|
||||
* Attempt to unlock the vault with the given [masterPassword] and syncs the vault data for the
|
||||
* currently active user.
|
||||
*/
|
||||
suspend fun unlockVaultAndSyncForCurrentUser(masterPassword: String): VaultUnlockResult
|
||||
suspend fun unlockVaultWithMasterPasswordAndSync(
|
||||
masterPassword: String,
|
||||
): VaultUnlockResult
|
||||
|
||||
/**
|
||||
* Attempt to unlock the vault with the given [pin] and syncs the vault data for the currently
|
||||
* active user.
|
||||
*/
|
||||
suspend fun unlockVaultWithPinAndSync(
|
||||
pin: String,
|
||||
): VaultUnlockResult
|
||||
|
||||
/**
|
||||
* Attempt to unlock the vault with the specified user information.
|
||||
|
|
|
@ -284,7 +284,7 @@ class VaultRepositoryImpl(
|
|||
}
|
||||
|
||||
@Suppress("ReturnCount")
|
||||
override suspend fun unlockVaultAndSyncForCurrentUser(
|
||||
override suspend fun unlockVaultWithMasterPasswordAndSync(
|
||||
masterPassword: String,
|
||||
): VaultUnlockResult {
|
||||
val userId = activeUserId ?: return VaultUnlockResult.InvalidStateError
|
||||
|
@ -304,6 +304,27 @@ class VaultRepositoryImpl(
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("ReturnCount")
|
||||
override suspend fun unlockVaultWithPinAndSync(
|
||||
pin: String,
|
||||
): VaultUnlockResult {
|
||||
val userId = activeUserId ?: return VaultUnlockResult.InvalidStateError
|
||||
val pinProtectedUserKey = authDiskSource.getPinProtectedUserKey(userId = userId)
|
||||
?: return VaultUnlockResult.InvalidStateError
|
||||
return unlockVaultForUser(
|
||||
userId = userId,
|
||||
initUserCryptoMethod = InitUserCryptoMethod.Pin(
|
||||
pin = pin,
|
||||
pinProtectedUserKey = pinProtectedUserKey,
|
||||
),
|
||||
)
|
||||
.also {
|
||||
if (it is VaultUnlockResult.Success) {
|
||||
sync()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun unlockVault(
|
||||
userId: String,
|
||||
masterPassword: String,
|
||||
|
|
|
@ -127,7 +127,7 @@ class VaultUnlockViewModel @Inject constructor(
|
|||
private fun handleUnlockClick() {
|
||||
mutableStateFlow.update { it.copy(dialog = VaultUnlockState.VaultUnlockDialog.Loading) }
|
||||
viewModelScope.launch {
|
||||
val vaultUnlockResult = vaultRepo.unlockVaultAndSyncForCurrentUser(
|
||||
val vaultUnlockResult = vaultRepo.unlockVaultWithMasterPasswordAndSync(
|
||||
mutableStateFlow.value.passwordInput,
|
||||
)
|
||||
sendAction(VaultUnlockAction.Internal.ReceiveVaultUnlockResult(vaultUnlockResult))
|
||||
|
|
|
@ -553,61 +553,111 @@ class VaultRepositoryTest {
|
|||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `unlockVaultAndSyncForCurrentUser with VaultLockManager Success should unlock for the current user, sync, and return Success`() =
|
||||
fun `unlockVaultWithMasterPasswordAndSync with missing user state should return InvalidStateError `() =
|
||||
runTest {
|
||||
val userId = "mockId-1"
|
||||
val mockSyncResponse = createMockSyncResponse(number = 1)
|
||||
coEvery { syncService.sync() } returns mockSyncResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.initializeOrganizationCrypto(
|
||||
userId = userId,
|
||||
request = InitOrgCryptoRequest(
|
||||
organizationKeys = createMockOrganizationKeys(1),
|
||||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = MOCK_USER_STATE.activeUserId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptSendList(
|
||||
userId = userId,
|
||||
sendList = listOf(createMockSdkSend(number = 1)),
|
||||
)
|
||||
} returns listOf(createMockSendView(number = 1)).asSuccess()
|
||||
fakeAuthDiskSource.userState = null
|
||||
assertEquals(
|
||||
VaultState(
|
||||
unlockedVaultUserIds = emptySet(),
|
||||
unlockingVaultUserIds = emptySet(),
|
||||
),
|
||||
vaultRepository.vaultStateFlow.value,
|
||||
)
|
||||
|
||||
val result = vaultRepository.unlockVaultWithMasterPasswordAndSync(masterPassword = "")
|
||||
|
||||
assertEquals(
|
||||
VaultUnlockResult.InvalidStateError,
|
||||
result,
|
||||
)
|
||||
assertEquals(
|
||||
VaultState(
|
||||
unlockedVaultUserIds = emptySet(),
|
||||
unlockingVaultUserIds = emptySet(),
|
||||
),
|
||||
vaultRepository.vaultStateFlow.value,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `unlockVaultWithMasterPasswordAndSync with missing user key should return InvalidStateError `() =
|
||||
runTest {
|
||||
assertEquals(
|
||||
VaultState(
|
||||
unlockedVaultUserIds = emptySet(),
|
||||
unlockingVaultUserIds = emptySet(),
|
||||
),
|
||||
vaultRepository.vaultStateFlow.value,
|
||||
)
|
||||
|
||||
val result = vaultRepository.unlockVaultWithMasterPasswordAndSync(masterPassword = "")
|
||||
fakeAuthDiskSource.storeUserKey(
|
||||
userId = "mockId-1",
|
||||
userKey = null,
|
||||
)
|
||||
fakeAuthDiskSource.storePrivateKey(
|
||||
userId = "mockId-1",
|
||||
privateKey = "mockPrivateKey-1",
|
||||
)
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
assertEquals(
|
||||
VaultUnlockResult.InvalidStateError,
|
||||
result,
|
||||
)
|
||||
assertEquals(
|
||||
VaultState(
|
||||
unlockedVaultUserIds = emptySet(),
|
||||
unlockingVaultUserIds = emptySet(),
|
||||
),
|
||||
vaultRepository.vaultStateFlow.value,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `unlockVaultWithMasterPasswordAndSync with missing private key should return InvalidStateError `() =
|
||||
runTest {
|
||||
assertEquals(
|
||||
VaultState(
|
||||
unlockedVaultUserIds = emptySet(),
|
||||
unlockingVaultUserIds = emptySet(),
|
||||
),
|
||||
vaultRepository.vaultStateFlow.value,
|
||||
)
|
||||
val result = vaultRepository.unlockVaultWithMasterPasswordAndSync(masterPassword = "")
|
||||
fakeAuthDiskSource.storeUserKey(
|
||||
userId = "mockId-1",
|
||||
userKey = "mockKey-1",
|
||||
)
|
||||
fakeAuthDiskSource.storeOrganizationKeys(
|
||||
fakeAuthDiskSource.storePrivateKey(
|
||||
userId = "mockId-1",
|
||||
organizationKeys = createMockOrganizationKeys(number = 1),
|
||||
privateKey = null,
|
||||
)
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
assertEquals(
|
||||
VaultUnlockResult.InvalidStateError,
|
||||
result,
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
VaultState(
|
||||
unlockedVaultUserIds = emptySet(),
|
||||
unlockingVaultUserIds = emptySet(),
|
||||
),
|
||||
vaultRepository.vaultStateFlow.value,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `unlockVaultWithMasterPasswordAndSync with VaultLockManager Success should unlock for the current user, sync, and return Success`() =
|
||||
runTest {
|
||||
val userId = "mockId-1"
|
||||
val mockVaultUnlockResult = VaultUnlockResult.Success
|
||||
coEvery {
|
||||
vaultLockManager.unlockVault(
|
||||
userId = userId,
|
||||
kdf = MOCK_PROFILE.toSdkParams(),
|
||||
email = "email",
|
||||
privateKey = "mockPrivateKey-1",
|
||||
initUserCryptoMethod = InitUserCryptoMethod.Password(
|
||||
password = "mockPassword-1",
|
||||
userKey = "mockKey-1",
|
||||
),
|
||||
prepareStateForUnlocking(unlockResult = mockVaultUnlockResult)
|
||||
|
||||
organizationKeys = createMockOrganizationKeys(number = 1),
|
||||
)
|
||||
} returns mockVaultUnlockResult
|
||||
|
||||
val result = vaultRepository.unlockVaultAndSyncForCurrentUser(
|
||||
val result = vaultRepository.unlockVaultWithMasterPasswordAndSync(
|
||||
masterPassword = "mockPassword-1",
|
||||
)
|
||||
|
||||
|
@ -634,61 +684,13 @@ class VaultRepositoryTest {
|
|||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `unlockVaultAndSyncForCurrentUser with VaultLockManager non-Success should unlock for the current user and return the error`() =
|
||||
fun `unlockVaultWithMasterPasswordAndSync with VaultLockManager non-Success should unlock for the current user and return the error`() =
|
||||
runTest {
|
||||
val userId = "mockId-1"
|
||||
val mockSyncResponse = createMockSyncResponse(number = 1)
|
||||
coEvery { syncService.sync() } returns mockSyncResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.initializeOrganizationCrypto(
|
||||
userId = userId,
|
||||
request = InitOrgCryptoRequest(
|
||||
organizationKeys = createMockOrganizationKeys(1),
|
||||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = MOCK_USER_STATE.activeUserId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptSendList(
|
||||
userId = userId,
|
||||
sendList = listOf(createMockSdkSend(number = 1)),
|
||||
)
|
||||
} returns listOf(createMockSendView(number = 1)).asSuccess()
|
||||
fakeAuthDiskSource.storePrivateKey(
|
||||
userId = "mockId-1",
|
||||
privateKey = "mockPrivateKey-1",
|
||||
)
|
||||
fakeAuthDiskSource.storeUserKey(
|
||||
userId = "mockId-1",
|
||||
userKey = "mockKey-1",
|
||||
)
|
||||
fakeAuthDiskSource.storeOrganizationKeys(
|
||||
userId = "mockId-1",
|
||||
organizationKeys = createMockOrganizationKeys(number = 1),
|
||||
)
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val mockVaultUnlockResult = VaultUnlockResult.InvalidStateError
|
||||
coEvery {
|
||||
vaultLockManager.unlockVault(
|
||||
userId = userId,
|
||||
kdf = MOCK_PROFILE.toSdkParams(),
|
||||
email = "email",
|
||||
privateKey = "mockPrivateKey-1",
|
||||
initUserCryptoMethod = InitUserCryptoMethod.Password(
|
||||
password = "mockPassword-1",
|
||||
userKey = "mockKey-1",
|
||||
),
|
||||
prepareStateForUnlocking(unlockResult = mockVaultUnlockResult)
|
||||
|
||||
organizationKeys = createMockOrganizationKeys(number = 1),
|
||||
)
|
||||
} returns mockVaultUnlockResult
|
||||
|
||||
val result = vaultRepository.unlockVaultAndSyncForCurrentUser(
|
||||
val result = vaultRepository.unlockVaultWithMasterPasswordAndSync(
|
||||
masterPassword = "mockPassword-1",
|
||||
)
|
||||
|
||||
|
@ -713,6 +715,163 @@ class VaultRepositoryTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `unlockVaultWithPinAndSync with missing user state should return InvalidStateError `() =
|
||||
runTest {
|
||||
fakeAuthDiskSource.userState = null
|
||||
assertEquals(
|
||||
VaultState(
|
||||
unlockedVaultUserIds = emptySet(),
|
||||
unlockingVaultUserIds = emptySet(),
|
||||
),
|
||||
vaultRepository.vaultStateFlow.value,
|
||||
)
|
||||
|
||||
val result = vaultRepository.unlockVaultWithPinAndSync(pin = "1234")
|
||||
|
||||
assertEquals(
|
||||
VaultUnlockResult.InvalidStateError,
|
||||
result,
|
||||
)
|
||||
assertEquals(
|
||||
VaultState(
|
||||
unlockedVaultUserIds = emptySet(),
|
||||
unlockingVaultUserIds = emptySet(),
|
||||
),
|
||||
vaultRepository.vaultStateFlow.value,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `unlockVaultWithPinAndSync with missing pin-protected user key should return InvalidStateError `() =
|
||||
runTest {
|
||||
assertEquals(
|
||||
VaultState(
|
||||
unlockedVaultUserIds = emptySet(),
|
||||
unlockingVaultUserIds = emptySet(),
|
||||
),
|
||||
vaultRepository.vaultStateFlow.value,
|
||||
)
|
||||
|
||||
val result = vaultRepository.unlockVaultWithPinAndSync(pin = "1234")
|
||||
fakeAuthDiskSource.storePinProtectedUserKey(
|
||||
userId = "mockId-1",
|
||||
pinProtectedUserKey = null,
|
||||
)
|
||||
fakeAuthDiskSource.storePrivateKey(
|
||||
userId = "mockId-1",
|
||||
privateKey = "mockPrivateKey-1",
|
||||
)
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
assertEquals(
|
||||
VaultUnlockResult.InvalidStateError,
|
||||
result,
|
||||
)
|
||||
assertEquals(
|
||||
VaultState(
|
||||
unlockedVaultUserIds = emptySet(),
|
||||
unlockingVaultUserIds = emptySet(),
|
||||
),
|
||||
vaultRepository.vaultStateFlow.value,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `unlockVaultWithPinAndSync with missing private key should return InvalidStateError `() =
|
||||
runTest {
|
||||
assertEquals(
|
||||
VaultState(
|
||||
unlockedVaultUserIds = emptySet(),
|
||||
unlockingVaultUserIds = emptySet(),
|
||||
),
|
||||
vaultRepository.vaultStateFlow.value,
|
||||
)
|
||||
val result = vaultRepository.unlockVaultWithPinAndSync(pin = "1234")
|
||||
fakeAuthDiskSource.storePinProtectedUserKey(
|
||||
userId = "mockId-1",
|
||||
pinProtectedUserKey = "mockKey-1",
|
||||
)
|
||||
fakeAuthDiskSource.storePrivateKey(
|
||||
userId = "mockId-1",
|
||||
privateKey = null,
|
||||
)
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
assertEquals(
|
||||
VaultUnlockResult.InvalidStateError,
|
||||
result,
|
||||
)
|
||||
assertEquals(
|
||||
VaultState(
|
||||
unlockedVaultUserIds = emptySet(),
|
||||
unlockingVaultUserIds = emptySet(),
|
||||
),
|
||||
vaultRepository.vaultStateFlow.value,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `unlockVaultWithPinAndSync with VaultLockManager Success should unlock for the current user, sync, and return Success`() =
|
||||
runTest {
|
||||
val userId = "mockId-1"
|
||||
val mockVaultUnlockResult = VaultUnlockResult.Success
|
||||
prepareStateForUnlocking(unlockResult = mockVaultUnlockResult)
|
||||
|
||||
val result = vaultRepository.unlockVaultWithPinAndSync(pin = "1234")
|
||||
|
||||
assertEquals(
|
||||
mockVaultUnlockResult,
|
||||
result,
|
||||
)
|
||||
coVerify { syncService.sync() }
|
||||
coVerify {
|
||||
vaultLockManager.unlockVault(
|
||||
userId = userId,
|
||||
kdf = MOCK_PROFILE.toSdkParams(),
|
||||
email = "email",
|
||||
privateKey = "mockPrivateKey-1",
|
||||
initUserCryptoMethod = InitUserCryptoMethod.Pin(
|
||||
pin = "1234",
|
||||
pinProtectedUserKey = "mockKey-1",
|
||||
),
|
||||
organizationKeys = createMockOrganizationKeys(number = 1),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `unlockVaultWithPinAndSync with VaultLockManager non-Success should unlock for the current user and return the error`() =
|
||||
runTest {
|
||||
val userId = "mockId-1"
|
||||
val mockVaultUnlockResult = VaultUnlockResult.InvalidStateError
|
||||
prepareStateForUnlocking(unlockResult = mockVaultUnlockResult)
|
||||
|
||||
val result = vaultRepository.unlockVaultWithPinAndSync(pin = "1234")
|
||||
|
||||
assertEquals(
|
||||
mockVaultUnlockResult,
|
||||
result,
|
||||
)
|
||||
coVerify(exactly = 0) { syncService.sync() }
|
||||
coVerify {
|
||||
vaultLockManager.unlockVault(
|
||||
userId = userId,
|
||||
kdf = MOCK_PROFILE.toSdkParams(),
|
||||
email = "email",
|
||||
privateKey = "mockPrivateKey-1",
|
||||
initUserCryptoMethod = InitUserCryptoMethod.Pin(
|
||||
pin = "1234",
|
||||
pinProtectedUserKey = "mockKey-1",
|
||||
),
|
||||
organizationKeys = createMockOrganizationKeys(number = 1),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `unlockVault should delegate to the VaultLockManager`() = runTest {
|
||||
val userId = "userId"
|
||||
|
@ -833,104 +992,6 @@ class VaultRepositoryTest {
|
|||
coVerify(exactly = 1) { syncService.sync() }
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `unlockVaultAndSyncForCurrentUser with missing user state should return InvalidStateError `() =
|
||||
runTest {
|
||||
fakeAuthDiskSource.userState = null
|
||||
assertEquals(
|
||||
VaultState(
|
||||
unlockedVaultUserIds = emptySet(),
|
||||
unlockingVaultUserIds = emptySet(),
|
||||
),
|
||||
vaultRepository.vaultStateFlow.value,
|
||||
)
|
||||
|
||||
val result = vaultRepository.unlockVaultAndSyncForCurrentUser(masterPassword = "")
|
||||
|
||||
assertEquals(
|
||||
VaultUnlockResult.InvalidStateError,
|
||||
result,
|
||||
)
|
||||
assertEquals(
|
||||
VaultState(
|
||||
unlockedVaultUserIds = emptySet(),
|
||||
unlockingVaultUserIds = emptySet(),
|
||||
),
|
||||
vaultRepository.vaultStateFlow.value,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `unlockVaultAndSyncForCurrentUser with missing user key should return InvalidStateError `() =
|
||||
runTest {
|
||||
assertEquals(
|
||||
VaultState(
|
||||
unlockedVaultUserIds = emptySet(),
|
||||
unlockingVaultUserIds = emptySet(),
|
||||
),
|
||||
vaultRepository.vaultStateFlow.value,
|
||||
)
|
||||
|
||||
val result = vaultRepository.unlockVaultAndSyncForCurrentUser(masterPassword = "")
|
||||
fakeAuthDiskSource.storeUserKey(
|
||||
userId = "mockId-1",
|
||||
userKey = null,
|
||||
)
|
||||
fakeAuthDiskSource.storePrivateKey(
|
||||
userId = "mockId-1",
|
||||
privateKey = "mockPrivateKey-1",
|
||||
)
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
assertEquals(
|
||||
VaultUnlockResult.InvalidStateError,
|
||||
result,
|
||||
)
|
||||
assertEquals(
|
||||
VaultState(
|
||||
unlockedVaultUserIds = emptySet(),
|
||||
unlockingVaultUserIds = emptySet(),
|
||||
),
|
||||
vaultRepository.vaultStateFlow.value,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `unlockVaultAndSyncForCurrentUser with missing private key should return InvalidStateError `() =
|
||||
runTest {
|
||||
assertEquals(
|
||||
VaultState(
|
||||
unlockedVaultUserIds = emptySet(),
|
||||
unlockingVaultUserIds = emptySet(),
|
||||
),
|
||||
vaultRepository.vaultStateFlow.value,
|
||||
)
|
||||
val result = vaultRepository.unlockVaultAndSyncForCurrentUser(masterPassword = "")
|
||||
fakeAuthDiskSource.storeUserKey(
|
||||
userId = "mockId-1",
|
||||
userKey = "mockKey-1",
|
||||
)
|
||||
fakeAuthDiskSource.storePrivateKey(
|
||||
userId = "mockId-1",
|
||||
privateKey = null,
|
||||
)
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
assertEquals(
|
||||
VaultUnlockResult.InvalidStateError,
|
||||
result,
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
VaultState(
|
||||
unlockedVaultUserIds = emptySet(),
|
||||
unlockingVaultUserIds = emptySet(),
|
||||
),
|
||||
vaultRepository.vaultStateFlow.value,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clearUnlockedData should update the vaultDataStateFlow to Loading`() = runTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
|
@ -1704,6 +1765,86 @@ class VaultRepositoryTest {
|
|||
|
||||
//region Helper functions
|
||||
|
||||
/**
|
||||
* Prepares for an unlock call with the given [unlockResult].
|
||||
*/
|
||||
private fun prepareStateForUnlocking(
|
||||
unlockResult: VaultUnlockResult,
|
||||
mockMasterPassword: String = "mockPassword-1",
|
||||
mockPin: String = "1234",
|
||||
) {
|
||||
val userId = "mockId-1"
|
||||
val mockSyncResponse = createMockSyncResponse(number = 1)
|
||||
coEvery { syncService.sync() } returns mockSyncResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.initializeOrganizationCrypto(
|
||||
userId = userId,
|
||||
request = InitOrgCryptoRequest(
|
||||
organizationKeys = createMockOrganizationKeys(1),
|
||||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = userId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptSendList(
|
||||
userId = userId,
|
||||
sendList = listOf(createMockSdkSend(number = 1)),
|
||||
)
|
||||
} returns listOf(createMockSendView(number = 1)).asSuccess()
|
||||
fakeAuthDiskSource.storePrivateKey(
|
||||
userId = userId,
|
||||
privateKey = "mockPrivateKey-1",
|
||||
)
|
||||
fakeAuthDiskSource.storeUserKey(
|
||||
userId = userId,
|
||||
userKey = "mockKey-1",
|
||||
)
|
||||
fakeAuthDiskSource.storePinProtectedUserKey(
|
||||
userId = userId,
|
||||
pinProtectedUserKey = "mockKey-1",
|
||||
)
|
||||
fakeAuthDiskSource.storeOrganizationKeys(
|
||||
userId = userId,
|
||||
organizationKeys = createMockOrganizationKeys(number = 1),
|
||||
)
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
|
||||
// Master password unlock
|
||||
coEvery {
|
||||
vaultLockManager.unlockVault(
|
||||
userId = userId,
|
||||
kdf = MOCK_PROFILE.toSdkParams(),
|
||||
email = "email",
|
||||
privateKey = "mockPrivateKey-1",
|
||||
initUserCryptoMethod = InitUserCryptoMethod.Password(
|
||||
password = mockMasterPassword,
|
||||
userKey = "mockKey-1",
|
||||
),
|
||||
organizationKeys = createMockOrganizationKeys(number = 1),
|
||||
)
|
||||
} returns unlockResult
|
||||
|
||||
// PIN unlock
|
||||
coEvery {
|
||||
vaultLockManager.unlockVault(
|
||||
userId = userId,
|
||||
kdf = MOCK_PROFILE.toSdkParams(),
|
||||
email = "email",
|
||||
privateKey = "mockPrivateKey-1",
|
||||
initUserCryptoMethod = InitUserCryptoMethod.Pin(
|
||||
pin = mockPin,
|
||||
pinProtectedUserKey = "mockKey-1",
|
||||
),
|
||||
organizationKeys = createMockOrganizationKeys(number = 1),
|
||||
)
|
||||
} returns unlockResult
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper setup all flows required to properly subscribe to the
|
||||
* [VaultRepository.vaultDataStateFlow].
|
||||
|
|
|
@ -252,7 +252,7 @@ class VaultUnlockViewModelTest : BaseViewModelTest() {
|
|||
val initialState = DEFAULT_STATE.copy(passwordInput = password)
|
||||
val viewModel = createViewModel(state = initialState)
|
||||
coEvery {
|
||||
vaultRepository.unlockVaultAndSyncForCurrentUser(password)
|
||||
vaultRepository.unlockVaultWithMasterPasswordAndSync(password)
|
||||
} returns VaultUnlockResult.AuthenticationError
|
||||
|
||||
viewModel.trySendAction(VaultUnlockAction.UnlockClick)
|
||||
|
@ -265,7 +265,7 @@ class VaultUnlockViewModelTest : BaseViewModelTest() {
|
|||
viewModel.stateFlow.value,
|
||||
)
|
||||
coVerify {
|
||||
vaultRepository.unlockVaultAndSyncForCurrentUser(password)
|
||||
vaultRepository.unlockVaultWithMasterPasswordAndSync(password)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,7 +275,7 @@ class VaultUnlockViewModelTest : BaseViewModelTest() {
|
|||
val initialState = DEFAULT_STATE.copy(passwordInput = password)
|
||||
val viewModel = createViewModel(state = initialState)
|
||||
coEvery {
|
||||
vaultRepository.unlockVaultAndSyncForCurrentUser(password)
|
||||
vaultRepository.unlockVaultWithMasterPasswordAndSync(password)
|
||||
} returns VaultUnlockResult.GenericError
|
||||
|
||||
viewModel.trySendAction(VaultUnlockAction.UnlockClick)
|
||||
|
@ -288,7 +288,7 @@ class VaultUnlockViewModelTest : BaseViewModelTest() {
|
|||
viewModel.stateFlow.value,
|
||||
)
|
||||
coVerify {
|
||||
vaultRepository.unlockVaultAndSyncForCurrentUser(password)
|
||||
vaultRepository.unlockVaultWithMasterPasswordAndSync(password)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -298,7 +298,7 @@ class VaultUnlockViewModelTest : BaseViewModelTest() {
|
|||
val initialState = DEFAULT_STATE.copy(passwordInput = password)
|
||||
val viewModel = createViewModel(state = initialState)
|
||||
coEvery {
|
||||
vaultRepository.unlockVaultAndSyncForCurrentUser(password)
|
||||
vaultRepository.unlockVaultWithMasterPasswordAndSync(password)
|
||||
} returns VaultUnlockResult.InvalidStateError
|
||||
|
||||
viewModel.trySendAction(VaultUnlockAction.UnlockClick)
|
||||
|
@ -311,7 +311,7 @@ class VaultUnlockViewModelTest : BaseViewModelTest() {
|
|||
viewModel.stateFlow.value,
|
||||
)
|
||||
coVerify {
|
||||
vaultRepository.unlockVaultAndSyncForCurrentUser(password)
|
||||
vaultRepository.unlockVaultWithMasterPasswordAndSync(password)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -321,7 +321,7 @@ class VaultUnlockViewModelTest : BaseViewModelTest() {
|
|||
val initialState = DEFAULT_STATE.copy(passwordInput = password)
|
||||
val viewModel = createViewModel(state = initialState)
|
||||
coEvery {
|
||||
vaultRepository.unlockVaultAndSyncForCurrentUser(password)
|
||||
vaultRepository.unlockVaultWithMasterPasswordAndSync(password)
|
||||
} returns VaultUnlockResult.Success
|
||||
|
||||
viewModel.trySendAction(VaultUnlockAction.UnlockClick)
|
||||
|
@ -330,7 +330,7 @@ class VaultUnlockViewModelTest : BaseViewModelTest() {
|
|||
viewModel.stateFlow.value,
|
||||
)
|
||||
coVerify {
|
||||
vaultRepository.unlockVaultAndSyncForCurrentUser(password)
|
||||
vaultRepository.unlockVaultWithMasterPasswordAndSync(password)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue