mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
Ignore some test in tust. Added some supports flags
This commit is contained in:
parent
238d10d4cb
commit
5f069264d0
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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")
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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)!!
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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>>
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
||||||
|
@ -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()
|
||||||
|
@ -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"
|
||||||
|
@ -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() {
|
||||||
|
@ -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) {}
|
||||||
|
@ -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" />
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user