From d2b92a03348b7cec56b464593e59f929f3fd6dff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Zag=C3=B3rski?= Date: Fri, 6 Dec 2024 13:45:24 +0100 Subject: [PATCH 1/6] chore: Core crypto 2.0 migration [WPB-14635] (#3141) * chore: Core crypto 2.0 migration [WPB-14635] * Code review * Rollback to INFO logs --- .../CoreCryptoCentral.kt | 19 ++++++++++ .../ProteusClientCoreCryptoImpl.kt | 37 ++++++++++++++----- .../exceptions/ProteusException.kt | 18 ++++++--- gradle/libs.versions.toml | 2 +- .../kalium/logic/CoreCryptoExceptionMapper.kt | 25 ++++++------- 5 files changed, 72 insertions(+), 29 deletions(-) diff --git a/cryptography/src/commonJvmAndroid/kotlin/com.wire.kalium.cryptography/CoreCryptoCentral.kt b/cryptography/src/commonJvmAndroid/kotlin/com.wire.kalium.cryptography/CoreCryptoCentral.kt index 89c70247f9e..72faee95ae6 100644 --- a/cryptography/src/commonJvmAndroid/kotlin/com.wire.kalium.cryptography/CoreCryptoCentral.kt +++ b/cryptography/src/commonJvmAndroid/kotlin/com.wire.kalium.cryptography/CoreCryptoCentral.kt @@ -20,7 +20,10 @@ package com.wire.kalium.cryptography import com.wire.crypto.ClientId import com.wire.crypto.CoreCrypto import com.wire.crypto.CoreCryptoCallbacks +import com.wire.crypto.CoreCryptoLogLevel +import com.wire.crypto.CoreCryptoLogger import com.wire.crypto.coreCryptoDeferredInit +import com.wire.crypto.setLogger import com.wire.kalium.cryptography.MLSClientImpl.Companion.toCrlRegistration import com.wire.kalium.cryptography.exceptions.CryptographyException import java.io.File @@ -36,12 +39,28 @@ actual suspend fun coreCryptoCentral( key = databaseKey ) coreCrypto.setCallbacks(Callbacks()) + setLogger(CoreCryptoLoggerImpl(), CoreCryptoLogLevel.INFO) return CoreCryptoCentralImpl( cc = coreCrypto, rootDir = rootDir ) } +private class CoreCryptoLoggerImpl : CoreCryptoLogger { + override fun log(level: CoreCryptoLogLevel, message: String, context: String?) { + when (level) { + CoreCryptoLogLevel.TRACE -> kaliumLogger.v("$message. $context") + CoreCryptoLogLevel.DEBUG -> kaliumLogger.d("$message. $context") + CoreCryptoLogLevel.INFO -> kaliumLogger.i("$message. $context") + CoreCryptoLogLevel.WARN -> kaliumLogger.w("$message. $context") + CoreCryptoLogLevel.ERROR -> kaliumLogger.e("$message. $context") + CoreCryptoLogLevel.OFF -> { + // nop + } + } + } +} + private class Callbacks : CoreCryptoCallbacks { override suspend fun authorize(conversationId: ByteArray, clientId: ClientId): Boolean { // We always return true because our BE is currently enforcing that this constraint is always true diff --git a/cryptography/src/commonJvmAndroid/kotlin/com.wire.kalium.cryptography/ProteusClientCoreCryptoImpl.kt b/cryptography/src/commonJvmAndroid/kotlin/com.wire.kalium.cryptography/ProteusClientCoreCryptoImpl.kt index fdc9bc2b69c..f972b6ea165 100644 --- a/cryptography/src/commonJvmAndroid/kotlin/com.wire.kalium.cryptography/ProteusClientCoreCryptoImpl.kt +++ b/cryptography/src/commonJvmAndroid/kotlin/com.wire.kalium.cryptography/ProteusClientCoreCryptoImpl.kt @@ -28,6 +28,7 @@ import io.ktor.util.encodeBase64 import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import java.io.File +import com.wire.crypto.ProteusException as ProteusExceptionNative @Suppress("TooManyFunctions") class ProteusClientCoreCryptoImpl private constructor( @@ -145,13 +146,12 @@ class ProteusClientCoreCryptoImpl private constructor( private inline fun wrapException(b: () -> T): T { try { return b() - } catch (e: CoreCryptoException) { - val proteusLastErrorCode = coreCrypto.proteusLastErrorCode() + } catch (e: CoreCryptoException.Proteus) { throw ProteusException( - e.message, - ProteusException.fromProteusCode(proteusLastErrorCode.toInt()), - proteusLastErrorCode.toInt(), - e + message = e.message, + code = mapProteusExceptionToErrorCode(e.v1), + intCode = mapProteusExceptionToRawIntErrorCode(e.v1), + cause = e ) } catch (e: Exception) { throw ProteusException(e.message, ProteusException.Code.UNKNOWN_ERROR, null, e) @@ -187,11 +187,11 @@ class ProteusClientCoreCryptoImpl private constructor( return ProteusClientCoreCryptoImpl(coreCrypto) } catch (exception: ProteusStorageMigrationException) { throw exception - } catch (e: CoreCryptoException) { + } catch (e: CoreCryptoException.Proteus) { throw ProteusException( message = e.message, - code = ProteusException.fromProteusCode(coreCrypto.proteusLastErrorCode().toInt()), - intCode = coreCrypto.proteusLastErrorCode().toInt(), + code = mapProteusExceptionToErrorCode(e.v1), + intCode = mapProteusExceptionToRawIntErrorCode(e.v1), cause = e.cause ) } catch (e: Exception) { @@ -218,5 +218,24 @@ class ProteusClientCoreCryptoImpl private constructor( throw ProteusStorageMigrationException("Failed to migrate from crypto box at $rootDir", exception) } } + + private fun mapProteusExceptionToErrorCode(proteusException: ProteusExceptionNative): ProteusException.Code { + return when (proteusException) { + is ProteusExceptionNative.SessionNotFound -> ProteusException.Code.SESSION_NOT_FOUND + is ProteusExceptionNative.DuplicateMessage -> ProteusException.Code.DUPLICATE_MESSAGE + is ProteusExceptionNative.RemoteIdentityChanged -> ProteusException.Code.REMOTE_IDENTITY_CHANGED + is ProteusExceptionNative.Other -> ProteusException.fromProteusCode(proteusException.v1.toInt()) + } + } + + @Suppress("MagicNumber") + private fun mapProteusExceptionToRawIntErrorCode(proteusException: ProteusExceptionNative): Int { + return when (proteusException) { + is ProteusExceptionNative.SessionNotFound -> 102 + is ProteusExceptionNative.DuplicateMessage -> 209 + is ProteusExceptionNative.RemoteIdentityChanged -> 204 + is ProteusExceptionNative.Other -> proteusException.v1.toInt() + } + } } } diff --git a/cryptography/src/commonMain/kotlin/com/wire/kalium/cryptography/exceptions/ProteusException.kt b/cryptography/src/commonMain/kotlin/com/wire/kalium/cryptography/exceptions/ProteusException.kt index 547d0deefa9..18750c29f92 100644 --- a/cryptography/src/commonMain/kotlin/com/wire/kalium/cryptography/exceptions/ProteusException.kt +++ b/cryptography/src/commonMain/kotlin/com/wire/kalium/cryptography/exceptions/ProteusException.kt @@ -176,19 +176,25 @@ open class ProteusException(message: String?, val code: Code, val intCode: Int?, } } - // Mapping source: - // https://github.com/wireapp/proteus/blob/2.x/crates/proteus-traits/src/lib.rs - // https://github.com/wireapp/wire-web-core/blob/7383e108f5e9d15d0b82c41ed504964667463cfc/packages/proteus/README.md + /** + * Those error codes are mapped directly from [com.wire.crypto.ProteusException]: + * - [Code.SESSION_NOT_FOUND] + * - [Code.REMOTE_IDENTITY_CHANGED] + * - [Code.DUPLICATE_MESSAGE] + * + * See the mapping: [com.wire.kalium.cryptography.ProteusClientCoreCryptoImpl.Companion.mapProteusExceptionToErrorCode] + * + * [Mapping sources](https://github.com/wireapp/proteus/blob/2.x/crates/proteus-traits/src/lib.rs) + * + * [Mapping source README](https://github.com/wireapp/wire-web-core/blob/7383e108f5e9d15d0b82c41ed504964667463cfc/packages/proteus/README.md) + */ fun fromProteusCode(code: Int): Code { @Suppress("MagicNumber") return when (code) { 501 -> Code.STORAGE_ERROR - 102 -> Code.SESSION_NOT_FOUND 3, 301, 302, 303 -> Code.DECODE_ERROR - 204 -> Code.REMOTE_IDENTITY_CHANGED 206, 207, 210 -> Code.INVALID_SIGNATURE 200, 201, 202, 205, 213 -> Code.INVALID_MESSAGE - 209 -> Code.DUPLICATE_MESSAGE 211, 212 -> Code.TOO_DISTANT_FUTURE 208 -> Code.OUTDATED_MESSAGE 300 -> Code.IDENTITY_ERROR diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8fe82ae3248..6c3b94a0f59 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -39,7 +39,7 @@ pbandk = "0.14.2" turbine = "1.1.0" avs = "10.0.1" jna = "5.14.0" -core-crypto = "1.0.2" +core-crypto = "2.0.0" core-crypto-multiplatform = "0.6.0-rc.3-multiplatform-pre1" completeKotlin = "1.1.0" desugar-jdk = "2.1.3" diff --git a/logic/src/commonJvmAndroid/kotlin/com/wire/kalium/logic/CoreCryptoExceptionMapper.kt b/logic/src/commonJvmAndroid/kotlin/com/wire/kalium/logic/CoreCryptoExceptionMapper.kt index a41535a1dc3..d2b7342a6d1 100644 --- a/logic/src/commonJvmAndroid/kotlin/com/wire/kalium/logic/CoreCryptoExceptionMapper.kt +++ b/logic/src/commonJvmAndroid/kotlin/com/wire/kalium/logic/CoreCryptoExceptionMapper.kt @@ -18,21 +18,20 @@ package com.wire.kalium.logic import com.wire.crypto.CoreCryptoException -import uniffi.core_crypto.CryptoError +import com.wire.crypto.MlsException actual fun mapMLSException(exception: Exception): MLSFailure = - if (exception is CoreCryptoException.CryptoException) { - when (exception.error) { - is CryptoError.WrongEpoch -> MLSFailure.WrongEpoch - is CryptoError.DuplicateMessage -> MLSFailure.DuplicateMessage - is CryptoError.BufferedFutureMessage -> MLSFailure.BufferedFutureMessage - is CryptoError.SelfCommitIgnored -> MLSFailure.SelfCommitIgnored - is CryptoError.UnmergedPendingGroup -> MLSFailure.UnmergedPendingGroup - is CryptoError.StaleProposal -> MLSFailure.StaleProposal - is CryptoError.StaleCommit -> MLSFailure.StaleCommit - is CryptoError.ConversationAlreadyExists -> MLSFailure.ConversationAlreadyExists - is CryptoError.MessageEpochTooOld -> MLSFailure.MessageEpochTooOld - is CryptoError.MlsException -> MLSFailure.InternalErrors + if (exception is CoreCryptoException.Mls) { + when (exception.v1) { + is MlsException.WrongEpoch -> MLSFailure.WrongEpoch + is MlsException.DuplicateMessage -> MLSFailure.DuplicateMessage + is MlsException.BufferedFutureMessage -> MLSFailure.BufferedFutureMessage + is MlsException.SelfCommitIgnored -> MLSFailure.SelfCommitIgnored + is MlsException.UnmergedPendingGroup -> MLSFailure.UnmergedPendingGroup + is MlsException.StaleProposal -> MLSFailure.StaleProposal + is MlsException.StaleCommit -> MLSFailure.StaleCommit + is MlsException.ConversationAlreadyExists -> MLSFailure.ConversationAlreadyExists + is MlsException.MessageEpochTooOld -> MLSFailure.MessageEpochTooOld else -> MLSFailure.Generic(exception) } } else { From 3d7c7122ebdc05f93773f3d5dee1155d5710647e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20=C5=BBerko?= Date: Fri, 6 Dec 2024 14:01:09 +0100 Subject: [PATCH 2/6] fix: folders slow sync [WPB-14396] (#3146) * fix: made folders sync as optional during slow sync * move first sync to fetch fav folder * test fix * removed unused use case --- .../kalium/logic/data/sync/SlowSyncStatus.kt | 3 +- .../kalium/logic/feature/UserSessionScope.kt | 8 +---- .../folder/GetFavoriteFolderUseCase.kt | 22 +++++++++--- .../folder/SyncConversationFoldersUseCase.kt | 36 ------------------- .../kalium/logic/sync/slow/SlowSyncManager.kt | 3 +- .../kalium/logic/sync/slow/SlowSyncWorker.kt | 3 -- .../folder/GetFavoriteFolderUseCaseTest.kt | 29 ++++++++++++++- .../logic/sync/slow/SlowSyncWorkerTest.kt | 15 +------- .../kalium/persistence/ConversationFolders.sq | 3 ++ .../folder/ConversationFolderDAOImpl.kt | 1 + 10 files changed, 55 insertions(+), 68 deletions(-) delete mode 100644 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/folder/SyncConversationFoldersUseCase.kt diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/sync/SlowSyncStatus.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/sync/SlowSyncStatus.kt index 5bb50ed3cf4..631400557e7 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/sync/SlowSyncStatus.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/sync/SlowSyncStatus.kt @@ -43,6 +43,5 @@ enum class SlowSyncStep { CONTACTS, JOINING_MLS_CONVERSATIONS, RESOLVE_ONE_ON_ONE_PROTOCOLS, - LEGAL_HOLD, - CONVERSATION_FOLDERS, + LEGAL_HOLD } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt index e7e1a1637a8..543d5f9030c 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt @@ -210,8 +210,6 @@ import com.wire.kalium.logic.feature.conversation.RecoverMLSConversationsUseCase import com.wire.kalium.logic.feature.conversation.SyncConversationsUseCase import com.wire.kalium.logic.feature.conversation.SyncConversationsUseCaseImpl import com.wire.kalium.logic.feature.conversation.TypingIndicatorSyncManager -import com.wire.kalium.logic.feature.conversation.folder.SyncConversationFoldersUseCase -import com.wire.kalium.logic.feature.conversation.folder.SyncConversationFoldersUseCaseImpl import com.wire.kalium.logic.feature.conversation.keyingmaterials.KeyingMaterialsManager import com.wire.kalium.logic.feature.conversation.keyingmaterials.KeyingMaterialsManagerImpl import com.wire.kalium.logic.feature.conversation.mls.MLSOneOnOneConversationResolver @@ -981,9 +979,6 @@ class UserSessionScope internal constructor( systemMessageInserter ) - private val syncConversationFolders: SyncConversationFoldersUseCase - get() = SyncConversationFoldersUseCaseImpl(conversationFolderRepository) - private val syncConnections: SyncConnectionsUseCase get() = SyncConnectionsUseCaseImpl( connectionRepository = connectionRepository @@ -1102,8 +1097,7 @@ class UserSessionScope internal constructor( syncContacts, joinExistingMLSConversations, fetchLegalHoldForSelfUserFromRemoteUseCase, - oneOnOneResolver, - syncConversationFolders + oneOnOneResolver ) } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/folder/GetFavoriteFolderUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/folder/GetFavoriteFolderUseCase.kt index c8e7b950850..45565664e16 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/folder/GetFavoriteFolderUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/folder/GetFavoriteFolderUseCase.kt @@ -17,9 +17,13 @@ */ package com.wire.kalium.logic.feature.conversation.folder +import com.wire.kalium.logic.StorageFailure import com.wire.kalium.logic.data.conversation.ConversationFolder import com.wire.kalium.logic.data.conversation.folders.ConversationFolderRepository import com.wire.kalium.logic.feature.conversation.folder.GetFavoriteFolderUseCase.Result +import com.wire.kalium.logic.functional.Either +import com.wire.kalium.logic.functional.flatMap +import com.wire.kalium.logic.functional.flatMapLeft import com.wire.kalium.logic.functional.fold /** @@ -41,9 +45,19 @@ internal class GetFavoriteFolderUseCaseImpl( ) : GetFavoriteFolderUseCase { override suspend operator fun invoke(): Result { - return conversationFolderRepository.getFavoriteConversationFolder().fold( - { Result.Failure }, - { Result.Success(it) } - ) + return conversationFolderRepository.getFavoriteConversationFolder() + .flatMapLeft { + if (it is StorageFailure.DataNotFound) { + conversationFolderRepository.fetchConversationFolders().flatMap { + conversationFolderRepository.getFavoriteConversationFolder() + } + } else { + Either.Left(it) + } + } + .fold( + { Result.Failure }, + { Result.Success(it) } + ) } } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/folder/SyncConversationFoldersUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/folder/SyncConversationFoldersUseCase.kt deleted file mode 100644 index 216290437e3..00000000000 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/folder/SyncConversationFoldersUseCase.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Wire - * Copyright (C) 2024 Wire Swiss GmbH - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ - -package com.wire.kalium.logic.feature.conversation.folder - -import com.wire.kalium.logic.CoreFailure -import com.wire.kalium.logic.data.conversation.folders.ConversationFolderRepository -import com.wire.kalium.logic.functional.Either - -internal interface SyncConversationFoldersUseCase { - suspend operator fun invoke(): Either -} - -/** - * This use case will sync against the backend the conversation folders of the current user. - */ -internal class SyncConversationFoldersUseCaseImpl( - private val conversationRepository: ConversationFolderRepository, -) : SyncConversationFoldersUseCase { - override suspend operator fun invoke(): Either = conversationRepository.fetchConversationFolders() -} diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/slow/SlowSyncManager.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/slow/SlowSyncManager.kt index a7bce64bfa5..f34f1ec3f8d 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/slow/SlowSyncManager.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/slow/SlowSyncManager.kt @@ -210,7 +210,8 @@ internal class SlowSyncManager( * Useful when a new step is added to Slow Sync, or when we fix some bug in Slow Sync, * and we'd like to get all users to take advantage of the fix. */ - const val CURRENT_VERSION = 9 + const val CURRENT_VERSION = 8 + // because we already had version 9, the next version should be 10 val MIN_RETRY_DELAY = 1.seconds val MAX_RETRY_DELAY = 10.minutes diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/slow/SlowSyncWorker.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/slow/SlowSyncWorker.kt index 2022b6c0f32..35fc040ee08 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/slow/SlowSyncWorker.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/slow/SlowSyncWorker.kt @@ -26,7 +26,6 @@ import com.wire.kalium.logic.data.event.EventRepository import com.wire.kalium.logic.data.sync.SlowSyncStep import com.wire.kalium.logic.feature.connection.SyncConnectionsUseCase import com.wire.kalium.logic.feature.conversation.SyncConversationsUseCase -import com.wire.kalium.logic.feature.conversation.folder.SyncConversationFoldersUseCase import com.wire.kalium.logic.feature.conversation.mls.OneOnOneResolver import com.wire.kalium.logic.feature.featureConfig.SyncFeatureConfigsUseCase import com.wire.kalium.logic.feature.legalhold.FetchLegalHoldForSelfUserFromRemoteUseCase @@ -72,7 +71,6 @@ internal class SlowSyncWorkerImpl( private val joinMLSConversations: JoinExistingMLSConversationsUseCase, private val fetchLegalHoldForSelfUserFromRemoteUseCase: FetchLegalHoldForSelfUserFromRemoteUseCase, private val oneOnOneResolver: OneOnOneResolver, - private val syncConversationFolders: SyncConversationFoldersUseCase, logger: KaliumLogger = kaliumLogger ) : SlowSyncWorker { @@ -104,7 +102,6 @@ internal class SlowSyncWorkerImpl( .continueWithStep(SlowSyncStep.CONTACTS, syncContacts::invoke) .continueWithStep(SlowSyncStep.JOINING_MLS_CONVERSATIONS, joinMLSConversations::invoke) .continueWithStep(SlowSyncStep.RESOLVE_ONE_ON_ONE_PROTOCOLS, oneOnOneResolver::resolveAllOneOnOneConversations) - .continueWithStep(SlowSyncStep.CONVERSATION_FOLDERS, syncConversationFolders::invoke) .flatMap { saveLastProcessedEventIdIfNeeded(lastProcessedEventIdToSaveOnSuccess) } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/folder/GetFavoriteFolderUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/folder/GetFavoriteFolderUseCaseTest.kt index ca6fc8e156f..23064583cf3 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/folder/GetFavoriteFolderUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/folder/GetFavoriteFolderUseCaseTest.kt @@ -18,6 +18,7 @@ package com.wire.kalium.logic.feature.conversation.folder import com.wire.kalium.logic.CoreFailure +import com.wire.kalium.logic.StorageFailure import com.wire.kalium.logic.data.conversation.ConversationFolder import com.wire.kalium.logic.data.conversation.folders.ConversationFolderRepository import com.wire.kalium.logic.feature.conversation.folder.GetFavoriteFolderUseCase.Result @@ -28,6 +29,7 @@ import io.mockative.coEvery import io.mockative.coVerify import io.mockative.mock import io.mockative.once +import io.mockative.twice import kotlinx.coroutines.test.runTest import kotlin.test.Test import kotlin.test.assertEquals @@ -53,7 +55,7 @@ class GetFavoriteFolderUseCaseTest { } @Test - fun givenFavoriteFolderDoesNotExist_WhenInvoked_ThenReturnFailure() = runTest { + fun givenFavoriteFolderReturnsFailure_WhenInvoked_ThenReturnFailure() = runTest { val (arrangement, getFavoriteFolderUseCase) = Arrangement() .withFavoriteFolder(Either.Left(CoreFailure.Unknown(null))) .arrange() @@ -67,6 +69,25 @@ class GetFavoriteFolderUseCaseTest { }.wasInvoked(exactly = once) } + @Test + fun givenFavoriteFolderDoesNotExist_WhenInvoked_ThenFetchConversationFoldersIsTriggered() = runTest { + val (arrangement, getFavoriteFolderUseCase) = Arrangement() + .withFavoriteFolder(Either.Left(StorageFailure.DataNotFound)) + .withFetchConversationFolders(Either.Right(Unit)) + .arrange() + + val result = getFavoriteFolderUseCase() + + assertIs(result) + + coVerify { + arrangement.conversationFolderRepository.getFavoriteConversationFolder() + }.wasInvoked(exactly = twice) + coVerify { + arrangement.conversationFolderRepository.fetchConversationFolders() + }.wasInvoked(exactly = once) + } + private class Arrangement { @Mock val conversationFolderRepository = mock(ConversationFolderRepository::class) @@ -81,6 +102,12 @@ class GetFavoriteFolderUseCaseTest { }.returns(either) } + suspend fun withFetchConversationFolders(either: Either) = apply { + coEvery { + conversationFolderRepository.fetchConversationFolders() + }.returns(either) + } + fun arrange(block: Arrangement.() -> Unit = { }) = apply(block).let { this to getFavoriteFolderUseCase } } } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/slow/SlowSyncWorkerTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/slow/SlowSyncWorkerTest.kt index facf5ddb70b..6a89816ead8 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/slow/SlowSyncWorkerTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/slow/SlowSyncWorkerTest.kt @@ -24,7 +24,6 @@ import com.wire.kalium.logic.data.sync.SlowSyncStep import com.wire.kalium.logic.data.user.LegalHoldStatus import com.wire.kalium.logic.feature.connection.SyncConnectionsUseCase import com.wire.kalium.logic.feature.conversation.SyncConversationsUseCase -import com.wire.kalium.logic.feature.conversation.folder.SyncConversationFoldersUseCase import com.wire.kalium.logic.feature.conversation.mls.OneOnOneResolver import com.wire.kalium.logic.feature.featureConfig.SyncFeatureConfigsUseCase import com.wire.kalium.logic.feature.legalhold.FetchLegalHoldForSelfUserFromRemoteUseCase @@ -72,7 +71,6 @@ class SlowSyncWorkerTest { .withJoinMLSConversationsSuccess() .withResolveOneOnOneConversationsSuccess() .withFetchLegalHoldStatusSuccess() - .withSyncFoldersSuccess() .arrange() worker.slowSyncStepsFlow(successfullyMigration).collect() @@ -410,7 +408,6 @@ class SlowSyncWorkerTest { .withJoinMLSConversationsSuccess() .withResolveOneOnOneConversationsSuccess() .withFetchLegalHoldStatusSuccess() - .withSyncFoldersSuccess() .arrange() slowSyncWorker.slowSyncStepsFlow(successfullyMigration).collect() @@ -514,9 +511,6 @@ class SlowSyncWorkerTest { @Mock val fetchLegalHoldForSelfUserFromRemoteUseCase = mock(FetchLegalHoldForSelfUserFromRemoteUseCase::class) - @Mock - val syncConversationFoldersUseCase = mock(SyncConversationFoldersUseCase::class) - init { runBlocking { withLastProcessedEventIdReturning(Either.Right("lastProcessedEventId")) @@ -534,8 +528,7 @@ class SlowSyncWorkerTest { joinMLSConversations = joinMLSConversations, updateSupportedProtocols = updateSupportedProtocols, fetchLegalHoldForSelfUserFromRemoteUseCase = fetchLegalHoldForSelfUserFromRemoteUseCase, - oneOnOneResolver = oneOnOneResolver, - syncConversationFolders = syncConversationFoldersUseCase + oneOnOneResolver = oneOnOneResolver ) suspend fun withSyncSelfUserFailure() = apply { @@ -651,12 +644,6 @@ class SlowSyncWorkerTest { oneOnOneResolver.resolveAllOneOnOneConversations(any()) }.returns(success) } - - suspend fun withSyncFoldersSuccess() = apply { - coEvery { - syncConversationFoldersUseCase.invoke() - }.returns(success) - } } private companion object { diff --git a/persistence/src/commonMain/db_user/com/wire/kalium/persistence/ConversationFolders.sq b/persistence/src/commonMain/db_user/com/wire/kalium/persistence/ConversationFolders.sq index e1e5d8f14cb..db44a482e77 100644 --- a/persistence/src/commonMain/db_user/com/wire/kalium/persistence/ConversationFolders.sq +++ b/persistence/src/commonMain/db_user/com/wire/kalium/persistence/ConversationFolders.sq @@ -62,3 +62,6 @@ DELETE FROM LabeledConversation WHERE conversation_id = ? AND folder_id = ?; clearFolders: DELETE FROM ConversationFolder; + +clearLabeledConversations: +DELETE FROM LabeledConversation; diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/conversation/folder/ConversationFolderDAOImpl.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/conversation/folder/ConversationFolderDAOImpl.kt index 3c19bd871b3..3316f030bd9 100644 --- a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/conversation/folder/ConversationFolderDAOImpl.kt +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/conversation/folder/ConversationFolderDAOImpl.kt @@ -79,6 +79,7 @@ class ConversationFolderDAOImpl internal constructor( override suspend fun updateConversationFolders(folderWithConversationsList: List) = withContext(coroutineContext) { conversationFoldersQueries.transaction { + conversationFoldersQueries.clearLabeledConversations() conversationFoldersQueries.clearFolders() folderWithConversationsList.forEach { folderWithConversations -> conversationFoldersQueries.upsertFolder( From 645b7dbc7655f504fe77aa10c3a7c94e48bb4c92 Mon Sep 17 00:00:00 2001 From: boris Date: Fri, 6 Dec 2024 15:24:48 +0200 Subject: [PATCH 3/6] feat: API v7 changes (#3145) --- .../api/v0/authenticated/ConversationApiV0.kt | 2 +- .../api/v7/authenticated/ConversationApiV7.kt | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/network/src/commonMain/kotlin/com/wire/kalium/network/api/v0/authenticated/ConversationApiV0.kt b/network/src/commonMain/kotlin/com/wire/kalium/network/api/v0/authenticated/ConversationApiV0.kt index 145a833620f..600c6102788 100644 --- a/network/src/commonMain/kotlin/com/wire/kalium/network/api/v0/authenticated/ConversationApiV0.kt +++ b/network/src/commonMain/kotlin/com/wire/kalium/network/api/v0/authenticated/ConversationApiV0.kt @@ -306,7 +306,7 @@ internal open class ConversationApiV0 internal constructor( } } - private suspend fun handleServiceAddedResponse( + protected suspend fun handleServiceAddedResponse( httpResponse: HttpResponse ): NetworkResponse = when (httpResponse.status) { diff --git a/network/src/commonMain/kotlin/com/wire/kalium/network/api/v7/authenticated/ConversationApiV7.kt b/network/src/commonMain/kotlin/com/wire/kalium/network/api/v7/authenticated/ConversationApiV7.kt index cd10ebd3b2f..5e0d237b95a 100644 --- a/network/src/commonMain/kotlin/com/wire/kalium/network/api/v7/authenticated/ConversationApiV7.kt +++ b/network/src/commonMain/kotlin/com/wire/kalium/network/api/v7/authenticated/ConversationApiV7.kt @@ -19,16 +19,23 @@ package com.wire.kalium.network.api.v7.authenticated import com.wire.kalium.network.AuthenticatedNetworkClient +import com.wire.kalium.network.api.authenticated.conversation.AddServiceRequest import com.wire.kalium.network.api.authenticated.conversation.ConversationResponse import com.wire.kalium.network.api.authenticated.conversation.ConversationResponseV6 import com.wire.kalium.network.api.model.ApiModelMapper import com.wire.kalium.network.api.model.ApiModelMapperImpl +import com.wire.kalium.network.api.model.ConversationId +import com.wire.kalium.network.api.model.ServiceAddedResponse import com.wire.kalium.network.api.model.UserId import com.wire.kalium.network.api.v6.authenticated.ConversationApiV6 +import com.wire.kalium.network.exceptions.KaliumException import com.wire.kalium.network.utils.NetworkResponse import com.wire.kalium.network.utils.mapSuccess import com.wire.kalium.network.utils.wrapKaliumResponse import io.ktor.client.request.get +import io.ktor.client.request.post +import io.ktor.client.request.setBody +import okio.IOException internal open class ConversationApiV7 internal constructor( authenticatedNetworkClient: AuthenticatedNetworkClient, @@ -42,7 +49,21 @@ internal open class ConversationApiV7 internal constructor( apiModelMapper.fromApiV6(it) } + override suspend fun addService( + addServiceRequest: AddServiceRequest, + conversationId: ConversationId + ): NetworkResponse = try { + httpClient.post("$PATH_BOT/$PATH_CONVERSATIONS/${conversationId.value}") { + setBody(addServiceRequest) + }.let { response -> + handleServiceAddedResponse(response) + } + } catch (e: IOException) { + NetworkResponse.Error(KaliumException.GenericError(e)) + } + protected companion object { const val PATH_ONE_2_ONE_CONVERSATIONS = "one2one-conversations" + const val PATH_BOT = "bot" } } From 212ddce4c8974f358ea8537e83d78940dd026c4b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 6 Dec 2024 13:56:30 +0000 Subject: [PATCH 4/6] =?UTF-8?q?fix:=20update=20federation=20flag=20when=20?= =?UTF-8?q?fetching=20server=20config=20[WPB-14728]=20=F0=9F=8D=92=20(#314?= =?UTF-8?q?4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Commit with unresolved merge conflicts * Update ServerConfigRepository.kt * Update ServerConfigurationDAO.kt --------- Co-authored-by: Mohamad Jaara --- .../server/CustomServerConfigRepository.kt | 6 ++- .../server/ServerConfigRepository.kt | 22 +++++++--- .../server/UpdateApiVersionsUseCase.kt | 2 +- .../CustomServerConfigRepositoryTest.kt | 6 +-- .../ServerConfigRepositoryTest.kt | 4 +- .../server/UpdateApiVersionUseCaseTest.kt | 26 ++++++------ .../kalium/persistence/GlobalDBBaseTest.kt | 1 + .../kalium/persistence/ServerConfiguration.sq | 4 +- .../daokaliumdb/ServerConfigurationDAO.kt | 8 ++-- .../daokaliumdb/ServerConfigurationDAOTest.kt | 41 +++++++++++++++---- .../persistence/globalDB/AccountsDAOTest.kt | 7 ++++ 11 files changed, 90 insertions(+), 37 deletions(-) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/server/CustomServerConfigRepository.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/server/CustomServerConfigRepository.kt index 519f7943258..8025edc4393 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/server/CustomServerConfigRepository.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/server/CustomServerConfigRepository.kt @@ -94,7 +94,11 @@ internal class CustomServerConfigDataSource internal constructor( val storedConfigId = serverConfigurationDAO.configByLinks(serverConfigMapper.toEntity(links))?.id if (storedConfigId != null) { // if already exists then just update it - serverConfigurationDAO.updateApiVersion(storedConfigId, metadata.commonApiVersion.version) + serverConfigurationDAO.updateServerMetaData( + id = storedConfigId, + federation = metadata.federation, + commonApiVersion = metadata.commonApiVersion.version + ) if (metadata.federation) serverConfigurationDAO.setFederationToTrue(storedConfigId) storedConfigId } else { diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/server/ServerConfigRepository.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/server/ServerConfigRepository.kt index faef6688735..4fd77d402b4 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/server/ServerConfigRepository.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/server/ServerConfigRepository.kt @@ -57,9 +57,9 @@ interface ServerConfigRepository { suspend fun fetchApiVersionAndStore(links: ServerConfig.Links): Either /** - * update the api version of a locally stored config + * update the api version and federation status of a locally stored config */ - suspend fun updateConfigApiVersion(serverConfig: ServerConfig): Either + suspend fun updateConfigMetaData(serverConfig: ServerConfig): Either /** * Return the server links and metadata for the given userId @@ -92,7 +92,11 @@ internal class ServerConfigDataSource( val storedConfigId = dao.configByLinks(serverConfigMapper.toEntity(links))?.id if (storedConfigId != null) { // if already exists then just update it - dao.updateApiVersion(storedConfigId, metadata.commonApiVersion.version) + dao.updateServerMetaData( + id = storedConfigId, + federation = metadata.federation, + commonApiVersion = metadata.commonApiVersion.version + ) if (metadata.federation) dao.setFederationToTrue(storedConfigId) storedConfigId } else { @@ -132,9 +136,17 @@ internal class ServerConfigDataSource( storeConfig(links, metaData) } - override suspend fun updateConfigApiVersion(serverConfig: ServerConfig): Either = + override suspend fun updateConfigMetaData(serverConfig: ServerConfig): Either = fetchMetadata(serverConfig.links) - .flatMap { wrapStorageRequest { dao.updateApiVersion(serverConfig.id, it.commonApiVersion.version) } } + .flatMap { newMetaData -> + wrapStorageRequest { + dao.updateServerMetaData( + id = serverConfig.id, + federation = newMetaData.federation, + commonApiVersion = newMetaData.commonApiVersion.version + ) + } + } override suspend fun configForUser(userId: UserId): Either = wrapStorageRequest { dao.configForUser(userId.toDao()) } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/server/UpdateApiVersionsUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/server/UpdateApiVersionsUseCase.kt index 0d6eb9dea57..db4d2746aa0 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/server/UpdateApiVersionsUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/server/UpdateApiVersionsUseCase.kt @@ -80,6 +80,6 @@ class UpdateApiVersionsUseCaseImpl internal constructor( } else { null } - serverConfigRepoProvider(serverConfig, proxyCredentials).updateConfigApiVersion(serverConfig) + serverConfigRepoProvider(serverConfig, proxyCredentials).updateConfigMetaData(serverConfig) } } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/configuration/CustomServerConfigRepositoryTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/configuration/CustomServerConfigRepositoryTest.kt index 401b0fbc908..3737f9b8900 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/configuration/CustomServerConfigRepositoryTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/configuration/CustomServerConfigRepositoryTest.kt @@ -78,7 +78,7 @@ class CustomServerConfigRepositoryTest { arrangement.serverConfigurationDAO.insert(any()) }.wasNotInvoked() coVerify { - arrangement.serverConfigurationDAO.updateApiVersion(any(), any()) + arrangement.serverConfigurationDAO.updateServerMetaData(any(), any(), any()) }.wasInvoked(exactly = once) coVerify { arrangement.serverConfigurationDAO.setFederationToTrue(any()) @@ -106,7 +106,7 @@ class CustomServerConfigRepositoryTest { arrangement.serverConfigurationDAO.insert(any()) }.wasInvoked(exactly = once) coVerify { - arrangement.serverConfigurationDAO.updateApiVersion(any(), any()) + arrangement.serverConfigurationDAO.updateServerMetaData(any(), any(), any()) }.wasNotInvoked() coVerify { arrangement.serverConfigurationDAO.setFederationToTrue(any()) @@ -145,7 +145,7 @@ class CustomServerConfigRepositoryTest { arrangement.serverConfigurationDAO.insert(any()) }.wasInvoked(exactly = once) coVerify { - arrangement.serverConfigurationDAO.updateApiVersion(any(), any()) + arrangement.serverConfigurationDAO.updateServerMetaData(any(), any(), any()) }.wasNotInvoked() coVerify { arrangement.serverConfigurationDAO.setFederationToTrue(any()) diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/configuration/ServerConfigRepositoryTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/configuration/ServerConfigRepositoryTest.kt index 79c65a3dd2a..8f2e1416856 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/configuration/ServerConfigRepositoryTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/configuration/ServerConfigRepositoryTest.kt @@ -131,7 +131,7 @@ class ServerConfigRepositoryTest { arrangement.serverConfigDAO.insert(any()) }.wasNotInvoked() coVerify { - arrangement.serverConfigDAO.updateApiVersion(any(), any()) + arrangement.serverConfigDAO.updateServerMetaData(any(), any(), any()) }.wasInvoked(exactly = once) coVerify { arrangement.serverConfigDAO.setFederationToTrue(any()) @@ -159,7 +159,7 @@ class ServerConfigRepositoryTest { arrangement.serverConfigDAO.insert(any()) }.wasInvoked(exactly = once) coVerify { - arrangement.serverConfigDAO.updateApiVersion(any(), any()) + arrangement.serverConfigDAO.updateServerMetaData(any(), any(), any()) }.wasNotInvoked() coVerify { arrangement.serverConfigDAO.setFederationToTrue(any()) diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/server/UpdateApiVersionUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/server/UpdateApiVersionUseCaseTest.kt index d883b34e4fe..3401f58963a 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/server/UpdateApiVersionUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/server/UpdateApiVersionUseCaseTest.kt @@ -77,7 +77,7 @@ class UpdateApiVersionUseCaseTest { ) ) ) - withUpdateConfigApiVersion(serverConfig1, Either.Right(Unit)) + withUpdateConfigMetaData(serverConfig1, Either.Right(Unit)) } updateApiVersionsUseCase() @@ -88,7 +88,7 @@ class UpdateApiVersionUseCaseTest { }.wasNotInvoked() coVerify { - arrangement.serverConfigRepository1.updateConfigApiVersion(eq(serverConfig1)) + arrangement.serverConfigRepository1.updateConfigMetaData(eq(serverConfig1)) }.wasInvoked(exactly = once) } @@ -111,7 +111,7 @@ class UpdateApiVersionUseCaseTest { ) ) ) - withUpdateConfigApiVersion(serverConfig1, Either.Right(Unit)) + withUpdateConfigMetaData(serverConfig1, Either.Right(Unit)) } updateApiVersionsUseCase() @@ -122,7 +122,7 @@ class UpdateApiVersionUseCaseTest { }.wasNotInvoked() coVerify { - arrangement.serverConfigRepository1.updateConfigApiVersion(any()) + arrangement.serverConfigRepository1.updateConfigMetaData(any()) }.wasInvoked(exactly = once) } @@ -145,7 +145,7 @@ class UpdateApiVersionUseCaseTest { ) ) ) - withUpdateConfigApiVersion(serverConfig1, Either.Right(Unit)) + withUpdateConfigMetaData(serverConfig1, Either.Right(Unit)) withProxyCredForUser(userId1.toDao(), ProxyCredentialsEntity("user", "pass")) } @@ -158,7 +158,7 @@ class UpdateApiVersionUseCaseTest { }.wasInvoked(exactly = once) coVerify { - arrangement.serverConfigRepository1.updateConfigApiVersion(any()) + arrangement.serverConfigRepository1.updateConfigMetaData(any()) }.wasInvoked(exactly = once) } @@ -190,8 +190,8 @@ class UpdateApiVersionUseCaseTest { ) ) ) - withUpdateConfigApiVersion(serverConfig1, Either.Right(Unit)) - withUpdateConfigApiVersion(serverConfig2, Either.Right(Unit)) + withUpdateConfigMetaData(serverConfig1, Either.Right(Unit)) + withUpdateConfigMetaData(serverConfig2, Either.Right(Unit)) withProxyCredForUser(userId2.toDao(), ProxyCredentialsEntity("user", "pass")) } @@ -208,11 +208,11 @@ class UpdateApiVersionUseCaseTest { }.wasNotInvoked() coVerify { - arrangement.serverConfigRepository1.updateConfigApiVersion(any()) + arrangement.serverConfigRepository1.updateConfigMetaData(any()) }.wasInvoked(exactly = once) coVerify { - arrangement.serverConfigRepository2.updateConfigApiVersion(any()) + arrangement.serverConfigRepository2.updateConfigMetaData(any()) }.wasInvoked(exactly = once) } @@ -249,16 +249,16 @@ class UpdateApiVersionUseCaseTest { }.returns(result) } - suspend fun withUpdateConfigApiVersion( + suspend fun withUpdateConfigMetaData( serverConfig: ServerConfig, result: Either ) { when (serverConfig.id) { serverConfig1.id -> - coEvery { serverConfigRepository1.updateConfigApiVersion(any()) } + coEvery { serverConfigRepository1.updateConfigMetaData(any()) } .returns(result) - serverConfig2.id -> coEvery { serverConfigRepository2.updateConfigApiVersion(any()) } + serverConfig2.id -> coEvery { serverConfigRepository2.updateConfigMetaData(any()) } .returns(result) else -> throw IllegalArgumentException("Unexpected server config: $serverConfig") diff --git a/persistence/src/androidUnitTest/kotlin/com/wire/kalium/persistence/GlobalDBBaseTest.kt b/persistence/src/androidUnitTest/kotlin/com/wire/kalium/persistence/GlobalDBBaseTest.kt index edb29062eb1..df3c50b7c8d 100644 --- a/persistence/src/androidUnitTest/kotlin/com/wire/kalium/persistence/GlobalDBBaseTest.kt +++ b/persistence/src/androidUnitTest/kotlin/com/wire/kalium/persistence/GlobalDBBaseTest.kt @@ -19,6 +19,7 @@ package com.wire.kalium.persistence import com.wire.kalium.persistence.db.GlobalDatabaseBuilder +import kotlinx.coroutines.test.TestDispatcher actual abstract class GlobalDBBaseTest { actual fun deleteDatabase() { diff --git a/persistence/src/commonMain/db_global/com/wire/kalium/persistence/ServerConfiguration.sq b/persistence/src/commonMain/db_global/com/wire/kalium/persistence/ServerConfiguration.sq index 48a8d2fe6fe..4fa81bcab28 100644 --- a/persistence/src/commonMain/db_global/com/wire/kalium/persistence/ServerConfiguration.sq +++ b/persistence/src/commonMain/db_global/com/wire/kalium/persistence/ServerConfiguration.sq @@ -28,8 +28,8 @@ insert: INSERT OR FAIL INTO ServerConfiguration(id, apiBaseUrl, accountBaseUrl, webSocketBaseUrl, blackListUrl, teamsUrl, websiteUrl, title, isOnPremises, federation, domain, commonApiVersion, apiProxyHost, apiProxyNeedsAuthentication, apiProxyPort) VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?,?,?); -updateApiVersion: -UPDATE ServerConfiguration SET commonApiVersion = ? WHERE id = ?; +updateServerMetaData: +UPDATE ServerConfiguration SET federation = ?, commonApiVersion = ? WHERE id = ?; /** this function will be used when a config get updated from v0 where domain can be null */ updateApiVersionAndDomain: diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/daokaliumdb/ServerConfigurationDAO.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/daokaliumdb/ServerConfigurationDAO.kt index 7774eae162a..04c83e96f77 100644 --- a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/daokaliumdb/ServerConfigurationDAO.kt +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/daokaliumdb/ServerConfigurationDAO.kt @@ -125,8 +125,8 @@ interface ServerConfigurationDAO { suspend fun allConfig(): List fun configById(id: String): ServerConfigEntity? suspend fun configByLinks(links: ServerConfigEntity.Links): ServerConfigEntity? - suspend fun updateApiVersion(id: String, commonApiVersion: Int) suspend fun getCommonApiVersion(domain: String): Int + suspend fun updateServerMetaData(id: String, federation: Boolean, commonApiVersion: Int) suspend fun updateApiVersionAndDomain(id: String, domain: String, commonApiVersion: Int) suspend fun configForUser(userId: UserIDEntity): ServerConfigEntity? suspend fun setFederationToTrue(id: String) @@ -210,8 +210,10 @@ internal class ServerConfigurationDAOImpl internal constructor( }.executeAsOneOrNull() } - override suspend fun updateApiVersion(id: String, commonApiVersion: Int) = withContext(queriesContext) { - queries.updateApiVersion(commonApiVersion, id) + override suspend fun updateServerMetaData(id: String, federation: Boolean, commonApiVersion: Int) { + withContext(queriesContext) { + queries.updateServerMetaData(federation, commonApiVersion, id) + } } override suspend fun getCommonApiVersion(domain: String): Int = withContext(queriesContext) { diff --git a/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/daokaliumdb/ServerConfigurationDAOTest.kt b/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/daokaliumdb/ServerConfigurationDAOTest.kt index 5ab0fe61e87..befaae85ff9 100644 --- a/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/daokaliumdb/ServerConfigurationDAOTest.kt +++ b/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/daokaliumdb/ServerConfigurationDAOTest.kt @@ -24,17 +24,26 @@ import com.wire.kalium.persistence.GlobalDBBaseTest import com.wire.kalium.persistence.db.GlobalDatabaseBuilder import com.wire.kalium.persistence.model.ServerConfigEntity import com.wire.kalium.persistence.utils.stubs.newServerConfig +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.first +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestDispatcher +import kotlinx.coroutines.test.advanceUntilIdle +import kotlinx.coroutines.test.resetMain import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.test.setMain +import kotlinx.coroutines.withContext import kotlin.test.AfterTest import kotlin.test.BeforeTest +import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFails import kotlin.test.assertNotEquals +import kotlin.test.assertNotNull -@OptIn(ExperimentalCoroutinesApi::class) class ServerConfigurationDAOTest : GlobalDBBaseTest() { private val config1 = newServerConfig(id = 1) @@ -142,13 +151,31 @@ class ServerConfigurationDAOTest : GlobalDBBaseTest() { @Test fun givenNewApiVersion_thenItCanBeUpdated() = runTest { - insertConfig(config1) - val newVersion = config1.metaData.copy(apiVersion = 2) - val expected = config1.copy(metaData = newVersion) + val oldConfig = config1.copy( + metaData = config1.metaData.copy( + apiVersion = 1, + federation = false + ), + ) - globalDatabaseBuilder.serverConfigurationDAO.updateApiVersion(config1.id, newVersion.apiVersion) - val actual = globalDatabaseBuilder.serverConfigurationDAO.configById(config1.id) - assertEquals(expected, actual) + val newVersion = config1.metaData.copy( + apiVersion = 2, + federation = true + ) + + val expected = oldConfig.copy(metaData = newVersion) + + insertConfig(oldConfig) + globalDatabaseBuilder.serverConfigurationDAO.updateServerMetaData( + id = oldConfig.id, + federation = true, + commonApiVersion = 2 + ) + globalDatabaseBuilder.serverConfigurationDAO.configById(oldConfig.id) + .also { actual -> + assertEquals(expected.metaData.federation, actual!!.metaData.federation) + assertEquals(expected.metaData.apiVersion, actual!!.metaData.apiVersion) + } } @Test diff --git a/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/globalDB/AccountsDAOTest.kt b/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/globalDB/AccountsDAOTest.kt index 31ba21d5bb5..d5d55507e5e 100644 --- a/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/globalDB/AccountsDAOTest.kt +++ b/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/globalDB/AccountsDAOTest.kt @@ -29,8 +29,15 @@ import com.wire.kalium.persistence.db.GlobalDatabaseBuilder import com.wire.kalium.persistence.model.LogoutReason import com.wire.kalium.persistence.model.ServerConfigEntity import com.wire.kalium.persistence.model.SsoIdEntity +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestCoroutineScheduler +import kotlinx.coroutines.test.TestDispatcher +import kotlinx.coroutines.test.resetMain import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.test.setMain +import kotlin.test.AfterTest import kotlin.test.BeforeTest import kotlin.test.Test import kotlin.test.assertEquals From d8b69f1202e0ea88889c98bf1e2f9cd5016d197c Mon Sep 17 00:00:00 2001 From: Yamil Medina Date: Fri, 6 Dec 2024 13:44:11 -0300 Subject: [PATCH 5/6] revert: conference simulcast support (WPB-11480) (#3107) (#3149) * Revert "feat: conference simulcast support (WPB-11480) (#3107)" This reverts commit 9273703fe301924bf7ae8c17723c57bb443df41f. * chore: empty commit bump --- .../wire/kalium/logic/data/call/CallClient.kt | 42 ++----------------- gradle/libs.versions.toml | 18 ++++---- .../logic/feature/call/CallManagerImpl.kt | 11 ++--- .../serialization/LenientJsonSerializer.kt | 32 -------------- 4 files changed, 16 insertions(+), 87 deletions(-) delete mode 100644 util/src/commonMain/kotlin/com.wire.kalium.util/serialization/LenientJsonSerializer.kt diff --git a/data/src/commonMain/kotlin/com/wire/kalium/logic/data/call/CallClient.kt b/data/src/commonMain/kotlin/com/wire/kalium/logic/data/call/CallClient.kt index 0c2f3bb9b79..7545545157e 100644 --- a/data/src/commonMain/kotlin/com/wire/kalium/logic/data/call/CallClient.kt +++ b/data/src/commonMain/kotlin/com/wire/kalium/logic/data/call/CallClient.kt @@ -18,55 +18,21 @@ package com.wire.kalium.logic.data.call -import com.wire.kalium.util.serialization.LenientJsonSerializer -import kotlinx.serialization.ExperimentalSerializationApi -import kotlinx.serialization.KSerializer import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlinx.serialization.descriptors.PrimitiveKind -import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.descriptors.nullable -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder +import kotlinx.serialization.json.Json @Serializable data class CallClient( @SerialName("userid") val userId: String, @SerialName("clientid") val clientId: String, - @SerialName("in_subconv") val isMemberOfSubconversation: Boolean = false, - @SerialName("quality") - @Serializable(with = CallQuality.CallQualityAsIntSerializer::class) - val quality: CallQuality = CallQuality.LOW + @SerialName("in_subconv") val isMemberOfSubconversation: Boolean = false ) @Serializable data class CallClientList( @SerialName("clients") val clients: List ) { - fun toJsonString(): String = LenientJsonSerializer.json.encodeToString(serializer(), this) -} - -enum class CallQuality { - ANY, - LOW, - HIGH; - - data object CallQualityAsIntSerializer : KSerializer { - override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("quality", PrimitiveKind.INT).nullable - - override fun serialize(encoder: Encoder, value: CallQuality) { - encoder.encodeInt(value.ordinal) - } - - @OptIn(ExperimentalSerializationApi::class) - override fun deserialize(decoder: Decoder): CallQuality { - val value = if (decoder.decodeNotNullMark()) decoder.decodeInt() else 0 - return when (value) { - 1 -> LOW - 2 -> HIGH - else -> ANY - } - } - } + // TODO(optimization): Use a shared Json instance instead of creating one every time. + fun toJsonString(): String = Json { isLenient = true }.encodeToString(serializer(), this) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6c3b94a0f59..9060b93e117 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ activity-compose = "1.9.0" app-compat = "1.6.1" android-paging3 = "3.2.1" cli-kt = "3.5.0" -coroutines = "1.8.1" +coroutines = "1.8.0" compose-compiler = "1.5.13" compose-ui = "1.6.6" compose-material = "1.6.6" @@ -17,12 +17,12 @@ okio = "3.9.0" ok-http = "4.12.0" mockative = "2.2.0" android-work = "2.9.0" -android-test-runner = "1.6.2" -android-test-core-ktx = "1.6.1" -android-test-rules = "1.6.1" -android-test-core = "1.6.1" +android-test-runner = "1.5.2" +android-test-core-ktx = "1.5.0" +android-test-rules = "1.5.0" +android-test-core = "1.5.0" androidx-arch = "2.2.0" -androidx-test-orchestrator = "1.5.1" +androidx-test-orchestrator = "1.4.2" androidx-sqlite = "2.4.0" benasher-uuid = "0.8.0" ktx-datetime = { strictly = "0.5.0" } @@ -37,12 +37,12 @@ sqldelight = "2.0.1" sqlcipher-android = "4.5.6" pbandk = "0.14.2" turbine = "1.1.0" -avs = "10.0.1" +avs = "9.10.16" jna = "5.14.0" core-crypto = "2.0.0" core-crypto-multiplatform = "0.6.0-rc.3-multiplatform-pre1" completeKotlin = "1.1.0" -desugar-jdk = "2.1.3" +desugar-jdk = "2.0.4" kermit = "2.0.3" detekt = "1.23.6" agp = "8.5.2" @@ -50,7 +50,7 @@ dokka = "1.8.20" carthage = "0.0.1" libsodiumBindings = "0.8.7" protobufCodegen = "0.9.4" -annotation = "1.9.1" +annotation = "1.7.1" mordant = "2.0.0-beta13" apache-tika = "2.9.2" mockk = "1.13.10" diff --git a/logic/src/commonJvmAndroid/kotlin/com/wire/kalium/logic/feature/call/CallManagerImpl.kt b/logic/src/commonJvmAndroid/kotlin/com/wire/kalium/logic/feature/call/CallManagerImpl.kt index 90244f7eb76..693c76d98f9 100644 --- a/logic/src/commonJvmAndroid/kotlin/com/wire/kalium/logic/feature/call/CallManagerImpl.kt +++ b/logic/src/commonJvmAndroid/kotlin/com/wire/kalium/logic/feature/call/CallManagerImpl.kt @@ -463,19 +463,14 @@ class CallManagerImpl internal constructor( callClients: CallClientList ) { withCalling { - // Mapping Needed to support calls between federated and non federated environments (domain separation) + // Needed to support calls between federated and non federated environments val clients = callClients.clients.map { callClient -> CallClient( - userId = federatedIdMapper.parseToFederatedId(callClient.userId), - clientId = callClient.clientId, - isMemberOfSubconversation = callClient.isMemberOfSubconversation, - quality = callClient.quality + federatedIdMapper.parseToFederatedId(callClient.userId), + callClient.clientId ) } val clientsJson = CallClientList(clients).toJsonString() - callingLogger.d( - "$TAG - wcall_request_video_streams() called -> Requesting video streams for conversation = ${conversationId.toLogString()}" - ) val conversationIdString = federatedIdMapper.parseToFederatedId(conversationId) calling.wcall_request_video_streams( inst = it, diff --git a/util/src/commonMain/kotlin/com.wire.kalium.util/serialization/LenientJsonSerializer.kt b/util/src/commonMain/kotlin/com.wire.kalium.util/serialization/LenientJsonSerializer.kt deleted file mode 100644 index 3d6507cf8ff..00000000000 --- a/util/src/commonMain/kotlin/com.wire.kalium.util/serialization/LenientJsonSerializer.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Wire - * Copyright (C) 2024 Wire Swiss GmbH - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ -package com.wire.kalium.util.serialization - -import kotlinx.serialization.json.Json - -/** - * The json serializer for shared usage. - */ -object LenientJsonSerializer { - - val json = Json { - isLenient = true - encodeDefaults = true - ignoreUnknownKeys = true - } -} From 46ab0bc9d2bbb0a2190f93eef72c6e6749943502 Mon Sep 17 00:00:00 2001 From: Mohamad Jaara Date: Fri, 6 Dec 2024 23:48:15 +0100 Subject: [PATCH 6/6] feat: set api v7 as supported (#3152) Co-authored-by: Vitor Hugo Schwaab --- .../kotlin/com/wire/kalium/network/BackendMetaDataUtil.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/network/src/commonMain/kotlin/com/wire/kalium/network/BackendMetaDataUtil.kt b/network/src/commonMain/kotlin/com/wire/kalium/network/BackendMetaDataUtil.kt index be435578cf3..179e1b936fa 100644 --- a/network/src/commonMain/kotlin/com/wire/kalium/network/BackendMetaDataUtil.kt +++ b/network/src/commonMain/kotlin/com/wire/kalium/network/BackendMetaDataUtil.kt @@ -23,11 +23,11 @@ import com.wire.kalium.network.api.unbound.versioning.VersionInfoDTO // They are not truly constants as set is not a primitive type, yet are treated as one in this context @Suppress("MagicNumber") -val SupportedApiVersions = setOf(0, 1, 2, 4, 5, 6) +val SupportedApiVersions: Set = setOf(0, 1, 2, 4, 5, 6, 7) // They are not truly constants as set is not a primitive type, yet are treated as one in this context @Suppress("MagicNumber") -val DevelopmentApiVersions = setOf(7) +val DevelopmentApiVersions: Set = emptySet() // You can use scripts/generate_new_api_version.sh or gradle task network:generateNewApiVersion to // bump API version and generate all needed classes