From 09b2e476f8bc498f276e57daa6e82c4829972cb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Zag=C3=B3rski?= Date: Mon, 28 Oct 2024 07:58:17 +0100 Subject: [PATCH 1/4] feat: Consider team settings when registering mls device #WPB-10119 --- .../com/wire/kalium/logic/feature/UserSessionScope.kt | 6 +++++- .../client/IsAllowedToRegisterMLSClientUseCase.kt | 11 +++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) 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 6d693de786a..13fb6d5e374 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 @@ -1979,7 +1979,11 @@ class UserSessionScope internal constructor( @OptIn(DelicateKaliumApi::class) private val isAllowedToRegisterMLSClient: IsAllowedToRegisterMLSClientUseCase - get() = IsAllowedToRegisterMLSClientUseCaseImpl(featureSupport, mlsPublicKeysRepository) + get() = IsAllowedToRegisterMLSClientUseCaseImpl( + featureSupport, + mlsPublicKeysRepository, + userConfigRepository + ) private val syncFeatureConfigsUseCase: SyncFeatureConfigsUseCase get() = SyncFeatureConfigsUseCaseImpl( diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/client/IsAllowedToRegisterMLSClientUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/client/IsAllowedToRegisterMLSClientUseCase.kt index 838619af9cb..ab77db9c23d 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/client/IsAllowedToRegisterMLSClientUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/client/IsAllowedToRegisterMLSClientUseCase.kt @@ -18,9 +18,12 @@ package com.wire.kalium.logic.feature.client +import com.wire.kalium.logic.configuration.UserConfigRepository import com.wire.kalium.logic.data.mlspublickeys.MLSPublicKeysRepository import com.wire.kalium.logic.featureFlags.FeatureSupport +import com.wire.kalium.logic.functional.fold import com.wire.kalium.logic.functional.isRight +import com.wire.kalium.logic.functional.right import com.wire.kalium.util.DelicateKaliumApi /** @@ -39,8 +42,12 @@ interface IsAllowedToRegisterMLSClientUseCase { internal class IsAllowedToRegisterMLSClientUseCaseImpl( private val featureSupport: FeatureSupport, private val mlsPublicKeysRepository: MLSPublicKeysRepository, + private val userConfigRepository: UserConfigRepository ) : IsAllowedToRegisterMLSClientUseCase { - override suspend operator fun invoke(): Boolean = - featureSupport.isMLSSupported && mlsPublicKeysRepository.getKeys().isRight() + override suspend operator fun invoke(): Boolean { + return featureSupport.isMLSSupported && + mlsPublicKeysRepository.getKeys().isRight() && + userConfigRepository.isMLSEnabled().fold({ false }, { isEnabled -> isEnabled }) + } } From 596f09b0a3551c974de99379c26c6dff5b3915e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Zag=C3=B3rski?= Date: Mon, 28 Oct 2024 15:18:16 +0100 Subject: [PATCH 2/4] Add unit tests --- .../IsAllowedToRegisterMLSClientUseCase.kt | 1 - ...IsAllowedToRegisterMLSClientUseCaseTest.kt | 172 ++++++++++++++++++ 2 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/client/IsAllowedToRegisterMLSClientUseCaseTest.kt diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/client/IsAllowedToRegisterMLSClientUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/client/IsAllowedToRegisterMLSClientUseCase.kt index ab77db9c23d..3feb0cd3b8e 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/client/IsAllowedToRegisterMLSClientUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/client/IsAllowedToRegisterMLSClientUseCase.kt @@ -23,7 +23,6 @@ import com.wire.kalium.logic.data.mlspublickeys.MLSPublicKeysRepository import com.wire.kalium.logic.featureFlags.FeatureSupport import com.wire.kalium.logic.functional.fold import com.wire.kalium.logic.functional.isRight -import com.wire.kalium.logic.functional.right import com.wire.kalium.util.DelicateKaliumApi /** diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/client/IsAllowedToRegisterMLSClientUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/client/IsAllowedToRegisterMLSClientUseCaseTest.kt new file mode 100644 index 00000000000..dfa49376049 --- /dev/null +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/client/IsAllowedToRegisterMLSClientUseCaseTest.kt @@ -0,0 +1,172 @@ +/* + * 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.client + +import com.wire.kalium.logic.CoreFailure +import com.wire.kalium.logic.StorageFailure +import com.wire.kalium.logic.configuration.UserConfigRepository +import com.wire.kalium.logic.data.mls.MLSPublicKeys +import com.wire.kalium.logic.data.mlspublickeys.MLSPublicKeysRepository +import com.wire.kalium.logic.featureFlags.FeatureSupport +import com.wire.kalium.logic.functional.Either +import io.mockative.Mock +import io.mockative.coEvery +import io.mockative.every +import io.mockative.mock +import kotlinx.coroutines.test.runTest +import kotlin.test.Test +import kotlin.test.assertEquals + +class IsAllowedToRegisterMLSClientUseCaseTest { + + @Test + fun givenAllMlsConditionsAreMet_whenUseCaseInvoked_returnsTrue() = runTest { + // given + val (_, isAllowedToRegisterMLSClientUseCase) = Arrangement() + .withMlsFeatureFlag(true) + .withUserConfigMlsEnabled(true) + .withGetPublicKeysSuccessful() + .arrange() + + // when + val result = isAllowedToRegisterMLSClientUseCase() + + // then + assertEquals(true, result) + } + + @Test + fun givenMlsFeatureFlagDisabled_whenUseCaseInvoked_returnsFalse() = runTest { + // given + val (_, isAllowedToRegisterMLSClientUseCase) = Arrangement() + .withMlsFeatureFlag(false) + .withUserConfigMlsEnabled(true) + .withGetPublicKeysSuccessful() + .arrange() + + // when + val result = isAllowedToRegisterMLSClientUseCase() + + // then + assertEquals(false, result) + } + + @Test + fun givenUserConfigMlsDisabled_whenUseCaseInvoked_returnsFalse() = runTest { + // given + val (_, isAllowedToRegisterMLSClientUseCase) = Arrangement() + .withMlsFeatureFlag(true) + .withUserConfigMlsEnabled(false) + .withGetPublicKeysSuccessful() + .arrange() + + // when + val result = isAllowedToRegisterMLSClientUseCase() + + // then + assertEquals(false, result) + } + + @Test + fun givenPublicKeysFailure_whenUseCaseInvoked_returnsFalse() = runTest { + // given + val (_, isAllowedToRegisterMLSClientUseCase) = Arrangement() + .withMlsFeatureFlag(true) + .withUserConfigMlsEnabled(true) + .withGetPublicKeysFailed() + .arrange() + + // when + val result = isAllowedToRegisterMLSClientUseCase() + + // then + assertEquals(false, result) + } + + @Test + fun givenUserConfigDataNotFound_whenUseCaseInvoked_returnsFalse() = runTest { + // given + val (_, isAllowedToRegisterMLSClientUseCase) = Arrangement() + .withMlsFeatureFlag(true) + .withUserConfigDataNotFound() + .withGetPublicKeysFailed() + .arrange() + + // when + val result = isAllowedToRegisterMLSClientUseCase() + + // then + assertEquals(false, result) + } + + + private class Arrangement { + @Mock + val featureSupport = mock(FeatureSupport::class) + + @Mock + val mlsPublicKeysRepository = mock(MLSPublicKeysRepository::class) + + @Mock + val userConfigRepository = mock(UserConfigRepository::class) + + fun withMlsFeatureFlag(enabled: Boolean) = apply { + every { + featureSupport.isMLSSupported + }.returns(enabled) + } + + fun withUserConfigMlsEnabled(enabled: Boolean) = apply { + every { + userConfigRepository.isMLSEnabled() + }.returns(Either.Right(enabled)) + } + + fun withUserConfigDataNotFound() = apply { + every { + userConfigRepository.isMLSEnabled() + }.returns(Either.Left(StorageFailure.DataNotFound)) + } + + suspend fun withGetPublicKeysSuccessful() = apply { + coEvery { + mlsPublicKeysRepository.getKeys() + }.returns(Either.Right(MLS_PUBLIC_KEY)) + } + + suspend fun withGetPublicKeysFailed() = apply { + coEvery { + mlsPublicKeysRepository.getKeys() + }.returns(Either.Left(CoreFailure.Unknown(Throwable("an error")))) + } + + fun arrange() = this to IsAllowedToRegisterMLSClientUseCaseImpl( + featureSupport = featureSupport, + mlsPublicKeysRepository = mlsPublicKeysRepository, + userConfigRepository = userConfigRepository + ) + + companion object { + val MLS_PUBLIC_KEY = MLSPublicKeys( + removal = mapOf( + "ed25519" to "gRNvFYReriXbzsGu7zXiPtS8kaTvhU1gUJEV9rdFHVw=" + ) + ) + } + } +} From 7a2d14ce1c148a9e0859cdfd745d58a0d5359f93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Zag=C3=B3rski?= Date: Wed, 30 Oct 2024 10:46:56 +0100 Subject: [PATCH 3/4] Remove compile time flag isMLSSupportEnabled --- .../kalium/logic/feature/UserSessionScope.kt | 2 -- .../message/PendingProposalScheduler.kt | 3 +-- .../logic/featureFlags/FeatureSupportImpl.kt | 3 +-- .../logic/featureFlags/KaliumConfigs.kt | 1 - .../message/PendingProposalSchedulerTest.kt | 19 ------------------- .../com/wire/kalium/monkeys/homeDirectory.kt | 1 - .../kotlin/PocIntegrationTest.kt | 1 - 7 files changed, 2 insertions(+), 28 deletions(-) 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 13fb6d5e374..859269f102c 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 @@ -591,7 +591,6 @@ class UserSessionScope internal constructor( kaliumLogger = userScopedLogger ) private val featureSupport: FeatureSupport = FeatureSupportImpl( - kaliumConfigs, sessionManager.serverConfig().metaData.commonApiVersion.version ) @@ -1225,7 +1224,6 @@ class UserSessionScope internal constructor( private val pendingProposalScheduler: PendingProposalScheduler = PendingProposalSchedulerImpl( - kaliumConfigs, incrementalSyncRepository, lazy { mlsConversationRepository }, lazy { subconversationRepository } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/PendingProposalScheduler.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/PendingProposalScheduler.kt index e7e000e3bdf..a3647722949 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/PendingProposalScheduler.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/PendingProposalScheduler.kt @@ -63,7 +63,6 @@ interface PendingProposalScheduler { } internal class PendingProposalSchedulerImpl( - private val kaliumConfigs: KaliumConfigs, private val incrementalSyncRepository: IncrementalSyncRepository, private val mlsConversationRepository: Lazy, private val subconversationRepository: Lazy, @@ -82,7 +81,7 @@ internal class PendingProposalSchedulerImpl( commitPendingProposalsScope.launch() { incrementalSyncRepository.incrementalSyncState.collectLatest { syncState -> ensureActive() - if (syncState == IncrementalSyncStatus.Live && kaliumConfigs.isMLSSupportEnabled) { + if (syncState == IncrementalSyncStatus.Live) { startCommittingPendingProposals() } } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/featureFlags/FeatureSupportImpl.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/featureFlags/FeatureSupportImpl.kt index cb11a6b34e1..81d9cf080b3 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/featureFlags/FeatureSupportImpl.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/featureFlags/FeatureSupportImpl.kt @@ -24,9 +24,8 @@ interface FeatureSupport { @Suppress("MagicNumber") class FeatureSupportImpl( - kaliumConfigs: KaliumConfigs, apiVersion: Int ) : FeatureSupport { - override val isMLSSupported: Boolean = kaliumConfigs.isMLSSupportEnabled && apiVersion >= 5 + override val isMLSSupported: Boolean = apiVersion >= 5 } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/featureFlags/KaliumConfigs.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/featureFlags/KaliumConfigs.kt index dc90b3b111f..1ca24af381a 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/featureFlags/KaliumConfigs.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/featureFlags/KaliumConfigs.kt @@ -26,7 +26,6 @@ import kotlin.time.Duration.Companion.hours data class KaliumConfigs( val forceConstantBitrateCalls: Boolean = false, val fileRestrictionState: BuildFileRestrictionState = BuildFileRestrictionState.NoRestriction, - var isMLSSupportEnabled: Boolean = true, // Disabling db-encryption will crash on android-api level below 30 val shouldEncryptData: Boolean = true, val encryptProteusStorage: Boolean = false, diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/message/PendingProposalSchedulerTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/message/PendingProposalSchedulerTest.kt index b8607eaee40..05215c911db 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/message/PendingProposalSchedulerTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/message/PendingProposalSchedulerTest.kt @@ -95,22 +95,6 @@ class PendingProposalSchedulerTest { }.wasInvoked(once) } - @Test - fun givenMLSSupportIsDisabled_whenSyncIsLive_thenPendingProposalIsNotCommitted() = runTest(TestKaliumDispatcher.default) { - val (arrangement, _) = Arrangement() - .withScheduledProposalTimers(listOf(ProposalTimer(TestConversation.GROUP_ID, Arrangement.INSTANT_PAST))) - .withCommitPendingProposalsSuccessful() - .arrange() - - arrangement.kaliumConfigs.isMLSSupportEnabled = false - arrangement.incrementalSyncRepository.updateIncrementalSyncState(IncrementalSyncStatus.Live) - yield() - - coVerify { - arrangement.mlsConversationRepository.commitPendingProposals(eq(TestConversation.GROUP_ID)) - }.wasNotInvoked() - } - @Test fun givenNonExpiredProposalTimer_whenSyncFinishes_thenPendingProposalIsNotCommitted() = runTest(TestKaliumDispatcher.default) { val (arrangement, _) = Arrangement() @@ -182,8 +166,6 @@ class PendingProposalSchedulerTest { private class Arrangement { - val kaliumConfigs = KaliumConfigs() - val incrementalSyncRepository = InMemoryIncrementalSyncRepository() @Mock @@ -193,7 +175,6 @@ class PendingProposalSchedulerTest { val subconversationRepository = mock(SubconversationRepository::class) val pendingProposalScheduler = PendingProposalSchedulerImpl( - kaliumConfigs, incrementalSyncRepository, lazy { mlsConversationRepository }, lazy { subconversationRepository }, diff --git a/monkeys/src/main/kotlin/com/wire/kalium/monkeys/homeDirectory.kt b/monkeys/src/main/kotlin/com/wire/kalium/monkeys/homeDirectory.kt index 86b973a04c3..7f5133ee75c 100644 --- a/monkeys/src/main/kotlin/com/wire/kalium/monkeys/homeDirectory.kt +++ b/monkeys/src/main/kotlin/com/wire/kalium/monkeys/homeDirectory.kt @@ -32,7 +32,6 @@ fun coreLogic( rootPath, kaliumConfigs = KaliumConfigs( developmentApiEnabled = true, encryptProteusStorage = true, - isMLSSupportEnabled = true, wipeOnDeviceRemoval = true, ), userAgent = "Wire Infinite Monkeys", useInMemoryStorage = true ) diff --git a/tango-tests/src/integrationTest/kotlin/PocIntegrationTest.kt b/tango-tests/src/integrationTest/kotlin/PocIntegrationTest.kt index ffcc205ca7a..270ea80e43e 100644 --- a/tango-tests/src/integrationTest/kotlin/PocIntegrationTest.kt +++ b/tango-tests/src/integrationTest/kotlin/PocIntegrationTest.kt @@ -231,7 +231,6 @@ class PocIntegrationTest { kaliumConfigs = KaliumConfigs( developmentApiEnabled = true, encryptProteusStorage = true, - isMLSSupportEnabled = true, wipeOnDeviceRemoval = true, mockedRequests = mockedRequests, mockNetworkStateObserver = TestNetworkStateObserver.DEFAULT_TEST_NETWORK_STATE_OBSERVER, From e6ff059d6c3a92d88eb4443936cb52ed3b560e0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Zag=C3=B3rski?= Date: Wed, 30 Oct 2024 11:35:14 +0100 Subject: [PATCH 4/4] Change api to 6 --- .../logic/feature/message/PendingProposalScheduler.kt | 1 - .../wire/kalium/logic/featureFlags/FeatureSupportImpl.kt | 2 +- .../main/kotlin/com/wire/kalium/monkeys/homeDirectory.kt | 7 +++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/PendingProposalScheduler.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/PendingProposalScheduler.kt index a3647722949..4993b062031 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/PendingProposalScheduler.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/PendingProposalScheduler.kt @@ -24,7 +24,6 @@ import com.wire.kalium.logic.data.conversation.SubconversationRepository import com.wire.kalium.logic.data.id.GroupID import com.wire.kalium.logic.data.sync.IncrementalSyncRepository import com.wire.kalium.logic.data.sync.IncrementalSyncStatus -import com.wire.kalium.logic.featureFlags.KaliumConfigs import com.wire.kalium.logic.functional.distinct import com.wire.kalium.logic.functional.onFailure import com.wire.kalium.logic.kaliumLogger diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/featureFlags/FeatureSupportImpl.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/featureFlags/FeatureSupportImpl.kt index 81d9cf080b3..fd37ac693ae 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/featureFlags/FeatureSupportImpl.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/featureFlags/FeatureSupportImpl.kt @@ -27,5 +27,5 @@ class FeatureSupportImpl( apiVersion: Int ) : FeatureSupport { - override val isMLSSupported: Boolean = apiVersion >= 5 + override val isMLSSupported: Boolean = apiVersion >= 6 } diff --git a/monkeys/src/main/kotlin/com/wire/kalium/monkeys/homeDirectory.kt b/monkeys/src/main/kotlin/com/wire/kalium/monkeys/homeDirectory.kt index 7f5133ee75c..5ad0ef16e75 100644 --- a/monkeys/src/main/kotlin/com/wire/kalium/monkeys/homeDirectory.kt +++ b/monkeys/src/main/kotlin/com/wire/kalium/monkeys/homeDirectory.kt @@ -29,11 +29,14 @@ fun coreLogic( rootPath: String, ): CoreLogic { val coreLogic = CoreLogic( - rootPath, kaliumConfigs = KaliumConfigs( + rootPath = rootPath, + kaliumConfigs = KaliumConfigs( developmentApiEnabled = true, encryptProteusStorage = true, wipeOnDeviceRemoval = true, - ), userAgent = "Wire Infinite Monkeys", useInMemoryStorage = true + ), + userAgent = "Wire Infinite Monkeys", + useInMemoryStorage = true ) coreLogic.updateApiVersionsScheduler.scheduleImmediateApiVersionUpdate() return coreLogic