Maybe working

This commit is contained in:
Hinton 2024-10-24 14:20:45 -07:00
parent 028d382a5b
commit 2e0f07e138
No known key found for this signature in database
GPG key ID: 5F7295599C5D965C
4 changed files with 91 additions and 0 deletions

View file

@ -26,6 +26,11 @@ interface VaultDiskSource {
*/ */
fun getOfflineCiphers(userId: String): Flow<List<OfflineCipherJson>> fun getOfflineCiphers(userId: String): Flow<List<OfflineCipherJson>>
/**
* Deletes an offline cipher from the data source for the given [userId] and [cipherId].
*/
suspend fun deleteOfflineCipher(userId: String, cipherId: String)
/** /**
* Retrieves all ciphers from the data source for a given [userId]. * Retrieves all ciphers from the data source for a given [userId].
*/ */

View file

@ -105,6 +105,10 @@ class VaultDiskSourceImpl(
}, },
) )
override suspend fun deleteOfflineCipher(userId: String, cipherId: String) {
offlineCiphersDao.deleteCipher(userId, cipherId)
}
override fun getCiphers( override fun getCiphers(
userId: String, userId: String,
): Flow<List<SyncResponseJson.Cipher>> = ): Flow<List<SyncResponseJson.Cipher>> =

View file

@ -6,11 +6,13 @@ import com.bitwarden.vault.AttachmentView
import com.bitwarden.vault.Cipher import com.bitwarden.vault.Cipher
import com.bitwarden.vault.CipherView import com.bitwarden.vault.CipherView
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
import com.x8bit.bitwarden.data.platform.manager.NetworkConnectionManager
import com.x8bit.bitwarden.data.platform.util.asFailure 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.platform.util.flatMap import com.x8bit.bitwarden.data.platform.util.flatMap
import com.x8bit.bitwarden.data.vault.datasource.disk.VaultDiskSource import com.x8bit.bitwarden.data.vault.datasource.disk.VaultDiskSource
import com.x8bit.bitwarden.data.vault.datasource.network.model.CreateCipherInOrganizationJsonRequest import com.x8bit.bitwarden.data.vault.datasource.network.model.CreateCipherInOrganizationJsonRequest
import com.x8bit.bitwarden.data.vault.datasource.network.model.OfflineCipherJson
import com.x8bit.bitwarden.data.vault.datasource.network.model.ShareCipherJsonRequest import com.x8bit.bitwarden.data.vault.datasource.network.model.ShareCipherJsonRequest
import com.x8bit.bitwarden.data.vault.datasource.network.model.UpdateCipherCollectionsJsonRequest import com.x8bit.bitwarden.data.vault.datasource.network.model.UpdateCipherCollectionsJsonRequest
import com.x8bit.bitwarden.data.vault.datasource.network.model.UpdateCipherResponseJson import com.x8bit.bitwarden.data.vault.datasource.network.model.UpdateCipherResponseJson
@ -25,16 +27,28 @@ import com.x8bit.bitwarden.data.vault.repository.model.DownloadAttachmentResult
import com.x8bit.bitwarden.data.vault.repository.model.RestoreCipherResult import com.x8bit.bitwarden.data.vault.repository.model.RestoreCipherResult
import com.x8bit.bitwarden.data.vault.repository.model.ShareCipherResult import com.x8bit.bitwarden.data.vault.repository.model.ShareCipherResult
import com.x8bit.bitwarden.data.vault.repository.model.UpdateCipherResult import com.x8bit.bitwarden.data.vault.repository.model.UpdateCipherResult
import com.x8bit.bitwarden.data.vault.repository.util.toCipher
import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedNetworkCipher import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedNetworkCipher
import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedNetworkCipherResponse import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedNetworkCipherResponse
import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedSdkCipher import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedSdkCipher
import com.x8bit.bitwarden.data.vault.repository.util.toNetworkAttachmentRequest import com.x8bit.bitwarden.data.vault.repository.util.toNetworkAttachmentRequest
import com.x8bit.bitwarden.data.vault.repository.util.toOfflineCipher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapConcat
import kotlinx.coroutines.flow.flattenConcat
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import java.io.File import java.io.File
import java.time.Clock import java.time.Clock
/** /**
* The default implementation of the [CipherManager]. * The default implementation of the [CipherManager].
*/ */
@OptIn(ExperimentalCoroutinesApi::class)
@Suppress("TooManyFunctions") @Suppress("TooManyFunctions")
class CipherManagerImpl( class CipherManagerImpl(
private val fileManager: FileManager, private val fileManager: FileManager,
@ -43,9 +57,74 @@ class CipherManagerImpl(
private val vaultDiskSource: VaultDiskSource, private val vaultDiskSource: VaultDiskSource,
private val vaultSdkSource: VaultSdkSource, private val vaultSdkSource: VaultSdkSource,
private val clock: Clock, private val clock: Clock,
private val networkConnectionManager: NetworkConnectionManager,
private val externalScope: CoroutineScope,
) : CipherManager { ) : CipherManager {
private val activeUserId: String? get() = authDiskSource.userState?.activeUserId private val activeUserId: String? get() = authDiskSource.userState?.activeUserId
init {
externalScope.launch {
networkConnectionManager.isNetworkConnectedFlow
.map {
if (it && activeUserId != null) {
// Device went online
// TODO: We need to add support for non active users!
vaultDiskSource.getOfflineCiphers(activeUserId!!)
} else {
flowOf(listOf<OfflineCipherJson>())
}
}.flattenConcat().collect {
if (activeUserId == null) {
return@collect
}
val userId = activeUserId!!
it.map { c ->
val cipher = c.toOfflineCipher().toCipher()
when (cipher.id) {
null -> ciphersService.createCipher(body = cipher.toEncryptedNetworkCipher())
.onSuccess {
vaultDiskSource.saveCipher(userId = userId, cipher = it)
vaultDiskSource.deleteOfflineCipher(userId = userId, cipherId = c.id)
}
.fold(
onFailure = { CreateCipherResult.Error },
onSuccess = { CreateCipherResult.Success },
)
else -> ciphersService.updateCipher(
cipherId = cipher.id!!,
body = cipher.toEncryptedNetworkCipher()
).map { response ->
when (response) {
is UpdateCipherResponseJson.Invalid -> {
UpdateCipherResult.Error(errorMessage = response.message)
}
is UpdateCipherResponseJson.Success -> {
vaultDiskSource.saveCipher(
userId = userId,
// TODO: Why are we doing this?
cipher = response.cipher.copy(collectionIds = cipher.collectionIds),
)
UpdateCipherResult.Success
}
}
}
.fold(
onFailure = { UpdateCipherResult.Error(errorMessage = null) },
onSuccess = { it },
)
}
}
}
}
}
override suspend fun createOfflineCipher(cipherView: CipherView): CreateCipherResult { override suspend fun createOfflineCipher(cipherView: CipherView): CreateCipherResult {
val userId = activeUserId ?: return CreateCipherResult.Error val userId = activeUserId ?: return CreateCipherResult.Error

View file

@ -6,6 +6,7 @@ import com.x8bit.bitwarden.data.auth.datasource.sdk.AuthSdkSource
import com.x8bit.bitwarden.data.auth.manager.TrustedDeviceManager import com.x8bit.bitwarden.data.auth.manager.TrustedDeviceManager
import com.x8bit.bitwarden.data.auth.manager.UserLogoutManager import com.x8bit.bitwarden.data.auth.manager.UserLogoutManager
import com.x8bit.bitwarden.data.platform.manager.AppForegroundManager import com.x8bit.bitwarden.data.platform.manager.AppForegroundManager
import com.x8bit.bitwarden.data.platform.manager.NetworkConnectionManager
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.SettingsRepository import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
import com.x8bit.bitwarden.data.vault.datasource.disk.VaultDiskSource import com.x8bit.bitwarden.data.vault.datasource.disk.VaultDiskSource
@ -44,6 +45,7 @@ object VaultManagerModule {
authDiskSource: AuthDiskSource, authDiskSource: AuthDiskSource,
fileManager: FileManager, fileManager: FileManager,
clock: Clock, clock: Clock,
networkConnectionManager: NetworkConnectionManager
): CipherManager = CipherManagerImpl( ): CipherManager = CipherManagerImpl(
fileManager = fileManager, fileManager = fileManager,
authDiskSource = authDiskSource, authDiskSource = authDiskSource,
@ -51,6 +53,7 @@ object VaultManagerModule {
vaultDiskSource = vaultDiskSource, vaultDiskSource = vaultDiskSource,
vaultSdkSource = vaultSdkSource, vaultSdkSource = vaultSdkSource,
clock = clock, clock = clock,
networkConnectionManager = networkConnectionManager
) )
@Provides @Provides