From 079972be69d8ea13aa1cbb733987cf39a0549f5e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 25 Sep 2024 11:36:44 +0000 Subject: [PATCH 1/2] fix: update group state when fetching conversation during slow sync WPB-11247 (#3029) (#3033) * fix: update group state when fetching conversation during slow sync * test: verify that group state is updated on re-insertion Co-authored-by: Jacob Persson <7156+typfel@users.noreply.github.com> --- .../wire/kalium/persistence/Conversations.sq | 1 + .../persistence/dao/ConversationDAOTest.kt | 43 +++++++++++++------ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/persistence/src/commonMain/db_user/com/wire/kalium/persistence/Conversations.sq b/persistence/src/commonMain/db_user/com/wire/kalium/persistence/Conversations.sq index ebc0abcd3cb..dcbc5c154bc 100644 --- a/persistence/src/commonMain/db_user/com/wire/kalium/persistence/Conversations.sq +++ b/persistence/src/commonMain/db_user/com/wire/kalium/persistence/Conversations.sq @@ -81,6 +81,7 @@ type = excluded.type, team_id = excluded.team_id, mls_group_id = excluded.mls_group_id, mls_epoch = excluded.mls_epoch, +mls_group_state = excluded.mls_group_state, protocol = excluded.protocol, muted_status = excluded.muted_status, muted_time = excluded.muted_time, diff --git a/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/dao/ConversationDAOTest.kt b/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/dao/ConversationDAOTest.kt index 36aaa92ae5f..a8f861d9345 100644 --- a/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/dao/ConversationDAOTest.kt +++ b/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/dao/ConversationDAOTest.kt @@ -120,6 +120,18 @@ class ConversationDAOTest : BaseDatabaseTest() { assertNull(result) } + @Test + fun givenExistingConversation_WhenReinserting_ThenGroupStateIsUpdated() = runTest { + conversationDAO.insertConversation(conversationEntity2) + conversationDAO.insertConversation(conversationEntity2.copy( + protocolInfo = mlsProtocolInfo1.copy( + groupState = ConversationEntity.GroupState.PENDING_JOIN + ) + )) + val result = conversationDAO.getConversationByQualifiedID(conversationEntity2.id) + assertEquals(ConversationEntity.GroupState.PENDING_JOIN, (result?.protocolInfo as ConversationEntity.ProtocolInfo.MLS).groupState) + } + @Test fun givenExistingConversation_ThenConversationCanBeUpdated() = runTest { conversationDAO.insertConversation(conversationEntity1) @@ -2043,6 +2055,21 @@ class ConversationDAOTest : BaseDatabaseTest() { isMLSCapable = false ) + val mlsProtocolInfo1 = ConversationEntity.ProtocolInfo.MLS( + "group2", + ConversationEntity.GroupState.ESTABLISHED, + 0UL, + Instant.parse("2021-03-30T15:36:00.000Z"), + cipherSuite = ConversationEntity.CipherSuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 + ) + val mlsProtocolInfo2 = ConversationEntity.ProtocolInfo.MLS( + "group3", + ConversationEntity.GroupState.PENDING_JOIN, + 0UL, + Instant.parse("2021-03-30T15:36:00.000Z"), + cipherSuite = ConversationEntity.CipherSuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 + ) + val team = TeamEntity(teamId, "teamName", "") val conversationEntity1 = ConversationEntity( @@ -2072,13 +2099,7 @@ class ConversationDAOTest : BaseDatabaseTest() { "conversation2", ConversationEntity.Type.ONE_ON_ONE, null, - ConversationEntity.ProtocolInfo.MLS( - "group2", - ConversationEntity.GroupState.ESTABLISHED, - 0UL, - Instant.parse("2021-03-30T15:36:00.000Z"), - cipherSuite = ConversationEntity.CipherSuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 - ), + protocolInfo = mlsProtocolInfo1, creatorId = "someValue", lastNotificationDate = null, lastModifiedDate = "2021-03-30T15:36:00.000Z".toInstant(), @@ -2101,13 +2122,7 @@ class ConversationDAOTest : BaseDatabaseTest() { "conversation3", ConversationEntity.Type.GROUP, null, - ConversationEntity.ProtocolInfo.MLS( - "group3", - ConversationEntity.GroupState.PENDING_JOIN, - 0UL, - Instant.parse("2021-03-30T15:36:00.000Z"), - cipherSuite = ConversationEntity.CipherSuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 - ), + protocolInfo = mlsProtocolInfo2, creatorId = "someValue", // This conversation was modified after the last time the user was notified about it lastNotificationDate = "2021-03-30T15:30:00.000Z".toInstant(), From e3902279afa408510e79b4f6a939cdcec91b0965 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 25 Sep 2024 13:06:11 +0000 Subject: [PATCH 2/2] fix: 404 when getting client domain crl [WPB-11243] (#3026) (#3028) * fix: 404 when getting client domain crl * detekt Co-authored-by: Mohamad Jaara --- .../e2ei/CheckCrlRevocationListUseCase.kt | 2 +- .../network/api/base/unbound/acme/ACMEApi.kt | 8 ++-- .../com/wire/kalium/api/common/ACMEApiTest.kt | 43 +++++++++++++++++++ 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/CheckCrlRevocationListUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/CheckCrlRevocationListUseCase.kt index 6979d9412cd..d8eea576ab8 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/CheckCrlRevocationListUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/e2ei/CheckCrlRevocationListUseCase.kt @@ -45,6 +45,6 @@ class CheckCrlRevocationListUseCase internal constructor( } } } - } + } ?: logger.w("No CRLs found.") } } diff --git a/network/src/commonMain/kotlin/com/wire/kalium/network/api/base/unbound/acme/ACMEApi.kt b/network/src/commonMain/kotlin/com/wire/kalium/network/api/base/unbound/acme/ACMEApi.kt index 9d84bb4a61e..db159b5703c 100644 --- a/network/src/commonMain/kotlin/com/wire/kalium/network/api/base/unbound/acme/ACMEApi.kt +++ b/network/src/commonMain/kotlin/com/wire/kalium/network/api/base/unbound/acme/ACMEApi.kt @@ -44,7 +44,6 @@ import io.ktor.client.request.setBody import io.ktor.client.statement.HttpResponse import io.ktor.http.ContentType import io.ktor.http.URLBuilder -import io.ktor.http.URLProtocol import io.ktor.http.Url import io.ktor.http.contentType import io.ktor.http.isSuccess @@ -269,8 +268,11 @@ class ACMEApiImpl internal constructor( } return wrapKaliumResponse { - val httpUrl = if (proxyUrl.isNullOrEmpty()) URLBuilder(url).apply { this.protocol = URLProtocol.HTTP }.build() - else URLBuilder(proxyUrl).apply { this.pathSegments = this.pathSegments.plus(url) }.build() + val crlUrlBuilder: URLBuilder = URLBuilder(url) + val proxyUrlBuilder: URLBuilder? = if (proxyUrl.isNullOrEmpty()) null else URLBuilder(proxyUrl) + + val httpUrl = proxyUrlBuilder?.apply { this.pathSegments += crlUrlBuilder.host }?.build() + ?: crlUrlBuilder.build() clearTextTrafficHttpClient.get(httpUrl) } diff --git a/network/src/commonTest/kotlin/com/wire/kalium/api/common/ACMEApiTest.kt b/network/src/commonTest/kotlin/com/wire/kalium/api/common/ACMEApiTest.kt index 960aed3c7d1..19c3090a873 100644 --- a/network/src/commonTest/kotlin/com/wire/kalium/api/common/ACMEApiTest.kt +++ b/network/src/commonTest/kotlin/com/wire/kalium/api/common/ACMEApiTest.kt @@ -211,6 +211,49 @@ internal class ACMEApiTest : ApiTest() { } } + @Test + fun givenProxyAndCrl_whenGettingClientDomainCRL_thenUseProxyUrlWithCRLHostAddedToPath() = runTest { + val crlUrl = "https://crl.wire.com/crl" + val proxyUrl = "https://proxy.wire:9000/proxy" + val expected = "$proxyUrl/crl.wire.com" + val networkClient = mockUnboundNetworkClient( + "", + statusCode = HttpStatusCode.OK, + assertion = { + assertJson() + assertUrlEqual(expected) + assertGet() + assertNoQueryParams() + } + ) + val acmeApi: ACMEApi = ACMEApiImpl(networkClient, networkClient) + + acmeApi.getClientDomainCRL(url = crlUrl, proxyUrl = proxyUrl).also { actual -> + assertIs>(actual) + } + } + + @Test + fun givenCRLWithHttpsProtocol_whenGettingClientDomainCRL_thenItShouldNotBeChanged() = runTest { + val crlUrl = "https://crl.wire.com/crl" + val expected = crlUrl + val networkClient = mockUnboundNetworkClient( + "", + statusCode = HttpStatusCode.OK, + assertion = { + assertJson() + assertUrlEqual(expected) + assertGet() + assertNoQueryParams() + } + ) + val acmeApi: ACMEApi = ACMEApiImpl(networkClient, networkClient) + + acmeApi.getClientDomainCRL(url = crlUrl, proxyUrl = null).also { actual -> + assertIs>(actual) + } + } + companion object { private const val ACME_DISCOVERY_URL = "https://balderdash.hogwash.work:9000/acme/google-android/directory" private const val ACME_DIRECTORIES_PATH = "https://balderdash.hogwash.work:9000/acme/google-android/directory"