Skip to content

Commit 8dc57fe

Browse files
authored
Merge pull request #5853 from vector-im/feature/aris/crypto_share_room_keys_past_messages
Share Megolm session keys when inviting a new user
2 parents bdb49f5 + d281f9d commit 8dc57fe

File tree

52 files changed

+1844
-397
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1844
-397
lines changed

changelog.d/5853.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve user experience when he is first invited to a room. Users will be able to decrypt and view previous messages

matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@ package org.matrix.android.sdk.common
1818

1919
import android.content.Context
2020
import android.net.Uri
21+
import android.util.Log
2122
import androidx.lifecycle.Observer
2223
import androidx.test.internal.runner.junit4.statement.UiThreadStatement
2324
import kotlinx.coroutines.CoroutineDispatcher
2425
import kotlinx.coroutines.CoroutineScope
2526
import kotlinx.coroutines.Dispatchers
27+
import kotlinx.coroutines.Job
2628
import kotlinx.coroutines.SupervisorJob
29+
import kotlinx.coroutines.cancel
2730
import kotlinx.coroutines.delay
2831
import kotlinx.coroutines.launch
2932
import kotlinx.coroutines.runBlocking
@@ -38,7 +41,10 @@ import org.matrix.android.sdk.api.auth.registration.RegistrationResult
3841
import org.matrix.android.sdk.api.session.Session
3942
import org.matrix.android.sdk.api.session.events.model.EventType
4043
import org.matrix.android.sdk.api.session.events.model.toModel
44+
import org.matrix.android.sdk.api.session.getRoomSummary
4145
import org.matrix.android.sdk.api.session.room.Room
46+
import org.matrix.android.sdk.api.session.room.failure.JoinRoomFailure
47+
import org.matrix.android.sdk.api.session.room.model.Membership
4248
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
4349
import org.matrix.android.sdk.api.session.room.send.SendState
4450
import org.matrix.android.sdk.api.session.room.timeline.Timeline
@@ -47,14 +53,15 @@ import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
4753
import org.matrix.android.sdk.api.session.sync.SyncState
4854
import timber.log.Timber
4955
import java.util.UUID
56+
import java.util.concurrent.CancellationException
5057
import java.util.concurrent.CountDownLatch
5158
import java.util.concurrent.TimeUnit
5259

5360
/**
5461
* This class exposes methods to be used in common cases
5562
* Registration, login, Sync, Sending messages...
5663
*/
57-
class CommonTestHelper private constructor(context: Context) {
64+
class CommonTestHelper internal constructor(context: Context) {
5865

5966
companion object {
6067
internal fun runSessionTest(context: Context, autoSignoutOnClose: Boolean = true, block: (CommonTestHelper) -> Unit) {
@@ -241,6 +248,37 @@ class CommonTestHelper private constructor(context: Context) {
241248
return sentEvents
242249
}
243250

251+
fun waitForAndAcceptInviteInRoom(otherSession: Session, roomID: String) {
252+
waitWithLatch { latch ->
253+
retryPeriodicallyWithLatch(latch) {
254+
val roomSummary = otherSession.getRoomSummary(roomID)
255+
(roomSummary != null && roomSummary.membership == Membership.INVITE).also {
256+
if (it) {
257+
Log.v("# TEST", "${otherSession.myUserId} can see the invite")
258+
}
259+
}
260+
}
261+
}
262+
263+
// not sure why it's taking so long :/
264+
runBlockingTest(90_000) {
265+
Log.v("#E2E TEST", "${otherSession.myUserId} tries to join room $roomID")
266+
try {
267+
otherSession.roomService().joinRoom(roomID)
268+
} catch (ex: JoinRoomFailure.JoinedWithTimeout) {
269+
// it's ok we will wait after
270+
}
271+
}
272+
273+
Log.v("#E2E TEST", "${otherSession.myUserId} waiting for join echo ...")
274+
waitWithLatch {
275+
retryPeriodicallyWithLatch(it) {
276+
val roomSummary = otherSession.getRoomSummary(roomID)
277+
roomSummary != null && roomSummary.membership == Membership.JOIN
278+
}
279+
}
280+
}
281+
244282
/**
245283
* Reply in a thread
246284
* @param room the room where to send the messages
@@ -285,6 +323,8 @@ class CommonTestHelper private constructor(context: Context) {
285323
)
286324
assertNotNull(session)
287325
return session.also {
326+
// most of the test was created pre-MSC3061 so ensure compatibility
327+
it.cryptoService().enableShareKeyOnInvite(false)
288328
trackedSessions.add(session)
289329
}
290330
}
@@ -428,16 +468,26 @@ class CommonTestHelper private constructor(context: Context) {
428468
* @param latch
429469
* @throws InterruptedException
430470
*/
431-
fun await(latch: CountDownLatch, timeout: Long? = TestConstants.timeOutMillis) {
471+
fun await(latch: CountDownLatch, timeout: Long? = TestConstants.timeOutMillis, job: Job? = null) {
432472
assertTrue(
433473
"Timed out after " + timeout + "ms waiting for something to happen. See stacktrace for cause.",
434-
latch.await(timeout ?: TestConstants.timeOutMillis, TimeUnit.MILLISECONDS)
474+
latch.await(timeout ?: TestConstants.timeOutMillis, TimeUnit.MILLISECONDS).also {
475+
if (!it) {
476+
// cancel job on timeout
477+
job?.cancel("Await timeout")
478+
}
479+
}
435480
)
436481
}
437482

438483
suspend fun retryPeriodicallyWithLatch(latch: CountDownLatch, condition: (() -> Boolean)) {
439484
while (true) {
440-
delay(1000)
485+
try {
486+
delay(1000)
487+
} catch (ex: CancellationException) {
488+
// the job was canceled, just stop
489+
return
490+
}
441491
if (condition()) {
442492
latch.countDown()
443493
return
@@ -447,10 +497,10 @@ class CommonTestHelper private constructor(context: Context) {
447497

448498
fun waitWithLatch(timeout: Long? = TestConstants.timeOutMillis, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend (CountDownLatch) -> Unit) {
449499
val latch = CountDownLatch(1)
450-
coroutineScope.launch(dispatcher) {
500+
val job = coroutineScope.launch(dispatcher) {
451501
block(latch)
452502
}
453-
await(latch, timeout)
503+
await(latch, timeout, job)
454504
}
455505

456506
fun <T> runBlockingTest(timeout: Long = TestConstants.timeOutMillis, block: suspend () -> T): T {

matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import org.matrix.android.sdk.api.session.events.model.toModel
5353
import org.matrix.android.sdk.api.session.getRoom
5454
import org.matrix.android.sdk.api.session.room.Room
5555
import org.matrix.android.sdk.api.session.room.model.Membership
56+
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility
5657
import org.matrix.android.sdk.api.session.room.model.RoomSummary
5758
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
5859
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
@@ -76,11 +77,14 @@ class CryptoTestHelper(val testHelper: CommonTestHelper) {
7677
/**
7778
* @return alice session
7879
*/
79-
fun doE2ETestWithAliceInARoom(encryptedRoom: Boolean = true): CryptoTestData {
80+
fun doE2ETestWithAliceInARoom(encryptedRoom: Boolean = true, roomHistoryVisibility: RoomHistoryVisibility? = null): CryptoTestData {
8081
val aliceSession = testHelper.createAccount(TestConstants.USER_ALICE, defaultSessionParams)
8182

8283
val roomId = testHelper.runBlockingTest {
83-
aliceSession.roomService().createRoom(CreateRoomParams().apply { name = "MyRoom" })
84+
aliceSession.roomService().createRoom(CreateRoomParams().apply {
85+
historyVisibility = roomHistoryVisibility
86+
name = "MyRoom"
87+
})
8488
}
8589
if (encryptedRoom) {
8690
testHelper.waitWithLatch { latch ->
@@ -104,8 +108,8 @@ class CryptoTestHelper(val testHelper: CommonTestHelper) {
104108
/**
105109
* @return alice and bob sessions
106110
*/
107-
fun doE2ETestWithAliceAndBobInARoom(encryptedRoom: Boolean = true): CryptoTestData {
108-
val cryptoTestData = doE2ETestWithAliceInARoom(encryptedRoom)
111+
fun doE2ETestWithAliceAndBobInARoom(encryptedRoom: Boolean = true, roomHistoryVisibility: RoomHistoryVisibility? = null): CryptoTestData {
112+
val cryptoTestData = doE2ETestWithAliceInARoom(encryptedRoom, roomHistoryVisibility)
109113
val aliceSession = cryptoTestData.firstSession
110114
val aliceRoomId = cryptoTestData.roomId
111115

0 commit comments

Comments
 (0)