Ignore some test in tust. Added some supports flags

This commit is contained in:
valere 2023-03-14 09:57:58 +01:00
parent 238d10d4cb
commit 5f069264d0
20 changed files with 210 additions and 117 deletions

View File

@ -45,6 +45,7 @@ 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.getRoomSummary
import org.matrix.android.sdk.api.session.room.Room 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.failure.JoinRoomFailure
import org.matrix.android.sdk.api.session.room.getTimelineEvent
import org.matrix.android.sdk.api.session.room.model.Membership 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.model.message.MessageContent
import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.api.session.room.send.SendState
@ -83,7 +84,7 @@ class CommonTestHelper internal constructor(context: Context, val cryptoConfig:
} }
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
internal fun runCryptoTest(context: Context, cryptoConfig: MXCryptoConfig? = null, autoSignoutOnClose: Boolean = true, block: suspend CoroutineScope.(CryptoTestHelper, CommonTestHelper) -> Unit) { internal fun runCryptoTest(context: Context, cryptoConfig: MXCryptoConfig? = null, autoSignoutOnClose: Boolean = true, block: suspend CoroutineScope.(CryptoTestHelper, CommonTestHelper) -> Unit) {
val testHelper = CommonTestHelper(context, cryptoConfig) val testHelper = CommonTestHelper(context, cryptoConfig)
val cryptoTestHelper = CryptoTestHelper(testHelper) val cryptoTestHelper = CryptoTestHelper(testHelper)
return try { return try {
@ -209,18 +210,28 @@ class CommonTestHelper internal constructor(context: Context, val cryptoConfig:
} }
}) })
return messageSent.await() return messageSent.await()
// return withTimeout(TestConstants.timeOutMillis) { messageSent.await() } // return withTimeout(TestConstants.timeOutMillis) { messageSent.await() }
} }
suspend fun ensureMessage(room: Room, eventId: String, block: ((event: TimelineEvent) -> Boolean)) { suspend fun ensureMessage(room: Room, eventId: String, block: ((event: TimelineEvent) -> Boolean)) {
Log.v("#E2E TEST", "ensureMessage room:${room.roomId} <$eventId>") Log.v("#E2E TEST", "ensureMessage room:${room.roomId} <$eventId>")
val timeline = room.timelineService().createTimeline(null, TimelineSettings(60)) val timeline = room.timelineService().createTimeline(null, TimelineSettings(60, buildReadReceipts = false))
// check if not already there?
val existing = withContext(Dispatchers.Main) {
room.getTimelineEvent(eventId)
}
if (existing != null && block(existing)) return Unit.also {
Log.v("#E2E TEST", "Already received")
}
val messageSent = CompletableDeferred<Unit>() val messageSent = CompletableDeferred<Unit>()
timeline.addListener(object : Timeline.Listener { timeline.addListener(object : Timeline.Listener {
override fun onNewTimelineEvents(eventIds: List<String>) { override fun onNewTimelineEvents(eventIds: List<String>) {
Log.v("#E2E TEST", "onNewTimelineEvents snapshot is $eventIds") Log.v("#E2E TEST", "onNewTimelineEvents snapshot is $eventIds")
} }
override fun onTimelineUpdated(snapshot: List<TimelineEvent>) { override fun onTimelineUpdated(snapshot: List<TimelineEvent>) {
val success = timeline.getSnapshot() val success = timeline.getSnapshot()
// .filter { it.root.getClearType() == EventType.MESSAGE } // .filter { it.root.getClearType() == EventType.MESSAGE }
@ -243,13 +254,13 @@ class CommonTestHelper internal constructor(context: Context, val cryptoConfig:
timeline.start() timeline.start()
return messageSent.await() return messageSent.await()
// withTimeout(TestConstants.timeOutMillis) { // withTimeout(TestConstants.timeOutMillis) {
// messageSent.await() // messageSent.await()
// } // }
} }
fun ensureMessagePromise(room: Room, eventId: String, block: ((event: TimelineEvent) -> Boolean)): CompletableDeferred<Unit> { fun ensureMessagePromise(room: Room, eventId: String, block: ((event: TimelineEvent) -> Boolean)): CompletableDeferred<Unit> {
val timeline = room.timelineService().createTimeline(null, TimelineSettings(60)) val timeline = room.timelineService().createTimeline(null, TimelineSettings(60))
timeline.start() timeline.start()
val messageSent = CompletableDeferred<Unit>() val messageSent = CompletableDeferred<Unit>()
@ -334,11 +345,11 @@ class CommonTestHelper internal constructor(context: Context, val cryptoConfig:
} }
suspend fun waitForAndAcceptInviteInRoom(otherSession: Session, roomID: String) { suspend fun waitForAndAcceptInviteInRoom(otherSession: Session, roomID: String) {
retryPeriodically { retryWithBackoff {
val roomSummary = otherSession.getRoomSummary(roomID) val roomSummary = otherSession.getRoomSummary(roomID)
(roomSummary != null && roomSummary.membership == Membership.INVITE).also { (roomSummary != null && roomSummary.membership == Membership.INVITE).also {
if (it) { if (it) {
Log.v("# TEST", "${otherSession.myUserId} can see the invite") Log.v("#E2E TEST", "${otherSession.myUserId} can see the invite")
} }
} }
} }
@ -354,7 +365,7 @@ class CommonTestHelper internal constructor(context: Context, val cryptoConfig:
} }
Log.v("#E2E TEST", "${otherSession.myUserId} waiting for join echo ...") Log.v("#E2E TEST", "${otherSession.myUserId} waiting for join echo ...")
retryPeriodically { retryWithBackoff {
val roomSummary = otherSession.getRoomSummary(roomID) val roomSummary = otherSession.getRoomSummary(roomID)
roomSummary != null && roomSummary.membership == Membership.JOIN roomSummary != null && roomSummary.membership == Membership.JOIN
} }

View File

@ -136,7 +136,9 @@ class CryptoTestHelper(val testHelper: CommonTestHelper) {
suspend fun inviteNewUsersAndWaitForThemToJoin(session: Session, roomId: String, usernames: List<String>): List<Session> { suspend fun inviteNewUsersAndWaitForThemToJoin(session: Session, roomId: String, usernames: List<String>): List<Session> {
val newSessions = usernames.map { username -> val newSessions = usernames.map { username ->
testHelper.createAccount(username, SessionTestParams(true)).also { testHelper.createAccount(username, SessionTestParams(true)).also {
it.cryptoService().enableKeyGossiping(false) if (it.cryptoService().supportsDisablingKeyGossiping()) {
it.cryptoService().enableKeyGossiping(false)
}
} }
} }
@ -560,7 +562,7 @@ class CryptoTestHelper(val testHelper: CommonTestHelper) {
} catch (error: MXCryptoError) { } catch (error: MXCryptoError) {
// nop // nop
} }
Log.v("TEST", "ensureCanDecrypt ${event.getClearType()} is ${event.getClearContent()}") Log.v("#E2E TEST", "ensureCanDecrypt ${event.getClearType()} is ${event.getClearContent()}")
event.getClearType() == EventType.MESSAGE && event.getClearType() == EventType.MESSAGE &&
messagesText[index] == event.getClearContent()?.toModel<MessageContent>()?.body messagesText[index] == event.getClearContent()?.toModel<MessageContent>()?.body
} }

View File

@ -20,6 +20,7 @@ import android.util.Log
import androidx.test.filters.LargeTest import androidx.test.filters.LargeTest
import org.amshove.kluent.internal.assertEquals import org.amshove.kluent.internal.assertEquals
import org.junit.Assert import org.junit.Assert
import org.junit.Assume
import org.junit.FixMethodOrder import org.junit.FixMethodOrder
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@ -28,6 +29,7 @@ import org.junit.runners.MethodSorters
import org.matrix.android.sdk.InstrumentedTest import org.matrix.android.sdk.InstrumentedTest
import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.getRoom import org.matrix.android.sdk.api.session.getRoom
import org.matrix.android.sdk.api.session.room.getTimelineEvent
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
@ -58,15 +60,15 @@ class E2EShareKeysConfigTest : InstrumentedTest {
enableEncryption() enableEncryption()
}) })
commonTestHelper.retryPeriodically { commonTestHelper.retryWithBackoff {
aliceSession.roomService().getRoomSummary(roomId)?.isEncrypted == true aliceSession.roomService().getRoomSummary(roomId)?.isEncrypted == true
} }
val roomAlice = aliceSession.roomService().getRoom(roomId)!! val roomAlice = aliceSession.roomService().getRoom(roomId)!!
// send some messages // send some messages
val withSession1 = commonTestHelper.sendTextMessage(roomAlice, "Hello", 1) val withSession1 = commonTestHelper.sendMessageInRoom(roomAlice, "Hello")
aliceSession.cryptoService().discardOutboundSession(roomId) aliceSession.cryptoService().discardOutboundSession(roomId)
val withSession2 = commonTestHelper.sendTextMessage(roomAlice, "World", 1) val withSession2 = commonTestHelper.sendMessageInRoom(roomAlice, "World")
// Create bob account // Create bob account
val bobSession = commonTestHelper.createAccount(TestConstants.USER_BOB, SessionTestParams(withInitialSync = true)) val bobSession = commonTestHelper.createAccount(TestConstants.USER_BOB, SessionTestParams(withInitialSync = true))
@ -78,7 +80,7 @@ class E2EShareKeysConfigTest : InstrumentedTest {
// Bob has join but should not be able to decrypt history // Bob has join but should not be able to decrypt history
cryptoTestHelper.ensureCannotDecrypt( cryptoTestHelper.ensureCannotDecrypt(
withSession1.map { it.eventId } + withSession2.map { it.eventId }, listOf(withSession1, withSession2),
bobSession, bobSession,
roomId roomId
) )
@ -86,44 +88,53 @@ class E2EShareKeysConfigTest : InstrumentedTest {
// We don't need bob anymore // We don't need bob anymore
commonTestHelper.signOutAndClose(bobSession) commonTestHelper.signOutAndClose(bobSession)
// Now let's enable history key sharing on alice side if (aliceSession.cryptoService().supportsShareKeysOnInvite()) {
aliceSession.cryptoService().enableShareKeyOnInvite(true) // Now let's enable history key sharing on alice side
aliceSession.cryptoService().enableShareKeyOnInvite(true)
// let's add a new message first // let's add a new message first
val afterFlagOn = commonTestHelper.sendTextMessage(roomAlice, "After", 1) val afterFlagOn = commonTestHelper.sendMessageInRoom(roomAlice, "After")
// Worth nothing to check that the session was rotated // Worth nothing to check that the session was rotated
Assert.assertNotEquals( Assert.assertNotEquals(
"Session should have been rotated", "Session should have been rotated",
withSession2.first().root.content?.get("session_id")!!, aliceSession.roomService().getRoom(roomId)?.getTimelineEvent(withSession1)?.root?.content?.get("session_id")!!,
afterFlagOn.first().root.content?.get("session_id")!! aliceSession.roomService().getRoom(roomId)?.getTimelineEvent(afterFlagOn)?.root?.content?.get("session_id")!!
) )
// Invite a new user // Invite a new user
val samSession = commonTestHelper.createAccount(TestConstants.USER_SAM, SessionTestParams(withInitialSync = true)) val samSession = commonTestHelper.createAccount(TestConstants.USER_SAM, SessionTestParams(withInitialSync = true))
// Let alice invite sam // Let alice invite sam
roomAlice.membershipService().invite(samSession.myUserId) roomAlice.membershipService().invite(samSession.myUserId)
commonTestHelper.waitForAndAcceptInviteInRoom(samSession, roomId) commonTestHelper.waitForAndAcceptInviteInRoom(samSession, roomId)
// Sam shouldn't be able to decrypt messages with the first session, but should decrypt the one with 3rd session // Sam shouldn't be able to decrypt messages with the first session, but should decrypt the one with 3rd session
cryptoTestHelper.ensureCannotDecrypt( cryptoTestHelper.ensureCannotDecrypt(
withSession1.map { it.eventId } + withSession2.map { it.eventId }, listOf(withSession1, withSession2),
samSession, samSession,
roomId roomId
) )
cryptoTestHelper.ensureCanDecrypt( cryptoTestHelper.ensureCanDecrypt(
afterFlagOn.map { it.eventId }, listOf(afterFlagOn),
samSession, samSession,
roomId, roomId,
afterFlagOn.map { it.root.getClearContent()?.get("body") as String }) listOf(aliceSession.roomService().getRoom(roomId)?.getTimelineEvent(afterFlagOn)?.root?.getClearContent()?.get("body") as String)
)
}
} }
@Test @Test
fun ifSharingDisabledOnAliceSideBobShouldNotShareAliceHistory() = runCryptoTest(context()) { cryptoTestHelper, commonTestHelper -> fun ifSharingDisabledOnAliceSideBobShouldNotShareAliceHistory() = runCryptoTest(context()) { cryptoTestHelper, commonTestHelper ->
val testData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(roomHistoryVisibility = RoomHistoryVisibility.SHARED) val testData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(roomHistoryVisibility = RoomHistoryVisibility.SHARED)
Assume.assumeTrue("Shared key on invite needed to test this",
testData.firstSession.cryptoService().supportsShareKeysOnInvite()
)
val aliceSession = testData.firstSession.also { val aliceSession = testData.firstSession.also {
it.cryptoService().enableShareKeyOnInvite(false) it.cryptoService().enableShareKeyOnInvite(false)
} }
@ -151,6 +162,11 @@ class E2EShareKeysConfigTest : InstrumentedTest {
@Test @Test
fun ifSharingEnabledOnAliceSideBobShouldShareAliceHistory() = runCryptoTest(context()) { cryptoTestHelper, commonTestHelper -> fun ifSharingEnabledOnAliceSideBobShouldShareAliceHistory() = runCryptoTest(context()) { cryptoTestHelper, commonTestHelper ->
val testData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(roomHistoryVisibility = RoomHistoryVisibility.SHARED) val testData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(roomHistoryVisibility = RoomHistoryVisibility.SHARED)
Assume.assumeTrue("Shared key on invite needed to test this",
testData.firstSession.cryptoService().supportsShareKeysOnInvite()
)
val aliceSession = testData.firstSession.also { val aliceSession = testData.firstSession.also {
it.cryptoService().enableShareKeyOnInvite(true) it.cryptoService().enableShareKeyOnInvite(true)
} }
@ -193,6 +209,11 @@ class E2EShareKeysConfigTest : InstrumentedTest {
@Test @Test
fun testBackupFlagIsCorrect() = runCryptoTest(context()) { cryptoTestHelper, commonTestHelper -> fun testBackupFlagIsCorrect() = runCryptoTest(context()) { cryptoTestHelper, commonTestHelper ->
val aliceSession = commonTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(withInitialSync = true)) val aliceSession = commonTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(withInitialSync = true))
Assume.assumeTrue("Shared key on invite needed to test this",
aliceSession.cryptoService().supportsShareKeysOnInvite()
)
aliceSession.cryptoService().enableShareKeyOnInvite(false) aliceSession.cryptoService().enableShareKeyOnInvite(false)
val roomId = aliceSession.roomService().createRoom(CreateRoomParams().apply { val roomId = aliceSession.roomService().createRoom(CreateRoomParams().apply {
historyVisibility = RoomHistoryVisibility.SHARED historyVisibility = RoomHistoryVisibility.SHARED
@ -206,9 +227,10 @@ class E2EShareKeysConfigTest : InstrumentedTest {
val roomAlice = aliceSession.roomService().getRoom(roomId)!! val roomAlice = aliceSession.roomService().getRoom(roomId)!!
// send some messages // send some messages
val notSharableMessage = commonTestHelper.sendTextMessage(roomAlice, "Hello", 1) val notSharableMessage = commonTestHelper.sendMessageInRoom(roomAlice, "Hello")
aliceSession.cryptoService().enableShareKeyOnInvite(true) aliceSession.cryptoService().enableShareKeyOnInvite(true)
val sharableMessage = commonTestHelper.sendTextMessage(roomAlice, "World", 1) val sharableMessage = commonTestHelper.sendMessageInRoom(roomAlice, "World")
Log.v("#E2E TEST", "Create and start key backup for bob ...") Log.v("#E2E TEST", "Create and start key backup for bob ...")
val keysBackupService = aliceSession.cryptoService().keysBackupService() val keysBackupService = aliceSession.cryptoService().keysBackupService()
@ -224,6 +246,7 @@ class E2EShareKeysConfigTest : InstrumentedTest {
commonTestHelper.signOutAndClose(aliceSession) commonTestHelper.signOutAndClose(aliceSession)
val newAliceSession = commonTestHelper.logIntoAccount(aliceSession.myUserId, SessionTestParams(true)) val newAliceSession = commonTestHelper.logIntoAccount(aliceSession.myUserId, SessionTestParams(true))
newAliceSession.cryptoService().enableShareKeyOnInvite(true) newAliceSession.cryptoService().enableShareKeyOnInvite(true)
newAliceSession.cryptoService().keysBackupService().let { kbs -> newAliceSession.cryptoService().keysBackupService().let { kbs ->
@ -251,15 +274,16 @@ class E2EShareKeysConfigTest : InstrumentedTest {
// Sam shouldn't be able to decrypt messages with the first session, but should decrypt the one with 3rd session // Sam shouldn't be able to decrypt messages with the first session, but should decrypt the one with 3rd session
cryptoTestHelper.ensureCannotDecrypt( cryptoTestHelper.ensureCannotDecrypt(
notSharableMessage.map { it.eventId }, listOf(notSharableMessage),
samSession, samSession,
roomId roomId
) )
cryptoTestHelper.ensureCanDecrypt( cryptoTestHelper.ensureCanDecrypt(
sharableMessage.map { it.eventId }, listOf(sharableMessage),
samSession, samSession,
roomId, roomId,
sharableMessage.map { it.root.getClearContent()?.get("body") as String }) listOf(roomAlice.getTimelineEvent(sharableMessage)?.root?.getClearContent()?.get("body") as String)
)
} }
} }

View File

@ -53,15 +53,13 @@ class E2eeConfigTest : InstrumentedTest {
val roomAlicePOV = cryptoTestData.firstSession.roomService().getRoom(cryptoTestData.roomId)!! val roomAlicePOV = cryptoTestData.firstSession.roomService().getRoom(cryptoTestData.roomId)!!
val sentMessage = testHelper.sendTextMessage(roomAlicePOV, "you are blocked", 1).first() val sentMessage = testHelper.sendMessageInRoom(roomAlicePOV, "you are blocked")
val roomBobPOV = cryptoTestData.secondSession!!.roomService().getRoom(cryptoTestData.roomId)!! val roomBobPOV = cryptoTestData.secondSession!!.roomService().getRoom(cryptoTestData.roomId)!!
// ensure other received // ensure other received
testHelper.retryPeriodically { testHelper.ensureMessage(roomBobPOV, sentMessage) { true }
roomBobPOV.timelineService().getTimelineEvent(sentMessage.eventId) != null
}
cryptoTestHelper.ensureCannotDecrypt(listOf(sentMessage.eventId), cryptoTestData.secondSession!!, cryptoTestData.roomId) cryptoTestHelper.ensureCannotDecrypt(listOf(sentMessage), cryptoTestData.secondSession!!, cryptoTestData.roomId)
} }
@Test @Test
@ -77,19 +75,20 @@ class E2eeConfigTest : InstrumentedTest {
val roomAlicePOV = cryptoTestData.firstSession.roomService().getRoom(cryptoTestData.roomId)!! val roomAlicePOV = cryptoTestData.firstSession.roomService().getRoom(cryptoTestData.roomId)!!
val sentMessage = testHelper.sendTextMessage(roomAlicePOV, "you can read", 1).first() val sentMessage = testHelper.sendMessageInRoom(roomAlicePOV, "you can read")
val roomBobPOV = cryptoTestData.secondSession!!.roomService().getRoom(cryptoTestData.roomId)!! val roomBobPOV = cryptoTestData.secondSession!!.roomService().getRoom(cryptoTestData.roomId)!!
// ensure other received // ensure other received
testHelper.retryPeriodically {
roomBobPOV.timelineService().getTimelineEvent(sentMessage.eventId) != null testHelper.ensureMessage(roomBobPOV, sentMessage) { true }
}
cryptoTestHelper.ensureCanDecrypt( cryptoTestHelper.ensureCanDecrypt(
listOf(sentMessage.eventId), listOf(sentMessage),
cryptoTestData.secondSession!!, cryptoTestData.secondSession!!,
cryptoTestData.roomId, cryptoTestData.roomId,
listOf(sentMessage.getLastMessageContent()!!.body) listOf(
roomBobPOV.timelineService().getTimelineEvent(sentMessage)?.getLastMessageContent()!!.body
)
) )
} }

View File

@ -75,8 +75,12 @@ class E2eeSanityTests : InstrumentedTest {
val e2eRoomID = cryptoTestData.roomId val e2eRoomID = cryptoTestData.roomId
val aliceRoomPOV = aliceSession.getRoom(e2eRoomID)!! val aliceRoomPOV = aliceSession.getRoom(e2eRoomID)!!
// we want to disable key gossiping to just check initial sending of keys // we want to disable key gossiping to just check initial sending of keys
aliceSession.cryptoService().enableKeyGossiping(false) if (aliceSession.cryptoService().supportsDisablingKeyGossiping()) {
cryptoTestData.secondSession?.cryptoService()?.enableKeyGossiping(false) aliceSession.cryptoService().enableKeyGossiping(false)
}
if (cryptoTestData.secondSession?.cryptoService()?.supportsDisablingKeyGossiping() == true) {
cryptoTestData.secondSession?.cryptoService()?.enableKeyGossiping(false)
}
// add some more users and invite them // add some more users and invite them
val otherAccounts = listOf("benoit", "valere", "ganfra") // , "adam", "manu") val otherAccounts = listOf("benoit", "valere", "ganfra") // , "adam", "manu")

View File

@ -22,6 +22,7 @@ import org.amshove.kluent.fail
import org.amshove.kluent.internal.assertEquals import org.amshove.kluent.internal.assertEquals
import org.amshove.kluent.internal.assertNotEquals import org.amshove.kluent.internal.assertNotEquals
import org.junit.Assert import org.junit.Assert
import org.junit.Assume
import org.junit.FixMethodOrder import org.junit.FixMethodOrder
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@ -79,9 +80,9 @@ class E2eeShareKeysHistoryTest : InstrumentedTest {
runCryptoTest(context()) { cryptoTestHelper, testHelper -> runCryptoTest(context()) { cryptoTestHelper, testHelper ->
val aliceMessageText = "Hello Bob, I am Alice!" val aliceMessageText = "Hello Bob, I am Alice!"
val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(true, roomHistoryVisibility) val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(true, roomHistoryVisibility)
val e2eRoomID = cryptoTestData.roomId val e2eRoomID = cryptoTestData.roomId
Assume.assumeTrue(cryptoTestData.firstSession.cryptoService().supportsShareKeysOnInvite())
// Alice // Alice
val aliceSession = cryptoTestData.firstSession.also { val aliceSession = cryptoTestData.firstSession.also {
it.cryptoService().enableShareKeyOnInvite(true) it.cryptoService().enableShareKeyOnInvite(true)
@ -251,6 +252,8 @@ class E2eeShareKeysHistoryTest : InstrumentedTest {
val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(true, initRoomHistoryVisibility) val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(true, initRoomHistoryVisibility)
val e2eRoomID = cryptoTestData.roomId val e2eRoomID = cryptoTestData.roomId
Assume.assumeTrue(cryptoTestData.firstSession.cryptoService().supportsShareKeysOnInvite())
// Alice // Alice
val aliceSession = cryptoTestData.firstSession.also { val aliceSession = cryptoTestData.firstSession.also {
it.cryptoService().enableShareKeyOnInvite(true) it.cryptoService().enableShareKeyOnInvite(true)

View File

@ -24,6 +24,7 @@ import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.junit.Assert.fail import org.junit.Assert.fail
import org.junit.Assume
import org.junit.FixMethodOrder import org.junit.FixMethodOrder
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@ -195,11 +196,15 @@ class XSigningTest : InstrumentedTest {
@Test @Test
fun testWarnOnCrossSigningReset() = runCryptoTest(context()) { cryptoTestHelper, testHelper -> fun testWarnOnCrossSigningReset() = runCryptoTest(context()) { cryptoTestHelper, testHelper ->
val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom() val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom()
val aliceSession = cryptoTestData.firstSession val aliceSession = cryptoTestData.firstSession
val bobSession = cryptoTestData.secondSession val bobSession = cryptoTestData.secondSession
// Remove when https://github.com/matrix-org/matrix-rust-sdk/issues/1129
Assume.assumeTrue("Not yet supported by rust", aliceSession.cryptoService().name() != "rust-sdk")
val aliceAuthParams = UserPasswordAuth( val aliceAuthParams = UserPasswordAuth(
user = aliceSession.myUserId, user = aliceSession.myUserId,
password = TestConstants.PASSWORD password = TestConstants.PASSWORD

View File

@ -25,6 +25,7 @@ import junit.framework.TestCase.assertTrue
import org.amshove.kluent.shouldBeEqualTo import org.amshove.kluent.shouldBeEqualTo
import org.junit.Assert import org.junit.Assert
import org.junit.Assert.assertNull import org.junit.Assert.assertNull
import org.junit.Assume
import org.junit.FixMethodOrder import org.junit.FixMethodOrder
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@ -59,6 +60,8 @@ class KeyShareTests : InstrumentedTest {
fun test_DoNotSelfShareIfNotTrusted() = runCryptoTest(context()) { cryptoTestHelper, commonTestHelper -> fun test_DoNotSelfShareIfNotTrusted() = runCryptoTest(context()) { cryptoTestHelper, commonTestHelper ->
val aliceSession = commonTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true)) val aliceSession = commonTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true))
Assume.assumeTrue("Not supported", aliceSession.cryptoService().supportKeyRequestInspection())
Log.v("#TEST", "=======> AliceSession 1 is ${aliceSession.sessionParams.deviceId}") Log.v("#TEST", "=======> AliceSession 1 is ${aliceSession.sessionParams.deviceId}")
// Create an encrypted room and add a message // Create an encrypted room and add a message
@ -70,8 +73,9 @@ class KeyShareTests : InstrumentedTest {
) )
val room = aliceSession.getRoom(roomId) val room = aliceSession.getRoom(roomId)
assertNotNull(room) assertNotNull(room)
Thread.sleep(4_000) commonTestHelper.retryWithBackoff {
assertTrue(room?.roomCryptoService()?.isEncrypted() == true) room?.roomCryptoService()?.isEncrypted() == true
}
val sentEvent = commonTestHelper.sendTextMessage(room!!, "My Message", 1).first() val sentEvent = commonTestHelper.sendTextMessage(room!!, "My Message", 1).first()
val sentEventId = sentEvent.eventId val sentEventId = sentEvent.eventId
@ -207,6 +211,9 @@ class KeyShareTests : InstrumentedTest {
val testData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(true) val testData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(true)
val aliceSession = testData.firstSession val aliceSession = testData.firstSession
Assume.assumeTrue("Not supported", aliceSession.cryptoService().supportKeyRequestInspection())
val roomFromAlice = aliceSession.getRoom(testData.roomId)!! val roomFromAlice = aliceSession.getRoom(testData.roomId)!!
val bobSession = testData.secondSession!! val bobSession = testData.secondSession!!
@ -239,6 +246,9 @@ class KeyShareTests : InstrumentedTest {
val testData = cryptoTestHelper.doE2ETestWithAliceInARoom(true) val testData = cryptoTestHelper.doE2ETestWithAliceInARoom(true)
val aliceSession = testData.firstSession val aliceSession = testData.firstSession
Assume.assumeTrue("Not supported", aliceSession.cryptoService().supportKeyRequestInspection())
val roomFromAlice = aliceSession.getRoom(testData.roomId)!! val roomFromAlice = aliceSession.getRoom(testData.roomId)!!
val aliceNewSession = commonTestHelper.logIntoAccount(aliceSession.myUserId, SessionTestParams(true)) val aliceNewSession = commonTestHelper.logIntoAccount(aliceSession.myUserId, SessionTestParams(true))
@ -274,6 +284,9 @@ class KeyShareTests : InstrumentedTest {
val testData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(true) val testData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(true)
val aliceSession = testData.firstSession val aliceSession = testData.firstSession
Assume.assumeTrue("Not supported", aliceSession.cryptoService().supportKeyRequestInspection())
val bobSession = testData.secondSession!! val bobSession = testData.secondSession!!
val roomFromBob = bobSession.getRoom(testData.roomId)!! val roomFromBob = bobSession.getRoom(testData.roomId)!!
@ -386,6 +399,9 @@ class KeyShareTests : InstrumentedTest {
) { cryptoTestHelper, commonTestHelper -> ) { cryptoTestHelper, commonTestHelper ->
val testData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(true) val testData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(true)
val aliceSession = testData.firstSession val aliceSession = testData.firstSession
Assume.assumeTrue("Not supported", aliceSession.cryptoService().supportKeyRequestInspection())
val bobSession = testData.secondSession!! val bobSession = testData.secondSession!!
val roomFromBob = bobSession.getRoom(testData.roomId)!! val roomFromBob = bobSession.getRoom(testData.roomId)!!

View File

@ -20,6 +20,7 @@ import android.util.Log
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest import androidx.test.filters.LargeTest
import org.junit.Assert import org.junit.Assert
import org.junit.Assume
import org.junit.FixMethodOrder import org.junit.FixMethodOrder
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -153,6 +154,7 @@ class WithHeldTests : InstrumentedTest {
val testData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom() val testData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom()
val aliceSession = testData.firstSession val aliceSession = testData.firstSession
Assume.assumeTrue("Not supported", aliceSession.cryptoService().supportKeyRequestInspection())
val bobSession = testData.secondSession!! val bobSession = testData.secondSession!!
val aliceInterceptor = testHelper.getTestInterceptor(aliceSession) val aliceInterceptor = testHelper.getTestInterceptor(aliceSession)
@ -222,6 +224,7 @@ class WithHeldTests : InstrumentedTest {
val testData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom() val testData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom()
val aliceSession = testData.firstSession val aliceSession = testData.firstSession
Assume.assumeTrue("Not supported by rust sdk", aliceSession.cryptoService().supportsForwardedKeyWiththeld())
val bobSession = testData.secondSession!! val bobSession = testData.secondSession!!
val roomAlicePov = aliceSession.getRoom(testData.roomId)!! val roomAlicePov = aliceSession.getRoom(testData.roomId)!!
@ -236,19 +239,9 @@ class WithHeldTests : InstrumentedTest {
// initialize to force request keys if missing // initialize to force request keys if missing
cryptoTestHelper.initializeCrossSigning(bobSecondSession) cryptoTestHelper.initializeCrossSigning(bobSecondSession)
// // wait until alice downloaded the new device // Trust bob second device from Alice POV
// testHelper.retryWithBackoff { aliceSession.cryptoService().crossSigningService().trustDevice(bobSecondSession.sessionParams.deviceId)
// aliceSession.cryptoService().getUserDevices(bobSession.myUserId).any { it.deviceId == bobSecondSession.sessionParams.deviceId} bobSecondSession.cryptoService().crossSigningService().trustDevice(aliceSession.sessionParams.deviceId)
// }
//
// // Trust bob second device from Alice POV
// aliceSession.cryptoService().crossSigningService().trustDevice(bobSecondSession.sessionParams.deviceId)
//
// // wait until bob downloaded alice device
// testHelper.retryWithBackoff {
// bobSecondSession.cryptoService().getUserDevices(aliceSession.myUserId).any { it.deviceId == aliceSession.sessionParams.deviceId}
// }
// bobSecondSession.cryptoService().crossSigningService().trustDevice(aliceSession.sessionParams.deviceId)
var sessionId: String? = null var sessionId: String? = null
// Check that the // Check that the
@ -264,18 +257,10 @@ class WithHeldTests : InstrumentedTest {
timeLineEvent != null timeLineEvent != null
} }
// Check that bob second session requested the key
mustFail( testHelper.retryPeriodically {
message = "This session should not be able to decrypt", val wc = bobSecondSession.cryptoService().getWithHeldMegolmSession(roomAlicePov.roomId, sessionId!!)
failureBlock = { failure -> wc?.code == WithHeldCode.UNAUTHORISED
val type = (failure as MXCryptoError.Base).errorType
val technicalMessage = failure.technicalMessage
Assert.assertEquals("Error should be withheld", MXCryptoError.ErrorType.KEYS_WITHHELD, type)
Assert.assertEquals("Cause should be unverified", WithHeldCode.UNVERIFIED.value, technicalMessage)
}
) {
val timeLineEvent = bobSecondSession.getRoom(testData.roomId)?.getTimelineEvent(eventId)
bobSecondSession.cryptoService().decryptEvent(timeLineEvent!!.root, "")
} }
// // Check that bob second session requested the key // // Check that bob second session requested the key
// testHelper.retryPeriodically { // testHelper.retryPeriodically {

View File

@ -21,6 +21,7 @@ import org.amshove.kluent.internal.assertFailsWith
import org.junit.Assert import org.junit.Assert
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.fail import org.junit.Assert.fail
import org.junit.Assume
import org.junit.FixMethodOrder import org.junit.FixMethodOrder
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@ -43,6 +44,9 @@ class ReplayAttackTest : InstrumentedTest {
// Alice // Alice
val aliceSession = cryptoTestData.firstSession val aliceSession = cryptoTestData.firstSession
// Until https://github.com/matrix-org/matrix-rust-sdk/issues/397
Assume.assumeTrue("Not yet supported by rust", cryptoTestData.firstSession.cryptoService().name() != "rust-sdk")
val aliceRoomPOV = aliceSession.roomService().getRoom(e2eRoomID)!! val aliceRoomPOV = aliceSession.roomService().getRoom(e2eRoomID)!!
// Bob // Bob

View File

@ -194,6 +194,15 @@ internal class DefaultCryptoService @Inject constructor(
private val isStarting = AtomicBoolean(false) private val isStarting = AtomicBoolean(false)
private val isStarted = AtomicBoolean(false) private val isStarted = AtomicBoolean(false)
override fun name() = "kotlin-sdk"
override fun supportsKeyWithheld() = true
override fun supportKeyRequestInspection() = true
override fun supportsDisablingKeyGossiping() = true
override fun supportsForwardedKeyWiththeld() = true
override suspend fun onStateEvent(roomId: String, event: Event, cryptoStoreAggregator: CryptoStoreAggregator?) { override suspend fun onStateEvent(roomId: String, event: Event, cryptoStoreAggregator: CryptoStoreAggregator?) {
when (event.type) { when (event.type) {
EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event) EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event)
@ -1395,7 +1404,7 @@ internal class DefaultCryptoService @Inject constructor(
throw IllegalArgumentException("Missing algorithm") throw IllegalArgumentException("Missing algorithm")
} }
(alg as? IMXGroupEncryption)?.preshareKey(userIds) (alg as? IMXGroupEncryption)?.preshareKey(userIds)
} }
} }

View File

@ -48,6 +48,7 @@ import org.matrix.android.sdk.internal.crypto.store.db.CryptoStoreAggregator
interface CryptoService { interface CryptoService {
fun name(): String
fun verificationService(): VerificationService fun verificationService(): VerificationService
fun crossSigningService(): CrossSigningService fun crossSigningService(): CrossSigningService
@ -80,6 +81,8 @@ interface CryptoService {
fun getLiveGlobalCryptoConfig(): LiveData<GlobalCryptoConfig> fun getLiveGlobalCryptoConfig(): LiveData<GlobalCryptoConfig>
fun supportsDisablingKeyGossiping(): Boolean
/** /**
* Enable or disable key gossiping. * Enable or disable key gossiping.
* Default is true. * Default is true.
@ -186,6 +189,8 @@ interface CryptoService {
fun addNewSessionListener(newSessionListener: NewSessionListener) fun addNewSessionListener(newSessionListener: NewSessionListener)
fun removeSessionListener(listener: NewSessionListener) fun removeSessionListener(listener: NewSessionListener)
fun supportKeyRequestInspection(): Boolean
fun getOutgoingRoomKeyRequests(): List<OutgoingKeyRequest> fun getOutgoingRoomKeyRequests(): List<OutgoingKeyRequest>
fun getOutgoingRoomKeyRequestsPaged(): LiveData<PagedList<OutgoingKeyRequest>> fun getOutgoingRoomKeyRequestsPaged(): LiveData<PagedList<OutgoingKeyRequest>>

View File

@ -28,4 +28,3 @@ internal class MigrateSessionTo052(realm: DynamicRealm) : RealmMigrator(realm, 5
?.setNullable(EventEntityFields.IS_VERIFICATION_STATE_DIRTY, true) ?.setNullable(EventEntityFields.IS_VERIFICATION_STATE_DIRTY, true)
} }
} }

View File

@ -43,6 +43,8 @@ import org.matrix.android.sdk.api.session.crypto.model.UnsignedDeviceInfo
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction
import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Content
import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.toContent
import org.matrix.android.sdk.api.session.sync.model.DeviceListResponse import org.matrix.android.sdk.api.session.sync.model.DeviceListResponse
import org.matrix.android.sdk.api.session.sync.model.DeviceOneTimeKeysCountSyncResponse import org.matrix.android.sdk.api.session.sync.model.DeviceOneTimeKeysCountSyncResponse
import org.matrix.android.sdk.api.session.sync.model.ToDeviceSyncResponse import org.matrix.android.sdk.api.session.sync.model.ToDeviceSyncResponse
@ -439,6 +441,19 @@ internal class OlmMachine @Inject constructor(
if (event.roomId.isNullOrBlank()) { if (event.roomId.isNullOrBlank()) {
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON) throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON)
} }
if (event.isRedacted()) {
// we shouldn't attempt to decrypt a redacted event because the content is cleared and decryption will fail because of null algorithm
// Workaround until https://github.com/matrix-org/matrix-rust-sdk/issues/1642
return@withContext MXEventDecryptionResult(
clearEvent = mapOf(
"room_id" to event.roomId,
"type" to EventType.MESSAGE,
"content" to emptyMap<String, Any>(),
"unsigned" to event.unsignedData.toContent()
)
)
}
val serializedEvent = adapter.toJson(event) val serializedEvent = adapter.toJson(event)
val decrypted = inner.decryptRoomEvent(serializedEvent, event.roomId, false, false) val decrypted = inner.decryptRoomEvent(serializedEvent, event.roomId, false, false)
@ -493,7 +508,7 @@ internal class OlmMachine @Inject constructor(
ShieldColor.RED -> { ShieldColor.RED -> {
when (this.message) { when (this.message) {
"Encrypted by an unverified device." -> MessageVerificationState.UN_SIGNED_DEVICE "Encrypted by an unverified device." -> MessageVerificationState.UN_SIGNED_DEVICE
"Encrypted by a device not verified by its owner." -> MessageVerificationState.UN_SIGNED_DEVICE_OF_VERIFIED_USER "Encrypted by a device not verified by its owner." -> MessageVerificationState.UN_SIGNED_DEVICE
"Encrypted by an unknown or deleted device." -> MessageVerificationState.UNKNOWN_DEVICE "Encrypted by an unknown or deleted device." -> MessageVerificationState.UNKNOWN_DEVICE
else -> MessageVerificationState.UN_SIGNED_DEVICE else -> MessageVerificationState.UN_SIGNED_DEVICE
} }

View File

@ -53,7 +53,6 @@ import org.matrix.android.sdk.api.session.crypto.model.IncomingRoomKeyRequest
import org.matrix.android.sdk.api.session.crypto.model.MXEncryptEventContentResult import org.matrix.android.sdk.api.session.crypto.model.MXEncryptEventContentResult
import org.matrix.android.sdk.api.session.crypto.model.MXEventDecryptionResult import org.matrix.android.sdk.api.session.crypto.model.MXEventDecryptionResult
import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap
import org.matrix.android.sdk.api.session.crypto.model.TrailType
import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Content
import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.EventType
@ -141,6 +140,8 @@ internal class RustCryptoService @Inject constructor(
private val isStarting = AtomicBoolean(false) private val isStarting = AtomicBoolean(false)
private val isStarted = AtomicBoolean(false) private val isStarted = AtomicBoolean(false)
override fun name() = "rust-sdk"
override suspend fun onStateEvent(roomId: String, event: Event, cryptoStoreAggregator: CryptoStoreAggregator?) { override suspend fun onStateEvent(roomId: String, event: Event, cryptoStoreAggregator: CryptoStoreAggregator?) {
when (event.type) { when (event.type) {
EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event) EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event)
@ -510,8 +511,8 @@ internal class RustCryptoService @Inject constructor(
// } catch (throwable: Throwable) { // } catch (throwable: Throwable) {
// Timber.e(throwable, "## CRYPTO | onRoomEncryptionEvent ERROR FAILED TO SETUP CRYPTO ") // Timber.e(throwable, "## CRYPTO | onRoomEncryptionEvent ERROR FAILED TO SETUP CRYPTO ")
// } finally { // } finally {
val userIds = getRoomUserIds(roomId) val userIds = getRoomUserIds(roomId)
setEncryptionInRoom(roomId, event.content?.toModel<EncryptionEventContent>(), userIds) setEncryptionInRoom(roomId, event.content?.toModel<EncryptionEventContent>(), userIds)
// } // }
// } // }
} }
@ -559,7 +560,7 @@ internal class RustCryptoService @Inject constructor(
// know what other servers are in the room at the time they've been invited. // know what other servers are in the room at the time they've been invited.
// They therefore will not send device updates if a user logs in whilst // They therefore will not send device updates if a user logs in whilst
// their state is invite. // their state is invite.
olmMachine.updateTrackedUsers(listOf(userId)) olmMachine.updateTrackedUsers(listOf(userId))
} else { } else {
// nop // nop
} }
@ -651,8 +652,8 @@ internal class RustCryptoService @Inject constructor(
this.verificationService.onEvent(null, event) this.verificationService.onEvent(null, event)
} }
} }
liveEventManager.get().dispatchOnLiveToDevice(event) liveEventManager.get().dispatchOnLiveToDevice(event)
} }
} }
/** /**
@ -717,12 +718,14 @@ internal class RustCryptoService @Inject constructor(
return cryptoStore.getLiveGlobalCryptoConfig() return cryptoStore.getLiveGlobalCryptoConfig()
} }
// Until https://github.com/matrix-org/matrix-rust-sdk/issues/1364
override fun supportsDisablingKeyGossiping() = false
override fun enableKeyGossiping(enable: Boolean) { override fun enableKeyGossiping(enable: Boolean) {
cryptoStore.enableKeyGossiping(enable) if (!enable) throw UnsupportedOperationException("Not supported by rust")
} }
override fun isKeyGossipingEnabled(): Boolean { override fun isKeyGossipingEnabled(): Boolean {
return cryptoStore.isKeyGossipingEnabled() return true
} }
override fun supportsShareKeysOnInvite() = false override fun supportsShareKeysOnInvite() = false
@ -730,10 +733,9 @@ internal class RustCryptoService @Inject constructor(
override fun supportsKeyWithheld() = true override fun supportsKeyWithheld() = true
override fun supportsForwardedKeyWiththeld() = false override fun supportsForwardedKeyWiththeld() = false
override fun enableShareKeyOnInvite(enable: Boolean) { override fun enableShareKeyOnInvite(enable: Boolean) {
if (enable && !supportsShareKeysOnInvite()) { if (enable && !supportsShareKeysOnInvite()) {
throw java.lang.UnsupportedOperationException("Enable share key on invite not implemented in rust"); throw java.lang.UnsupportedOperationException("Enable share key on invite not implemented in rust")
} }
} }
@ -844,19 +846,20 @@ internal class RustCryptoService @Inject constructor(
return "DefaultCryptoService of $myUserId ($deviceId)" return "DefaultCryptoService of $myUserId ($deviceId)"
} }
// Until https://github.com/matrix-org/matrix-rust-sdk/issues/701
// https://github.com/matrix-org/matrix-rust-sdk/issues/702
override fun supportKeyRequestInspection() = false
override fun getOutgoingRoomKeyRequests(): List<OutgoingKeyRequest> { override fun getOutgoingRoomKeyRequests(): List<OutgoingKeyRequest> {
return cryptoStore.getOutgoingRoomKeyRequests() throw UnsupportedOperationException("Not supported by rust")
} }
override fun getOutgoingRoomKeyRequestsPaged(): LiveData<PagedList<OutgoingKeyRequest>> { override fun getOutgoingRoomKeyRequestsPaged(): LiveData<PagedList<OutgoingKeyRequest>> {
return cryptoStore.getOutgoingRoomKeyRequestsPaged() throw UnsupportedOperationException("Not supported by rust")
// return cryptoStore.getOutgoingRoomKeyRequestsPaged()
} }
override fun getIncomingRoomKeyRequestsPaged(): LiveData<PagedList<IncomingRoomKeyRequest>> { override fun getIncomingRoomKeyRequestsPaged(): LiveData<PagedList<IncomingRoomKeyRequest>> {
return cryptoStore.getGossipingEventsTrail(TrailType.IncomingKeyRequest) { throw UnsupportedOperationException("Not supported by rust")
IncomingRoomKeyRequest.fromEvent(it)
?: IncomingRoomKeyRequest(localCreationTimestamp = 0L)
}
} }
override suspend fun manuallyAcceptRoomKeyRequest(request: IncomingRoomKeyRequest) { override suspend fun manuallyAcceptRoomKeyRequest(request: IncomingRoomKeyRequest) {
@ -864,25 +867,23 @@ internal class RustCryptoService @Inject constructor(
} }
override fun getIncomingRoomKeyRequests(): List<IncomingRoomKeyRequest> { override fun getIncomingRoomKeyRequests(): List<IncomingRoomKeyRequest> {
return emptyList() throw UnsupportedOperationException("Not supported by rust")
} }
override fun getGossipingEventsTrail(): LiveData<PagedList<AuditTrail>> { override fun getGossipingEventsTrail(): LiveData<PagedList<AuditTrail>> {
return cryptoStore.getGossipingEventsTrail() throw UnsupportedOperationException("Not supported by rust")
} }
override fun getGossipingEvents(): List<AuditTrail> { override fun getGossipingEvents(): List<AuditTrail> {
return cryptoStore.getGossipingEvents() throw UnsupportedOperationException("Not supported by rust")
} }
override fun getSharedWithInfo(roomId: String?, sessionId: String): MXUsersDevicesMap<Int> { override fun getSharedWithInfo(roomId: String?, sessionId: String): MXUsersDevicesMap<Int> {
// TODO not exposed in rust? throw UnsupportedOperationException("Not supported by rust")
return cryptoStore.getSharedWithInfo(roomId, sessionId)
} }
override fun getWithHeldMegolmSession(roomId: String, sessionId: String): RoomKeyWithHeldContent? { override fun getWithHeldMegolmSession(roomId: String, sessionId: String): RoomKeyWithHeldContent? {
// TODO not exposed in rust. throw UnsupportedOperationException("Not supported by rust")
return cryptoStore.getWithHeldMegolmSession(roomId, sessionId)
} }
override fun logDbUsageInfo() { override fun logDbUsageInfo() {

View File

@ -242,6 +242,9 @@ class BugReporter @Inject constructor(
activeSessionHolder.getSafeActiveSession() activeSessionHolder.getSafeActiveSession()
?.takeIf { !mIsCancelled && withKeyRequestHistory } ?.takeIf { !mIsCancelled && withKeyRequestHistory }
?.cryptoService() ?.cryptoService()
?.takeIf {
it.supportKeyRequestInspection()
}
?.getGossipingEvents() ?.getGossipingEvents()
?.let { GossipingEventsSerializer().serialize(it) } ?.let { GossipingEventsSerializer().serialize(it) }
?.toByteArray() ?.toByteArray()

View File

@ -187,6 +187,7 @@ class VectorPreferences @Inject constructor(
const val SETTINGS_PREF_SPACE_CATEGORY = "SETTINGS_PREF_SPACE_CATEGORY" const val SETTINGS_PREF_SPACE_CATEGORY = "SETTINGS_PREF_SPACE_CATEGORY"
private const val SETTINGS_DEVELOPER_MODE_PREFERENCE_KEY = "SETTINGS_DEVELOPER_MODE_PREFERENCE_KEY" private const val SETTINGS_DEVELOPER_MODE_PREFERENCE_KEY = "SETTINGS_DEVELOPER_MODE_PREFERENCE_KEY"
const val SETTINGS_DEVELOPER_MODE_KEY_REQUEST_AUDIT_KEY = "SETTINGS_DEVELOPER_MODE_KEY_REQUEST_AUDIT_KEY"
private const val SETTINGS_LABS_SHOW_HIDDEN_EVENTS_PREFERENCE_KEY = "SETTINGS_LABS_SHOW_HIDDEN_EVENTS_PREFERENCE_KEY" private const val SETTINGS_LABS_SHOW_HIDDEN_EVENTS_PREFERENCE_KEY = "SETTINGS_LABS_SHOW_HIDDEN_EVENTS_PREFERENCE_KEY"
private const val SETTINGS_LABS_ENABLE_SWIPE_TO_REPLY = "SETTINGS_LABS_ENABLE_SWIPE_TO_REPLY" private const val SETTINGS_LABS_ENABLE_SWIPE_TO_REPLY = "SETTINGS_LABS_ENABLE_SWIPE_TO_REPLY"
private const val SETTINGS_DEVELOPER_MODE_FAIL_FAST_PREFERENCE_KEY = "SETTINGS_DEVELOPER_MODE_FAIL_FAST_PREFERENCE_KEY" private const val SETTINGS_DEVELOPER_MODE_FAIL_FAST_PREFERENCE_KEY = "SETTINGS_DEVELOPER_MODE_FAIL_FAST_PREFERENCE_KEY"

View File

@ -73,6 +73,10 @@ class VectorSettingsAdvancedSettingsFragment :
copyToClipboard(requireActivity(), session.sessionParams.credentials.accessToken) copyToClipboard(requireActivity(), session.sessionParams.credentials.accessToken)
true true
} }
findPreference<VectorPreference>(VectorPreferences.SETTINGS_DEVELOPER_MODE_KEY_REQUEST_AUDIT_KEY)?.apply {
isVisible = session.cryptoService().supportKeyRequestInspection()
}
} }
private fun setupRageShakeSection() { private fun setupRageShakeSection() {

View File

@ -52,11 +52,13 @@ class GossipingEventsPaperTrailViewModel @AssistedInject constructor(
setState { setState {
copy(events = Loading()) copy(events = Loading())
} }
session.cryptoService().getGossipingEventsTrail() if (session.cryptoService().supportKeyRequestInspection()) {
.asFlow() session.cryptoService().getGossipingEventsTrail()
.execute { .asFlow()
copy(events = it) .execute {
} copy(events = it)
}
}
} }
override fun handle(action: EmptyAction) {} override fun handle(action: EmptyAction) {}

View File

@ -90,6 +90,7 @@
<im.vector.app.core.preference.VectorPreference <im.vector.app.core.preference.VectorPreference
android:persistent="false" android:persistent="false"
android:key="SETTINGS_DEVELOPER_MODE_KEY_REQUEST_AUDIT_KEY"
android:title="@string/settings_key_requests" android:title="@string/settings_key_requests"
app:fragment="im.vector.app.features.settings.devtools.KeyRequestsFragment" /> app:fragment="im.vector.app.features.settings.devtools.KeyRequestsFragment" />