Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Share Megolm session keys when inviting a new user #5853

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
34713d5
Add sharing existing inbound sessions functionality on new room invites
ariskotsomitopoulos Apr 20, 2022
98b5545
Add sendSharedHistoryKeys in crypto service
ariskotsomitopoulos Apr 21, 2022
6e57aeb
Add roomId in InboundSessionEntity for better performance
ariskotsomitopoulos Apr 21, 2022
e861edd
Implement history key sharing functionality with respect to room visi…
ariskotsomitopoulos Apr 26, 2022
b3bfd05
- Share only the first chunk of inbound sessions instead of the whole…
ariskotsomitopoulos Apr 27, 2022
dd3928f
Remove sendSharedHistoryKeys while we will only share latest messages
ariskotsomitopoulos Apr 28, 2022
28a3ae2
Remove sharedHistory from OlmInboundGroupSessionWrapper2 while there …
ariskotsomitopoulos Apr 28, 2022
d6358dc
Prevent injecting a forged encrypted message and using session_id/sen…
ariskotsomitopoulos Apr 28, 2022
497f7cf
Rotate our session when there is a room history visibility change sin…
ariskotsomitopoulos Apr 29, 2022
395d48f
Refactor code structure and improve naming
ariskotsomitopoulos Apr 29, 2022
243463a
Add logs
ariskotsomitopoulos Apr 29, 2022
45c80de
Add changelog
ariskotsomitopoulos Apr 29, 2022
96f0d52
Update copyright
ariskotsomitopoulos May 3, 2022
28dd507
Add crypto shared history sanity test
ariskotsomitopoulos May 3, 2022
3a5b737
Fix existing E2eeSanityTests to support changes for key history sharing
ariskotsomitopoulos May 3, 2022
2e88998
Add integration tests for shared keys rotation on room history visibi…
ariskotsomitopoulos May 3, 2022
93aac8f
post rebase fix
BillCarsonFr May 11, 2022
9b8e45e
share keys for history take2
BillCarsonFr May 12, 2022
8c26592
cleaning
BillCarsonFr May 12, 2022
d8d808d
removed deprecated annotation, CI don't like
BillCarsonFr May 12, 2022
fb352ff
quick format
BillCarsonFr May 12, 2022
a9a7400
Add MXCryptoConfig flag for key history sharing
ariskotsomitopoulos May 20, 2022
d3a516b
Enhance key sharing to respect matrix configuration
ariskotsomitopoulos May 31, 2022
55fdff4
Resolve merge conflicts
ariskotsomitopoulos May 31, 2022
010cf54
Fix broken unit test
ariskotsomitopoulos May 31, 2022
df241db
Fix broken unit test
ariskotsomitopoulos May 31, 2022
34145f0
post rebase fix
BillCarsonFr Jun 10, 2022
f64adeb
fix bad sender key export
BillCarsonFr Jun 13, 2022
d9fb58f
Fix tests
BillCarsonFr Jun 14, 2022
8e829c6
Add lab flag and more tests
BillCarsonFr Jun 15, 2022
ddd8244
kdoc
BillCarsonFr Jun 15, 2022
b0907de
Fix migration
BillCarsonFr Jun 16, 2022
a885ff5
Fix test
BillCarsonFr Jun 16, 2022
5a67c39
reuse code for test
BillCarsonFr Jun 16, 2022
e7322e8
outdated configuration
BillCarsonFr Jun 16, 2022
fb5f0cb
Fix test compilation
BillCarsonFr Jun 28, 2022
08cb6de
Fix migration
BillCarsonFr Jul 1, 2022
90a4e71
update flacky test
BillCarsonFr Jul 1, 2022
6fd99dc
resist ConnectivityManager$TooManyRequestsException
BillCarsonFr Jul 1, 2022
d281f9d
use XXX not TODO
BillCarsonFr Jul 1, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/5853.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Improve user experience when he is first invited to a room. Users will be able to decrypt and view previous messages
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@ package org.matrix.android.sdk.common

import android.content.Context
import android.net.Uri
import android.util.Log
import androidx.lifecycle.Observer
import androidx.test.internal.runner.junit4.statement.UiThreadStatement
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
Expand All @@ -38,7 +41,10 @@ import org.matrix.android.sdk.api.auth.registration.RegistrationResult
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.getRoomSummary
import org.matrix.android.sdk.api.session.room.Room
import org.matrix.android.sdk.api.session.room.failure.JoinRoomFailure
import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
import org.matrix.android.sdk.api.session.room.send.SendState
import org.matrix.android.sdk.api.session.room.timeline.Timeline
Expand All @@ -47,14 +53,15 @@ import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
import org.matrix.android.sdk.api.session.sync.SyncState
import timber.log.Timber
import java.util.UUID
import java.util.concurrent.CancellationException
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit

/**
* This class exposes methods to be used in common cases
* Registration, login, Sync, Sending messages...
*/
class CommonTestHelper private constructor(context: Context) {
class CommonTestHelper internal constructor(context: Context) {

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

fun waitForAndAcceptInviteInRoom(otherSession: Session, roomID: String) {
waitWithLatch { latch ->
retryPeriodicallyWithLatch(latch) {
val roomSummary = otherSession.getRoomSummary(roomID)
(roomSummary != null && roomSummary.membership == Membership.INVITE).also {
if (it) {
Log.v("# TEST", "${otherSession.myUserId} can see the invite")
}
}
}
}

// not sure why it's taking so long :/
runBlockingTest(90_000) {
Log.v("#E2E TEST", "${otherSession.myUserId} tries to join room $roomID")
try {
otherSession.roomService().joinRoom(roomID)
} catch (ex: JoinRoomFailure.JoinedWithTimeout) {
// it's ok we will wait after
}
}

Log.v("#E2E TEST", "${otherSession.myUserId} waiting for join echo ...")
waitWithLatch {
retryPeriodicallyWithLatch(it) {
val roomSummary = otherSession.getRoomSummary(roomID)
roomSummary != null && roomSummary.membership == Membership.JOIN
}
}
}

/**
* Reply in a thread
* @param room the room where to send the messages
Expand Down Expand Up @@ -285,6 +323,8 @@ class CommonTestHelper private constructor(context: Context) {
)
assertNotNull(session)
return session.also {
// most of the test was created pre-MSC3061 so ensure compatibility
it.cryptoService().enableShareKeyOnInvite(false)
trackedSessions.add(session)
}
}
Expand Down Expand Up @@ -428,16 +468,26 @@ class CommonTestHelper private constructor(context: Context) {
* @param latch
* @throws InterruptedException
*/
fun await(latch: CountDownLatch, timeout: Long? = TestConstants.timeOutMillis) {
fun await(latch: CountDownLatch, timeout: Long? = TestConstants.timeOutMillis, job: Job? = null) {
assertTrue(
"Timed out after " + timeout + "ms waiting for something to happen. See stacktrace for cause.",
latch.await(timeout ?: TestConstants.timeOutMillis, TimeUnit.MILLISECONDS)
latch.await(timeout ?: TestConstants.timeOutMillis, TimeUnit.MILLISECONDS).also {
if (!it) {
// cancel job on timeout
job?.cancel("Await timeout")
}
}
)
}

suspend fun retryPeriodicallyWithLatch(latch: CountDownLatch, condition: (() -> Boolean)) {
while (true) {
delay(1000)
try {
delay(1000)
} catch (ex: CancellationException) {
// the job was canceled, just stop
return
}
if (condition()) {
latch.countDown()
return
Expand All @@ -447,10 +497,10 @@ class CommonTestHelper private constructor(context: Context) {

fun waitWithLatch(timeout: Long? = TestConstants.timeOutMillis, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend (CountDownLatch) -> Unit) {
val latch = CountDownLatch(1)
coroutineScope.launch(dispatcher) {
val job = coroutineScope.launch(dispatcher) {
block(latch)
}
await(latch, timeout)
await(latch, timeout, job)
}

fun <T> runBlockingTest(timeout: Long = TestConstants.timeOutMillis, block: suspend () -> T): T {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.getRoom
import org.matrix.android.sdk.api.session.room.Room
import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
Expand All @@ -76,11 +77,14 @@ class CryptoTestHelper(val testHelper: CommonTestHelper) {
/**
* @return alice session
*/
fun doE2ETestWithAliceInARoom(encryptedRoom: Boolean = true): CryptoTestData {
fun doE2ETestWithAliceInARoom(encryptedRoom: Boolean = true, roomHistoryVisibility: RoomHistoryVisibility? = null): CryptoTestData {
val aliceSession = testHelper.createAccount(TestConstants.USER_ALICE, defaultSessionParams)

val roomId = testHelper.runBlockingTest {
aliceSession.roomService().createRoom(CreateRoomParams().apply { name = "MyRoom" })
aliceSession.roomService().createRoom(CreateRoomParams().apply {
historyVisibility = roomHistoryVisibility
name = "MyRoom"
})
}
if (encryptedRoom) {
testHelper.waitWithLatch { latch ->
Expand All @@ -104,8 +108,8 @@ class CryptoTestHelper(val testHelper: CommonTestHelper) {
/**
* @return alice and bob sessions
*/
fun doE2ETestWithAliceAndBobInARoom(encryptedRoom: Boolean = true): CryptoTestData {
val cryptoTestData = doE2ETestWithAliceInARoom(encryptedRoom)
fun doE2ETestWithAliceAndBobInARoom(encryptedRoom: Boolean = true, roomHistoryVisibility: RoomHistoryVisibility? = null): CryptoTestData {
val cryptoTestData = doE2ETestWithAliceInARoom(encryptedRoom, roomHistoryVisibility)
val aliceSession = cryptoTestData.firstSession
val aliceRoomId = cryptoTestData.roomId

Expand Down
Loading