From 9332629149ca45e6036a0d9dd5918c56e61d6a08 Mon Sep 17 00:00:00 2001 From: MohamadJaara Date: Thu, 20 Jun 2024 23:43:34 +0200 Subject: [PATCH 1/6] fix: asset sending restriction --- .../kalium/logic/feature/UserSessionScope.kt | 1 + .../asset/ScheduleNewAssetMessageUseCase.kt | 23 +++++++++++++++---- .../logic/feature/message/MessageScope.kt | 6 +++++ 3 files changed, 26 insertions(+), 4 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 00e11e7fc5e..cdfe3d273f9 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 @@ -1383,6 +1383,7 @@ class UserSessionScope internal constructor( protoContentMapper, observeSelfDeletingMessages, messageMetadataRepository, + observeFileSharingStatus, this ) val users: UserScope diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/asset/ScheduleNewAssetMessageUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/asset/ScheduleNewAssetMessageUseCase.kt index e0598cbfb96..e0921966c88 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/asset/ScheduleNewAssetMessageUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/asset/ScheduleNewAssetMessageUseCase.kt @@ -23,6 +23,7 @@ import com.wire.kalium.cryptography.utils.AES256Key import com.wire.kalium.cryptography.utils.SHA256Key import com.wire.kalium.cryptography.utils.generateRandomAES256Key import com.wire.kalium.logic.CoreFailure +import com.wire.kalium.logic.configuration.FileSharingStatus import com.wire.kalium.logic.data.asset.AssetRepository import com.wire.kalium.logic.data.asset.UploadedAssetId import com.wire.kalium.logic.data.asset.isAudioMimeType @@ -42,6 +43,7 @@ import com.wire.kalium.logic.feature.CurrentClientIdProvider import com.wire.kalium.logic.feature.message.MessageSendFailureHandler import com.wire.kalium.logic.feature.message.MessageSender import com.wire.kalium.logic.feature.selfDeletingMessages.ObserveSelfDeletionTimerSettingsForConversationUseCase +import com.wire.kalium.logic.feature.user.ObserveFileSharingStatusUseCase import com.wire.kalium.logic.functional.Either import com.wire.kalium.logic.functional.flatMap import com.wire.kalium.logic.functional.fold @@ -106,6 +108,7 @@ internal class ScheduleNewAssetMessageUseCaseImpl( private val userPropertyRepository: UserPropertyRepository, private val selfDeleteTimer: ObserveSelfDeletionTimerSettingsForConversationUseCase, private val scope: CoroutineScope, + private val observeFileSharingStatus: ObserveFileSharingStatusUseCase, private val dispatcher: KaliumDispatcher, ) : ScheduleNewAssetMessageUseCase { @@ -122,6 +125,14 @@ internal class ScheduleNewAssetMessageUseCaseImpl( assetHeight: Int?, audioLengthInMs: Long ): ScheduleNewAssetMessageResult { + observeFileSharingStatus().first().also { + when(it.state) { + FileSharingStatus.Value.Disabled -> return ScheduleNewAssetMessageResult.Failure.DisabledByTeam + FileSharingStatus.Value.EnabledAll -> { /* no-op*/ } + is FileSharingStatus.Value.EnabledSome -> return ScheduleNewAssetMessageResult.Failure.RestrictedFileType + } + } + slowSyncRepository.slowSyncStatus.first { it is SlowSyncStatus.Complete } @@ -174,7 +185,7 @@ internal class ScheduleNewAssetMessageUseCaseImpl( } } }.fold({ - ScheduleNewAssetMessageResult.Failure(it) + ScheduleNewAssetMessageResult.Failure.Generic(it) }, { (_, message) -> ScheduleNewAssetMessageResult.Success(message.id) }) @@ -345,9 +356,13 @@ internal class ScheduleNewAssetMessageUseCaseImpl( } } -sealed class ScheduleNewAssetMessageResult { - class Success(val messageId: String) : ScheduleNewAssetMessageResult() - class Failure(val coreFailure: CoreFailure) : ScheduleNewAssetMessageResult() +sealed interface ScheduleNewAssetMessageResult { + data class Success(val messageId: String) : ScheduleNewAssetMessageResult + sealed interface Failure : ScheduleNewAssetMessageResult { + data class Generic(val coreFailure: CoreFailure) : Failure + data object DisabledByTeam: Failure + data object RestrictedFileType: Failure + } } private data class AssetMessageMetadata( diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MessageScope.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MessageScope.kt index 67d32fb1162..bf8ea243254 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MessageScope.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MessageScope.kt @@ -19,6 +19,8 @@ package com.wire.kalium.logic.feature.message import com.wire.kalium.logic.cache.SelfConversationIdProvider +import com.wire.kalium.logic.configuration.UserConfigDataSource +import com.wire.kalium.logic.configuration.UserConfigRepository import com.wire.kalium.logic.data.asset.AssetRepository import com.wire.kalium.logic.data.client.ClientRepository import com.wire.kalium.logic.data.client.MLSClientProvider @@ -58,6 +60,8 @@ import com.wire.kalium.logic.feature.message.ephemeral.EphemeralMessageDeletionH import com.wire.kalium.logic.feature.selfDeletingMessages.ObserveSelfDeletionTimerSettingsForConversationUseCase import com.wire.kalium.logic.feature.sessionreset.ResetSessionUseCase import com.wire.kalium.logic.feature.sessionreset.ResetSessionUseCaseImpl +import com.wire.kalium.logic.feature.user.ObserveFileSharingStatusUseCase +import com.wire.kalium.logic.feature.user.ObserveFileSharingStatusUseCaseImpl import com.wire.kalium.logic.sync.SyncManager import com.wire.kalium.logic.util.MessageContentEncoder import com.wire.kalium.util.KaliumDispatcher @@ -89,6 +93,7 @@ class MessageScope internal constructor( private val protoContentMapper: ProtoContentMapper, private val observeSelfDeletingMessages: ObserveSelfDeletionTimerSettingsForConversationUseCase, private val messageMetadataRepository: MessageMetadataRepository, + private val observeFileSharingStatusUseCase: ObserveFileSharingStatusUseCase, private val scope: CoroutineScope, internal val dispatcher: KaliumDispatcher = KaliumDispatcherImpl ) { @@ -204,6 +209,7 @@ class MessageScope internal constructor( userPropertyRepository, observeSelfDeletingMessages, scope, + observeFileSharingStatusUseCase, dispatcher ) From a297337f8181eb124b58070561043c170090fc82 Mon Sep 17 00:00:00 2001 From: MohamadJaara Date: Fri, 21 Jun 2024 12:03:02 +0200 Subject: [PATCH 2/6] add test --- .../asset/ScheduleNewAssetMessageUseCase.kt | 5 +- .../logic/feature/message/MessageScope.kt | 6 + .../ScheduleNewAssetMessageUseCaseTest.kt | 140 ++++++++++++++++++ 3 files changed, 150 insertions(+), 1 deletion(-) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/asset/ScheduleNewAssetMessageUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/asset/ScheduleNewAssetMessageUseCase.kt index e0921966c88..3855053c961 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/asset/ScheduleNewAssetMessageUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/asset/ScheduleNewAssetMessageUseCase.kt @@ -109,6 +109,7 @@ internal class ScheduleNewAssetMessageUseCaseImpl( private val selfDeleteTimer: ObserveSelfDeletionTimerSettingsForConversationUseCase, private val scope: CoroutineScope, private val observeFileSharingStatus: ObserveFileSharingStatusUseCase, + private val validateAssetMimeTypeUseCase: ValidateAssetMimeTypeUseCase, private val dispatcher: KaliumDispatcher, ) : ScheduleNewAssetMessageUseCase { @@ -129,7 +130,9 @@ internal class ScheduleNewAssetMessageUseCaseImpl( when(it.state) { FileSharingStatus.Value.Disabled -> return ScheduleNewAssetMessageResult.Failure.DisabledByTeam FileSharingStatus.Value.EnabledAll -> { /* no-op*/ } - is FileSharingStatus.Value.EnabledSome -> return ScheduleNewAssetMessageResult.Failure.RestrictedFileType + is FileSharingStatus.Value.EnabledSome -> if(!validateAssetMimeTypeUseCase(assetMimeType, it.state.allowedType)) { + return ScheduleNewAssetMessageResult.Failure.RestrictedFileType + } } } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MessageScope.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MessageScope.kt index bf8ea243254..0d191eb1060 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MessageScope.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MessageScope.kt @@ -50,6 +50,8 @@ import com.wire.kalium.logic.feature.asset.UpdateAssetMessageDownloadStatusUseCa import com.wire.kalium.logic.feature.asset.UpdateAssetMessageDownloadStatusUseCaseImpl import com.wire.kalium.logic.feature.asset.UpdateAssetMessageUploadStatusUseCase import com.wire.kalium.logic.feature.asset.UpdateAssetMessageUploadStatusUseCaseImpl +import com.wire.kalium.logic.feature.asset.ValidateAssetMimeTypeUseCase +import com.wire.kalium.logic.feature.asset.ValidateAssetMimeTypeUseCaseImpl import com.wire.kalium.logic.feature.message.composite.SendButtonActionMessageUseCase import com.wire.kalium.logic.feature.message.ephemeral.DeleteEphemeralMessageForSelfUserAsReceiverUseCaseImpl import com.wire.kalium.logic.feature.message.ephemeral.DeleteEphemeralMessageForSelfUserAsSenderUseCaseImpl @@ -118,6 +120,9 @@ class MessageScope internal constructor( protoContentMapper = protoContentMapper ) + private val validateAssetMimeTypeUseCase: ValidateAssetMimeTypeUseCase + get() = ValidateAssetMimeTypeUseCaseImpl() + private val messageContentEncoder = MessageContentEncoder() private val messageSendingInterceptor: MessageSendingInterceptor get() = MessageSendingInterceptorImpl(messageContentEncoder, messageRepository) @@ -210,6 +215,7 @@ class MessageScope internal constructor( observeSelfDeletingMessages, scope, observeFileSharingStatusUseCase, + validateAssetMimeTypeUseCase, dispatcher ) diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/asset/ScheduleNewAssetMessageUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/asset/ScheduleNewAssetMessageUseCaseTest.kt index aa847d77b3e..ebad24b3f0f 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/asset/ScheduleNewAssetMessageUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/asset/ScheduleNewAssetMessageUseCaseTest.kt @@ -22,6 +22,7 @@ import com.wire.kalium.cryptography.utils.SHA256Key import com.wire.kalium.logic.CoreFailure import com.wire.kalium.logic.NetworkFailure import com.wire.kalium.logic.StorageFailure +import com.wire.kalium.logic.configuration.FileSharingStatus import com.wire.kalium.logic.data.asset.AssetRepository import com.wire.kalium.logic.data.asset.FakeKaliumFileSystem import com.wire.kalium.logic.data.asset.UploadedAssetId @@ -40,6 +41,7 @@ import com.wire.kalium.logic.feature.message.MessageSendFailureHandler import com.wire.kalium.logic.feature.message.MessageSender import com.wire.kalium.logic.feature.selfDeletingMessages.ObserveSelfDeletionTimerSettingsForConversationUseCase import com.wire.kalium.logic.feature.selfDeletingMessages.SelfDeletionTimer +import com.wire.kalium.logic.feature.user.ObserveFileSharingStatusUseCase import com.wire.kalium.logic.framework.TestAsset.dummyUploadedAssetId import com.wire.kalium.logic.framework.TestAsset.mockedLongAssetData import com.wire.kalium.logic.functional.Either @@ -92,6 +94,7 @@ class ScheduleNewAssetMessageUseCaseTest { .withObserveMessageVisibility() .withDeleteAssetLocally() .withSelfDeleteTimer(SelfDeletionTimer.Disabled) + .withObserveFileSharingStatusResult(FileSharingStatus.Value.EnabledAll) .arrange() // When @@ -125,6 +128,7 @@ class ScheduleNewAssetMessageUseCaseTest { .withSelfDeleteTimer(SelfDeletionTimer.Disabled) .withDeleteAssetLocally() .withObserveMessageVisibility() + .withObserveFileSharingStatusResult(FileSharingStatus.Value.EnabledAll) .arrange() // When @@ -158,6 +162,7 @@ class ScheduleNewAssetMessageUseCaseTest { .withSelfDeleteTimer(SelfDeletionTimer.Disabled) .withObserveMessageVisibility() .withDeleteAssetLocally() + .withObserveFileSharingStatusResult(FileSharingStatus.Value.EnabledAll) .arrange() // When @@ -198,6 +203,7 @@ class ScheduleNewAssetMessageUseCaseTest { .withSelfDeleteTimer(SelfDeletionTimer.Disabled) .withObserveMessageVisibility() .withDeleteAssetLocally() + .withObserveFileSharingStatusResult(FileSharingStatus.Value.EnabledAll) .arrange() // When @@ -248,6 +254,7 @@ class ScheduleNewAssetMessageUseCaseTest { .withSelfDeleteTimer(SelfDeletionTimer.Disabled) .withObserveMessageVisibility() .withDeleteAssetLocally() + .withObserveFileSharingStatusResult(FileSharingStatus.Value.EnabledAll) .arrange() // When @@ -298,6 +305,7 @@ class ScheduleNewAssetMessageUseCaseTest { .withSelfDeleteTimer(SelfDeletionTimer.Disabled) .withObserveMessageVisibility() .withDeleteAssetLocally() + .withObserveFileSharingStatusResult(FileSharingStatus.Value.EnabledAll) .arrange() // When @@ -338,6 +346,7 @@ class ScheduleNewAssetMessageUseCaseTest { .withSelfDeleteTimer(SelfDeletionTimer.Disabled) .withObserveMessageVisibility() .withDeleteAssetLocally() + .withObserveFileSharingStatusResult(FileSharingStatus.Value.EnabledAll) .arrange() // When @@ -386,6 +395,7 @@ class ScheduleNewAssetMessageUseCaseTest { .withSelfDeleteTimer(SelfDeletionTimer.Disabled) .withObserveMessageVisibility() .withDeleteAssetLocally() + .withObserveFileSharingStatusResult(FileSharingStatus.Value.EnabledAll) .arrange() // When @@ -441,6 +451,7 @@ class ScheduleNewAssetMessageUseCaseTest { .withSelfDeleteTimer(SelfDeletionTimer.Disabled) .withObserveMessageVisibility() .withDeleteAssetLocally() + .withObserveFileSharingStatusResult(FileSharingStatus.Value.EnabledAll) .arrange() // When @@ -486,6 +497,7 @@ class ScheduleNewAssetMessageUseCaseTest { .withSelfDeleteTimer(SelfDeletionTimer.Disabled) .withObserveMessageVisibility() .withDeleteAssetLocally() + .withObserveFileSharingStatusResult(FileSharingStatus.Value.EnabledAll) .arrange() // When @@ -529,6 +541,7 @@ class ScheduleNewAssetMessageUseCaseTest { .withSelfDeleteTimer(SelfDeletionTimer.Enabled(expectedDuration)) .withObserveMessageVisibility() .withDeleteAssetLocally() + .withObserveFileSharingStatusResult(FileSharingStatus.Value.EnabledAll) .arrange() // When @@ -555,6 +568,111 @@ class ScheduleNewAssetMessageUseCaseTest { }) } + @Test + fun givenFileSendingRestrictedByTeam_whenSending_thenReturnDisabledByTeam() = runTest { + // Given + val assetToSend = mockedLongAssetData() + val assetName = "some-asset.txt" + val inputDataPath = fakeKaliumFileSystem.providePersistentAssetPath(assetName) + val conversationId = ConversationId("some-convo-id", "some-domain-id") + val (_, sendAssetUseCase) = Arrangement(this) + .withStoredData(assetToSend, inputDataPath) + .withObserveFileSharingStatusResult(FileSharingStatus.Value.Disabled) + .arrange() + + // When + val result = sendAssetUseCase.invoke( + conversationId = conversationId, + assetDataPath = inputDataPath, + assetDataSize = assetToSend.size.toLong(), + assetName = assetName, + assetMimeType = "text/plain", + assetWidth = null, + assetHeight = null, + audioLengthInMs = 0 + ) + advanceUntilIdle() + + // Then + assertTrue(result is ScheduleNewAssetMessageResult.Failure.DisabledByTeam) + } + + @Test + fun givenAseetMimeTypeRestricted_whenSending_thenReturnRestrictedFileType() = runTest { + // Given + val assetToSend = mockedLongAssetData() + val assetName = "some-asset.txt" + val inputDataPath = fakeKaliumFileSystem.providePersistentAssetPath(assetName) + val conversationId = ConversationId("some-convo-id", "some-domain-id") + val (arrangement, sendAssetUseCase) = Arrangement(this) + .withStoredData(assetToSend, inputDataPath) + .withObserveFileSharingStatusResult(FileSharingStatus.Value.EnabledSome(listOf("png"))) + .withValidateAsseMimeTypeResult(false) + .arrange() + + // When + val result = sendAssetUseCase.invoke( + conversationId = conversationId, + assetDataPath = inputDataPath, + assetDataSize = assetToSend.size.toLong(), + assetName = assetName, + assetMimeType = "text/plain", + assetWidth = null, + assetHeight = null, + audioLengthInMs = 0 + ) + advanceUntilIdle() + + // Then + assertTrue(result is ScheduleNewAssetMessageResult.Failure.RestrictedFileType) + + verify(arrangement.validateAssetMimeTypeUseCase) + .function(arrangement.validateAssetMimeTypeUseCase::invoke) + .with(eq("text/plain"), eq(listOf("png"))) + .wasInvoked(exactly = once) + } + + @Test + fun givenAssetMimeTypeRestrictedAndFileAllowed_whenSending_thenReturnSendTheFile() = runTest(testDispatcher.default) { + // Given + val assetToSend = mockedLongAssetData() + val assetName = "some-asset.txt" + val inputDataPath = fakeKaliumFileSystem.providePersistentAssetPath(assetName) + val expectedAssetId = dummyUploadedAssetId + val expectedAssetSha256 = SHA256Key("some-asset-sha-256".toByteArray()) + val conversationId = ConversationId("some-convo-id", "some-domain-id") + val (arrangement, sendAssetUseCase) = Arrangement(this) + .withStoredData(assetToSend, inputDataPath) + .withSuccessfulResponse(expectedAssetId, expectedAssetSha256) + .withObserveFileSharingStatusResult(FileSharingStatus.Value.EnabledSome(listOf("png"))) + .withValidateAsseMimeTypeResult(true) + .withSelfDeleteTimer(SelfDeletionTimer.Disabled) + .withObserveMessageVisibility() + .withDeleteAssetLocally() + .arrange() + + // When + val result = sendAssetUseCase.invoke( + conversationId = conversationId, + assetDataPath = inputDataPath, + assetDataSize = assetToSend.size.toLong(), + assetName = assetName, + assetMimeType = "image/png", + assetWidth = null, + assetHeight = null, + audioLengthInMs = 0 + ) + advanceUntilIdle() + + // Then + assertTrue(result is ScheduleNewAssetMessageResult.Success) + + verify(arrangement.validateAssetMimeTypeUseCase) + .function(arrangement.validateAssetMimeTypeUseCase::invoke) + .with(eq("image/png"), eq(listOf("png"))) + .wasInvoked(exactly = once) + } + private class Arrangement(val coroutineScope: CoroutineScope) { @Mock @@ -587,6 +705,12 @@ class ScheduleNewAssetMessageUseCaseTest { @Mock private val messageRepository: MessageRepository = mock(MessageRepository::class) + @Mock + val validateAssetMimeTypeUseCase: ValidateAssetMimeTypeUseCase = mock(ValidateAssetMimeTypeUseCase::class) + + @Mock + val observerFileSharingStatusUseCase: ObserveFileSharingStatusUseCase = mock(ObserveFileSharingStatusUseCase::class) + val someClientId = ClientId("some-client-id") val completeStateFlow = MutableStateFlow(SlowSyncStatus.Complete).asStateFlow() @@ -596,6 +720,20 @@ class ScheduleNewAssetMessageUseCaseTest { withToggleReadReceiptsStatus() } + fun withValidateAsseMimeTypeResult(result: Boolean) = apply { + given(validateAssetMimeTypeUseCase) + .function(validateAssetMimeTypeUseCase::invoke) + .whenInvokedWith(any(), any()) + .thenReturn(result) + } + + fun withObserveFileSharingStatusResult(result: FileSharingStatus.Value) = apply { + given(observerFileSharingStatusUseCase) + .function(observerFileSharingStatusUseCase::invoke) + .whenInvoked() + .thenReturn(flowOf(FileSharingStatus(result, false))) + } + fun withToggleReadReceiptsStatus(enabled: Boolean = false) = apply { given(userPropertyRepository) .suspendFunction(userPropertyRepository::getReadReceiptsStatus) @@ -785,6 +923,8 @@ class ScheduleNewAssetMessageUseCaseTest { userPropertyRepository, observeSelfDeletionTimerSettingsForConversation, coroutineScope, + observerFileSharingStatusUseCase, + validateAssetMimeTypeUseCase, testDispatcher ) } From 9d906bb58dfac77b755ec4d2646f2eab453fd19e Mon Sep 17 00:00:00 2001 From: MohamadJaara Date: Fri, 21 Jun 2024 14:41:33 +0200 Subject: [PATCH 3/6] add error messages and detekt --- .../asset/ScheduleNewAssetMessageUseCase.kt | 17 ++++++++++------- .../logic/feature/message/MessageScope.kt | 3 --- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/asset/ScheduleNewAssetMessageUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/asset/ScheduleNewAssetMessageUseCase.kt index 3855053c961..f23ca055be4 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/asset/ScheduleNewAssetMessageUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/asset/ScheduleNewAssetMessageUseCase.kt @@ -115,7 +115,7 @@ internal class ScheduleNewAssetMessageUseCaseImpl( private var outGoingAssetUploadJob: Job? = null - @Suppress("LongMethod") + @Suppress("LongMethod", "ReturnCount") override suspend fun invoke( conversationId: ConversationId, assetDataPath: Path, @@ -127,11 +127,14 @@ internal class ScheduleNewAssetMessageUseCaseImpl( audioLengthInMs: Long ): ScheduleNewAssetMessageResult { observeFileSharingStatus().first().also { - when(it.state) { + when (it.state) { FileSharingStatus.Value.Disabled -> return ScheduleNewAssetMessageResult.Failure.DisabledByTeam - FileSharingStatus.Value.EnabledAll -> { /* no-op*/ } - is FileSharingStatus.Value.EnabledSome -> if(!validateAssetMimeTypeUseCase(assetMimeType, it.state.allowedType)) { - return ScheduleNewAssetMessageResult.Failure.RestrictedFileType + FileSharingStatus.Value.EnabledAll -> { /* no-op*/ + } + + is FileSharingStatus.Value.EnabledSome -> if (!validateAssetMimeTypeUseCase(assetMimeType, it.state.allowedType)) { + kaliumLogger.e("The asset message trying to be processed has invalid content data") + return ScheduleNewAssetMessageResult.Failure.RestrictedFileType } } } @@ -363,8 +366,8 @@ sealed interface ScheduleNewAssetMessageResult { data class Success(val messageId: String) : ScheduleNewAssetMessageResult sealed interface Failure : ScheduleNewAssetMessageResult { data class Generic(val coreFailure: CoreFailure) : Failure - data object DisabledByTeam: Failure - data object RestrictedFileType: Failure + data object DisabledByTeam : Failure + data object RestrictedFileType : Failure } } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MessageScope.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MessageScope.kt index 0d191eb1060..470c718cd22 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MessageScope.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MessageScope.kt @@ -19,8 +19,6 @@ package com.wire.kalium.logic.feature.message import com.wire.kalium.logic.cache.SelfConversationIdProvider -import com.wire.kalium.logic.configuration.UserConfigDataSource -import com.wire.kalium.logic.configuration.UserConfigRepository import com.wire.kalium.logic.data.asset.AssetRepository import com.wire.kalium.logic.data.client.ClientRepository import com.wire.kalium.logic.data.client.MLSClientProvider @@ -63,7 +61,6 @@ import com.wire.kalium.logic.feature.selfDeletingMessages.ObserveSelfDeletionTim import com.wire.kalium.logic.feature.sessionreset.ResetSessionUseCase import com.wire.kalium.logic.feature.sessionreset.ResetSessionUseCaseImpl import com.wire.kalium.logic.feature.user.ObserveFileSharingStatusUseCase -import com.wire.kalium.logic.feature.user.ObserveFileSharingStatusUseCaseImpl import com.wire.kalium.logic.sync.SyncManager import com.wire.kalium.logic.util.MessageContentEncoder import com.wire.kalium.util.KaliumDispatcher From 5425ed6269ca87ea1070838dc3a13003b205eb7b Mon Sep 17 00:00:00 2001 From: MohamadJaara Date: Fri, 21 Jun 2024 21:41:25 +0200 Subject: [PATCH 4/6] fist test service --- .../managed/ConversationRepository.kt | 57 ++++++++++++------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/testservice/src/main/kotlin/com/wire/kalium/testservice/managed/ConversationRepository.kt b/testservice/src/main/kotlin/com/wire/kalium/testservice/managed/ConversationRepository.kt index 8b0401c8399..9ddfd97ad47 100644 --- a/testservice/src/main/kotlin/com/wire/kalium/testservice/managed/ConversationRepository.kt +++ b/testservice/src/main/kotlin/com/wire/kalium/testservice/managed/ConversationRepository.kt @@ -331,16 +331,26 @@ sealed class ConversationRepository { } when (sendResult) { is ScheduleNewAssetMessageResult.Failure -> { - if (sendResult.coreFailure is StorageFailure.Generic) { - val rootCause = (sendResult.coreFailure as StorageFailure.Generic) - .rootCause.message - Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity("Instance ${instance.instanceId}: Sending failed with $rootCause") - .build() - } else { - Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity("Instance ${instance.instanceId}: Sending file $fileName failed") - .build() + // if the IDE tels you that this casting is unnecessary + // first check kotlin version + // if version < 2 then casting is necessary + // if version >= 2 then casting is unnecessary + when(val result = sendResult as ScheduleNewAssetMessageResult.Failure) { + ScheduleNewAssetMessageResult.Failure.RestrictedFileType, + ScheduleNewAssetMessageResult.Failure.DisabledByTeam -> { + throw WebApplicationException("Instance ${instance.instanceId}: Sending failed with $sendResult") + } + + is ScheduleNewAssetMessageResult.Failure.Generic -> { + if (result.coreFailure is StorageFailure.Generic) { + val rootCause = (result.coreFailure as StorageFailure.Generic).rootCause.message + throw WebApplicationException( + "Instance ${instance.instanceId}: Sending failed with $rootCause" + ) + } else { + throw WebApplicationException("Instance ${instance.instanceId}: Sending failed") + } + } } } @@ -409,17 +419,24 @@ sealed class ConversationRepository { height, 0L ) - if (sendResult is ScheduleNewAssetMessageResult.Failure) { - if (sendResult.coreFailure is StorageFailure.Generic) { - val rootCause = (sendResult.coreFailure as StorageFailure.Generic).rootCause.message - throw WebApplicationException( - "Instance ${instance.instanceId}: Sending failed with $rootCause" - ) - } else { - throw WebApplicationException("Instance ${instance.instanceId}: Sending failed") + when (sendResult) { + ScheduleNewAssetMessageResult.Failure.RestrictedFileType, + ScheduleNewAssetMessageResult.Failure.DisabledByTeam -> { + throw WebApplicationException("Instance ${instance.instanceId}: Sending failed with $sendResult") } - } else { - Response.status(Response.Status.OK).build() + + is ScheduleNewAssetMessageResult.Failure.Generic -> { + if (sendResult.coreFailure is StorageFailure.Generic) { + val rootCause = (sendResult.coreFailure as StorageFailure.Generic).rootCause.message + throw WebApplicationException( + "Instance ${instance.instanceId}: Sending failed with $rootCause" + ) + } else { + throw WebApplicationException("Instance ${instance.instanceId}: Sending failed") + } + } + + is ScheduleNewAssetMessageResult.Success -> Response.status(Response.Status.OK).build() } } } From 93563df9988b12b2aba438af93fc6043992096fe Mon Sep 17 00:00:00 2001 From: MohamadJaara Date: Fri, 21 Jun 2024 22:20:32 +0200 Subject: [PATCH 5/6] detekt --- .../testservice/managed/ConversationRepository.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/testservice/src/main/kotlin/com/wire/kalium/testservice/managed/ConversationRepository.kt b/testservice/src/main/kotlin/com/wire/kalium/testservice/managed/ConversationRepository.kt index 9ddfd97ad47..29465947ed2 100644 --- a/testservice/src/main/kotlin/com/wire/kalium/testservice/managed/ConversationRepository.kt +++ b/testservice/src/main/kotlin/com/wire/kalium/testservice/managed/ConversationRepository.kt @@ -269,7 +269,7 @@ sealed class ConversationRepository { throw WebApplicationException("Instance ${instance.instanceId}: Could not get recent messages") } - @Suppress("LongParameterList", "LongMethod", "ThrowsCount") + @Suppress("LongParameterList", "LongMethod", "ThrowsCount", "ComplexMethod") suspend fun sendFile( instance: Instance, conversationId: ConversationId, @@ -335,10 +335,12 @@ sealed class ConversationRepository { // first check kotlin version // if version < 2 then casting is necessary // if version >= 2 then casting is unnecessary - when(val result = sendResult as ScheduleNewAssetMessageResult.Failure) { + when (val result = sendResult as ScheduleNewAssetMessageResult.Failure) { ScheduleNewAssetMessageResult.Failure.RestrictedFileType, ScheduleNewAssetMessageResult.Failure.DisabledByTeam -> { - throw WebApplicationException("Instance ${instance.instanceId}: Sending failed with $sendResult") + throw WebApplicationException( + "Instance ${instance.instanceId}: Sending failed with $sendResult" + ) } is ScheduleNewAssetMessageResult.Failure.Generic -> { @@ -376,7 +378,7 @@ sealed class ConversationRepository { } } - @Suppress("LongParameterList") + @Suppress("LongParameterList", "ThrowsCount") suspend fun sendImage( instance: Instance, conversationId: ConversationId, From 4aa439f5df61abd67499920b13cfc88e5ab6195d Mon Sep 17 00:00:00 2001 From: Yamil Medina Date: Mon, 24 Jun 2024 10:43:41 +0200 Subject: [PATCH 6/6] chore: update gradle-ios-tests.yml for runner at that time --- .github/workflows/gradle-ios-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-ios-tests.yml b/.github/workflows/gradle-ios-tests.yml index 29c88256fb7..dbdfdbd3bdf 100644 --- a/.github/workflows/gradle-ios-tests.yml +++ b/.github/workflows/gradle-ios-tests.yml @@ -14,7 +14,7 @@ jobs: uses: ./.github/workflows/codestyle.yml gradle-run-tests: needs: [detekt] - runs-on: macos-latest + runs-on: macos-12 steps: - name: Checkout