mirror of
https://github.com/bitwarden/android.git
synced 2024-11-22 17:36:01 +03:00
BIT-1091: Initialize crypto for organizations (#370)
This commit is contained in:
parent
970e913373
commit
65b9005cbe
10 changed files with 661 additions and 81 deletions
|
@ -179,9 +179,10 @@ class AuthRepositoryImpl constructor(
|
||||||
kdf = userStateJson.activeAccount.profile.toSdkParams(),
|
kdf = userStateJson.activeAccount.profile.toSdkParams(),
|
||||||
userKey = loginResponse.key,
|
userKey = loginResponse.key,
|
||||||
privateKey = loginResponse.privateKey,
|
privateKey = loginResponse.privateKey,
|
||||||
// TODO use actual organization keys BIT-1091
|
|
||||||
organizationalKeys = emptyMap(),
|
|
||||||
masterPassword = password,
|
masterPassword = password,
|
||||||
|
// We can separately unlock the vault for organization data after
|
||||||
|
// receiving the sync response.
|
||||||
|
organizationKeys = null,
|
||||||
)
|
)
|
||||||
authDiskSource.userState = userStateJson
|
authDiskSource.userState = userStateJson
|
||||||
authDiskSource.storeUserKey(
|
authDiskSource.storeUserKey(
|
||||||
|
|
|
@ -7,6 +7,7 @@ import com.bitwarden.core.Collection
|
||||||
import com.bitwarden.core.CollectionView
|
import com.bitwarden.core.CollectionView
|
||||||
import com.bitwarden.core.Folder
|
import com.bitwarden.core.Folder
|
||||||
import com.bitwarden.core.FolderView
|
import com.bitwarden.core.FolderView
|
||||||
|
import com.bitwarden.core.InitOrgCryptoRequest
|
||||||
import com.bitwarden.core.InitUserCryptoRequest
|
import com.bitwarden.core.InitUserCryptoRequest
|
||||||
import com.bitwarden.core.Send
|
import com.bitwarden.core.Send
|
||||||
import com.bitwarden.core.SendView
|
import com.bitwarden.core.SendView
|
||||||
|
@ -19,11 +20,21 @@ import com.x8bit.bitwarden.data.vault.datasource.sdk.model.InitializeCryptoResul
|
||||||
interface VaultSdkSource {
|
interface VaultSdkSource {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to initialize cryptography functionality for the Bitwarden SDK
|
* Attempts to initialize cryptography functionality for an individual user for the
|
||||||
* with a given [InitCryptoRequest].
|
* Bitwarden SDK with a given [InitUserCryptoRequest].
|
||||||
*/
|
*/
|
||||||
suspend fun initializeCrypto(request: InitUserCryptoRequest): Result<InitializeCryptoResult>
|
suspend fun initializeCrypto(request: InitUserCryptoRequest): Result<InitializeCryptoResult>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to initialize cryptography functionality for organization data associated with
|
||||||
|
* the current user for the Bitwarden SDK with a given [InitOrgCryptoRequest].
|
||||||
|
*
|
||||||
|
* This should only be called after a successful call to [initializeCrypto].
|
||||||
|
*/
|
||||||
|
suspend fun initializeOrganizationCrypto(
|
||||||
|
request: InitOrgCryptoRequest,
|
||||||
|
): Result<InitializeCryptoResult>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypts a [CipherView] returning a [Cipher] wrapped in a [Result].
|
* Encrypts a [CipherView] returning a [Cipher] wrapped in a [Result].
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,6 +7,7 @@ import com.bitwarden.core.Collection
|
||||||
import com.bitwarden.core.CollectionView
|
import com.bitwarden.core.CollectionView
|
||||||
import com.bitwarden.core.Folder
|
import com.bitwarden.core.Folder
|
||||||
import com.bitwarden.core.FolderView
|
import com.bitwarden.core.FolderView
|
||||||
|
import com.bitwarden.core.InitOrgCryptoRequest
|
||||||
import com.bitwarden.core.InitUserCryptoRequest
|
import com.bitwarden.core.InitUserCryptoRequest
|
||||||
import com.bitwarden.core.Send
|
import com.bitwarden.core.Send
|
||||||
import com.bitwarden.core.SendView
|
import com.bitwarden.core.SendView
|
||||||
|
@ -32,7 +33,20 @@ class VaultSdkSourceImpl(
|
||||||
clientCrypto.initializeUserCrypto(req = request)
|
clientCrypto.initializeUserCrypto(req = request)
|
||||||
InitializeCryptoResult.Success
|
InitializeCryptoResult.Success
|
||||||
} catch (exception: BitwardenException) {
|
} catch (exception: BitwardenException) {
|
||||||
// The only truly expected error from the SDK is an incorrect password.
|
// The only truly expected error from the SDK is an incorrect key/password.
|
||||||
|
InitializeCryptoResult.AuthenticationError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun initializeOrganizationCrypto(
|
||||||
|
request: InitOrgCryptoRequest,
|
||||||
|
): Result<InitializeCryptoResult> =
|
||||||
|
runCatching {
|
||||||
|
try {
|
||||||
|
clientCrypto.initializeOrgCrypto(req = request)
|
||||||
|
InitializeCryptoResult.Success
|
||||||
|
} catch (exception: BitwardenException) {
|
||||||
|
// The only truly expected error from the SDK is for incorrect keys.
|
||||||
InitializeCryptoResult.AuthenticationError
|
InitializeCryptoResult.AuthenticationError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ sealed class InitializeCryptoResult {
|
||||||
data object Success : InitializeCryptoResult()
|
data object Success : InitializeCryptoResult()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Incorrect password provided.
|
* Incorrect password or key(s) provided.
|
||||||
*/
|
*/
|
||||||
data object AuthenticationError : InitializeCryptoResult()
|
data object AuthenticationError : InitializeCryptoResult()
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,9 @@ interface VaultRepository {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to unlock the vault with the specified user information.
|
* Attempt to unlock the vault with the specified user information.
|
||||||
|
*
|
||||||
|
* Note that when [organizationKeys] is absent, no attempt will be made to unlock the vault
|
||||||
|
* for organization data.
|
||||||
*/
|
*/
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
suspend fun unlockVault(
|
suspend fun unlockVault(
|
||||||
|
@ -80,7 +83,7 @@ interface VaultRepository {
|
||||||
kdf: Kdf,
|
kdf: Kdf,
|
||||||
userKey: String,
|
userKey: String,
|
||||||
privateKey: String,
|
privateKey: String,
|
||||||
organizationalKeys: Map<String, String>,
|
organizationKeys: Map<String, String>?,
|
||||||
): VaultUnlockResult
|
): VaultUnlockResult
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.x8bit.bitwarden.data.vault.repository
|
||||||
|
|
||||||
import com.bitwarden.core.CipherView
|
import com.bitwarden.core.CipherView
|
||||||
import com.bitwarden.core.FolderView
|
import com.bitwarden.core.FolderView
|
||||||
|
import com.bitwarden.core.InitOrgCryptoRequest
|
||||||
import com.bitwarden.core.InitUserCryptoMethod
|
import com.bitwarden.core.InitUserCryptoMethod
|
||||||
import com.bitwarden.core.InitUserCryptoRequest
|
import com.bitwarden.core.InitUserCryptoRequest
|
||||||
import com.bitwarden.core.Kdf
|
import com.bitwarden.core.Kdf
|
||||||
|
@ -12,11 +13,13 @@ import com.x8bit.bitwarden.data.platform.datasource.network.util.isNoConnectionE
|
||||||
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
|
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
|
||||||
import com.x8bit.bitwarden.data.platform.repository.model.DataState
|
import com.x8bit.bitwarden.data.platform.repository.model.DataState
|
||||||
import com.x8bit.bitwarden.data.platform.repository.util.map
|
import com.x8bit.bitwarden.data.platform.repository.util.map
|
||||||
|
import com.x8bit.bitwarden.data.platform.util.asSuccess
|
||||||
import com.x8bit.bitwarden.data.platform.util.flatMap
|
import com.x8bit.bitwarden.data.platform.util.flatMap
|
||||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||||
import com.x8bit.bitwarden.data.vault.datasource.network.service.CiphersService
|
import com.x8bit.bitwarden.data.vault.datasource.network.service.CiphersService
|
||||||
import com.x8bit.bitwarden.data.vault.datasource.network.service.SyncService
|
import com.x8bit.bitwarden.data.vault.datasource.network.service.SyncService
|
||||||
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource
|
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource
|
||||||
|
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.InitializeCryptoResult
|
||||||
import com.x8bit.bitwarden.data.vault.repository.model.CreateCipherResult
|
import com.x8bit.bitwarden.data.vault.repository.model.CreateCipherResult
|
||||||
import com.x8bit.bitwarden.data.vault.repository.model.SendData
|
import com.x8bit.bitwarden.data.vault.repository.model.SendData
|
||||||
import com.x8bit.bitwarden.data.vault.repository.model.UpdateCipherResult
|
import com.x8bit.bitwarden.data.vault.repository.model.UpdateCipherResult
|
||||||
|
@ -107,6 +110,7 @@ class VaultRepositoryImpl constructor(
|
||||||
syncResponse = syncResponse,
|
syncResponse = syncResponse,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
unlockVaultForOrganizationsIfNecessary(syncResponse = syncResponse)
|
||||||
storeKeys(syncResponse = syncResponse)
|
storeKeys(syncResponse = syncResponse)
|
||||||
decryptSyncResponseAndUpdateVaultDataState(syncResponse = syncResponse)
|
decryptSyncResponseAndUpdateVaultDataState(syncResponse = syncResponse)
|
||||||
decryptSendsAndUpdateSendDataState(sendList = syncResponse.sends)
|
decryptSendsAndUpdateSendDataState(sendList = syncResponse.sends)
|
||||||
|
@ -177,6 +181,8 @@ class VaultRepositoryImpl constructor(
|
||||||
?: return VaultUnlockResult.InvalidStateError
|
?: return VaultUnlockResult.InvalidStateError
|
||||||
val privateKey = authDiskSource.getPrivateKey(userId = userState.activeUserId)
|
val privateKey = authDiskSource.getPrivateKey(userId = userState.activeUserId)
|
||||||
?: return VaultUnlockResult.InvalidStateError
|
?: return VaultUnlockResult.InvalidStateError
|
||||||
|
val organizationKeys = authDiskSource
|
||||||
|
.getOrganizationKeys(userId = userState.activeUserId)
|
||||||
return unlockVault(
|
return unlockVault(
|
||||||
userId = userState.activeUserId,
|
userId = userState.activeUserId,
|
||||||
masterPassword = masterPassword,
|
masterPassword = masterPassword,
|
||||||
|
@ -184,8 +190,7 @@ class VaultRepositoryImpl constructor(
|
||||||
kdf = userState.activeAccount.profile.toSdkParams(),
|
kdf = userState.activeAccount.profile.toSdkParams(),
|
||||||
userKey = userKey,
|
userKey = userKey,
|
||||||
privateKey = privateKey,
|
privateKey = privateKey,
|
||||||
// TODO use actual organization keys BIT-1091
|
organizationKeys = organizationKeys,
|
||||||
organizationalKeys = emptyMap(),
|
|
||||||
)
|
)
|
||||||
.also {
|
.also {
|
||||||
if (it is VaultUnlockResult.Success) {
|
if (it is VaultUnlockResult.Success) {
|
||||||
|
@ -201,7 +206,7 @@ class VaultRepositoryImpl constructor(
|
||||||
kdf: Kdf,
|
kdf: Kdf,
|
||||||
userKey: String,
|
userKey: String,
|
||||||
privateKey: String,
|
privateKey: String,
|
||||||
organizationalKeys: Map<String, String>,
|
organizationKeys: Map<String, String>?,
|
||||||
): VaultUnlockResult =
|
): VaultUnlockResult =
|
||||||
flow {
|
flow {
|
||||||
willSyncAfterUnlock = true
|
willSyncAfterUnlock = true
|
||||||
|
@ -218,6 +223,20 @@ class VaultRepositoryImpl constructor(
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
.flatMap { result ->
|
||||||
|
// Initialize the SDK for organizations if necessary
|
||||||
|
if (organizationKeys != null &&
|
||||||
|
result is InitializeCryptoResult.Success
|
||||||
|
) {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = organizationKeys,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
result.asSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
.fold(
|
.fold(
|
||||||
onFailure = { VaultUnlockResult.GenericError },
|
onFailure = { VaultUnlockResult.GenericError },
|
||||||
onSuccess = { initializeCryptoResult ->
|
onSuccess = { initializeCryptoResult ->
|
||||||
|
@ -320,6 +339,27 @@ class VaultRepositoryImpl constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun unlockVaultForOrganizationsIfNecessary(
|
||||||
|
syncResponse: SyncResponseJson,
|
||||||
|
) {
|
||||||
|
val profile = syncResponse.profile ?: return
|
||||||
|
val organizationKeys = profile.organizations
|
||||||
|
.orEmpty()
|
||||||
|
.filter { it.key != null }
|
||||||
|
.associate { it.id to requireNotNull(it.key) }
|
||||||
|
.takeUnless { it.isEmpty() }
|
||||||
|
?: return
|
||||||
|
|
||||||
|
// There shouldn't be issues when unlocking directly from the syncResponse so we can ignore
|
||||||
|
// the return type here.
|
||||||
|
vaultSdkSource
|
||||||
|
.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = organizationKeys,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun decryptSendsAndUpdateSendDataState(sendList: List<SyncResponseJson.Send>?) {
|
private suspend fun decryptSendsAndUpdateSendDataState(sendList: List<SyncResponseJson.Send>?) {
|
||||||
val newState = vaultSdkSource
|
val newState = vaultSdkSource
|
||||||
.decryptSendList(
|
.decryptSendList(
|
||||||
|
|
|
@ -429,7 +429,7 @@ class AuthRepositoryTest {
|
||||||
kdf = ACCOUNT_1.profile.toSdkParams(),
|
kdf = ACCOUNT_1.profile.toSdkParams(),
|
||||||
userKey = successResponse.key,
|
userKey = successResponse.key,
|
||||||
privateKey = successResponse.privateKey,
|
privateKey = successResponse.privateKey,
|
||||||
organizationalKeys = emptyMap(),
|
organizationKeys = null,
|
||||||
masterPassword = PASSWORD,
|
masterPassword = PASSWORD,
|
||||||
)
|
)
|
||||||
} returns VaultUnlockResult.Success
|
} returns VaultUnlockResult.Success
|
||||||
|
@ -465,7 +465,7 @@ class AuthRepositoryTest {
|
||||||
kdf = ACCOUNT_1.profile.toSdkParams(),
|
kdf = ACCOUNT_1.profile.toSdkParams(),
|
||||||
userKey = successResponse.key,
|
userKey = successResponse.key,
|
||||||
privateKey = successResponse.privateKey,
|
privateKey = successResponse.privateKey,
|
||||||
organizationalKeys = emptyMap(),
|
organizationKeys = null,
|
||||||
masterPassword = PASSWORD,
|
masterPassword = PASSWORD,
|
||||||
)
|
)
|
||||||
vaultRepository.sync()
|
vaultRepository.sync()
|
||||||
|
@ -508,7 +508,7 @@ class AuthRepositoryTest {
|
||||||
kdf = ACCOUNT_1.profile.toSdkParams(),
|
kdf = ACCOUNT_1.profile.toSdkParams(),
|
||||||
userKey = successResponse.key,
|
userKey = successResponse.key,
|
||||||
privateKey = successResponse.privateKey,
|
privateKey = successResponse.privateKey,
|
||||||
organizationalKeys = emptyMap(),
|
organizationKeys = null,
|
||||||
masterPassword = PASSWORD,
|
masterPassword = PASSWORD,
|
||||||
)
|
)
|
||||||
} returns VaultUnlockResult.Success
|
} returns VaultUnlockResult.Success
|
||||||
|
@ -546,7 +546,7 @@ class AuthRepositoryTest {
|
||||||
kdf = ACCOUNT_1.profile.toSdkParams(),
|
kdf = ACCOUNT_1.profile.toSdkParams(),
|
||||||
userKey = successResponse.key,
|
userKey = successResponse.key,
|
||||||
privateKey = successResponse.privateKey,
|
privateKey = successResponse.privateKey,
|
||||||
organizationalKeys = emptyMap(),
|
organizationKeys = null,
|
||||||
masterPassword = PASSWORD,
|
masterPassword = PASSWORD,
|
||||||
)
|
)
|
||||||
vaultRepository.sync()
|
vaultRepository.sync()
|
||||||
|
@ -946,7 +946,7 @@ class AuthRepositoryTest {
|
||||||
kdf = ACCOUNT_1.profile.toSdkParams(),
|
kdf = ACCOUNT_1.profile.toSdkParams(),
|
||||||
userKey = successResponse.key,
|
userKey = successResponse.key,
|
||||||
privateKey = successResponse.privateKey,
|
privateKey = successResponse.privateKey,
|
||||||
organizationalKeys = emptyMap(),
|
organizationKeys = null,
|
||||||
masterPassword = PASSWORD,
|
masterPassword = PASSWORD,
|
||||||
)
|
)
|
||||||
} returns VaultUnlockResult.Success
|
} returns VaultUnlockResult.Success
|
||||||
|
@ -1028,7 +1028,7 @@ class AuthRepositoryTest {
|
||||||
kdf = ACCOUNT_1.profile.toSdkParams(),
|
kdf = ACCOUNT_1.profile.toSdkParams(),
|
||||||
userKey = successResponse.key,
|
userKey = successResponse.key,
|
||||||
privateKey = successResponse.privateKey,
|
privateKey = successResponse.privateKey,
|
||||||
organizationalKeys = emptyMap(),
|
organizationKeys = null,
|
||||||
masterPassword = PASSWORD,
|
masterPassword = PASSWORD,
|
||||||
)
|
)
|
||||||
} returns VaultUnlockResult.Success
|
} returns VaultUnlockResult.Success
|
||||||
|
|
|
@ -77,6 +77,13 @@ fun createMockOrganization(number: Int): SyncResponseJson.Profile.Organization =
|
||||||
status = 1,
|
status = 1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a mock set of organization keys with the given [number].
|
||||||
|
*/
|
||||||
|
fun createMockOrganizationKeys(number: Int): Map<String, String> =
|
||||||
|
createMockOrganization(number = number)
|
||||||
|
.let { mapOf(it.id to requireNotNull(it.key)) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a mock [SyncResponseJson.Profile.Permissions].
|
* Create a mock [SyncResponseJson.Profile.Permissions].
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,6 +7,7 @@ import com.bitwarden.core.Collection
|
||||||
import com.bitwarden.core.CollectionView
|
import com.bitwarden.core.CollectionView
|
||||||
import com.bitwarden.core.Folder
|
import com.bitwarden.core.Folder
|
||||||
import com.bitwarden.core.FolderView
|
import com.bitwarden.core.FolderView
|
||||||
|
import com.bitwarden.core.InitOrgCryptoRequest
|
||||||
import com.bitwarden.core.InitUserCryptoRequest
|
import com.bitwarden.core.InitUserCryptoRequest
|
||||||
import com.bitwarden.core.Send
|
import com.bitwarden.core.Send
|
||||||
import com.bitwarden.core.SendView
|
import com.bitwarden.core.SendView
|
||||||
|
@ -32,7 +33,7 @@ class VaultSdkSourceTest {
|
||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `initializeCrypto with sdk success should return InitializeCryptoResult Success`() =
|
fun `initializeUserCrypto with sdk success should return InitializeCryptoResult Success`() =
|
||||||
runBlocking {
|
runBlocking {
|
||||||
val mockInitCryptoRequest = mockk<InitUserCryptoRequest>()
|
val mockInitCryptoRequest = mockk<InitUserCryptoRequest>()
|
||||||
coEvery {
|
coEvery {
|
||||||
|
@ -101,6 +102,76 @@ class VaultSdkSourceTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `initializeOrgCrypto with sdk success should return InitializeCryptoResult Success`() =
|
||||||
|
runBlocking {
|
||||||
|
val mockInitCryptoRequest = mockk<InitOrgCryptoRequest>()
|
||||||
|
coEvery {
|
||||||
|
clientCrypto.initializeOrgCrypto(
|
||||||
|
req = mockInitCryptoRequest,
|
||||||
|
)
|
||||||
|
} returns Unit
|
||||||
|
val result = vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = mockInitCryptoRequest,
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
InitializeCryptoResult.Success.asSuccess(),
|
||||||
|
result,
|
||||||
|
)
|
||||||
|
coVerify {
|
||||||
|
clientCrypto.initializeOrgCrypto(
|
||||||
|
req = mockInitCryptoRequest,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `initializeOrgCrypto with sdk failure should return failure`() = runBlocking {
|
||||||
|
val mockInitCryptoRequest = mockk<InitOrgCryptoRequest>()
|
||||||
|
val expectedException = IllegalStateException("mock")
|
||||||
|
coEvery {
|
||||||
|
clientCrypto.initializeOrgCrypto(
|
||||||
|
req = mockInitCryptoRequest,
|
||||||
|
)
|
||||||
|
} throws expectedException
|
||||||
|
val result = vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = mockInitCryptoRequest,
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
expectedException.asFailure(),
|
||||||
|
result,
|
||||||
|
)
|
||||||
|
coVerify {
|
||||||
|
clientCrypto.initializeOrgCrypto(
|
||||||
|
req = mockInitCryptoRequest,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `initializeOrgCrypto with BitwardenException failure should return AuthenticationError`() =
|
||||||
|
runBlocking {
|
||||||
|
val mockInitCryptoRequest = mockk<InitOrgCryptoRequest>()
|
||||||
|
val expectedException = BitwardenException.E(message = "")
|
||||||
|
coEvery {
|
||||||
|
clientCrypto.initializeOrgCrypto(
|
||||||
|
req = mockInitCryptoRequest,
|
||||||
|
)
|
||||||
|
} throws expectedException
|
||||||
|
val result = vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = mockInitCryptoRequest,
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
InitializeCryptoResult.AuthenticationError.asSuccess(),
|
||||||
|
result,
|
||||||
|
)
|
||||||
|
coVerify {
|
||||||
|
clientCrypto.initializeOrgCrypto(
|
||||||
|
req = mockInitCryptoRequest,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `decryptCipher should call SDK and return a Result with correct data`() = runBlocking {
|
fun `decryptCipher should call SDK and return a Result with correct data`() = runBlocking {
|
||||||
val mockCipher = mockk<CipherView>()
|
val mockCipher = mockk<CipherView>()
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.x8bit.bitwarden.data.vault.repository
|
||||||
import app.cash.turbine.test
|
import app.cash.turbine.test
|
||||||
import com.bitwarden.core.CipherView
|
import com.bitwarden.core.CipherView
|
||||||
import com.bitwarden.core.FolderView
|
import com.bitwarden.core.FolderView
|
||||||
|
import com.bitwarden.core.InitOrgCryptoRequest
|
||||||
import com.bitwarden.core.InitUserCryptoMethod
|
import com.bitwarden.core.InitUserCryptoMethod
|
||||||
import com.bitwarden.core.InitUserCryptoRequest
|
import com.bitwarden.core.InitUserCryptoRequest
|
||||||
import com.bitwarden.core.Kdf
|
import com.bitwarden.core.Kdf
|
||||||
|
@ -18,6 +19,7 @@ import com.x8bit.bitwarden.data.platform.util.asFailure
|
||||||
import com.x8bit.bitwarden.data.platform.util.asSuccess
|
import com.x8bit.bitwarden.data.platform.util.asSuccess
|
||||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockCipher
|
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockCipher
|
||||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockCipherJsonRequest
|
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockCipherJsonRequest
|
||||||
|
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockOrganizationKeys
|
||||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockSyncResponse
|
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockSyncResponse
|
||||||
import com.x8bit.bitwarden.data.vault.datasource.network.service.CiphersService
|
import com.x8bit.bitwarden.data.vault.datasource.network.service.CiphersService
|
||||||
import com.x8bit.bitwarden.data.vault.datasource.network.service.SyncService
|
import com.x8bit.bitwarden.data.vault.datasource.network.service.SyncService
|
||||||
|
@ -65,12 +67,20 @@ class VaultRepositoryTest {
|
||||||
dispatcherManager = dispatcherManager,
|
dispatcherManager = dispatcherManager,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `sync with syncService Success should update AuthDiskSource and DataStateFlows`() =
|
fun `sync with syncService Success should unlock the vault for orgs if necessary and update AuthDiskSource and DataStateFlows`() =
|
||||||
runTest {
|
runTest {
|
||||||
coEvery {
|
coEvery {
|
||||||
syncService.sync()
|
syncService.sync()
|
||||||
} returns Result.success(createMockSyncResponse(number = 1))
|
} returns Result.success(createMockSyncResponse(number = 1))
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||||
|
@ -127,6 +137,13 @@ class VaultRepositoryTest {
|
||||||
),
|
),
|
||||||
vaultRepository.sendDataStateFlow.value,
|
vaultRepository.sendDataStateFlow.value,
|
||||||
)
|
)
|
||||||
|
coVerify {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -135,6 +152,13 @@ class VaultRepositoryTest {
|
||||||
coEvery {
|
coEvery {
|
||||||
syncService.sync()
|
syncService.sync()
|
||||||
} returns Result.success(createMockSyncResponse(number = 1))
|
} returns Result.success(createMockSyncResponse(number = 1))
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||||
|
@ -189,6 +213,13 @@ class VaultRepositoryTest {
|
||||||
coEvery {
|
coEvery {
|
||||||
syncService.sync()
|
syncService.sync()
|
||||||
} returns Result.success(createMockSyncResponse(number = 1))
|
} returns Result.success(createMockSyncResponse(number = 1))
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||||
|
@ -241,6 +272,13 @@ class VaultRepositoryTest {
|
||||||
coEvery {
|
coEvery {
|
||||||
syncService.sync()
|
syncService.sync()
|
||||||
} returns Result.success(createMockSyncResponse(number = 1))
|
} returns Result.success(createMockSyncResponse(number = 1))
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||||
} returns mockException.asFailure()
|
} returns mockException.asFailure()
|
||||||
|
@ -267,6 +305,13 @@ class VaultRepositoryTest {
|
||||||
coEvery {
|
coEvery {
|
||||||
syncService.sync()
|
syncService.sync()
|
||||||
} returns Result.success(createMockSyncResponse(number = 1))
|
} returns Result.success(createMockSyncResponse(number = 1))
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||||
|
@ -293,6 +338,13 @@ class VaultRepositoryTest {
|
||||||
coEvery {
|
coEvery {
|
||||||
syncService.sync()
|
syncService.sync()
|
||||||
} returns Result.success(createMockSyncResponse(number = 1))
|
} returns Result.success(createMockSyncResponse(number = 1))
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||||
|
@ -369,6 +421,13 @@ class VaultRepositoryTest {
|
||||||
coEvery {
|
coEvery {
|
||||||
syncService.sync()
|
syncService.sync()
|
||||||
} returns Result.success(createMockSyncResponse(number = 1))
|
} returns Result.success(createMockSyncResponse(number = 1))
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||||
|
@ -429,6 +488,13 @@ class VaultRepositoryTest {
|
||||||
Result.success(createMockSyncResponse(number = 1)),
|
Result.success(createMockSyncResponse(number = 1)),
|
||||||
UnknownHostException().asFailure(),
|
UnknownHostException().asFailure(),
|
||||||
)
|
)
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||||
|
@ -529,6 +595,13 @@ class VaultRepositoryTest {
|
||||||
coEvery {
|
coEvery {
|
||||||
syncService.sync()
|
syncService.sync()
|
||||||
} returns Result.success(createMockSyncResponse(number = 1))
|
} returns Result.success(createMockSyncResponse(number = 1))
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||||
|
@ -546,6 +619,10 @@ class VaultRepositoryTest {
|
||||||
userId = "mockId-1",
|
userId = "mockId-1",
|
||||||
userKey = "mockKey-1",
|
userKey = "mockKey-1",
|
||||||
)
|
)
|
||||||
|
fakeAuthDiskSource.storeOrganizationKeys(
|
||||||
|
userId = "mockId-1",
|
||||||
|
organizationKeys = createMockOrganizationKeys(number = 1),
|
||||||
|
)
|
||||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.initializeCrypto(
|
vaultSdkSource.initializeCrypto(
|
||||||
|
@ -590,6 +667,13 @@ class VaultRepositoryTest {
|
||||||
coEvery {
|
coEvery {
|
||||||
syncService.sync()
|
syncService.sync()
|
||||||
} returns Result.success(createMockSyncResponse(number = 1))
|
} returns Result.success(createMockSyncResponse(number = 1))
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||||
|
@ -681,8 +765,9 @@ class VaultRepositoryTest {
|
||||||
coVerify(exactly = 0) { syncService.sync() }
|
coVerify(exactly = 0) { syncService.sync() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `unlockVaultAndSyncForCurrentUser with unlockVault failure should return GenericError`() =
|
fun `unlockVaultAndSyncForCurrentUser with unlockVault failure for users should return GenericError`() =
|
||||||
runTest {
|
runTest {
|
||||||
coEvery {
|
coEvery {
|
||||||
syncService.sync()
|
syncService.sync()
|
||||||
|
@ -740,7 +825,77 @@ class VaultRepositoryTest {
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `unlockVaultAndSyncForCurrentUser with unlockVault AuthenticationError should return AuthenticationError`() =
|
fun `unlockVaultAndSyncForCurrentUser with unlockVault failure for orgs should return GenericError`() =
|
||||||
|
runTest {
|
||||||
|
coEvery {
|
||||||
|
syncService.sync()
|
||||||
|
} returns Result.success(createMockSyncResponse(number = 1))
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||||
|
} returns mockk()
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(1)))
|
||||||
|
} returns mockk()
|
||||||
|
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
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeCrypto(
|
||||||
|
request = InitUserCryptoRequest(
|
||||||
|
kdfParams = Kdf.Pbkdf2(iterations = DEFAULT_PBKDF2_ITERATIONS.toUInt()),
|
||||||
|
email = "email",
|
||||||
|
privateKey = "mockPrivateKey-1",
|
||||||
|
method = InitUserCryptoMethod.Password(
|
||||||
|
password = "mockPassword-1",
|
||||||
|
userKey = "mockKey-1",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns IllegalStateException().asFailure()
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
VaultState(
|
||||||
|
unlockedVaultUserIds = emptySet(),
|
||||||
|
),
|
||||||
|
vaultRepository.vaultStateFlow.value,
|
||||||
|
)
|
||||||
|
|
||||||
|
val result = vaultRepository.unlockVaultAndSyncForCurrentUser(
|
||||||
|
masterPassword = "mockPassword-1",
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
VaultUnlockResult.GenericError,
|
||||||
|
result,
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
VaultState(
|
||||||
|
unlockedVaultUserIds = emptySet(),
|
||||||
|
),
|
||||||
|
vaultRepository.vaultStateFlow.value,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("MaxLineLength")
|
||||||
|
@Test
|
||||||
|
fun `unlockVaultAndSyncForCurrentUser with unlockVault AuthenticationError for users should return AuthenticationError`() =
|
||||||
runTest {
|
runTest {
|
||||||
coEvery { syncService.sync() } returns Result.success(createMockSyncResponse(number = 1))
|
coEvery { syncService.sync() } returns Result.success(createMockSyncResponse(number = 1))
|
||||||
coEvery {
|
coEvery {
|
||||||
|
@ -791,6 +946,70 @@ class VaultRepositoryTest {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("MaxLineLength")
|
||||||
|
@Test
|
||||||
|
fun `unlockVaultAndSyncForCurrentUser with unlockVault AuthenticationError for orgs should return AuthenticationError`() =
|
||||||
|
runTest {
|
||||||
|
coEvery { syncService.sync() } returns Result.success(createMockSyncResponse(number = 1))
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||||
|
} returns mockk()
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(1)))
|
||||||
|
} returns mockk()
|
||||||
|
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
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeCrypto(
|
||||||
|
request = InitUserCryptoRequest(
|
||||||
|
kdfParams = Kdf.Pbkdf2(iterations = DEFAULT_PBKDF2_ITERATIONS.toUInt()),
|
||||||
|
email = "email",
|
||||||
|
privateKey = "mockPrivateKey-1",
|
||||||
|
method = InitUserCryptoMethod.Password(
|
||||||
|
password = "",
|
||||||
|
userKey = "mockKey-1",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.AuthenticationError.asSuccess()
|
||||||
|
assertEquals(
|
||||||
|
VaultState(
|
||||||
|
unlockedVaultUserIds = emptySet(),
|
||||||
|
),
|
||||||
|
vaultRepository.vaultStateFlow.value,
|
||||||
|
)
|
||||||
|
|
||||||
|
val result = vaultRepository.unlockVaultAndSyncForCurrentUser(masterPassword = "")
|
||||||
|
assertEquals(
|
||||||
|
VaultUnlockResult.AuthenticationError,
|
||||||
|
result,
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
VaultState(
|
||||||
|
unlockedVaultUserIds = emptySet(),
|
||||||
|
),
|
||||||
|
vaultRepository.vaultStateFlow.value,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `unlockVaultAndSyncForCurrentUser with missing user state should return InvalidStateError `() =
|
fun `unlockVaultAndSyncForCurrentUser with missing user state should return InvalidStateError `() =
|
||||||
|
@ -890,7 +1109,7 @@ class VaultRepositoryTest {
|
||||||
val masterPassword = "drowssap"
|
val masterPassword = "drowssap"
|
||||||
val userKey = "12345"
|
val userKey = "12345"
|
||||||
val privateKey = "54321"
|
val privateKey = "54321"
|
||||||
val organizationalKeys = emptyMap<String, String>()
|
val organizationKeys = mapOf("orgId1" to "orgKey1")
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.initializeCrypto(
|
vaultSdkSource.initializeCrypto(
|
||||||
request = InitUserCryptoRequest(
|
request = InitUserCryptoRequest(
|
||||||
|
@ -904,6 +1123,11 @@ class VaultRepositoryTest {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
} returns InitializeCryptoResult.Success.asSuccess()
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(organizationKeys = organizationKeys),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
VaultState(
|
VaultState(
|
||||||
unlockedVaultUserIds = emptySet(),
|
unlockedVaultUserIds = emptySet(),
|
||||||
|
@ -918,7 +1142,7 @@ class VaultRepositoryTest {
|
||||||
email = email,
|
email = email,
|
||||||
userKey = userKey,
|
userKey = userKey,
|
||||||
privateKey = privateKey,
|
privateKey = privateKey,
|
||||||
organizationalKeys = organizationalKeys,
|
organizationKeys = organizationKeys,
|
||||||
)
|
)
|
||||||
|
|
||||||
assertEquals(VaultUnlockResult.Success, result)
|
assertEquals(VaultUnlockResult.Success, result)
|
||||||
|
@ -941,11 +1165,16 @@ class VaultRepositoryTest {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
coVerify(exactly = 1) {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(organizationKeys = organizationKeys),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `unlockVault with initializeCrypto authentication failure should return AuthenticationError`() =
|
fun `unlockVault with initializeCrypto authentication failure for users should return AuthenticationError`() =
|
||||||
runTest {
|
runTest {
|
||||||
val userId = "userId"
|
val userId = "userId"
|
||||||
val kdf = MOCK_PROFILE.toSdkParams()
|
val kdf = MOCK_PROFILE.toSdkParams()
|
||||||
|
@ -953,7 +1182,7 @@ class VaultRepositoryTest {
|
||||||
val masterPassword = "drowssap"
|
val masterPassword = "drowssap"
|
||||||
val userKey = "12345"
|
val userKey = "12345"
|
||||||
val privateKey = "54321"
|
val privateKey = "54321"
|
||||||
val organizationalKeys = emptyMap<String, String>()
|
val organizationKeys = mapOf("orgId1" to "orgKey1")
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.initializeCrypto(
|
vaultSdkSource.initializeCrypto(
|
||||||
request = InitUserCryptoRequest(
|
request = InitUserCryptoRequest(
|
||||||
|
@ -967,6 +1196,7 @@ class VaultRepositoryTest {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
} returns InitializeCryptoResult.AuthenticationError.asSuccess()
|
} returns InitializeCryptoResult.AuthenticationError.asSuccess()
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
VaultState(
|
VaultState(
|
||||||
unlockedVaultUserIds = emptySet(),
|
unlockedVaultUserIds = emptySet(),
|
||||||
|
@ -981,7 +1211,7 @@ class VaultRepositoryTest {
|
||||||
email = email,
|
email = email,
|
||||||
userKey = userKey,
|
userKey = userKey,
|
||||||
privateKey = privateKey,
|
privateKey = privateKey,
|
||||||
organizationalKeys = organizationalKeys,
|
organizationKeys = organizationKeys,
|
||||||
)
|
)
|
||||||
|
|
||||||
assertEquals(VaultUnlockResult.AuthenticationError, result)
|
assertEquals(VaultUnlockResult.AuthenticationError, result)
|
||||||
|
@ -1006,66 +1236,213 @@ class VaultRepositoryTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `unlockVault with initializeCrypto failure should return GenericError`() = runTest {
|
fun `unlockVault with initializeCrypto authentication failure for orgs should return AuthenticationError`() =
|
||||||
val userId = "userId"
|
runTest {
|
||||||
val kdf = MOCK_PROFILE.toSdkParams()
|
val userId = "userId"
|
||||||
val email = MOCK_PROFILE.email
|
val kdf = MOCK_PROFILE.toSdkParams()
|
||||||
val masterPassword = "drowssap"
|
val email = MOCK_PROFILE.email
|
||||||
val userKey = "12345"
|
val masterPassword = "drowssap"
|
||||||
val privateKey = "54321"
|
val userKey = "12345"
|
||||||
val organizationalKeys = emptyMap<String, String>()
|
val privateKey = "54321"
|
||||||
coEvery {
|
val organizationKeys = mapOf("orgId1" to "orgKey1")
|
||||||
vaultSdkSource.initializeCrypto(
|
coEvery {
|
||||||
request = InitUserCryptoRequest(
|
vaultSdkSource.initializeCrypto(
|
||||||
kdfParams = kdf,
|
request = InitUserCryptoRequest(
|
||||||
email = email,
|
kdfParams = kdf,
|
||||||
privateKey = privateKey,
|
email = email,
|
||||||
method = InitUserCryptoMethod.Password(
|
privateKey = privateKey,
|
||||||
password = masterPassword,
|
method = InitUserCryptoMethod.Password(
|
||||||
userKey = userKey,
|
password = masterPassword,
|
||||||
|
userKey = userKey,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(organizationKeys = organizationKeys),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.AuthenticationError.asSuccess()
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
VaultState(
|
||||||
|
unlockedVaultUserIds = emptySet(),
|
||||||
),
|
),
|
||||||
|
vaultRepository.vaultStateFlow.value,
|
||||||
)
|
)
|
||||||
} returns Throwable("Fail").asFailure()
|
|
||||||
assertEquals(
|
|
||||||
VaultState(
|
|
||||||
unlockedVaultUserIds = emptySet(),
|
|
||||||
),
|
|
||||||
vaultRepository.vaultStateFlow.value,
|
|
||||||
)
|
|
||||||
|
|
||||||
val result = vaultRepository.unlockVault(
|
val result = vaultRepository.unlockVault(
|
||||||
userId = userId,
|
userId = userId,
|
||||||
masterPassword = masterPassword,
|
masterPassword = masterPassword,
|
||||||
kdf = kdf,
|
kdf = kdf,
|
||||||
email = email,
|
email = email,
|
||||||
userKey = userKey,
|
userKey = userKey,
|
||||||
privateKey = privateKey,
|
privateKey = privateKey,
|
||||||
organizationalKeys = organizationalKeys,
|
organizationKeys = organizationKeys,
|
||||||
)
|
)
|
||||||
|
|
||||||
assertEquals(VaultUnlockResult.GenericError, result)
|
assertEquals(VaultUnlockResult.AuthenticationError, result)
|
||||||
assertEquals(
|
assertEquals(
|
||||||
VaultState(
|
VaultState(
|
||||||
unlockedVaultUserIds = emptySet(),
|
unlockedVaultUserIds = emptySet(),
|
||||||
),
|
),
|
||||||
vaultRepository.vaultStateFlow.value,
|
vaultRepository.vaultStateFlow.value,
|
||||||
)
|
)
|
||||||
coVerify(exactly = 1) {
|
coVerify(exactly = 1) {
|
||||||
vaultSdkSource.initializeCrypto(
|
vaultSdkSource.initializeCrypto(
|
||||||
request = InitUserCryptoRequest(
|
request = InitUserCryptoRequest(
|
||||||
kdfParams = kdf,
|
kdfParams = kdf,
|
||||||
email = email,
|
email = email,
|
||||||
privateKey = privateKey,
|
privateKey = privateKey,
|
||||||
method = InitUserCryptoMethod.Password(
|
method = InitUserCryptoMethod.Password(
|
||||||
password = masterPassword,
|
password = masterPassword,
|
||||||
userKey = userKey,
|
userKey = userKey,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
)
|
}
|
||||||
|
coVerify(exactly = 1) {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(organizationKeys = organizationKeys),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `unlockVault with initializeCrypto failure for users should return GenericError`() =
|
||||||
|
runTest {
|
||||||
|
val userId = "userId"
|
||||||
|
val kdf = MOCK_PROFILE.toSdkParams()
|
||||||
|
val email = MOCK_PROFILE.email
|
||||||
|
val masterPassword = "drowssap"
|
||||||
|
val userKey = "12345"
|
||||||
|
val privateKey = "54321"
|
||||||
|
val organizationKeys = mapOf("orgId1" to "orgKey1")
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeCrypto(
|
||||||
|
request = InitUserCryptoRequest(
|
||||||
|
kdfParams = kdf,
|
||||||
|
email = email,
|
||||||
|
privateKey = privateKey,
|
||||||
|
method = InitUserCryptoMethod.Password(
|
||||||
|
password = masterPassword,
|
||||||
|
userKey = userKey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns Throwable("Fail").asFailure()
|
||||||
|
assertEquals(
|
||||||
|
VaultState(
|
||||||
|
unlockedVaultUserIds = emptySet(),
|
||||||
|
),
|
||||||
|
vaultRepository.vaultStateFlow.value,
|
||||||
|
)
|
||||||
|
|
||||||
|
val result = vaultRepository.unlockVault(
|
||||||
|
userId = userId,
|
||||||
|
masterPassword = masterPassword,
|
||||||
|
kdf = kdf,
|
||||||
|
email = email,
|
||||||
|
userKey = userKey,
|
||||||
|
privateKey = privateKey,
|
||||||
|
organizationKeys = organizationKeys,
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(VaultUnlockResult.GenericError, result)
|
||||||
|
assertEquals(
|
||||||
|
VaultState(
|
||||||
|
unlockedVaultUserIds = emptySet(),
|
||||||
|
),
|
||||||
|
vaultRepository.vaultStateFlow.value,
|
||||||
|
)
|
||||||
|
coVerify(exactly = 1) {
|
||||||
|
vaultSdkSource.initializeCrypto(
|
||||||
|
request = InitUserCryptoRequest(
|
||||||
|
kdfParams = kdf,
|
||||||
|
email = email,
|
||||||
|
privateKey = privateKey,
|
||||||
|
method = InitUserCryptoMethod.Password(
|
||||||
|
password = masterPassword,
|
||||||
|
userKey = userKey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `unlockVault with initializeCrypto failure for orgs should return GenericError`() =
|
||||||
|
runTest {
|
||||||
|
val userId = "userId"
|
||||||
|
val kdf = MOCK_PROFILE.toSdkParams()
|
||||||
|
val email = MOCK_PROFILE.email
|
||||||
|
val masterPassword = "drowssap"
|
||||||
|
val userKey = "12345"
|
||||||
|
val privateKey = "54321"
|
||||||
|
val organizationKeys = mapOf("orgId1" to "orgKey1")
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeCrypto(
|
||||||
|
request = InitUserCryptoRequest(
|
||||||
|
kdfParams = kdf,
|
||||||
|
email = email,
|
||||||
|
privateKey = privateKey,
|
||||||
|
method = InitUserCryptoMethod.Password(
|
||||||
|
password = masterPassword,
|
||||||
|
userKey = userKey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(organizationKeys = organizationKeys),
|
||||||
|
)
|
||||||
|
} returns Throwable("Fail").asFailure()
|
||||||
|
assertEquals(
|
||||||
|
VaultState(
|
||||||
|
unlockedVaultUserIds = emptySet(),
|
||||||
|
),
|
||||||
|
vaultRepository.vaultStateFlow.value,
|
||||||
|
)
|
||||||
|
|
||||||
|
val result = vaultRepository.unlockVault(
|
||||||
|
userId = userId,
|
||||||
|
masterPassword = masterPassword,
|
||||||
|
kdf = kdf,
|
||||||
|
email = email,
|
||||||
|
userKey = userKey,
|
||||||
|
privateKey = privateKey,
|
||||||
|
organizationKeys = organizationKeys,
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(VaultUnlockResult.GenericError, result)
|
||||||
|
assertEquals(
|
||||||
|
VaultState(
|
||||||
|
unlockedVaultUserIds = emptySet(),
|
||||||
|
),
|
||||||
|
vaultRepository.vaultStateFlow.value,
|
||||||
|
)
|
||||||
|
coVerify(exactly = 1) {
|
||||||
|
vaultSdkSource.initializeCrypto(
|
||||||
|
request = InitUserCryptoRequest(
|
||||||
|
kdfParams = kdf,
|
||||||
|
email = email,
|
||||||
|
privateKey = privateKey,
|
||||||
|
method = InitUserCryptoMethod.Password(
|
||||||
|
password = masterPassword,
|
||||||
|
userKey = userKey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
coVerify(exactly = 1) {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(organizationKeys = organizationKeys),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `unlockVault with initializeCrypto awaiting should block calls to sync`() = runTest {
|
fun `unlockVault with initializeCrypto awaiting should block calls to sync`() = runTest {
|
||||||
|
@ -1075,7 +1452,7 @@ class VaultRepositoryTest {
|
||||||
val masterPassword = "drowssap"
|
val masterPassword = "drowssap"
|
||||||
val userKey = "12345"
|
val userKey = "12345"
|
||||||
val privateKey = "54321"
|
val privateKey = "54321"
|
||||||
val organizationalKeys = emptyMap<String, String>()
|
val organizationKeys = null
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.initializeCrypto(
|
vaultSdkSource.initializeCrypto(
|
||||||
request = InitUserCryptoRequest(
|
request = InitUserCryptoRequest(
|
||||||
|
@ -1099,7 +1476,7 @@ class VaultRepositoryTest {
|
||||||
email = email,
|
email = email,
|
||||||
userKey = userKey,
|
userKey = userKey,
|
||||||
privateKey = privateKey,
|
privateKey = privateKey,
|
||||||
organizationalKeys = organizationalKeys,
|
organizationKeys = organizationKeys,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// Does nothing because we are blocking
|
// Does nothing because we are blocking
|
||||||
|
@ -1128,6 +1505,13 @@ class VaultRepositoryTest {
|
||||||
coEvery {
|
coEvery {
|
||||||
syncService.sync()
|
syncService.sync()
|
||||||
} returns Result.success(createMockSyncResponse(number = 1))
|
} returns Result.success(createMockSyncResponse(number = 1))
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||||
|
@ -1170,6 +1554,13 @@ class VaultRepositoryTest {
|
||||||
coEvery {
|
coEvery {
|
||||||
syncService.sync()
|
syncService.sync()
|
||||||
} returns Result.success(createMockSyncResponse(number = 1))
|
} returns Result.success(createMockSyncResponse(number = 1))
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||||
|
@ -1213,6 +1604,13 @@ class VaultRepositoryTest {
|
||||||
coEvery {
|
coEvery {
|
||||||
syncService.sync()
|
syncService.sync()
|
||||||
} returns Result.success(createMockSyncResponse(itemId))
|
} returns Result.success(createMockSyncResponse(itemId))
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(itemId),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(itemId)))
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(itemId)))
|
||||||
} returns listOf(item).asSuccess()
|
} returns listOf(item).asSuccess()
|
||||||
|
@ -1287,6 +1685,13 @@ class VaultRepositoryTest {
|
||||||
coEvery {
|
coEvery {
|
||||||
syncService.sync()
|
syncService.sync()
|
||||||
} returns Result.success(createMockSyncResponse(1))
|
} returns Result.success(createMockSyncResponse(1))
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||||
} returns listOf(createMockCipherView(1)).asSuccess()
|
} returns listOf(createMockCipherView(1)).asSuccess()
|
||||||
|
@ -1319,6 +1724,13 @@ class VaultRepositoryTest {
|
||||||
coEvery {
|
coEvery {
|
||||||
syncService.sync()
|
syncService.sync()
|
||||||
} returns Result.success(createMockSyncResponse(folderId))
|
} returns Result.success(createMockSyncResponse(folderId))
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(folderId),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(folderId)))
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(folderId)))
|
||||||
} returns listOf(createMockCipherView(folderId)).asSuccess()
|
} returns listOf(createMockCipherView(folderId)).asSuccess()
|
||||||
|
@ -1393,6 +1805,13 @@ class VaultRepositoryTest {
|
||||||
coEvery {
|
coEvery {
|
||||||
syncService.sync()
|
syncService.sync()
|
||||||
} returns Result.success(createMockSyncResponse(1))
|
} returns Result.success(createMockSyncResponse(1))
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||||
} returns listOf(createMockCipherView(1)).asSuccess()
|
} returns listOf(createMockCipherView(1)).asSuccess()
|
||||||
|
@ -1471,6 +1890,13 @@ class VaultRepositoryTest {
|
||||||
coEvery {
|
coEvery {
|
||||||
syncService.sync()
|
syncService.sync()
|
||||||
} returns Result.success(createMockSyncResponse(1))
|
} returns Result.success(createMockSyncResponse(1))
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||||
} returns listOf(createMockCipherView(1)).asSuccess()
|
} returns listOf(createMockCipherView(1)).asSuccess()
|
||||||
|
@ -1548,6 +1974,13 @@ class VaultRepositoryTest {
|
||||||
coEvery {
|
coEvery {
|
||||||
syncService.sync()
|
syncService.sync()
|
||||||
} returns Result.success(createMockSyncResponse(1))
|
} returns Result.success(createMockSyncResponse(1))
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.initializeOrganizationCrypto(
|
||||||
|
request = InitOrgCryptoRequest(
|
||||||
|
organizationKeys = createMockOrganizationKeys(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns InitializeCryptoResult.Success.asSuccess()
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||||
} returns listOf(createMockCipherView(1)).asSuccess()
|
} returns listOf(createMockCipherView(1)).asSuccess()
|
||||||
|
@ -1577,7 +2010,7 @@ class VaultRepositoryTest {
|
||||||
val masterPassword = "drowssap"
|
val masterPassword = "drowssap"
|
||||||
val userKey = "12345"
|
val userKey = "12345"
|
||||||
val privateKey = "54321"
|
val privateKey = "54321"
|
||||||
val organizationalKeys = emptyMap<String, String>()
|
val organizationKeys = null
|
||||||
coEvery {
|
coEvery {
|
||||||
vaultSdkSource.initializeCrypto(
|
vaultSdkSource.initializeCrypto(
|
||||||
request = InitUserCryptoRequest(
|
request = InitUserCryptoRequest(
|
||||||
|
@ -1599,7 +2032,7 @@ class VaultRepositoryTest {
|
||||||
email = email,
|
email = email,
|
||||||
userKey = userKey,
|
userKey = userKey,
|
||||||
privateKey = privateKey,
|
privateKey = privateKey,
|
||||||
organizationalKeys = organizationalKeys,
|
organizationKeys = organizationKeys,
|
||||||
)
|
)
|
||||||
|
|
||||||
assertEquals(VaultUnlockResult.Success, result)
|
assertEquals(VaultUnlockResult.Success, result)
|
||||||
|
|
Loading…
Reference in a new issue