[PM-25523] Add importCxfPayload to VaultRepository (#5846)

This commit is contained in:
Patrick Honkonen 2025-09-05 15:57:43 -04:00 committed by GitHub
parent 46c7e79039
commit 0702078b04
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 87 additions and 0 deletions

View File

@ -24,6 +24,7 @@ import com.x8bit.bitwarden.data.vault.repository.model.DeleteSendResult
import com.x8bit.bitwarden.data.vault.repository.model.DomainsData
import com.x8bit.bitwarden.data.vault.repository.model.ExportVaultDataResult
import com.x8bit.bitwarden.data.vault.repository.model.GenerateTotpResult
import com.x8bit.bitwarden.data.vault.repository.model.ImportCxfPayloadResult
import com.x8bit.bitwarden.data.vault.repository.model.RemovePasswordSendResult
import com.x8bit.bitwarden.data.vault.repository.model.SendData
import com.x8bit.bitwarden.data.vault.repository.model.SyncVaultDataResult
@ -258,6 +259,13 @@ interface VaultRepository : CipherManager, VaultLockManager {
restrictedTypes: List<CipherType>,
): ExportVaultDataResult
/**
* Attempt to import a CXF payload.
*
* @param payload The CXF payload to import.
*/
suspend fun importCxfPayload(payload: String): ImportCxfPayloadResult
/**
* Flow that represents the data for a specific vault list item as found by ID. This may emit
* `null` if the item cannot be found.

View File

@ -73,6 +73,7 @@ import com.x8bit.bitwarden.data.vault.repository.model.DeleteSendResult
import com.x8bit.bitwarden.data.vault.repository.model.DomainsData
import com.x8bit.bitwarden.data.vault.repository.model.ExportVaultDataResult
import com.x8bit.bitwarden.data.vault.repository.model.GenerateTotpResult
import com.x8bit.bitwarden.data.vault.repository.model.ImportCxfPayloadResult
import com.x8bit.bitwarden.data.vault.repository.model.RemovePasswordSendResult
import com.x8bit.bitwarden.data.vault.repository.model.SendData
import com.x8bit.bitwarden.data.vault.repository.model.SyncVaultDataResult
@ -971,6 +972,20 @@ class VaultRepositoryImpl(
)
}
override suspend fun importCxfPayload(payload: String): ImportCxfPayloadResult {
val userId = activeUserId
?: return ImportCxfPayloadResult.Error(error = NoActiveUserException())
return vaultSdkSource
.importCxf(
userId = userId,
payload = payload,
)
.fold(
onSuccess = { ImportCxfPayloadResult.Success(it) },
onFailure = { ImportCxfPayloadResult.Error(error = it) },
)
}
/**
* Checks if the given [userId] has an associated encrypted PIN key but not a pin-protected user
* key. This indicates a scenario in which a user has requested PIN unlocking but requires

View File

@ -0,0 +1,21 @@
package com.x8bit.bitwarden.data.vault.repository.model
import com.bitwarden.vault.Cipher
/**
* Models result of the vault data being imported from a CXF payload.
*/
sealed class ImportCxfPayloadResult {
/**
* The vault data has been successfully imported.
*/
data class Success(val ciphers: List<Cipher>) : ImportCxfPayloadResult()
/**
* There was an error importing the vault data.
*
* @param error The error that occurred during import.
*/
data class Error(val error: Throwable) : ImportCxfPayloadResult()
}

View File

@ -92,6 +92,7 @@ import com.x8bit.bitwarden.data.vault.repository.model.DeleteSendResult
import com.x8bit.bitwarden.data.vault.repository.model.DomainsData
import com.x8bit.bitwarden.data.vault.repository.model.ExportVaultDataResult
import com.x8bit.bitwarden.data.vault.repository.model.GenerateTotpResult
import com.x8bit.bitwarden.data.vault.repository.model.ImportCxfPayloadResult
import com.x8bit.bitwarden.data.vault.repository.model.RemovePasswordSendResult
import com.x8bit.bitwarden.data.vault.repository.model.SendData
import com.x8bit.bitwarden.data.vault.repository.model.SyncVaultDataResult
@ -4255,6 +4256,48 @@ class VaultRepositoryTest {
)
}
@Test
fun `importCxfPayload should return success result`() = runTest {
val userId = "mockId-1"
val payload = "payload"
val ciphers = listOf(createMockSdkCipher(number = 1))
fakeAuthDiskSource.userState = MOCK_USER_STATE
coEvery {
vaultSdkSource.importCxf(
userId = userId,
payload = payload,
)
} returns ciphers.asSuccess()
val result = vaultRepository.importCxfPayload(payload)
assertEquals(
ImportCxfPayloadResult.Success(ciphers),
result,
)
}
@Test
fun `importCxfPayload should return error result`() = runTest {
val userId = "mockId-1"
val payload = "payload"
val expected = Throwable()
fakeAuthDiskSource.userState = MOCK_USER_STATE
coEvery {
vaultSdkSource.importCxf(
userId = userId,
payload = payload,
)
} returns expected.asFailure()
val result = vaultRepository.importCxfPayload(payload)
assertEquals(
ImportCxfPayloadResult.Error(expected),
result,
)
}
@Test
fun `silentlyDiscoverCredentials should return result`() = runTest {
val userId = "userId"