diff --git a/.editorconfig b/.editorconfig
index 19a95806d3..0a49eadc0b 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -12,7 +12,7 @@ max_line_length=off
# Comma-separated list of rules to disable (Since 0.34.0)
# Note that rules in any ruleset other than the standard ruleset will need to be prefixed
# by the ruleset identifier.
-disabled_rules=no-wildcard-imports,no-multi-spaces,colon-spacing,chain-wrapping,import-ordering,experimental:annotation
+disabled_rules=no-multi-spaces,colon-spacing,chain-wrapping,import-ordering,experimental:annotation
# The following (so far identified) rules are kept:
# no-blank-line-before-rbrace
@@ -30,3 +30,4 @@ disabled_rules=no-wildcard-imports,no-multi-spaces,colon-spacing,chain-wrapping,
# no-empty-class-body
# experimental:multiline-if-else
# experimental:no-empty-first-line-in-method-block
+# no-wildcard-imports
diff --git a/.idea/dictionaries/bmarty.xml b/.idea/dictionaries/bmarty.xml
index 680a1d57cf..f351ec8bfd 100644
--- a/.idea/dictionaries/bmarty.xml
+++ b/.idea/dictionaries/bmarty.xml
@@ -22,6 +22,7 @@
signin
signout
signup
+ ssss
threepid
diff --git a/CHANGES.md b/CHANGES.md
index 5b7c04d3ac..95f35e3e1d 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,36 @@
+Changes in RiotX 0.17.0 (2020-02-27)
+===================================================
+
+Features ✨:
+ - Secured Shared Storage Support (#984, #936)
+ - It's now possible to select several rooms (with a possible mix of clear/encrypted rooms) when sharing elements to RiotX (#1010)
+ - Media preview: media are previewed before being sent to a room (#1010)
+ - Image edition: it's now possible to edit image before sending: crop, rotate, and delete actions are supported (#1010)
+ - Sending image: image are sent to rooms with a reduced size. It's still possible to send original image file (#1010)
+
+Improvements 🙌:
+ - Migrate to binary QR code verification (#994)
+ - Share action is added to room profile and room member profile (#858)
+ - Display avatar in fullscreen (#861)
+ - Fix some performance issues with crypto
+
+Bugfix 🐛:
+ - Account creation: wrongly hints that an email can be used to create an account (#941)
+ - Fix crash in the room directory, when public room has no name (#1023)
+ - Fix restoring keys backup with passphrase (#526)
+ - Fix rotation of full-size image (#647)
+ - Fix joining rooms from directory via federation isn't working. (#808)
+ - Leaving a room creates a stuck "leaving room" loading screen. (#1041)
+ - Fix some invitation handling issues (#1013)
+ - New direct chat: selecting a participant sometimes results in two breadcrumbs (#1022)
+ - New direct chat: selecting several participants was not adding the room to the direct chats list
+ - Room overview shows deleted messages as “Encrypted message” (#758)
+
+SDK API changes ⚠️:
+ - Get crypto methods through Session.cryptoService()
+ - ProgressListener.onProgress() function will be invoked on the background thread instead of UI thread
+ - Improve CreateRoomParams API (#1070)
+
Changes in RiotX 0.16.0 (2020-02-14)
===================================================
diff --git a/build.gradle b/build.gradle
index a2fac55175..74a62f0d17 100644
--- a/build.gradle
+++ b/build.gradle
@@ -34,6 +34,10 @@ allprojects {
includeGroupByRegex "com\\.github\\.jaiselrahman"
// And monarchy
includeGroupByRegex "com\\.github\\.Zhuinden"
+ // And ucrop
+ includeGroupByRegex "com\\.github\\.yalantis"
+ // JsonViewer
+ includeGroupByRegex 'com\\.github\\.BillCarsonFr'
}
}
maven {
diff --git a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt
index 2cd2bf2dd3..87ff6f0390 100644
--- a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt
+++ b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt
@@ -31,6 +31,7 @@ import im.vector.matrix.android.api.util.JsonDict
import im.vector.matrix.android.api.util.Optional
import im.vector.matrix.android.api.util.toOptional
import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
+import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
import io.reactivex.Observable
import io.reactivex.Single
@@ -94,10 +95,10 @@ class RxSession(private val session: Session) {
session.searchUsersDirectory(search, limit, excludedUserIds, it)
}
- fun joinRoom(roomId: String,
+ fun joinRoom(roomIdOrAlias: String,
reason: String? = null,
viaServers: List = emptyList()): Single = singleBuilder {
- session.joinRoom(roomId, reason, viaServers, it)
+ session.joinRoom(roomIdOrAlias, reason, viaServers, it)
}
fun getRoomIdByAlias(roomAlias: String,
@@ -110,15 +111,22 @@ class RxSession(private val session: Session) {
}
fun liveUserCryptoDevices(userId: String): Observable> {
- return session.getLiveCryptoDeviceInfo(userId).asObservable().startWithCallable {
- session.getCryptoDeviceInfo(userId)
+ return session.cryptoService().getLiveCryptoDeviceInfo(userId).asObservable().startWithCallable {
+ session.cryptoService().getCryptoDeviceInfo(userId)
}
}
fun liveCrossSigningInfo(userId: String): Observable> {
- return session.getCrossSigningService().getLiveCrossSigningKeys(userId).asObservable()
+ return session.cryptoService().crossSigningService().getLiveCrossSigningKeys(userId).asObservable()
.startWithCallable {
- session.getCrossSigningService().getUserCrossSigningKeys(userId).toOptional()
+ session.cryptoService().crossSigningService().getUserCrossSigningKeys(userId).toOptional()
+ }
+ }
+
+ fun liveAccountData(types: Set): Observable> {
+ return session.getLiveAccountDataEvents(types).asObservable()
+ .startWithCallable {
+ session.getAccountDataEvents(types)
}
}
}
diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle
index ea27df8ab6..062b590acf 100644
--- a/matrix-sdk-android/build.gradle
+++ b/matrix-sdk-android/build.gradle
@@ -119,6 +119,7 @@ dependencies {
// Image
implementation 'androidx.exifinterface:exifinterface:1.1.0'
+ implementation 'id.zelory:compressor:3.0.0'
// Database
implementation 'com.github.Zhuinden:realm-monarchy:0.5.1'
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/account/AccountCreationTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/account/AccountCreationTest.kt
index c44ac9c47b..679ea8f3fe 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/account/AccountCreationTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/account/AccountCreationTest.kt
@@ -38,9 +38,7 @@ class AccountCreationTest : InstrumentedTest {
fun createAccountTest() {
val session = commonTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(withInitialSync = true))
- commonTestHelper.signout(session)
-
- session.close()
+ commonTestHelper.signOutAndClose(session)
}
@Test
@@ -50,14 +48,14 @@ class AccountCreationTest : InstrumentedTest {
// Log again to the same account
val session2 = commonTestHelper.logIntoAccount(session.myUserId, SessionTestParams(withInitialSync = true))
- session.close()
- session2.close()
+ commonTestHelper.signOutAndClose(session)
+ commonTestHelper.signOutAndClose(session2)
}
@Test
fun simpleE2eTest() {
val res = cryptoTestHelper.doE2ETestWithAliceInARoom()
- res.close()
+ res.cleanUp(commonTestHelper)
}
}
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CommonTestHelper.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CommonTestHelper.kt
index 2e18133071..386787b882 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CommonTestHelper.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CommonTestHelper.kt
@@ -28,7 +28,10 @@ import im.vector.matrix.android.api.auth.data.LoginFlowResult
import im.vector.matrix.android.api.auth.registration.RegistrationResult
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.events.model.EventType
+import im.vector.matrix.android.api.session.events.model.LocalEcho
+import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.Room
+import im.vector.matrix.android.api.session.room.model.message.MessageContent
import im.vector.matrix.android.api.session.room.timeline.Timeline
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.api.session.room.timeline.TimelineSettings
@@ -113,7 +116,7 @@ class CommonTestHelper(context: Context) {
fun sendTextMessage(room: Room, message: String, nbOfMessages: Int): List {
val sentEvents = ArrayList(nbOfMessages)
val latch = CountDownLatch(nbOfMessages)
- val onEventSentListener = object : Timeline.Listener {
+ val timelineListener = object : Timeline.Listener {
override fun onTimelineFailure(throwable: Throwable) {
}
@@ -122,20 +125,26 @@ class CommonTestHelper(context: Context) {
}
override fun onTimelineUpdated(snapshot: List) {
- // TODO Count only new messages?
- if (snapshot.count { it.root.type == EventType.MESSAGE } == nbOfMessages) {
- sentEvents.addAll(snapshot.filter { it.root.type == EventType.MESSAGE })
+ val newMessages = snapshot
+ .filter { LocalEcho.isLocalEchoId(it.eventId).not() }
+ .filter { it.root.getClearType() == EventType.MESSAGE }
+ .filter { it.root.getClearContent().toModel()?.body?.startsWith(message) == true }
+
+ if (newMessages.size == nbOfMessages) {
+ sentEvents.addAll(newMessages)
latch.countDown()
}
}
}
val timeline = room.createTimeline(null, TimelineSettings(10))
- timeline.addListener(onEventSentListener)
+ timeline.start()
+ timeline.addListener(timelineListener)
for (i in 0 until nbOfMessages) {
room.sendTextMessage(message + " #" + (i + 1))
}
await(latch)
- timeline.removeListener(onEventSentListener)
+ timeline.removeListener(timelineListener)
+ timeline.dispose()
// Check that all events has been created
assertEquals(nbOfMessages.toLong(), sentEvents.size.toLong())
@@ -283,11 +292,10 @@ class CommonTestHelper(context: Context) {
/**
* Clear all provided sessions
*/
- fun Iterable.close() = forEach { it.close() }
+ fun Iterable.signOutAndClose() = forEach { signOutAndClose(it) }
- fun signout(session: Session) {
- val lock = CountDownLatch(1)
- session.signOut(true, TestMatrixCallback(lock))
- await(lock)
+ fun signOutAndClose(session: Session) {
+ doSync { session.signOut(true, it) }
+ session.close()
}
}
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CryptoTestData.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CryptoTestData.kt
index 8ad9f1ec6f..7eea832160 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CryptoTestData.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CryptoTestData.kt
@@ -23,9 +23,9 @@ data class CryptoTestData(val firstSession: Session,
val secondSession: Session? = null,
val thirdSession: Session? = null) {
- fun close() {
- firstSession.close()
- secondSession?.close()
- secondSession?.close()
+ fun cleanUp(testHelper: CommonTestHelper) {
+ testHelper.signOutAndClose(firstSession)
+ secondSession?.let { testHelper.signOutAndClose(it) }
+ thirdSession?.let { testHelper.signOutAndClose(it) }
}
}
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CryptoTestHelper.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CryptoTestHelper.kt
index f94c8455c2..826c70a63f 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CryptoTestHelper.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CryptoTestHelper.kt
@@ -41,16 +41,15 @@ import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
-import java.util.Arrays
import java.util.HashMap
import java.util.concurrent.CountDownLatch
-class CryptoTestHelper(val mTestHelper: CommonTestHelper) {
+class CryptoTestHelper(private val mTestHelper: CommonTestHelper) {
- val messagesFromAlice: List = Arrays.asList("0 - Hello I'm Alice!", "4 - Go!")
- val messagesFromBob: List = Arrays.asList("1 - Hello I'm Bob!", "2 - Isn't life grand?", "3 - Let's go to the opera.")
+ private val messagesFromAlice: List = listOf("0 - Hello I'm Alice!", "4 - Go!")
+ private val messagesFromBob: List = listOf("1 - Hello I'm Bob!", "2 - Isn't life grand?", "3 - Let's go to the opera.")
- val defaultSessionParams = SessionTestParams(true)
+ private val defaultSessionParams = SessionTestParams(true)
/**
* @return alice session
@@ -58,34 +57,23 @@ class CryptoTestHelper(val mTestHelper: CommonTestHelper) {
fun doE2ETestWithAliceInARoom(): CryptoTestData {
val aliceSession = mTestHelper.createAccount(TestConstants.USER_ALICE, defaultSessionParams)
- var roomId: String? = null
- val lock1 = CountDownLatch(1)
+ val roomId = mTestHelper.doSync {
+ aliceSession.createRoom(CreateRoomParams(name = "MyRoom"), it)
+ }
- aliceSession.createRoom(CreateRoomParams(name = "MyRoom"), object : TestMatrixCallback(lock1) {
- override fun onSuccess(data: String) {
- roomId = data
- super.onSuccess(data)
- }
- })
+ val room = aliceSession.getRoom(roomId)!!
- mTestHelper.await(lock1)
- assertNotNull(roomId)
+ mTestHelper.doSync {
+ room.enableEncryption(callback = it)
+ }
- val room = aliceSession.getRoom(roomId!!)!!
-
- val lock2 = CountDownLatch(1)
- room.enableEncryption(callback = TestMatrixCallback(lock2))
- mTestHelper.await(lock2)
-
- return CryptoTestData(aliceSession, roomId!!)
+ return CryptoTestData(aliceSession, roomId)
}
/**
* @return alice and bob sessions
*/
fun doE2ETestWithAliceAndBobInARoom(): CryptoTestData {
- val statuses = HashMap()
-
val cryptoTestData = doE2ETestWithAliceInARoom()
val aliceSession = cryptoTestData.firstSession
val aliceRoomId = cryptoTestData.roomId
@@ -94,7 +82,7 @@ class CryptoTestHelper(val mTestHelper: CommonTestHelper) {
val bobSession = mTestHelper.createAccount(TestConstants.USER_BOB, defaultSessionParams)
- val lock1 = CountDownLatch(2)
+ val lock1 = CountDownLatch(1)
val bobRoomSummariesLive = runBlocking(Dispatchers.Main) {
bobSession.getRoomSummariesLive(roomSummaryQueryParams { })
@@ -103,7 +91,6 @@ class CryptoTestHelper(val mTestHelper: CommonTestHelper) {
val newRoomObserver = object : Observer> {
override fun onChanged(t: List?) {
if (t?.isNotEmpty() == true) {
- statuses["onNewRoom"] = "onNewRoom"
lock1.countDown()
bobRoomSummariesLive.removeObserver(this)
}
@@ -114,26 +101,20 @@ class CryptoTestHelper(val mTestHelper: CommonTestHelper) {
bobRoomSummariesLive.observeForever(newRoomObserver)
}
- aliceRoom.invite(bobSession.myUserId, callback = object : TestMatrixCallback(lock1) {
- override fun onSuccess(data: Unit) {
- statuses["invite"] = "invite"
- super.onSuccess(data)
- }
- })
+ mTestHelper.doSync {
+ aliceRoom.invite(bobSession.myUserId, callback = it)
+ }
mTestHelper.await(lock1)
- assertTrue(statuses.containsKey("invite") && statuses.containsKey("onNewRoom"))
-
- val lock2 = CountDownLatch(2)
+ val lock = CountDownLatch(1)
val roomJoinedObserver = object : Observer> {
override fun onChanged(t: List?) {
if (bobSession.getRoom(aliceRoomId)
?.getRoomMember(aliceSession.myUserId)
?.membership == Membership.JOIN) {
- statuses["AliceJoin"] = "AliceJoin"
- lock2.countDown()
+ lock.countDown()
bobRoomSummariesLive.removeObserver(this)
}
}
@@ -143,19 +124,15 @@ class CryptoTestHelper(val mTestHelper: CommonTestHelper) {
bobRoomSummariesLive.observeForever(roomJoinedObserver)
}
- bobSession.joinRoom(aliceRoomId, callback = TestMatrixCallback(lock2))
+ mTestHelper.doSync { bobSession.joinRoom(aliceRoomId, callback = it) }
- mTestHelper.await(lock2)
+ mTestHelper.await(lock)
// Ensure bob can send messages to the room
// val roomFromBobPOV = bobSession.getRoom(aliceRoomId)!!
// assertNotNull(roomFromBobPOV.powerLevels)
// assertTrue(roomFromBobPOV.powerLevels.maySendMessage(bobSession.myUserId))
- assertTrue(statuses.toString() + "", statuses.containsKey("AliceJoin"))
-
-// bobSession.dataHandler.removeListener(bobEventListener)
-
return CryptoTestData(aliceSession, aliceRoomId, bobSession)
}
@@ -230,14 +207,14 @@ class CryptoTestHelper(val mTestHelper: CommonTestHelper) {
val aliceRoomId = cryptoTestData.roomId
val bobSession = cryptoTestData.secondSession!!
- bobSession.setWarnOnUnknownDevices(false)
+ bobSession.cryptoService().setWarnOnUnknownDevices(false)
- aliceSession.setWarnOnUnknownDevices(false)
+ aliceSession.cryptoService().setWarnOnUnknownDevices(false)
val roomFromBobPOV = bobSession.getRoom(aliceRoomId)!!
val roomFromAlicePOV = aliceSession.getRoom(aliceRoomId)!!
- var lock = CountDownLatch(1)
+ val lock = CountDownLatch(1)
val bobEventsListener = object : Timeline.Listener {
override fun onTimelineFailure(throwable: Throwable) {
@@ -249,63 +226,35 @@ class CryptoTestHelper(val mTestHelper: CommonTestHelper) {
}
override fun onTimelineUpdated(snapshot: List) {
- val size = snapshot.filter { it.root.senderId != bobSession.myUserId && it.root.getClearType() == EventType.MESSAGE }
- .size
+ val messages = snapshot.filter { it.root.getClearType() == EventType.MESSAGE }
+ .groupBy { it.root.senderId!! }
- if (size == 3) {
+ // Alice has sent 2 messages and Bob has sent 3 messages
+ if (messages[aliceSession.myUserId]?.size == 2 && messages[bobSession.myUserId]?.size == 3) {
lock.countDown()
}
}
}
- val bobTimeline = roomFromBobPOV.createTimeline(null, TimelineSettings(10))
+ val bobTimeline = roomFromBobPOV.createTimeline(null, TimelineSettings(20))
+ bobTimeline.start()
bobTimeline.addListener(bobEventsListener)
- val results = HashMap()
-
- // bobSession.dataHandler.addListener(object : MXEventListener() {
- // override fun onToDeviceEvent(event: Event) {
- // results["onToDeviceEvent"] = event
- // lock.countDown()
- // }
- // })
-
// Alice sends a message
roomFromAlicePOV.sendTextMessage(messagesFromAlice[0])
- assertTrue(results.containsKey("onToDeviceEvent"))
-// assertEquals(1, messagesReceivedByBobCount)
- // Bob send a message
- lock = CountDownLatch(1)
+ // Bob send 3 messages
roomFromBobPOV.sendTextMessage(messagesFromBob[0])
- // android does not echo the messages sent from itself
-// messagesReceivedByBobCount++
- mTestHelper.await(lock)
-// assertEquals(2, messagesReceivedByBobCount)
-
- // Bob send a message
- lock = CountDownLatch(1)
roomFromBobPOV.sendTextMessage(messagesFromBob[1])
- // android does not echo the messages sent from itself
-// messagesReceivedByBobCount++
- mTestHelper.await(lock)
-// assertEquals(3, messagesReceivedByBobCount)
-
- // Bob send a message
- lock = CountDownLatch(1)
roomFromBobPOV.sendTextMessage(messagesFromBob[2])
- // android does not echo the messages sent from itself
-// messagesReceivedByBobCount++
- mTestHelper.await(lock)
-// assertEquals(4, messagesReceivedByBobCount)
// Alice sends a message
- lock = CountDownLatch(2)
roomFromAlicePOV.sendTextMessage(messagesFromAlice[1])
+
mTestHelper.await(lock)
-// assertEquals(5, messagesReceivedByBobCount)
bobTimeline.removeListener(bobEventsListener)
+ bobTimeline.dispose()
return cryptoTestData
}
@@ -340,18 +289,14 @@ class CryptoTestHelper(val mTestHelper: CommonTestHelper) {
fun createFakeMegolmBackupAuthData(): MegolmBackupAuthData {
return MegolmBackupAuthData(
publicKey = "abcdefg",
- signatures = HashMap>().apply {
- this["something"] = HashMap().apply {
- this["ed25519:something"] = "hijklmnop"
- }
- }
+ signatures = mapOf("something" to mapOf("ed25519:something" to "hijklmnop"))
)
}
fun createFakeMegolmBackupCreationInfo(): MegolmBackupCreationInfo {
- return MegolmBackupCreationInfo().apply {
- algorithm = MXCRYPTO_ALGORITHM_MEGOLM_BACKUP
- authData = createFakeMegolmBackupAuthData()
- }
+ return MegolmBackupCreationInfo(
+ algorithm = MXCRYPTO_ALGORITHM_MEGOLM_BACKUP,
+ authData = createFakeMegolmBackupAuthData()
+ )
}
}
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/TestAssertUtil.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/TestAssertUtil.kt
index 2a62165210..287a80db72 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/TestAssertUtil.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/TestAssertUtil.kt
@@ -16,7 +16,10 @@
package im.vector.matrix.android.common
-import org.junit.Assert.*
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertNull
+import org.junit.Assert.fail
/**
* Compare two lists and their content
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/TestConstants.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/TestConstants.kt
index 60cc87d330..2346898ca7 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/TestConstants.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/TestConstants.kt
@@ -22,11 +22,11 @@ object TestConstants {
const val TESTS_HOME_SERVER_URL = "http://10.0.2.2:8080"
- // Time out to use when waiting for server response. 60s
- private const val AWAIT_TIME_OUT_MILLIS = 60000
+ // Time out to use when waiting for server response. 10s
+ private const val AWAIT_TIME_OUT_MILLIS = 10_000
// Time out to use when waiting for server response, when the debugger is connected. 10 minutes
- private const val AWAIT_TIME_OUT_WITH_DEBUGGER_MILLIS = 10 * 60000
+ private const val AWAIT_TIME_OUT_WITH_DEBUGGER_MILLIS = 10 * 60_000
const val USER_ALICE = "Alice"
const val USER_BOB = "Bob"
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/AttachmentEncryptionTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/AttachmentEncryptionTest.kt
index 7aedab7e2b..6041114777 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/AttachmentEncryptionTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/AttachmentEncryptionTest.kt
@@ -22,7 +22,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import im.vector.matrix.android.internal.crypto.attachments.MXEncryptedAttachments
import im.vector.matrix.android.internal.crypto.model.rest.EncryptedFileInfo
import im.vector.matrix.android.internal.crypto.model.rest.EncryptedFileKey
-import org.junit.Assert.*
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotEquals
+import org.junit.Assert.assertNotNull
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/CryptoStoreTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/CryptoStoreTest.kt
index df503f2486..45589a49a4 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/CryptoStoreTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/CryptoStoreTest.kt
@@ -21,7 +21,11 @@ import im.vector.matrix.android.InstrumentedTest
import im.vector.matrix.android.internal.crypto.model.OlmSessionWrapper
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import io.realm.Realm
-import org.junit.Assert.*
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNotEquals
+import org.junit.Assert.assertNull
+import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/ExportEncryptionTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/ExportEncryptionTest.kt
index 89ed3c2e65..f873e7a809 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/ExportEncryptionTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/ExportEncryptionTest.kt
@@ -17,7 +17,9 @@
package im.vector.matrix.android.internal.crypto
import androidx.test.ext.junit.runners.AndroidJUnit4
-import org.junit.Assert.*
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.Assert.fail
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/crosssigning/XSigningTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/crosssigning/XSigningTest.kt
index c8e7355d7a..f8d30a2679 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/crosssigning/XSigningTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/crosssigning/XSigningTest.kt
@@ -2,12 +2,10 @@ package im.vector.matrix.android.internal.crypto.crosssigning
import androidx.test.ext.junit.runners.AndroidJUnit4
import im.vector.matrix.android.InstrumentedTest
-import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.common.CommonTestHelper
import im.vector.matrix.android.common.CryptoTestHelper
import im.vector.matrix.android.common.SessionTestParams
import im.vector.matrix.android.common.TestConstants
-import im.vector.matrix.android.common.TestMatrixCallback
import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
@@ -21,7 +19,6 @@ import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
-import java.util.concurrent.CountDownLatch
@RunWith(AndroidJUnit4::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@@ -34,16 +31,15 @@ class XSigningTest : InstrumentedTest {
fun test_InitializeAndStoreKeys() {
val aliceSession = mTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true))
- val aliceLatch = CountDownLatch(1)
- aliceSession.getCrossSigningService()
- .initializeCrossSigning(UserPasswordAuth(
- user = aliceSession.myUserId,
- password = TestConstants.PASSWORD
- ), TestMatrixCallback(aliceLatch))
+ mTestHelper.doSync {
+ aliceSession.cryptoService().crossSigningService()
+ .initializeCrossSigning(UserPasswordAuth(
+ user = aliceSession.myUserId,
+ password = TestConstants.PASSWORD
+ ), it)
+ }
- mTestHelper.await(aliceLatch)
-
- val myCrossSigningKeys = aliceSession.getCrossSigningService().getMyCrossSigningKeys()
+ val myCrossSigningKeys = aliceSession.cryptoService().crossSigningService().getMyCrossSigningKeys()
val masterPubKey = myCrossSigningKeys?.masterKey()
assertNotNull("Master key should be stored", masterPubKey?.unpaddedBase64PublicKey)
val selfSigningKey = myCrossSigningKeys?.selfSigningKey()
@@ -53,9 +49,9 @@ class XSigningTest : InstrumentedTest {
assertTrue("Signing Keys should be trusted", myCrossSigningKeys?.isTrusted() == true)
- assertTrue("Signing Keys should be trusted", aliceSession.getCrossSigningService().checkUserTrust(aliceSession.myUserId).isVerified())
+ assertTrue("Signing Keys should be trusted", aliceSession.cryptoService().crossSigningService().checkUserTrust(aliceSession.myUserId).isVerified())
- mTestHelper.signout(aliceSession)
+ mTestHelper.signOutAndClose(aliceSession)
}
@Test
@@ -74,30 +70,24 @@ class XSigningTest : InstrumentedTest {
password = TestConstants.PASSWORD
)
- val latch = CountDownLatch(2)
-
- aliceSession.getCrossSigningService().initializeCrossSigning(aliceAuthParams, TestMatrixCallback(latch))
- bobSession.getCrossSigningService().initializeCrossSigning(bobAuthParams, TestMatrixCallback(latch))
-
- mTestHelper.await(latch)
+ mTestHelper.doSync { aliceSession.cryptoService().crossSigningService().initializeCrossSigning(aliceAuthParams, it) }
+ mTestHelper.doSync { bobSession.cryptoService().crossSigningService().initializeCrossSigning(bobAuthParams, it) }
// Check that alice can see bob keys
- val downloadLatch = CountDownLatch(1)
- aliceSession.downloadKeys(listOf(bobSession.myUserId), true, TestMatrixCallback(downloadLatch))
- mTestHelper.await(downloadLatch)
+ mTestHelper.doSync> { aliceSession.cryptoService().downloadKeys(listOf(bobSession.myUserId), true, it) }
- val bobKeysFromAlicePOV = aliceSession.getCrossSigningService().getUserCrossSigningKeys(bobSession.myUserId)
+ val bobKeysFromAlicePOV = aliceSession.cryptoService().crossSigningService().getUserCrossSigningKeys(bobSession.myUserId)
assertNotNull("Alice can see bob Master key", bobKeysFromAlicePOV!!.masterKey())
assertNull("Alice should not see bob User key", bobKeysFromAlicePOV.userKey())
assertNotNull("Alice can see bob SelfSigned key", bobKeysFromAlicePOV.selfSigningKey())
- assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.masterKey()?.unpaddedBase64PublicKey, bobSession.getCrossSigningService().getMyCrossSigningKeys()?.masterKey()?.unpaddedBase64PublicKey)
- assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.selfSigningKey()?.unpaddedBase64PublicKey, bobSession.getCrossSigningService().getMyCrossSigningKeys()?.selfSigningKey()?.unpaddedBase64PublicKey)
+ assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.masterKey()?.unpaddedBase64PublicKey, bobSession.cryptoService().crossSigningService().getMyCrossSigningKeys()?.masterKey()?.unpaddedBase64PublicKey)
+ assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.selfSigningKey()?.unpaddedBase64PublicKey, bobSession.cryptoService().crossSigningService().getMyCrossSigningKeys()?.selfSigningKey()?.unpaddedBase64PublicKey)
assertFalse("Bob keys from alice pov should not be trusted", bobKeysFromAlicePOV.isTrusted())
- mTestHelper.signout(aliceSession)
- mTestHelper.signout(bobSession)
+ mTestHelper.signOutAndClose(aliceSession)
+ mTestHelper.signOutAndClose(bobSession)
}
@Test
@@ -116,94 +106,56 @@ class XSigningTest : InstrumentedTest {
password = TestConstants.PASSWORD
)
- val latch = CountDownLatch(2)
-
- aliceSession.getCrossSigningService().initializeCrossSigning(aliceAuthParams, TestMatrixCallback(latch))
- bobSession.getCrossSigningService().initializeCrossSigning(bobAuthParams, TestMatrixCallback(latch))
-
- mTestHelper.await(latch)
+ mTestHelper.doSync { aliceSession.cryptoService().crossSigningService().initializeCrossSigning(aliceAuthParams, it) }
+ mTestHelper.doSync { bobSession.cryptoService().crossSigningService().initializeCrossSigning(bobAuthParams, it) }
// Check that alice can see bob keys
- val downloadLatch = CountDownLatch(1)
val bobUserId = bobSession.myUserId
- aliceSession.downloadKeys(listOf(bobUserId), true, TestMatrixCallback(downloadLatch))
- mTestHelper.await(downloadLatch)
+ mTestHelper.doSync> { aliceSession.cryptoService().downloadKeys(listOf(bobUserId), true, it) }
- val bobKeysFromAlicePOV = aliceSession.getCrossSigningService().getUserCrossSigningKeys(bobUserId)
+ val bobKeysFromAlicePOV = aliceSession.cryptoService().crossSigningService().getUserCrossSigningKeys(bobUserId)
assertTrue("Bob keys from alice pov should not be trusted", bobKeysFromAlicePOV?.isTrusted() == false)
- val trustLatch = CountDownLatch(1)
- aliceSession.getCrossSigningService().trustUser(bobUserId, object : MatrixCallback {
- override fun onSuccess(data: Unit) {
- trustLatch.countDown()
- }
-
- override fun onFailure(failure: Throwable) {
- fail("Failed to trust bob")
- }
- })
- mTestHelper.await(trustLatch)
+ mTestHelper.doSync { aliceSession.cryptoService().crossSigningService().trustUser(bobUserId, it) }
// Now bobs logs in on a new device and verifies it
// We will want to test that in alice POV, this new device would be trusted by cross signing
val bobSession2 = mTestHelper.logIntoAccount(bobUserId, SessionTestParams(true))
- val bobSecondDeviceId = bobSession2.sessionParams.credentials.deviceId
+ val bobSecondDeviceId = bobSession2.sessionParams.credentials.deviceId!!
// Check that bob first session sees the new login
- val bobKeysLatch = CountDownLatch(1)
- bobSession.downloadKeys(listOf(bobUserId), true, object : MatrixCallback> {
- override fun onFailure(failure: Throwable) {
- fail("Failed to get device")
- }
+ val data = mTestHelper.doSync> {
+ bobSession.cryptoService().downloadKeys(listOf(bobUserId), true, it)
+ }
- override fun onSuccess(data: MXUsersDevicesMap) {
- if (data.getUserDeviceIds(bobUserId)?.contains(bobSecondDeviceId!!) == false) {
- fail("Bob should see the new device")
- }
- bobKeysLatch.countDown()
- }
- })
- mTestHelper.await(bobKeysLatch)
+ if (data.getUserDeviceIds(bobUserId)?.contains(bobSecondDeviceId) == false) {
+ fail("Bob should see the new device")
+ }
- val bobSecondDevicePOVFirstDevice = bobSession.getDeviceInfo(bobUserId, bobSecondDeviceId)
+ val bobSecondDevicePOVFirstDevice = bobSession.cryptoService().getDeviceInfo(bobUserId, bobSecondDeviceId)
assertNotNull("Bob Second device should be known and persisted from first", bobSecondDevicePOVFirstDevice)
// Manually mark it as trusted from first session
- val bobSignLatch = CountDownLatch(1)
- bobSession.getCrossSigningService().signDevice(bobSecondDeviceId!!, object : MatrixCallback {
- override fun onSuccess(data: Unit) {
- bobSignLatch.countDown()
- }
-
- override fun onFailure(failure: Throwable) {
- fail("Failed to trust bob ${failure.localizedMessage}")
- }
- })
- mTestHelper.await(bobSignLatch)
+ mTestHelper.doSync {
+ bobSession.cryptoService().crossSigningService().trustDevice(bobSecondDeviceId, it)
+ }
// Now alice should cross trust bob's second device
- val aliceKeysLatch = CountDownLatch(1)
- aliceSession.downloadKeys(listOf(bobUserId), true, object : MatrixCallback> {
- override fun onFailure(failure: Throwable) {
- fail("Failed to get device")
- }
+ val data2 = mTestHelper.doSync> {
+ aliceSession.cryptoService().downloadKeys(listOf(bobUserId), true, it)
+ }
- override fun onSuccess(data: MXUsersDevicesMap) {
- // check that the device is seen
- if (data.getUserDeviceIds(bobUserId)?.contains(bobSecondDeviceId) == false) {
- fail("Alice should see the new device")
- }
- aliceKeysLatch.countDown()
- }
- })
- mTestHelper.await(aliceKeysLatch)
+ // check that the device is seen
+ if (data2.getUserDeviceIds(bobUserId)?.contains(bobSecondDeviceId) == false) {
+ fail("Alice should see the new device")
+ }
- val result = aliceSession.getCrossSigningService().checkDeviceTrust(bobUserId, bobSecondDeviceId, null)
+ val result = aliceSession.cryptoService().crossSigningService().checkDeviceTrust(bobUserId, bobSecondDeviceId, null)
assertTrue("Bob second device should be trusted from alice POV", result.isCrossSignedVerified())
- mTestHelper.signout(aliceSession)
- mTestHelper.signout(bobSession)
- mTestHelper.signout(bobSession2)
+ mTestHelper.signOutAndClose(aliceSession)
+ mTestHelper.signOutAndClose(bobSession)
+ mTestHelper.signOutAndClose(bobSession2)
}
}
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupPasswordTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupPasswordTest.kt
index 53e68383ee..b1b111babf 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupPasswordTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupPasswordTest.kt
@@ -20,7 +20,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import im.vector.matrix.android.InstrumentedTest
import im.vector.matrix.android.api.listeners.ProgressListener
import im.vector.matrix.android.common.assertByteArrayNotEqual
-import org.junit.Assert.*
+import org.junit.Assert.assertArrayEquals
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.FixMethodOrder
import org.junit.Test
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupTest.kt
index 312ad03a06..77ba66d341 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupTest.kt
@@ -18,7 +18,6 @@ package im.vector.matrix.android.internal.crypto.keysbackup
import androidx.test.ext.junit.runners.AndroidJUnit4
import im.vector.matrix.android.InstrumentedTest
-import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.listeners.ProgressListener
import im.vector.matrix.android.api.listeners.StepProgressListener
import im.vector.matrix.android.api.session.Session
@@ -58,7 +57,7 @@ import java.util.Collections
import java.util.concurrent.CountDownLatch
@RunWith(AndroidJUnit4::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FixMethodOrder(MethodSorters.JVM)
class KeysBackupTest : InstrumentedTest {
private val mTestHelper = CommonTestHelper(context())
@@ -77,21 +76,21 @@ class KeysBackupTest : InstrumentedTest {
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
// From doE2ETestWithAliceAndBobInARoomWithEncryptedMessages, we should have no backed up keys
- val cryptoStore = (cryptoTestData.firstSession.getKeysBackupService() as KeysBackup).store
+ val cryptoStore = (cryptoTestData.firstSession.cryptoService().keysBackupService() as DefaultKeysBackupService).store
val sessions = cryptoStore.inboundGroupSessionsToBackup(100)
val sessionsCount = sessions.size
assertFalse(sessions.isEmpty())
- assertEquals(sessionsCount, cryptoTestData.firstSession.inboundGroupSessionsCount(false))
- assertEquals(0, cryptoTestData.firstSession.inboundGroupSessionsCount(true))
+ assertEquals(sessionsCount, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false))
+ assertEquals(0, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true))
// - Check backup keys after having marked one as backed up
val session = sessions[0]
cryptoStore.markBackupDoneForInboundGroupSessions(Collections.singletonList(session))
- assertEquals(sessionsCount, cryptoTestData.firstSession.inboundGroupSessionsCount(false))
- assertEquals(1, cryptoTestData.firstSession.inboundGroupSessionsCount(true))
+ assertEquals(sessionsCount, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false))
+ assertEquals(1, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true))
val sessions2 = cryptoStore.inboundGroupSessionsToBackup(100)
assertEquals(sessionsCount - 1, sessions2.size)
@@ -101,8 +100,10 @@ class KeysBackupTest : InstrumentedTest {
val sessions3 = cryptoStore.inboundGroupSessionsToBackup(100)
assertEquals(sessionsCount, sessions3.size)
- assertEquals(sessionsCount, cryptoTestData.firstSession.inboundGroupSessionsCount(false))
- assertEquals(0, cryptoTestData.firstSession.inboundGroupSessionsCount(true))
+ assertEquals(sessionsCount, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false))
+ assertEquals(0, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true))
+
+ cryptoTestData.cleanUp(mTestHelper)
}
/**
@@ -112,39 +113,26 @@ class KeysBackupTest : InstrumentedTest {
fun prepareKeysBackupVersionTest() {
val bobSession = mTestHelper.createAccount(TestConstants.USER_BOB, defaultSessionParams)
- assertNotNull(bobSession.getKeysBackupService())
+ assertNotNull(bobSession.cryptoService().keysBackupService())
- val keysBackup = bobSession.getKeysBackupService()
+ val keysBackup = bobSession.cryptoService().keysBackupService()
val stateObserver = StateObserver(keysBackup)
assertFalse(keysBackup.isEnabled)
- val latch = CountDownLatch(1)
+ val megolmBackupCreationInfo = mTestHelper.doSync {
+ keysBackup.prepareKeysBackupVersion(null, null, it)
+ }
- keysBackup.prepareKeysBackupVersion(null, null, object : MatrixCallback {
- override fun onSuccess(data: MegolmBackupCreationInfo) {
- assertNotNull(data)
-
- assertEquals(MXCRYPTO_ALGORITHM_MEGOLM_BACKUP, data.algorithm)
- assertNotNull(data.authData)
- assertNotNull(data.authData!!.publicKey)
- assertNotNull(data.authData!!.signatures)
- assertNotNull(data.recoveryKey)
-
- latch.countDown()
- }
-
- override fun onFailure(failure: Throwable) {
- fail(failure.localizedMessage)
-
- latch.countDown()
- }
- })
- mTestHelper.await(latch)
+ assertEquals(MXCRYPTO_ALGORITHM_MEGOLM_BACKUP, megolmBackupCreationInfo.algorithm)
+ assertNotNull(megolmBackupCreationInfo.authData)
+ assertNotNull(megolmBackupCreationInfo.authData!!.publicKey)
+ assertNotNull(megolmBackupCreationInfo.authData!!.signatures)
+ assertNotNull(megolmBackupCreationInfo.recoveryKey)
stateObserver.stopAndCheckStates(null)
- bobSession.close()
+ mTestHelper.signOutAndClose(bobSession)
}
/**
@@ -154,51 +142,28 @@ class KeysBackupTest : InstrumentedTest {
fun createKeysBackupVersionTest() {
val bobSession = mTestHelper.createAccount(TestConstants.USER_BOB, defaultSessionParams)
- val keysBackup = bobSession.getKeysBackupService()
+ val keysBackup = bobSession.cryptoService().keysBackupService()
val stateObserver = StateObserver(keysBackup)
assertFalse(keysBackup.isEnabled)
- var megolmBackupCreationInfo: MegolmBackupCreationInfo? = null
- val latch = CountDownLatch(1)
- keysBackup.prepareKeysBackupVersion(null, null, object : MatrixCallback {
- override fun onSuccess(data: MegolmBackupCreationInfo) {
- megolmBackupCreationInfo = data
-
- latch.countDown()
- }
-
- override fun onFailure(failure: Throwable) {
- fail(failure.localizedMessage)
-
- latch.countDown()
- }
- })
- mTestHelper.await(latch)
-
- assertNotNull(megolmBackupCreationInfo)
+ val megolmBackupCreationInfo = mTestHelper.doSync {
+ keysBackup.prepareKeysBackupVersion(null, null, it)
+ }
assertFalse(keysBackup.isEnabled)
- val latch2 = CountDownLatch(1)
-
// Create the version
- keysBackup.createKeysBackupVersion(megolmBackupCreationInfo!!, object : TestMatrixCallback(latch2) {
- override fun onSuccess(data: KeysVersion) {
- assertNotNull(data)
- assertNotNull(data.version)
-
- super.onSuccess(data)
- }
- })
- mTestHelper.await(latch2)
+ mTestHelper.doSync {
+ keysBackup.createKeysBackupVersion(megolmBackupCreationInfo, it)
+ }
// Backup must be enable now
assertTrue(keysBackup.isEnabled)
stateObserver.stopAndCheckStates(null)
- bobSession.close()
+ mTestHelper.signOutAndClose(bobSession)
}
/**
@@ -209,12 +174,12 @@ class KeysBackupTest : InstrumentedTest {
fun backupAfterCreateKeysBackupVersionTest() {
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
- val keysBackup = cryptoTestData.firstSession.getKeysBackupService()
+ val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService()
val latch = CountDownLatch(1)
- assertEquals(2, cryptoTestData.firstSession.inboundGroupSessionsCount(false))
- assertEquals(0, cryptoTestData.firstSession.inboundGroupSessionsCount(true))
+ assertEquals(2, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false))
+ assertEquals(0, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true))
val stateObserver = StateObserver(keysBackup, latch, 5)
@@ -222,8 +187,8 @@ class KeysBackupTest : InstrumentedTest {
mTestHelper.await(latch)
- val nbOfKeys = cryptoTestData.firstSession.inboundGroupSessionsCount(false)
- val backedUpKeys = cryptoTestData.firstSession.inboundGroupSessionsCount(true)
+ val nbOfKeys = cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false)
+ val backedUpKeys = cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true)
assertEquals(2, nbOfKeys)
assertEquals("All keys must have been marked as backed up", nbOfKeys, backedUpKeys)
@@ -238,7 +203,7 @@ class KeysBackupTest : InstrumentedTest {
KeysBackupState.ReadyToBackUp
)
)
- cryptoTestData.close()
+ cryptoTestData.cleanUp(mTestHelper)
}
/**
@@ -248,37 +213,36 @@ class KeysBackupTest : InstrumentedTest {
fun backupAllGroupSessionsTest() {
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
- val keysBackup = cryptoTestData.firstSession.getKeysBackupService()
+ val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService()
val stateObserver = StateObserver(keysBackup)
prepareAndCreateKeysBackupData(keysBackup)
// Check that backupAllGroupSessions returns valid data
- val nbOfKeys = cryptoTestData.firstSession.inboundGroupSessionsCount(false)
+ val nbOfKeys = cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false)
assertEquals(2, nbOfKeys)
- val latch = CountDownLatch(1)
-
var lastBackedUpKeysProgress = 0
- keysBackup.backupAllGroupSessions(object : ProgressListener {
- override fun onProgress(progress: Int, total: Int) {
- assertEquals(nbOfKeys, total)
- lastBackedUpKeysProgress = progress
- }
- }, TestMatrixCallback(latch))
+ mTestHelper.doSync {
+ keysBackup.backupAllGroupSessions(object : ProgressListener {
+ override fun onProgress(progress: Int, total: Int) {
+ assertEquals(nbOfKeys, total)
+ lastBackedUpKeysProgress = progress
+ }
+ }, it)
+ }
- mTestHelper.await(latch)
assertEquals(nbOfKeys, lastBackedUpKeysProgress)
- val backedUpKeys = cryptoTestData.firstSession.inboundGroupSessionsCount(true)
+ val backedUpKeys = cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true)
assertEquals("All keys must have been marked as backed up", nbOfKeys, backedUpKeys)
stateObserver.stopAndCheckStates(null)
- cryptoTestData.close()
+ cryptoTestData.cleanUp(mTestHelper)
}
/**
@@ -293,7 +257,7 @@ class KeysBackupTest : InstrumentedTest {
fun testEncryptAndDecryptKeysBackupData() {
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
- val keysBackup = cryptoTestData.firstSession.getKeysBackupService() as KeysBackup
+ val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService() as DefaultKeysBackupService
val stateObserver = StateObserver(keysBackup)
@@ -321,7 +285,7 @@ class KeysBackupTest : InstrumentedTest {
assertKeysEquals(session.exportKeys(), sessionData)
stateObserver.stopAndCheckStates(null)
- cryptoTestData.close()
+ cryptoTestData.cleanUp(mTestHelper)
}
/**
@@ -335,25 +299,19 @@ class KeysBackupTest : InstrumentedTest {
val testData = createKeysBackupScenarioWithPassword(null)
// - Restore the e2e backup from the homeserver
- val latch2 = CountDownLatch(1)
- var importRoomKeysResult: ImportRoomKeysResult? = null
- testData.aliceSession2.getKeysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
- testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey,
- null,
- null,
- null,
- object : TestMatrixCallback(latch2) {
- override fun onSuccess(data: ImportRoomKeysResult) {
- importRoomKeysResult = data
- super.onSuccess(data)
- }
- }
- )
- mTestHelper.await(latch2)
+ val importRoomKeysResult = mTestHelper.doSync {
+ testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
+ testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey,
+ null,
+ null,
+ null,
+ it
+ )
+ }
- checkRestoreSuccess(testData, importRoomKeysResult!!.totalNumberOfKeys, importRoomKeysResult!!.successfullyNumberOfImportedKeys)
+ checkRestoreSuccess(testData, importRoomKeysResult.totalNumberOfKeys, importRoomKeysResult.successfullyNumberOfImportedKeys)
- testData.cryptoTestData.close()
+ testData.cleanUp(mTestHelper)
}
/**
@@ -370,10 +328,12 @@ class KeysBackupTest : InstrumentedTest {
*/
@Test
fun restoreKeysBackupAndKeyShareRequestTest() {
+ fail("Check with Valere for this test. I think we do not send key share request")
+
val testData = createKeysBackupScenarioWithPassword(null)
// - Check the SDK sent key share requests
- val cryptoStore2 = (testData.aliceSession2.getKeysBackupService() as KeysBackup).store
+ val cryptoStore2 = (testData.aliceSession2.cryptoService().keysBackupService() as DefaultKeysBackupService).store
val unsentRequest = cryptoStore2
.getOutgoingRoomKeyRequestByState(setOf(OutgoingRoomKeyRequest.RequestState.UNSENT))
val sentRequest = cryptoStore2
@@ -383,23 +343,17 @@ class KeysBackupTest : InstrumentedTest {
assertTrue(unsentRequest != null || sentRequest != null)
// - Restore the e2e backup from the homeserver
- val latch2 = CountDownLatch(1)
- var importRoomKeysResult: ImportRoomKeysResult? = null
- testData.aliceSession2.getKeysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
- testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey,
- null,
- null,
- null,
- object : TestMatrixCallback(latch2) {
- override fun onSuccess(data: ImportRoomKeysResult) {
- importRoomKeysResult = data
- super.onSuccess(data)
- }
- }
- )
- mTestHelper.await(latch2)
+ val importRoomKeysResult = mTestHelper.doSync {
+ testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
+ testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey,
+ null,
+ null,
+ null,
+ it
+ )
+ }
- checkRestoreSuccess(testData, importRoomKeysResult!!.totalNumberOfKeys, importRoomKeysResult!!.successfullyNumberOfImportedKeys)
+ checkRestoreSuccess(testData, importRoomKeysResult.totalNumberOfKeys, importRoomKeysResult.successfullyNumberOfImportedKeys)
// - There must be no more pending key share requests
val unsentRequestAfterRestoration = cryptoStore2
@@ -410,7 +364,7 @@ class KeysBackupTest : InstrumentedTest {
// Request is either sent or unsent
assertTrue(unsentRequestAfterRestoration == null && sentRequestAfterRestoration == null)
- testData.cryptoTestData.close()
+ testData.cleanUp(mTestHelper)
}
/**
@@ -429,62 +383,47 @@ class KeysBackupTest : InstrumentedTest {
// - And log Alice on a new device
val testData = createKeysBackupScenarioWithPassword(null)
- val stateObserver = StateObserver(testData.aliceSession2.getKeysBackupService())
+ val stateObserver = StateObserver(testData.aliceSession2.cryptoService().keysBackupService())
// - The new device must see the previous backup as not trusted
- assertNotNull(testData.aliceSession2.getKeysBackupService().keysBackupVersion)
- assertFalse(testData.aliceSession2.getKeysBackupService().isEnabled)
- assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.getKeysBackupService().state)
+ assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
+ assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
+ assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
// - Trust the backup from the new device
- val latch = CountDownLatch(1)
- testData.aliceSession2.getKeysBackupService().trustKeysBackupVersion(
- testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
- true,
- TestMatrixCallback(latch)
- )
- mTestHelper.await(latch)
+ mTestHelper.doSync {
+ testData.aliceSession2.cryptoService().keysBackupService().trustKeysBackupVersion(
+ testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
+ true,
+ it
+ )
+ }
// Wait for backup state to be ReadyToBackUp
waitForKeysBackupToBeInState(testData.aliceSession2, KeysBackupState.ReadyToBackUp)
// - Backup must be enabled on the new device, on the same version
- assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.getKeysBackupService().keysBackupVersion?.version)
- assertTrue(testData.aliceSession2.getKeysBackupService().isEnabled)
+ assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion?.version)
+ assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
// - Retrieve the last version from the server
- val latch2 = CountDownLatch(1)
- var keysVersionResult: KeysVersionResult? = null
- testData.aliceSession2.getKeysBackupService().getCurrentVersion(
- object : TestMatrixCallback(latch2) {
- override fun onSuccess(data: KeysVersionResult?) {
- keysVersionResult = data
- super.onSuccess(data)
- }
- }
- )
- mTestHelper.await(latch2)
+ val keysVersionResult = mTestHelper.doSync {
+ testData.aliceSession2.cryptoService().keysBackupService().getCurrentVersion(it)
+ }
// - It must be the same
assertEquals(testData.prepareKeysBackupDataResult.version, keysVersionResult!!.version)
- val latch3 = CountDownLatch(1)
- var keysBackupVersionTrust: KeysBackupVersionTrust? = null
- testData.aliceSession2.getKeysBackupService().getKeysBackupTrust(keysVersionResult!!,
- object : TestMatrixCallback(latch3) {
- override fun onSuccess(data: KeysBackupVersionTrust) {
- keysBackupVersionTrust = data
- super.onSuccess(data)
- }
- })
- mTestHelper.await(latch3)
+ val keysBackupVersionTrust = mTestHelper.doSync {
+ testData.aliceSession2.cryptoService().keysBackupService().getKeysBackupTrust(keysVersionResult, it)
+ }
// - It must be trusted and must have 2 signatures now
- assertTrue(keysBackupVersionTrust!!.usable)
- assertEquals(2, keysBackupVersionTrust!!.signatures.size)
+ assertTrue(keysBackupVersionTrust.usable)
+ assertEquals(2, keysBackupVersionTrust.signatures.size)
stateObserver.stopAndCheckStates(null)
- testData.cryptoTestData.close()
+ testData.cleanUp(mTestHelper)
}
/**
@@ -503,62 +442,47 @@ class KeysBackupTest : InstrumentedTest {
// - And log Alice on a new device
val testData = createKeysBackupScenarioWithPassword(null)
- val stateObserver = StateObserver(testData.aliceSession2.getKeysBackupService())
+ val stateObserver = StateObserver(testData.aliceSession2.cryptoService().keysBackupService())
// - The new device must see the previous backup as not trusted
- assertNotNull(testData.aliceSession2.getKeysBackupService().keysBackupVersion)
- assertFalse(testData.aliceSession2.getKeysBackupService().isEnabled)
- assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.getKeysBackupService().state)
+ assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
+ assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
+ assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
// - Trust the backup from the new device with the recovery key
- val latch = CountDownLatch(1)
- testData.aliceSession2.getKeysBackupService().trustKeysBackupVersionWithRecoveryKey(
- testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
- testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey,
- TestMatrixCallback(latch)
- )
- mTestHelper.await(latch)
+ mTestHelper.doSync {
+ testData.aliceSession2.cryptoService().keysBackupService().trustKeysBackupVersionWithRecoveryKey(
+ testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
+ testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey,
+ it
+ )
+ }
// Wait for backup state to be ReadyToBackUp
waitForKeysBackupToBeInState(testData.aliceSession2, KeysBackupState.ReadyToBackUp)
// - Backup must be enabled on the new device, on the same version
- assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.getKeysBackupService().keysBackupVersion?.version)
- assertTrue(testData.aliceSession2.getKeysBackupService().isEnabled)
+ assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion?.version)
+ assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
// - Retrieve the last version from the server
- val latch2 = CountDownLatch(1)
- var keysVersionResult: KeysVersionResult? = null
- testData.aliceSession2.getKeysBackupService().getCurrentVersion(
- object : TestMatrixCallback(latch2) {
- override fun onSuccess(data: KeysVersionResult?) {
- keysVersionResult = data
- super.onSuccess(data)
- }
- }
- )
- mTestHelper.await(latch2)
+ val keysVersionResult = mTestHelper.doSync {
+ testData.aliceSession2.cryptoService().keysBackupService().getCurrentVersion(it)
+ }
// - It must be the same
assertEquals(testData.prepareKeysBackupDataResult.version, keysVersionResult!!.version)
- val latch3 = CountDownLatch(1)
- var keysBackupVersionTrust: KeysBackupVersionTrust? = null
- testData.aliceSession2.getKeysBackupService().getKeysBackupTrust(keysVersionResult!!,
- object : TestMatrixCallback(latch3) {
- override fun onSuccess(data: KeysBackupVersionTrust) {
- keysBackupVersionTrust = data
- super.onSuccess(data)
- }
- })
- mTestHelper.await(latch3)
+ val keysBackupVersionTrust = mTestHelper.doSync {
+ testData.aliceSession2.cryptoService().keysBackupService().getKeysBackupTrust(keysVersionResult, it)
+ }
// - It must be trusted and must have 2 signatures now
- assertTrue(keysBackupVersionTrust!!.usable)
- assertEquals(2, keysBackupVersionTrust!!.signatures.size)
+ assertTrue(keysBackupVersionTrust.usable)
+ assertEquals(2, keysBackupVersionTrust.signatures.size)
stateObserver.stopAndCheckStates(null)
- testData.cryptoTestData.close()
+ testData.cleanUp(mTestHelper)
}
/**
@@ -575,29 +499,29 @@ class KeysBackupTest : InstrumentedTest {
// - And log Alice on a new device
val testData = createKeysBackupScenarioWithPassword(null)
- val stateObserver = StateObserver(testData.aliceSession2.getKeysBackupService())
+ val stateObserver = StateObserver(testData.aliceSession2.cryptoService().keysBackupService())
// - The new device must see the previous backup as not trusted
- assertNotNull(testData.aliceSession2.getKeysBackupService().keysBackupVersion)
- assertFalse(testData.aliceSession2.getKeysBackupService().isEnabled)
- assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.getKeysBackupService().state)
+ assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
+ assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
+ assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
// - Try to trust the backup from the new device with a wrong recovery key
val latch = CountDownLatch(1)
- testData.aliceSession2.getKeysBackupService().trustKeysBackupVersionWithRecoveryKey(
- testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
+ testData.aliceSession2.cryptoService().keysBackupService().trustKeysBackupVersionWithRecoveryKey(
+ testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
"Bad recovery key",
TestMatrixCallback(latch, false)
)
mTestHelper.await(latch)
// - The new device must still see the previous backup as not trusted
- assertNotNull(testData.aliceSession2.getKeysBackupService().keysBackupVersion)
- assertFalse(testData.aliceSession2.getKeysBackupService().isEnabled)
- assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.getKeysBackupService().state)
+ assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
+ assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
+ assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
stateObserver.stopAndCheckStates(null)
- testData.cryptoTestData.close()
+ testData.cleanUp(mTestHelper)
}
/**
@@ -618,62 +542,47 @@ class KeysBackupTest : InstrumentedTest {
// - And log Alice on a new device
val testData = createKeysBackupScenarioWithPassword(password)
- val stateObserver = StateObserver(testData.aliceSession2.getKeysBackupService())
+ val stateObserver = StateObserver(testData.aliceSession2.cryptoService().keysBackupService())
// - The new device must see the previous backup as not trusted
- assertNotNull(testData.aliceSession2.getKeysBackupService().keysBackupVersion)
- assertFalse(testData.aliceSession2.getKeysBackupService().isEnabled)
- assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.getKeysBackupService().state)
+ assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
+ assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
+ assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
// - Trust the backup from the new device with the password
- val latch = CountDownLatch(1)
- testData.aliceSession2.getKeysBackupService().trustKeysBackupVersionWithPassphrase(
- testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
- password,
- TestMatrixCallback(latch)
- )
- mTestHelper.await(latch)
+ mTestHelper.doSync {
+ testData.aliceSession2.cryptoService().keysBackupService().trustKeysBackupVersionWithPassphrase(
+ testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
+ password,
+ it
+ )
+ }
// Wait for backup state to be ReadyToBackUp
waitForKeysBackupToBeInState(testData.aliceSession2, KeysBackupState.ReadyToBackUp)
// - Backup must be enabled on the new device, on the same version
- assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.getKeysBackupService().keysBackupVersion?.version)
- assertTrue(testData.aliceSession2.getKeysBackupService().isEnabled)
+ assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion?.version)
+ assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
// - Retrieve the last version from the server
- val latch2 = CountDownLatch(1)
- var keysVersionResult: KeysVersionResult? = null
- testData.aliceSession2.getKeysBackupService().getCurrentVersion(
- object : TestMatrixCallback(latch2) {
- override fun onSuccess(data: KeysVersionResult?) {
- keysVersionResult = data
- super.onSuccess(data)
- }
- }
- )
- mTestHelper.await(latch2)
+ val keysVersionResult = mTestHelper.doSync {
+ testData.aliceSession2.cryptoService().keysBackupService().getCurrentVersion(it)
+ }
// - It must be the same
assertEquals(testData.prepareKeysBackupDataResult.version, keysVersionResult!!.version)
- val latch3 = CountDownLatch(1)
- var keysBackupVersionTrust: KeysBackupVersionTrust? = null
- testData.aliceSession2.getKeysBackupService().getKeysBackupTrust(keysVersionResult!!,
- object : TestMatrixCallback(latch3) {
- override fun onSuccess(data: KeysBackupVersionTrust) {
- keysBackupVersionTrust = data
- super.onSuccess(data)
- }
- })
- mTestHelper.await(latch3)
+ val keysBackupVersionTrust = mTestHelper.doSync {
+ testData.aliceSession2.cryptoService().keysBackupService().getKeysBackupTrust(keysVersionResult, it)
+ }
// - It must be trusted and must have 2 signatures now
- assertTrue(keysBackupVersionTrust!!.usable)
- assertEquals(2, keysBackupVersionTrust!!.signatures.size)
+ assertTrue(keysBackupVersionTrust.usable)
+ assertEquals(2, keysBackupVersionTrust.signatures.size)
stateObserver.stopAndCheckStates(null)
- testData.cryptoTestData.close()
+ testData.cleanUp(mTestHelper)
}
/**
@@ -693,29 +602,29 @@ class KeysBackupTest : InstrumentedTest {
// - And log Alice on a new device
val testData = createKeysBackupScenarioWithPassword(password)
- val stateObserver = StateObserver(testData.aliceSession2.getKeysBackupService())
+ val stateObserver = StateObserver(testData.aliceSession2.cryptoService().keysBackupService())
// - The new device must see the previous backup as not trusted
- assertNotNull(testData.aliceSession2.getKeysBackupService().keysBackupVersion)
- assertFalse(testData.aliceSession2.getKeysBackupService().isEnabled)
- assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.getKeysBackupService().state)
+ assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
+ assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
+ assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
// - Try to trust the backup from the new device with a wrong password
val latch = CountDownLatch(1)
- testData.aliceSession2.getKeysBackupService().trustKeysBackupVersionWithPassphrase(
- testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
+ testData.aliceSession2.cryptoService().keysBackupService().trustKeysBackupVersionWithPassphrase(
+ testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
badPassword,
TestMatrixCallback(latch, false)
)
mTestHelper.await(latch)
// - The new device must still see the previous backup as not trusted
- assertNotNull(testData.aliceSession2.getKeysBackupService().keysBackupVersion)
- assertFalse(testData.aliceSession2.getKeysBackupService().isEnabled)
- assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.getKeysBackupService().state)
+ assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
+ assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
+ assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
stateObserver.stopAndCheckStates(null)
- testData.cryptoTestData.close()
+ testData.cleanUp(mTestHelper)
}
/**
@@ -731,7 +640,7 @@ class KeysBackupTest : InstrumentedTest {
// - Try to restore the e2e backup with a wrong recovery key
val latch2 = CountDownLatch(1)
var importRoomKeysResult: ImportRoomKeysResult? = null
- testData.aliceSession2.getKeysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
+ testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
"EsTc LW2K PGiF wKEA 3As5 g5c4 BXwk qeeJ ZJV8 Q9fu gUMN UE4d",
null,
null,
@@ -748,7 +657,7 @@ class KeysBackupTest : InstrumentedTest {
// onSuccess may not have been called
assertNull(importRoomKeysResult)
- testData.cryptoTestData.close()
+ testData.cleanUp(mTestHelper)
}
/**
@@ -764,27 +673,21 @@ class KeysBackupTest : InstrumentedTest {
val testData = createKeysBackupScenarioWithPassword(password)
// - Restore the e2e backup with the password
- val latch2 = CountDownLatch(1)
- var importRoomKeysResult: ImportRoomKeysResult? = null
val steps = ArrayList()
- testData.aliceSession2.getKeysBackupService().restoreKeyBackupWithPassword(testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
- password,
- null,
- null,
- object : StepProgressListener {
- override fun onStepProgress(step: StepProgressListener.Step) {
- steps.add(step)
- }
- },
- object : TestMatrixCallback(latch2) {
- override fun onSuccess(data: ImportRoomKeysResult) {
- importRoomKeysResult = data
- super.onSuccess(data)
- }
- }
- )
- mTestHelper.await(latch2)
+ val importRoomKeysResult = mTestHelper.doSync {
+ testData.aliceSession2.cryptoService().keysBackupService().restoreKeyBackupWithPassword(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
+ password,
+ null,
+ null,
+ object : StepProgressListener {
+ override fun onStepProgress(step: StepProgressListener.Step) {
+ steps.add(step)
+ }
+ },
+ it
+ )
+ }
// Check steps
assertEquals(105, steps.size)
@@ -807,9 +710,9 @@ class KeysBackupTest : InstrumentedTest {
assertEquals(50, (steps[103] as StepProgressListener.Step.ImportingKey).progress)
assertEquals(100, (steps[104] as StepProgressListener.Step.ImportingKey).progress)
- checkRestoreSuccess(testData, importRoomKeysResult!!.totalNumberOfKeys, importRoomKeysResult!!.successfullyNumberOfImportedKeys)
+ checkRestoreSuccess(testData, importRoomKeysResult.totalNumberOfKeys, importRoomKeysResult.successfullyNumberOfImportedKeys)
- testData.cryptoTestData.close()
+ testData.cleanUp(mTestHelper)
}
/**
@@ -828,7 +731,7 @@ class KeysBackupTest : InstrumentedTest {
// - Try to restore the e2e backup with a wrong password
val latch2 = CountDownLatch(1)
var importRoomKeysResult: ImportRoomKeysResult? = null
- testData.aliceSession2.getKeysBackupService().restoreKeyBackupWithPassword(testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
+ testData.aliceSession2.cryptoService().keysBackupService().restoreKeyBackupWithPassword(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
wrongPassword,
null,
null,
@@ -845,7 +748,7 @@ class KeysBackupTest : InstrumentedTest {
// onSuccess may not have been called
assertNull(importRoomKeysResult)
- testData.cryptoTestData.close()
+ testData.cleanUp(mTestHelper)
}
/**
@@ -861,25 +764,19 @@ class KeysBackupTest : InstrumentedTest {
val testData = createKeysBackupScenarioWithPassword(password)
// - Restore the e2e backup with the recovery key.
- val latch2 = CountDownLatch(1)
- var importRoomKeysResult: ImportRoomKeysResult? = null
- testData.aliceSession2.getKeysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
- testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey,
- null,
- null,
- null,
- object : TestMatrixCallback(latch2) {
- override fun onSuccess(data: ImportRoomKeysResult) {
- importRoomKeysResult = data
- super.onSuccess(data)
- }
- }
- )
- mTestHelper.await(latch2)
+ val importRoomKeysResult = mTestHelper.doSync {
+ testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
+ testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey,
+ null,
+ null,
+ null,
+ it
+ )
+ }
- checkRestoreSuccess(testData, importRoomKeysResult!!.totalNumberOfKeys, importRoomKeysResult!!.successfullyNumberOfImportedKeys)
+ checkRestoreSuccess(testData, importRoomKeysResult.totalNumberOfKeys, importRoomKeysResult.successfullyNumberOfImportedKeys)
- testData.cryptoTestData.close()
+ testData.cleanUp(mTestHelper)
}
/**
@@ -895,7 +792,7 @@ class KeysBackupTest : InstrumentedTest {
// - Try to restore the e2e backup with a password
val latch2 = CountDownLatch(1)
var importRoomKeysResult: ImportRoomKeysResult? = null
- testData.aliceSession2.getKeysBackupService().restoreKeyBackupWithPassword(testData.aliceSession2.getKeysBackupService().keysBackupVersion!!,
+ testData.aliceSession2.cryptoService().keysBackupService().restoreKeyBackupWithPassword(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
"password",
null,
null,
@@ -912,7 +809,7 @@ class KeysBackupTest : InstrumentedTest {
// onSuccess may not have been called
assertNull(importRoomKeysResult)
- testData.cryptoTestData.close()
+ testData.cleanUp(mTestHelper)
}
/**
@@ -924,7 +821,7 @@ class KeysBackupTest : InstrumentedTest {
// - Create a backup version
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
- val keysBackup = cryptoTestData.firstSession.getKeysBackupService()
+ val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService()
val stateObserver = StateObserver(keysBackup)
@@ -932,46 +829,27 @@ class KeysBackupTest : InstrumentedTest {
prepareAndCreateKeysBackupData(keysBackup)
// Get key backup version from the home server
- var keysVersionResult: KeysVersionResult? = null
- val lock = CountDownLatch(1)
- keysBackup.getCurrentVersion(object : TestMatrixCallback(lock) {
- override fun onSuccess(data: KeysVersionResult?) {
- keysVersionResult = data
- super.onSuccess(data)
- }
- })
- mTestHelper.await(lock)
-
- assertNotNull(keysVersionResult)
+ val keysVersionResult = mTestHelper.doSync {
+ keysBackup.getCurrentVersion(it)
+ }
// - Check the returned KeyBackupVersion is trusted
- val latch = CountDownLatch(1)
- var keysBackupVersionTrust: KeysBackupVersionTrust? = null
- keysBackup.getKeysBackupTrust(keysVersionResult!!, object : MatrixCallback {
- override fun onSuccess(data: KeysBackupVersionTrust) {
- keysBackupVersionTrust = data
- latch.countDown()
- }
-
- override fun onFailure(failure: Throwable) {
- super.onFailure(failure)
- latch.countDown()
- }
- })
- mTestHelper.await(latch)
+ val keysBackupVersionTrust = mTestHelper.doSync {
+ keysBackup.getKeysBackupTrust(keysVersionResult!!, it)
+ }
assertNotNull(keysBackupVersionTrust)
- assertTrue(keysBackupVersionTrust!!.usable)
- assertEquals(1, keysBackupVersionTrust!!.signatures.size)
+ assertTrue(keysBackupVersionTrust.usable)
+ assertEquals(1, keysBackupVersionTrust.signatures.size)
- val signature = keysBackupVersionTrust!!.signatures[0]
+ val signature = keysBackupVersionTrust.signatures[0]
assertTrue(signature.valid)
assertNotNull(signature.device)
- assertEquals(cryptoTestData.firstSession.getMyDevice().deviceId, signature.deviceId)
+ assertEquals(cryptoTestData.firstSession.cryptoService().getMyDevice().deviceId, signature.deviceId)
assertEquals(signature.device!!.deviceId, cryptoTestData.firstSession.sessionParams.credentials.deviceId)
stateObserver.stopAndCheckStates(null)
- cryptoTestData.close()
+ cryptoTestData.cleanUp(mTestHelper)
}
/**
@@ -983,10 +861,11 @@ class KeysBackupTest : InstrumentedTest {
*/
@Test
fun testCheckAndStartKeysBackupWhenRestartingAMatrixSession() {
+ fail("This test still fail. To investigate")
// - Create a backup version
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
- val keysBackup = cryptoTestData.firstSession.getKeysBackupService()
+ val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService()
val stateObserver = StateObserver(keysBackup)
@@ -1000,9 +879,9 @@ class KeysBackupTest : InstrumentedTest {
// - Log Alice on a new device
val aliceSession2 = mTestHelper.logIntoAccount(cryptoTestData.firstSession.myUserId, defaultSessionParamsWithInitialSync)
- cryptoTestData.close()
+ cryptoTestData.cleanUp(mTestHelper)
- val keysBackup2 = aliceSession2.getKeysBackupService()
+ val keysBackup2 = aliceSession2.cryptoService().keysBackupService()
val stateObserver2 = StateObserver(keysBackup2)
@@ -1012,12 +891,12 @@ class KeysBackupTest : InstrumentedTest {
keysBackup2.addListener(object : KeysBackupStateListener {
override fun onStateChange(newState: KeysBackupState) {
// Check the backup completes
- if (keysBackup.state == KeysBackupState.ReadyToBackUp) {
+ if (newState == KeysBackupState.ReadyToBackUp) {
count++
if (count == 2) {
// Remove itself from the list of listeners
- keysBackup.removeListener(this)
+ keysBackup2.removeListener(this)
latch.countDown()
}
@@ -1030,7 +909,7 @@ class KeysBackupTest : InstrumentedTest {
stateObserver.stopAndCheckStates(null)
stateObserver2.stopAndCheckStates(null)
- aliceSession2.close()
+ mTestHelper.signOutAndClose(aliceSession2)
}
/**
@@ -1046,7 +925,7 @@ class KeysBackupTest : InstrumentedTest {
// - Create a backup version
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
- val keysBackup = cryptoTestData.firstSession.getKeysBackupService()
+ val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService()
val stateObserver = StateObserver(keysBackup)
@@ -1079,21 +958,17 @@ class KeysBackupTest : InstrumentedTest {
mTestHelper.await(latch0)
// - Create a new backup with fake data on the homeserver, directly using the rest client
- val latch = CountDownLatch(1)
-
val megolmBackupCreationInfo = mCryptoTestHelper.createFakeMegolmBackupCreationInfo()
- (keysBackup as KeysBackup).createFakeKeysBackupVersion(megolmBackupCreationInfo, TestMatrixCallback(latch))
- mTestHelper.await(latch)
+ mTestHelper.doSync {
+ (keysBackup as DefaultKeysBackupService).createFakeKeysBackupVersion(megolmBackupCreationInfo, it)
+ }
// Reset the store backup status for keys
- (cryptoTestData.firstSession.getKeysBackupService() as KeysBackup).store.resetBackupMarkers()
+ (cryptoTestData.firstSession.cryptoService().keysBackupService() as DefaultKeysBackupService).store.resetBackupMarkers()
// - Make alice back up all her keys again
val latch2 = CountDownLatch(1)
- keysBackup.backupAllGroupSessions(object : ProgressListener {
- override fun onProgress(progress: Int, total: Int) {
- }
- }, TestMatrixCallback(latch2, false))
+ keysBackup.backupAllGroupSessions(null, TestMatrixCallback(latch2, false))
mTestHelper.await(latch2)
// -> That must fail and her backup state must be WrongBackUpVersion
@@ -1101,7 +976,7 @@ class KeysBackupTest : InstrumentedTest {
assertFalse(keysBackup.isEnabled)
stateObserver.stopAndCheckStates(null)
- cryptoTestData.close()
+ cryptoTestData.cleanUp(mTestHelper)
}
/**
@@ -1121,7 +996,7 @@ class KeysBackupTest : InstrumentedTest {
// - Create a backup version
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
- val keysBackup = cryptoTestData.firstSession.getKeysBackupService()
+ val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService()
val stateObserver = StateObserver(keysBackup)
@@ -1129,46 +1004,39 @@ class KeysBackupTest : InstrumentedTest {
prepareAndCreateKeysBackupData(keysBackup)
// Wait for keys backup to finish by asking again to backup keys.
- val latch = CountDownLatch(1)
- keysBackup.backupAllGroupSessions(object : ProgressListener {
- override fun onProgress(progress: Int, total: Int) {
- }
- }, TestMatrixCallback(latch))
- mTestHelper.await(latch)
+ mTestHelper.doSync {
+ keysBackup.backupAllGroupSessions(null, it)
+ }
val oldDeviceId = cryptoTestData.firstSession.sessionParams.credentials.deviceId!!
val oldKeyBackupVersion = keysBackup.currentBackupVersion
val aliceUserId = cryptoTestData.firstSession.myUserId
- // Close first Alice session, else they will share the same Crypto store and the test fails.
- cryptoTestData.firstSession.close()
-
// - Log Alice on a new device
val aliceSession2 = mTestHelper.logIntoAccount(aliceUserId, defaultSessionParamsWithInitialSync)
// - Post a message to have a new megolm session
- aliceSession2.setWarnOnUnknownDevices(false)
+ aliceSession2.cryptoService().setWarnOnUnknownDevices(false)
val room2 = aliceSession2.getRoom(cryptoTestData.roomId)!!
mTestHelper.sendTextMessage(room2, "New key", 1)
// - Try to backup all in aliceSession2, it must fail
- val keysBackup2 = aliceSession2.getKeysBackupService()
+ val keysBackup2 = aliceSession2.cryptoService().keysBackupService()
val stateObserver2 = StateObserver(keysBackup2)
var isSuccessful = false
val latch2 = CountDownLatch(1)
- keysBackup2.backupAllGroupSessions(object : ProgressListener {
- override fun onProgress(progress: Int, total: Int) {
- }
- }, object : TestMatrixCallback(latch2, false) {
- override fun onSuccess(data: Unit) {
- isSuccessful = true
- super.onSuccess(data)
- }
- })
+ keysBackup2.backupAllGroupSessions(
+ null,
+ object : TestMatrixCallback(latch2, false) {
+ override fun onSuccess(data: Unit) {
+ isSuccessful = true
+ super.onSuccess(data)
+ }
+ })
mTestHelper.await(latch2)
assertFalse(isSuccessful)
@@ -1178,7 +1046,7 @@ class KeysBackupTest : InstrumentedTest {
assertFalse(keysBackup2.isEnabled)
// - Validate the old device from the new one
- aliceSession2.setDeviceVerification(DeviceTrustLevel(false, true), aliceSession2.myUserId, oldDeviceId)
+ aliceSession2.cryptoService().setDeviceVerification(DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true), aliceSession2.myUserId, oldDeviceId)
// -> Backup should automatically enable on the new device
val latch4 = CountDownLatch(1)
@@ -1196,19 +1064,19 @@ class KeysBackupTest : InstrumentedTest {
mTestHelper.await(latch4)
// -> It must use the same backup version
- assertEquals(oldKeyBackupVersion, aliceSession2.getKeysBackupService().currentBackupVersion)
+ assertEquals(oldKeyBackupVersion, aliceSession2.cryptoService().keysBackupService().currentBackupVersion)
- val latch5 = CountDownLatch(1)
- aliceSession2.getKeysBackupService().backupAllGroupSessions(null, TestMatrixCallback(latch5))
- mTestHelper.await(latch5)
+ mTestHelper.doSync {
+ aliceSession2.cryptoService().keysBackupService().backupAllGroupSessions(null, it)
+ }
// -> It must success
- assertTrue(aliceSession2.getKeysBackupService().isEnabled)
+ assertTrue(aliceSession2.cryptoService().keysBackupService().isEnabled)
stateObserver.stopAndCheckStates(null)
stateObserver2.stopAndCheckStates(null)
- aliceSession2.close()
- cryptoTestData.close()
+ mTestHelper.signOutAndClose(aliceSession2)
+ cryptoTestData.cleanUp(mTestHelper)
}
/**
@@ -1220,7 +1088,7 @@ class KeysBackupTest : InstrumentedTest {
// - Create a backup version
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
- val keysBackup = cryptoTestData.firstSession.getKeysBackupService()
+ val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService()
val stateObserver = StateObserver(keysBackup)
@@ -1230,18 +1098,14 @@ class KeysBackupTest : InstrumentedTest {
assertTrue(keysBackup.isEnabled)
- val latch = CountDownLatch(1)
-
// Delete the backup
- keysBackup.deleteBackup(keyBackupCreationInfo.version, TestMatrixCallback(latch))
-
- mTestHelper.await(latch)
+ mTestHelper.doSync { keysBackup.deleteBackup(keyBackupCreationInfo.version, it) }
// Backup is now disabled
assertFalse(keysBackup.isEnabled)
stateObserver.stopAndCheckStates(null)
- cryptoTestData.close()
+ cryptoTestData.cleanUp(mTestHelper)
}
/* ==========================================================================================
@@ -1254,17 +1118,17 @@ class KeysBackupTest : InstrumentedTest {
*/
private fun waitForKeysBackupToBeInState(session: Session, state: KeysBackupState) {
// If already in the wanted state, return
- if (session.getKeysBackupService().state == state) {
+ if (session.cryptoService().keysBackupService().state == state) {
return
}
// Else observe state changes
val latch = CountDownLatch(1)
- session.getKeysBackupService().addListener(object : KeysBackupStateListener {
+ session.cryptoService().keysBackupService().addListener(object : KeysBackupStateListener {
override fun onStateChange(newState: KeysBackupState) {
if (newState == state) {
- session.getKeysBackupService().removeListener(this)
+ session.cryptoService().keysBackupService().removeListener(this)
latch.countDown()
}
}
@@ -1280,49 +1144,26 @@ class KeysBackupTest : InstrumentedTest {
password: String? = null): PrepareKeysBackupDataResult {
val stateObserver = StateObserver(keysBackup)
- var megolmBackupCreationInfo: MegolmBackupCreationInfo? = null
- val latch = CountDownLatch(1)
- keysBackup.prepareKeysBackupVersion(password, null, object : MatrixCallback {
- override fun onSuccess(data: MegolmBackupCreationInfo) {
- megolmBackupCreationInfo = data
-
- latch.countDown()
- }
-
- override fun onFailure(failure: Throwable) {
- fail(failure.localizedMessage)
-
- latch.countDown()
- }
- })
- mTestHelper.await(latch)
+ val megolmBackupCreationInfo = mTestHelper.doSync {
+ keysBackup.prepareKeysBackupVersion(password, null, it)
+ }
assertNotNull(megolmBackupCreationInfo)
assertFalse(keysBackup.isEnabled)
- val latch2 = CountDownLatch(1)
-
// Create the version
- var version: String? = null
- keysBackup.createKeysBackupVersion(megolmBackupCreationInfo!!, object : TestMatrixCallback(latch2) {
- override fun onSuccess(data: KeysVersion) {
- assertNotNull(data)
- assertNotNull(data.version)
+ val keysVersion = mTestHelper.doSync {
+ keysBackup.createKeysBackupVersion(megolmBackupCreationInfo, it)
+ }
- version = data.version
-
- super.onSuccess(data)
- }
- })
- mTestHelper.await(latch2)
+ assertNotNull(keysVersion.version)
// Backup must be enable now
assertTrue(keysBackup.isEnabled)
- assertNotNull(version)
stateObserver.stopAndCheckStates(null)
- return PrepareKeysBackupDataResult(megolmBackupCreationInfo!!, version!!)
+ return PrepareKeysBackupDataResult(megolmBackupCreationInfo, keysVersion.version!!)
}
private fun assertKeysEquals(keys1: MegolmSessionData?, keys2: MegolmSessionData?) {
@@ -1347,7 +1188,12 @@ class KeysBackupTest : InstrumentedTest {
private data class KeysBackupScenarioData(val cryptoTestData: CryptoTestData,
val aliceKeys: List,
val prepareKeysBackupDataResult: PrepareKeysBackupDataResult,
- val aliceSession2: Session)
+ val aliceSession2: Session) {
+ fun cleanUp(testHelper: CommonTestHelper) {
+ cryptoTestData.cleanUp(testHelper)
+ testHelper.signOutAndClose(aliceSession2)
+ }
+ }
/**
* Common initial condition
@@ -1359,8 +1205,8 @@ class KeysBackupTest : InstrumentedTest {
private fun createKeysBackupScenarioWithPassword(password: String?): KeysBackupScenarioData {
val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages()
- val cryptoStore = (cryptoTestData.firstSession.getKeysBackupService() as KeysBackup).store
- val keysBackup = cryptoTestData.firstSession.getKeysBackupService()
+ val cryptoStore = (cryptoTestData.firstSession.cryptoService().keysBackupService() as DefaultKeysBackupService).store
+ val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService()
val stateObserver = StateObserver(keysBackup)
@@ -1369,32 +1215,27 @@ class KeysBackupTest : InstrumentedTest {
// - Do an e2e backup to the homeserver
val prepareKeysBackupDataResult = prepareAndCreateKeysBackupData(keysBackup, password)
- val latch = CountDownLatch(1)
var lastProgress = 0
var lastTotal = 0
- keysBackup.backupAllGroupSessions(object : ProgressListener {
- override fun onProgress(progress: Int, total: Int) {
- lastProgress = progress
- lastTotal = total
- }
- }, TestMatrixCallback(latch))
- mTestHelper.await(latch)
+ mTestHelper.doSync {
+ keysBackup.backupAllGroupSessions(object : ProgressListener {
+ override fun onProgress(progress: Int, total: Int) {
+ lastProgress = progress
+ lastTotal = total
+ }
+ }, it)
+ }
assertEquals(2, lastProgress)
assertEquals(2, lastTotal)
val aliceUserId = cryptoTestData.firstSession.myUserId
- // Logout first Alice session, else they will share the same Crypto store and some tests may fail.
- val latch2 = CountDownLatch(1)
- cryptoTestData.firstSession.signOut(true, TestMatrixCallback(latch2))
- mTestHelper.await(latch2)
-
// - Log Alice on a new device
val aliceSession2 = mTestHelper.logIntoAccount(aliceUserId, defaultSessionParamsWithInitialSync)
// Test check: aliceSession2 has no keys at login
- assertEquals(0, aliceSession2.inboundGroupSessionsCount(false))
+ assertEquals(0, aliceSession2.cryptoService().inboundGroupSessionsCount(false))
// Wait for backup state to be NotTrusted
waitForKeysBackupToBeInState(aliceSession2, KeysBackupState.NotTrusted)
@@ -1421,11 +1262,11 @@ class KeysBackupTest : InstrumentedTest {
assertEquals(total, imported)
// - The new device must have the same count of megolm keys
- assertEquals(testData.aliceKeys.size, testData.aliceSession2.inboundGroupSessionsCount(false))
+ assertEquals(testData.aliceKeys.size, testData.aliceSession2.cryptoService().inboundGroupSessionsCount(false))
// - Alice must have the same keys on both devices
for (aliceKey1 in testData.aliceKeys) {
- val aliceKey2 = (testData.aliceSession2.getKeysBackupService() as KeysBackup).store
+ val aliceKey2 = (testData.aliceSession2.cryptoService().keysBackupService() as DefaultKeysBackupService).store
.getInboundGroupSession(aliceKey1.olmInboundGroupSession!!.sessionIdentifier(), aliceKey1.senderKey!!)
assertNotNull(aliceKey2)
assertKeysEquals(aliceKey1.exportKeys(), aliceKey2!!.exportKeys())
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/ssss/QuadSTests.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/ssss/QuadSTests.kt
new file mode 100644
index 0000000000..1a0723c725
--- /dev/null
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/ssss/QuadSTests.kt
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.internal.crypto.ssss
+
+import androidx.lifecycle.Observer
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import im.vector.matrix.android.InstrumentedTest
+import im.vector.matrix.android.api.MatrixCallback
+import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.api.session.securestorage.EncryptedSecretContent
+import im.vector.matrix.android.api.session.securestorage.KeySigner
+import im.vector.matrix.android.api.session.securestorage.RawBytesKeySpec
+import im.vector.matrix.android.api.session.securestorage.SecretStorageKeyContent
+import im.vector.matrix.android.api.session.securestorage.SharedSecretStorageService
+import im.vector.matrix.android.api.session.securestorage.SsssKeyCreationInfo
+import im.vector.matrix.android.api.util.Optional
+import im.vector.matrix.android.common.CommonTestHelper
+import im.vector.matrix.android.common.SessionTestParams
+import im.vector.matrix.android.common.TestConstants
+import im.vector.matrix.android.common.TestMatrixCallback
+import im.vector.matrix.android.internal.crypto.SSSS_ALGORITHM_AES_HMAC_SHA2
+import im.vector.matrix.android.internal.crypto.crosssigning.toBase64NoPadding
+import im.vector.matrix.android.internal.crypto.secrets.DefaultSharedSecretStorageService
+import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
+import org.amshove.kluent.shouldBe
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertNull
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import java.util.concurrent.CountDownLatch
+
+@RunWith(AndroidJUnit4::class)
+@FixMethodOrder(MethodSorters.JVM)
+class QuadSTests : InstrumentedTest {
+
+ private val mTestHelper = CommonTestHelper(context())
+
+ private val emptyKeySigner = object : KeySigner {
+ override fun sign(canonicalJson: String): Map>? {
+ return null
+ }
+ }
+
+ @Test
+ fun test_Generate4SKey() {
+ val aliceSession = mTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true))
+
+ val quadS = aliceSession.sharedSecretStorageService
+
+ val TEST_KEY_ID = "my.test.Key"
+
+ mTestHelper.doSync {
+ quadS.generateKey(TEST_KEY_ID, "Test Key", emptyKeySigner, it)
+ }
+
+ // Assert Account data is updated
+ val accountDataLock = CountDownLatch(1)
+ var accountData: UserAccountDataEvent? = null
+
+ val liveAccountData = runBlocking(Dispatchers.Main) {
+ aliceSession.getLiveAccountDataEvent("${DefaultSharedSecretStorageService.KEY_ID_BASE}.$TEST_KEY_ID")
+ }
+ val accountDataObserver = Observer?> { t ->
+ if (t?.getOrNull()?.type == "${DefaultSharedSecretStorageService.KEY_ID_BASE}.$TEST_KEY_ID") {
+ accountData = t.getOrNull()
+ accountDataLock.countDown()
+ }
+ }
+ GlobalScope.launch(Dispatchers.Main) { liveAccountData.observeForever(accountDataObserver) }
+
+ mTestHelper.await(accountDataLock)
+
+ assertNotNull("Key should be stored in account data", accountData)
+ val parsed = SecretStorageKeyContent.fromJson(accountData!!.content)
+ assertNotNull("Key Content cannot be parsed", parsed)
+ assertEquals("Unexpected Algorithm", SSSS_ALGORITHM_AES_HMAC_SHA2, parsed!!.algorithm)
+ assertEquals("Unexpected key name", "Test Key", parsed.name)
+ assertNull("Key was not generated from passphrase", parsed.passphrase)
+
+ // Set as default key
+ quadS.setDefaultKey(TEST_KEY_ID, object : MatrixCallback {})
+
+ var defaultKeyAccountData: UserAccountDataEvent? = null
+ val defaultDataLock = CountDownLatch(1)
+
+ val liveDefAccountData = runBlocking(Dispatchers.Main) {
+ aliceSession.getLiveAccountDataEvent(DefaultSharedSecretStorageService.DEFAULT_KEY_ID)
+ }
+ val accountDefDataObserver = Observer?> { t ->
+ if (t?.getOrNull()?.type == DefaultSharedSecretStorageService.DEFAULT_KEY_ID) {
+ defaultKeyAccountData = t.getOrNull()!!
+ defaultDataLock.countDown()
+ }
+ }
+ GlobalScope.launch(Dispatchers.Main) { liveDefAccountData.observeForever(accountDefDataObserver) }
+
+ mTestHelper.await(defaultDataLock)
+
+ assertNotNull(defaultKeyAccountData?.content)
+ assertEquals("Unexpected default key ${defaultKeyAccountData?.content}", TEST_KEY_ID, defaultKeyAccountData?.content?.get("key"))
+
+ mTestHelper.signOutAndClose(aliceSession)
+ }
+
+ @Test
+ fun test_StoreSecret() {
+ val aliceSession = mTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true))
+ val keyId = "My.Key"
+ val info = generatedSecret(aliceSession, keyId, true)
+
+ val keySpec = RawBytesKeySpec.fromRecoveryKey(info.recoveryKey)
+
+ // Store a secret
+ val clearSecret = "42".toByteArray().toBase64NoPadding()
+ mTestHelper.doSync {
+ aliceSession.sharedSecretStorageService.storeSecret(
+ "secret.of.life",
+ clearSecret,
+ listOf(SharedSecretStorageService.KeyRef(null, keySpec)), // default key
+ it
+ )
+ }
+
+ val secretAccountData = assertAccountData(aliceSession, "secret.of.life")
+
+ val encryptedContent = secretAccountData.content.get("encrypted") as? Map<*, *>
+ assertNotNull("Element should be encrypted", encryptedContent)
+ assertNotNull("Secret should be encrypted with default key", encryptedContent?.get(keyId))
+
+ val secret = EncryptedSecretContent.fromJson(encryptedContent?.get(keyId))
+ assertNotNull(secret?.ciphertext)
+ assertNotNull(secret?.mac)
+ assertNotNull(secret?.initializationVector)
+
+ // Try to decrypt??
+
+ val decryptedSecret = mTestHelper.doSync {
+ aliceSession.sharedSecretStorageService.getSecret(
+ "secret.of.life",
+ null, // default key
+ keySpec!!,
+ it
+ )
+ }
+
+ assertEquals("Secret mismatch", clearSecret, decryptedSecret)
+ mTestHelper.signOutAndClose(aliceSession)
+ }
+
+ @Test
+ fun test_SetDefaultLocalEcho() {
+ val aliceSession = mTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true))
+
+ val quadS = aliceSession.sharedSecretStorageService
+
+ val TEST_KEY_ID = "my.test.Key"
+
+ mTestHelper.doSync {
+ quadS.generateKey(TEST_KEY_ID, "Test Key", emptyKeySigner, it)
+ }
+
+ // Test that we don't need to wait for an account data sync to access directly the keyid from DB
+ mTestHelper.doSync {
+ quadS.setDefaultKey(TEST_KEY_ID, it)
+ }
+
+ mTestHelper.signOutAndClose(aliceSession)
+ }
+
+ @Test
+ fun test_StoreSecretWithMultipleKey() {
+ val aliceSession = mTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true))
+ val keyId1 = "Key.1"
+ val key1Info = generatedSecret(aliceSession, keyId1, true)
+ val keyId2 = "Key2"
+ val key2Info = generatedSecret(aliceSession, keyId2, true)
+
+ val mySecretText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
+
+ mTestHelper.doSync {
+ aliceSession.sharedSecretStorageService.storeSecret(
+ "my.secret",
+ mySecretText.toByteArray().toBase64NoPadding(),
+ listOf(
+ SharedSecretStorageService.KeyRef(keyId1, RawBytesKeySpec.fromRecoveryKey(key1Info.recoveryKey)),
+ SharedSecretStorageService.KeyRef(keyId2, RawBytesKeySpec.fromRecoveryKey(key2Info.recoveryKey))
+ ),
+ it
+ )
+ }
+
+ val accountDataEvent = aliceSession.getAccountDataEvent("my.secret")
+ val encryptedContent = accountDataEvent?.content?.get("encrypted") as? Map<*, *>
+
+ assertEquals("Content should contains two encryptions", 2, encryptedContent?.keys?.size ?: 0)
+
+ assertNotNull(encryptedContent?.get(keyId1))
+ assertNotNull(encryptedContent?.get(keyId2))
+
+ // Assert that can decrypt with both keys
+ mTestHelper.doSync {
+ aliceSession.sharedSecretStorageService.getSecret("my.secret",
+ keyId1,
+ RawBytesKeySpec.fromRecoveryKey(key1Info.recoveryKey)!!,
+ it
+ )
+ }
+
+ mTestHelper.doSync {
+ aliceSession.sharedSecretStorageService.getSecret("my.secret",
+ keyId2,
+ RawBytesKeySpec.fromRecoveryKey(key2Info.recoveryKey)!!,
+ it
+ )
+ }
+
+ mTestHelper.signOutAndClose(aliceSession)
+ }
+
+ @Test
+ fun test_GetSecretWithBadPassphrase() {
+ val aliceSession = mTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true))
+ val keyId1 = "Key.1"
+ val passphrase = "The good pass phrase"
+ val key1Info = generatedSecretFromPassphrase(aliceSession, passphrase, keyId1, true)
+
+ val mySecretText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
+
+ mTestHelper.doSync {
+ aliceSession.sharedSecretStorageService.storeSecret(
+ "my.secret",
+ mySecretText.toByteArray().toBase64NoPadding(),
+ listOf(SharedSecretStorageService.KeyRef(keyId1, RawBytesKeySpec.fromRecoveryKey(key1Info.recoveryKey))),
+ it
+ )
+ }
+
+ val decryptCountDownLatch = CountDownLatch(1)
+ var error = false
+ aliceSession.sharedSecretStorageService.getSecret("my.secret",
+ keyId1,
+ RawBytesKeySpec.fromPassphrase(
+ "A bad passphrase",
+ key1Info.content?.passphrase?.salt ?: "",
+ key1Info.content?.passphrase?.iterations ?: 0,
+ null),
+ object : MatrixCallback {
+ override fun onSuccess(data: String) {
+ decryptCountDownLatch.countDown()
+ }
+
+ override fun onFailure(failure: Throwable) {
+ error = true
+ decryptCountDownLatch.countDown()
+ }
+ }
+ )
+
+ mTestHelper.await(decryptCountDownLatch)
+
+ error shouldBe true
+
+ // Now try with correct key
+ mTestHelper.doSync {
+ aliceSession.sharedSecretStorageService.getSecret("my.secret",
+ keyId1,
+ RawBytesKeySpec.fromPassphrase(
+ passphrase,
+ key1Info.content?.passphrase?.salt ?: "",
+ key1Info.content?.passphrase?.iterations ?: 0,
+ null),
+ it
+ )
+ }
+
+ mTestHelper.signOutAndClose(aliceSession)
+ }
+
+ private fun assertAccountData(session: Session, type: String): UserAccountDataEvent {
+ val accountDataLock = CountDownLatch(1)
+ var accountData: UserAccountDataEvent? = null
+
+ val liveAccountData = runBlocking(Dispatchers.Main) {
+ session.getLiveAccountDataEvent(type)
+ }
+ val accountDataObserver = Observer?> { t ->
+ if (t?.getOrNull()?.type == type) {
+ accountData = t.getOrNull()
+ accountDataLock.countDown()
+ }
+ }
+ GlobalScope.launch(Dispatchers.Main) { liveAccountData.observeForever(accountDataObserver) }
+ mTestHelper.await(accountDataLock)
+
+ assertNotNull("Account Data type:$type should be found", accountData)
+
+ return accountData!!
+ }
+
+ private fun generatedSecret(session: Session, keyId: String, asDefault: Boolean = true): SsssKeyCreationInfo {
+ val quadS = session.sharedSecretStorageService
+
+ val creationInfo = mTestHelper.doSync {
+ quadS.generateKey(keyId, keyId, emptyKeySigner, it)
+ }
+
+ assertAccountData(session, "${DefaultSharedSecretStorageService.KEY_ID_BASE}.$keyId")
+
+ if (asDefault) {
+ mTestHelper.doSync {
+ quadS.setDefaultKey(keyId, it)
+ }
+ assertAccountData(session, DefaultSharedSecretStorageService.DEFAULT_KEY_ID)
+ }
+
+ return creationInfo
+ }
+
+ private fun generatedSecretFromPassphrase(session: Session, passphrase: String, keyId: String, asDefault: Boolean = true): SsssKeyCreationInfo {
+ val quadS = session.sharedSecretStorageService
+
+ val creationInfo = mTestHelper.doSync {
+ quadS.generateKeyWithPassphrase(
+ keyId,
+ keyId,
+ passphrase,
+ emptyKeySigner,
+ null,
+ it)
+ }
+
+ assertAccountData(session, "${DefaultSharedSecretStorageService.KEY_ID_BASE}.$keyId")
+ if (asDefault) {
+ val setDefaultLatch = CountDownLatch(1)
+ quadS.setDefaultKey(keyId, TestMatrixCallback(setDefaultLatch))
+ mTestHelper.await(setDefaultLatch)
+ assertAccountData(session, DefaultSharedSecretStorageService.DEFAULT_KEY_ID)
+ }
+
+ return creationInfo
+ }
+}
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt
index 79670bb21e..db48d7653c 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt
@@ -19,14 +19,14 @@ package im.vector.matrix.android.internal.crypto.verification
import androidx.test.ext.junit.runners.AndroidJUnit4
import im.vector.matrix.android.InstrumentedTest
import im.vector.matrix.android.api.session.Session
-import im.vector.matrix.android.api.session.crypto.sas.CancelCode
-import im.vector.matrix.android.api.session.crypto.sas.IncomingSasVerificationTransaction
-import im.vector.matrix.android.api.session.crypto.sas.OutgoingSasVerificationTransaction
-import im.vector.matrix.android.api.session.crypto.sas.SasMode
-import im.vector.matrix.android.api.session.crypto.sas.VerificationMethod
-import im.vector.matrix.android.api.session.crypto.sas.VerificationService
-import im.vector.matrix.android.api.session.crypto.sas.VerificationTransaction
-import im.vector.matrix.android.api.session.crypto.sas.VerificationTxState
+import im.vector.matrix.android.api.session.crypto.verification.CancelCode
+import im.vector.matrix.android.api.session.crypto.verification.IncomingSasVerificationTransaction
+import im.vector.matrix.android.api.session.crypto.verification.OutgoingSasVerificationTransaction
+import im.vector.matrix.android.api.session.crypto.verification.SasMode
+import im.vector.matrix.android.api.session.crypto.verification.VerificationMethod
+import im.vector.matrix.android.api.session.crypto.verification.VerificationService
+import im.vector.matrix.android.api.session.crypto.verification.VerificationTransaction
+import im.vector.matrix.android.api.session.crypto.verification.VerificationTxState
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.common.CommonTestHelper
@@ -62,8 +62,8 @@ class SASTest : InstrumentedTest {
val aliceSession = cryptoTestData.firstSession
val bobSession = cryptoTestData.secondSession
- val aliceVerificationService = aliceSession.getVerificationService()
- val bobVerificationService = bobSession!!.getVerificationService()
+ val aliceVerificationService = aliceSession.cryptoService().verificationService()
+ val bobVerificationService = bobSession!!.cryptoService().verificationService()
val bobTxCreatedLatch = CountDownLatch(1)
val bobListener = object : VerificationService.Listener {
@@ -75,7 +75,7 @@ class SASTest : InstrumentedTest {
val txID = aliceVerificationService.beginKeyVerification(VerificationMethod.SAS,
bobSession.myUserId,
- bobSession.getMyDevice().deviceId,
+ bobSession.cryptoService().getMyDevice().deviceId,
null)
assertNotNull("Alice should have a started transaction", txID)
@@ -132,7 +132,7 @@ class SASTest : InstrumentedTest {
assertNull(bobVerificationService.getExistingTransaction(aliceSession.myUserId, txID))
assertNull(aliceVerificationService.getExistingTransaction(bobSession.myUserId, txID))
- cryptoTestData.close()
+ cryptoTestData.cleanUp(mTestHelper)
}
@Test
@@ -157,7 +157,7 @@ class SASTest : InstrumentedTest {
}
}
}
- bobSession.getVerificationService().addListener(bobListener)
+ bobSession.cryptoService().verificationService().addListener(bobListener)
// TODO bobSession!!.dataHandler.addListener(object : MXEventListener() {
// TODO override fun onToDeviceEvent(event: Event?) {
@@ -172,7 +172,7 @@ class SASTest : InstrumentedTest {
val aliceSession = cryptoTestData.firstSession
val aliceUserID = aliceSession.myUserId
- val aliceDevice = aliceSession.getMyDevice().deviceId
+ val aliceDevice = aliceSession.cryptoService().getMyDevice().deviceId
val aliceListener = object : VerificationService.Listener {
override fun transactionUpdated(tx: VerificationTransaction) {
@@ -181,7 +181,7 @@ class SASTest : InstrumentedTest {
}
}
}
- aliceSession.getVerificationService().addListener(aliceListener)
+ aliceSession.cryptoService().verificationService().addListener(aliceListener)
fakeBobStart(bobSession, aliceUserID, aliceDevice, tid, protocols = protocols)
@@ -189,7 +189,7 @@ class SASTest : InstrumentedTest {
assertEquals("Request should be cancelled with m.unknown_method", CancelCode.UnknownMethod, cancelReason)
- cryptoTestData.close()
+ cryptoTestData.cleanUp(mTestHelper)
}
@Test
@@ -218,7 +218,7 @@ class SASTest : InstrumentedTest {
val aliceSession = cryptoTestData.firstSession
val aliceUserID = aliceSession.myUserId
- val aliceDevice = aliceSession.getMyDevice().deviceId
+ val aliceDevice = aliceSession.cryptoService().getMyDevice().deviceId
fakeBobStart(bobSession, aliceUserID, aliceDevice, tid, mac = mac)
@@ -227,7 +227,7 @@ class SASTest : InstrumentedTest {
val cancelReq = canceledToDeviceEvent!!.content.toModel()!!
assertEquals("Request should be cancelled with m.unknown_method", CancelCode.UnknownMethod.value, cancelReq.code)
- cryptoTestData.close()
+ cryptoTestData.cleanUp(mTestHelper)
}
@Test
@@ -256,7 +256,7 @@ class SASTest : InstrumentedTest {
val aliceSession = cryptoTestData.firstSession
val aliceUserID = aliceSession.myUserId
- val aliceDevice = aliceSession.getMyDevice().deviceId
+ val aliceDevice = aliceSession.cryptoService().getMyDevice().deviceId
fakeBobStart(bobSession, aliceUserID, aliceDevice, tid, codes = codes)
@@ -265,7 +265,7 @@ class SASTest : InstrumentedTest {
val cancelReq = canceledToDeviceEvent!!.content.toModel()!!
assertEquals("Request should be cancelled with m.unknown_method", CancelCode.UnknownMethod.value, cancelReq.code)
- cryptoTestData.close()
+ cryptoTestData.cleanUp(mTestHelper)
}
private fun fakeBobStart(bobSession: Session,
@@ -277,7 +277,7 @@ class SASTest : InstrumentedTest {
mac: List = SASDefaultVerificationTransaction.KNOWN_MACS,
codes: List = SASDefaultVerificationTransaction.KNOWN_SHORT_CODES) {
val startMessage = KeyVerificationStart(
- fromDevice = bobSession.getMyDevice().deviceId,
+ fromDevice = bobSession.cryptoService().getMyDevice().deviceId,
method = VerificationMethod.SAS.toValue(),
transactionID = tid,
keyAgreementProtocols = protocols,
@@ -307,7 +307,7 @@ class SASTest : InstrumentedTest {
val aliceSession = cryptoTestData.firstSession
val bobSession = cryptoTestData.secondSession
- val aliceVerificationService = aliceSession.getVerificationService()
+ val aliceVerificationService = aliceSession.cryptoService().verificationService()
val aliceCreatedLatch = CountDownLatch(2)
val aliceCancelledLatch = CountDownLatch(2)
@@ -327,14 +327,14 @@ class SASTest : InstrumentedTest {
aliceVerificationService.addListener(aliceListener)
val bobUserId = bobSession!!.myUserId
- val bobDeviceId = bobSession.getMyDevice().deviceId
+ val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
mTestHelper.await(aliceCreatedLatch)
mTestHelper.await(aliceCancelledLatch)
- cryptoTestData.close()
+ cryptoTestData.cleanUp(mTestHelper)
}
/**
@@ -347,8 +347,8 @@ class SASTest : InstrumentedTest {
val aliceSession = cryptoTestData.firstSession
val bobSession = cryptoTestData.secondSession
- val aliceVerificationService = aliceSession.getVerificationService()
- val bobVerificationService = bobSession!!.getVerificationService()
+ val aliceVerificationService = aliceSession.cryptoService().verificationService()
+ val bobVerificationService = bobSession!!.cryptoService().verificationService()
var accepted: KeyVerificationAccept? = null
var startReq: KeyVerificationStart? = null
@@ -377,7 +377,7 @@ class SASTest : InstrumentedTest {
bobVerificationService.addListener(bobListener)
val bobUserId = bobSession.myUserId
- val bobDeviceId = bobSession.getMyDevice().deviceId
+ val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
mTestHelper.await(aliceAcceptedLatch)
@@ -393,7 +393,7 @@ class SASTest : InstrumentedTest {
assertTrue("all agreed Short Code should be known by alice", startReq!!.shortAuthenticationStrings!!.contains(it))
}
- cryptoTestData.close()
+ cryptoTestData.cleanUp(mTestHelper)
}
@Test
@@ -403,8 +403,8 @@ class SASTest : InstrumentedTest {
val aliceSession = cryptoTestData.firstSession
val bobSession = cryptoTestData.secondSession
- val aliceVerificationService = aliceSession.getVerificationService()
- val bobVerificationService = bobSession!!.getVerificationService()
+ val aliceVerificationService = aliceSession.cryptoService().verificationService()
+ val bobVerificationService = bobSession!!.cryptoService().verificationService()
val aliceSASLatch = CountDownLatch(1)
val aliceListener = object : VerificationService.Listener {
@@ -438,7 +438,7 @@ class SASTest : InstrumentedTest {
bobVerificationService.addListener(bobListener)
val bobUserId = bobSession.myUserId
- val bobDeviceId = bobSession.getMyDevice().deviceId
+ val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId
val verificationSAS = aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
mTestHelper.await(aliceSASLatch)
mTestHelper.await(bobSASLatch)
@@ -449,7 +449,7 @@ class SASTest : InstrumentedTest {
assertEquals("Should have same SAS", aliceTx.getShortCodeRepresentation(SasMode.DECIMAL),
bobTx.getShortCodeRepresentation(SasMode.DECIMAL))
- cryptoTestData.close()
+ cryptoTestData.cleanUp(mTestHelper)
}
@Test
@@ -459,8 +459,8 @@ class SASTest : InstrumentedTest {
val aliceSession = cryptoTestData.firstSession
val bobSession = cryptoTestData.secondSession
- val aliceVerificationService = aliceSession.getVerificationService()
- val bobVerificationService = bobSession!!.getVerificationService()
+ val aliceVerificationService = aliceSession.cryptoService().verificationService()
+ val bobVerificationService = bobSession!!.cryptoService().verificationService()
val aliceSASLatch = CountDownLatch(1)
val aliceListener = object : VerificationService.Listener {
@@ -500,20 +500,20 @@ class SASTest : InstrumentedTest {
bobVerificationService.addListener(bobListener)
val bobUserId = bobSession.myUserId
- val bobDeviceId = bobSession.getMyDevice().deviceId
+ val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
mTestHelper.await(aliceSASLatch)
mTestHelper.await(bobSASLatch)
// Assert that devices are verified
- val bobDeviceInfoFromAlicePOV: CryptoDeviceInfo? = aliceSession.getDeviceInfo(bobUserId, bobDeviceId)
- val aliceDeviceInfoFromBobPOV: CryptoDeviceInfo? = bobSession.getDeviceInfo(aliceSession.myUserId, aliceSession.getMyDevice().deviceId)
+ val bobDeviceInfoFromAlicePOV: CryptoDeviceInfo? = aliceSession.cryptoService().getDeviceInfo(bobUserId, bobDeviceId)
+ val aliceDeviceInfoFromBobPOV: CryptoDeviceInfo? = bobSession.cryptoService().getDeviceInfo(aliceSession.myUserId, aliceSession.cryptoService().getMyDevice().deviceId)
// latch wait a bit again
Thread.sleep(1000)
assertTrue("alice device should be verified from bob point of view", aliceDeviceInfoFromBobPOV!!.isVerified)
assertTrue("bob device should be verified from alice point of view", bobDeviceInfoFromAlicePOV!!.isVerified)
- cryptoTestData.close()
+ cryptoTestData.cleanUp(mTestHelper)
}
}
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/HexParser.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/HexParser.kt
new file mode 100644
index 0000000000..387b627713
--- /dev/null
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/HexParser.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.internal.crypto.verification.qrcode
+
+fun hexToByteArray(hex: String): ByteArray {
+ // Remove all spaces
+ return hex.replace(" ", "")
+ .let {
+ if (it.length % 2 != 0) "0$it" else it
+ }
+ .let {
+ ByteArray(it.length / 2)
+ .apply {
+ for (i in this.indices) {
+ val index = i * 2
+ val v = it.substring(index, index + 2).toInt(16)
+ this[i] = v.toByte()
+ }
+ }
+ }
+}
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/QrCodeTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/QrCodeTest.kt
new file mode 100644
index 0000000000..d19fad4b59
--- /dev/null
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/QrCodeTest.kt
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.internal.crypto.verification.qrcode
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import im.vector.matrix.android.InstrumentedTest
+import org.amshove.kluent.shouldBeNull
+import org.amshove.kluent.shouldEqual
+import org.amshove.kluent.shouldEqualTo
+import org.amshove.kluent.shouldNotBeNull
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+
+@RunWith(AndroidJUnit4::class)
+@FixMethodOrder(MethodSorters.JVM)
+class QrCodeTest : InstrumentedTest {
+
+ private val qrCode1 = QrCodeData.VerifyingAnotherUser(
+ transactionId = "MaTransaction",
+ userMasterCrossSigningPublicKey = "ktEwcUP6su1xh+GuE+CYkQ3H6W/DIl+ybHFdaEOrolU",
+ otherUserMasterCrossSigningPublicKey = "TXluZKTZLvSRWOTPlOqLq534bA+/K4zLFKSu9cGLQaU",
+ sharedSecret = "MTIzNDU2Nzg"
+ )
+
+ private val value1 = "MATRIX\u0002\u0000\u0000\u000DMaTransaction\u0092Ñ0qCú²íq\u0087á®\u0013à\u0098\u0091\u000DÇéoÃ\"_²lq]hC«¢UMynd¤Ù.ô\u0091XäÏ\u0094ê\u008B«\u009Døl\u000F¿+\u008CË\u0014¤®õÁ\u008BA¥12345678"
+
+ private val qrCode2 = QrCodeData.SelfVerifyingMasterKeyTrusted(
+ transactionId = "MaTransaction",
+ userMasterCrossSigningPublicKey = "ktEwcUP6su1xh+GuE+CYkQ3H6W/DIl+ybHFdaEOrolU",
+ otherDeviceKey = "TXluZKTZLvSRWOTPlOqLq534bA+/K4zLFKSu9cGLQaU",
+ sharedSecret = "MTIzNDU2Nzg"
+ )
+
+ private val value2 = "MATRIX\u0002\u0001\u0000\u000DMaTransaction\u0092Ñ0qCú²íq\u0087á®\u0013à\u0098\u0091\u000DÇéoÃ\"_²lq]hC«¢UMynd¤Ù.ô\u0091XäÏ\u0094ê\u008B«\u009Døl\u000F¿+\u008CË\u0014¤®õÁ\u008BA¥12345678"
+
+ private val qrCode3 = QrCodeData.SelfVerifyingMasterKeyNotTrusted(
+ transactionId = "MaTransaction",
+ deviceKey = "TXluZKTZLvSRWOTPlOqLq534bA+/K4zLFKSu9cGLQaU",
+ userMasterCrossSigningPublicKey = "ktEwcUP6su1xh+GuE+CYkQ3H6W/DIl+ybHFdaEOrolU",
+ sharedSecret = "MTIzNDU2Nzg"
+ )
+
+ private val value3 = "MATRIX\u0002\u0002\u0000\u000DMaTransactionMynd¤Ù.ô\u0091XäÏ\u0094ê\u008B«\u009Døl\u000F¿+\u008CË\u0014¤®õÁ\u008BA¥\u0092Ñ0qCú²íq\u0087á®\u0013à\u0098\u0091\u000DÇéoÃ\"_²lq]hC«¢U12345678"
+
+ private val sharedSecretByteArray = "12345678".toByteArray(Charsets.ISO_8859_1)
+
+ private val tlx_byteArray = hexToByteArray("4d 79 6e 64 a4 d9 2e f4 91 58 e4 cf 94 ea 8b ab 9d f8 6c 0f bf 2b 8c cb 14 a4 ae f5 c1 8b 41 a5")
+
+ private val kte_byteArray = hexToByteArray("92 d1 30 71 43 fa b2 ed 71 87 e1 ae 13 e0 98 91 0d c7 e9 6f c3 22 5f b2 6c 71 5d 68 43 ab a2 55")
+
+ @Test
+ fun testEncoding1() {
+ qrCode1.toEncodedString() shouldEqual value1
+ }
+
+ @Test
+ fun testEncoding2() {
+ qrCode2.toEncodedString() shouldEqual value2
+ }
+
+ @Test
+ fun testEncoding3() {
+ qrCode3.toEncodedString() shouldEqual value3
+ }
+
+ @Test
+ fun testSymmetry1() {
+ qrCode1.toEncodedString().toQrCodeData() shouldEqual qrCode1
+ }
+
+ @Test
+ fun testSymmetry2() {
+ qrCode2.toEncodedString().toQrCodeData() shouldEqual qrCode2
+ }
+
+ @Test
+ fun testSymmetry3() {
+ qrCode3.toEncodedString().toQrCodeData() shouldEqual qrCode3
+ }
+
+ @Test
+ fun testCase1() {
+ val url = qrCode1.toEncodedString()
+
+ val byteArray = url.toByteArray(Charsets.ISO_8859_1)
+ checkHeader(byteArray)
+
+ // Mode
+ byteArray[7] shouldEqualTo 0
+
+ checkSizeAndTransaction(byteArray)
+
+ compareArray(byteArray.copyOfRange(23, 23 + 32), kte_byteArray)
+ compareArray(byteArray.copyOfRange(23 + 32, 23 + 64), tlx_byteArray)
+
+ compareArray(byteArray.copyOfRange(23 + 64, byteArray.size), sharedSecretByteArray)
+ }
+
+ @Test
+ fun testCase2() {
+ val url = qrCode2.toEncodedString()
+
+ val byteArray = url.toByteArray(Charsets.ISO_8859_1)
+ checkHeader(byteArray)
+
+ // Mode
+ byteArray[7] shouldEqualTo 1
+
+ checkSizeAndTransaction(byteArray)
+ compareArray(byteArray.copyOfRange(23, 23 + 32), kte_byteArray)
+ compareArray(byteArray.copyOfRange(23 + 32, 23 + 64), tlx_byteArray)
+
+ compareArray(byteArray.copyOfRange(23 + 64, byteArray.size), sharedSecretByteArray)
+ }
+
+ @Test
+ fun testCase3() {
+ val url = qrCode3.toEncodedString()
+
+ val byteArray = url.toByteArray(Charsets.ISO_8859_1)
+ checkHeader(byteArray)
+
+ // Mode
+ byteArray[7] shouldEqualTo 2
+
+ checkSizeAndTransaction(byteArray)
+ compareArray(byteArray.copyOfRange(23, 23 + 32), tlx_byteArray)
+ compareArray(byteArray.copyOfRange(23 + 32, 23 + 64), kte_byteArray)
+
+ compareArray(byteArray.copyOfRange(23 + 64, byteArray.size), sharedSecretByteArray)
+ }
+
+ @Test
+ fun testLongTransactionId() {
+ // Size on two bytes (2_000 = 0x07D0)
+ val longTransactionId = "PatternId_".repeat(200)
+
+ val qrCode = qrCode1.copy(transactionId = longTransactionId)
+
+ val result = qrCode.toEncodedString()
+ val expected = value1.replace("\u0000\u000DMaTransaction", "\u0007\u00D0$longTransactionId")
+
+ result shouldEqual expected
+
+ // Reverse operation
+ expected.toQrCodeData() shouldEqual qrCode
+ }
+
+ @Test
+ fun testAnyTransactionId() {
+ for (qty in 0 until 0x1FFF step 200) {
+ val longTransactionId = "a".repeat(qty)
+
+ val qrCode = qrCode1.copy(transactionId = longTransactionId)
+
+ // Symmetric operation
+ qrCode.toEncodedString().toQrCodeData() shouldEqual qrCode
+ }
+ }
+
+ // Error cases
+ @Test
+ fun testErrorHeader() {
+ value1.replace("MATRIX", "MOTRIX").toQrCodeData().shouldBeNull()
+ value1.replace("MATRIX", "MATRI").toQrCodeData().shouldBeNull()
+ value1.replace("MATRIX", "").toQrCodeData().shouldBeNull()
+ }
+
+ @Test
+ fun testErrorVersion() {
+ value1.replace("MATRIX\u0002", "MATRIX\u0000").toQrCodeData().shouldBeNull()
+ value1.replace("MATRIX\u0002", "MATRIX\u0001").toQrCodeData().shouldBeNull()
+ value1.replace("MATRIX\u0002", "MATRIX\u0003").toQrCodeData().shouldBeNull()
+ value1.replace("MATRIX\u0002", "MATRIX").toQrCodeData().shouldBeNull()
+ }
+
+ @Test
+ fun testErrorSecretTooShort() {
+ value1.replace("12345678", "1234567").toQrCodeData().shouldBeNull()
+ }
+
+ @Test
+ fun testErrorNoTransactionNoKeyNoSecret() {
+ // But keep transaction length
+ "MATRIX\u0002\u0000\u0000\u000D".toQrCodeData().shouldBeNull()
+ }
+
+ @Test
+ fun testErrorNoKeyNoSecret() {
+ "MATRIX\u0002\u0000\u0000\u000DMaTransaction".toQrCodeData().shouldBeNull()
+ }
+
+ @Test
+ fun testErrorTransactionLengthTooShort() {
+ // In this case, the secret will be longer, so this is not an error, but it will lead to keys mismatch
+ value1.replace("\u000DMaTransaction", "\u000CMaTransaction").toQrCodeData().shouldNotBeNull()
+ }
+
+ @Test
+ fun testErrorTransactionLengthTooBig() {
+ value1.replace("\u000DMaTransaction", "\u000EMaTransaction").toQrCodeData().shouldBeNull()
+ }
+
+ private fun compareArray(actual: ByteArray, expected: ByteArray) {
+ actual.size shouldEqual expected.size
+
+ for (i in actual.indices) {
+ actual[i] shouldEqualTo expected[i]
+ }
+ }
+
+ private fun checkHeader(byteArray: ByteArray) {
+ // MATRIX
+ byteArray[0] shouldEqualTo 'M'.toByte()
+ byteArray[1] shouldEqualTo 'A'.toByte()
+ byteArray[2] shouldEqualTo 'T'.toByte()
+ byteArray[3] shouldEqualTo 'R'.toByte()
+ byteArray[4] shouldEqualTo 'I'.toByte()
+ byteArray[5] shouldEqualTo 'X'.toByte()
+
+ // Version
+ byteArray[6] shouldEqualTo 2
+ }
+
+ private fun checkSizeAndTransaction(byteArray: ByteArray) {
+ // Size
+ byteArray[8] shouldEqualTo 0
+ byteArray[9] shouldEqualTo 13
+
+ // Transaction
+ byteArray.copyOfRange(10, 10 + "MaTransaction".length).toString(Charsets.ISO_8859_1) shouldEqual "MaTransaction"
+ }
+}
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/SharedSecretTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/SharedSecretTest.kt
index 7a07c16d14..4ab79be18b 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/SharedSecretTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/SharedSecretTest.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 New Vector Ltd
+ * Copyright (c) 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,14 +32,14 @@ class SharedSecretTest : InstrumentedTest {
@Test
fun testSharedSecretLengthCase() {
repeat(100) {
- generateSharedSecret().length shouldBe 43
+ generateSharedSecretV2().length shouldBe 11
}
}
@Test
fun testSharedDiffCase() {
- val sharedSecret1 = generateSharedSecret()
- val sharedSecret2 = generateSharedSecret()
+ val sharedSecret1 = generateSharedSecretV2()
+ val sharedSecret2 = generateSharedSecretV2()
sharedSecret1 shouldNotBeEqualTo sharedSecret2
}
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/VerificationTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/VerificationTest.kt
index 61ea0f35b4..e5ffc2ae01 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/VerificationTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/VerificationTest.kt
@@ -18,8 +18,8 @@ package im.vector.matrix.android.internal.crypto.verification.qrcode
import androidx.test.ext.junit.runners.AndroidJUnit4
import im.vector.matrix.android.InstrumentedTest
-import im.vector.matrix.android.api.session.crypto.sas.VerificationMethod
-import im.vector.matrix.android.api.session.crypto.sas.VerificationService
+import im.vector.matrix.android.api.session.crypto.verification.VerificationMethod
+import im.vector.matrix.android.api.session.crypto.verification.VerificationService
import im.vector.matrix.android.common.CommonTestHelper
import im.vector.matrix.android.common.CryptoTestHelper
import im.vector.matrix.android.common.TestConstants
@@ -156,7 +156,7 @@ class VerificationTest : InstrumentedTest {
val bobSession = cryptoTestData.secondSession!!
mTestHelper.doSync { callback ->
- aliceSession.getCrossSigningService()
+ aliceSession.cryptoService().crossSigningService()
.initializeCrossSigning(UserPasswordAuth(
user = aliceSession.myUserId,
password = TestConstants.PASSWORD
@@ -164,15 +164,15 @@ class VerificationTest : InstrumentedTest {
}
mTestHelper.doSync { callback ->
- bobSession.getCrossSigningService()
+ bobSession.cryptoService().crossSigningService()
.initializeCrossSigning(UserPasswordAuth(
user = bobSession.myUserId,
password = TestConstants.PASSWORD
), callback)
}
- val aliceVerificationService = aliceSession.getVerificationService()
- val bobVerificationService = bobSession.getVerificationService()
+ val aliceVerificationService = aliceSession.cryptoService().verificationService()
+ val bobVerificationService = bobSession.cryptoService().verificationService()
var aliceReadyPendingVerificationRequest: PendingVerificationRequest? = null
var bobReadyPendingVerificationRequest: PendingVerificationRequest? = null
@@ -227,6 +227,6 @@ class VerificationTest : InstrumentedTest {
pr.otherCanScanQrCode() shouldBe expectedResultForBob.otherCanScanQrCode
}
- cryptoTestData.close()
+ cryptoTestData.cleanUp(mTestHelper)
}
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/MatrixPatterns.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/MatrixPatterns.kt
index e30d139cd3..bba925b89f 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/MatrixPatterns.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/MatrixPatterns.kt
@@ -122,9 +122,9 @@ object MatrixPatterns {
*/
fun isEventId(str: String?): Boolean {
return str != null
- && (str matches PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER
- || str matches PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER_V3
- || str matches PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER_V4)
+ && (str matches PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER
+ || str matches PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER_V3
+ || str matches PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER_V4)
}
/**
@@ -144,14 +144,6 @@ object MatrixPatterns {
* @return null if not found or if matrixId is null
*/
fun extractServerNameFromId(matrixId: String?): String? {
- if (matrixId == null) {
- return null
- }
-
- val index = matrixId.indexOf(":")
-
- return if (index == -1) {
- null
- } else matrixId.substring(index + 1)
+ return matrixId?.substringAfter(":", missingDelimiterValue = "")?.takeIf { it.isNotEmpty() }
}
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/WellKnown.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/WellKnown.kt
index 6285e866cc..bdad4702b7 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/WellKnown.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/WellKnown.kt
@@ -46,13 +46,13 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class WellKnown(
@Json(name = "m.homeserver")
- var homeServer: WellKnownBaseConfig? = null,
+ val homeServer: WellKnownBaseConfig? = null,
@Json(name = "m.identity_server")
- var identityServer: WellKnownBaseConfig? = null,
+ val identityServer: WellKnownBaseConfig? = null,
@Json(name = "m.integrations")
- var integrations: Map? = null
+ val integrations: Map? = null
) {
/**
* Returns the list of integration managers proposed
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/crypto/Emojis.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/crypto/Emojis.kt
index 943b2c1b10..469721a4c8 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/crypto/Emojis.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/crypto/Emojis.kt
@@ -16,7 +16,7 @@
package im.vector.matrix.android.api.crypto
-import im.vector.matrix.android.api.session.crypto.sas.EmojiRepresentation
+import im.vector.matrix.android.api.session.crypto.verification.EmojiRepresentation
import im.vector.matrix.android.internal.crypto.verification.getEmojiForCode
/**
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/extensions/MatrixSdkExtensions.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/extensions/MatrixSdkExtensions.kt
index 23e8c70386..6ce04f8b30 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/extensions/MatrixSdkExtensions.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/extensions/MatrixSdkExtensions.kt
@@ -16,7 +16,6 @@
package im.vector.matrix.android.api.extensions
-import im.vector.matrix.android.api.comparators.DatedObjectComparators
import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
@@ -33,7 +32,5 @@ fun CryptoDeviceInfo.getFingerprintHumanReadable() = fingerprint()
* ========================================================================================== */
fun List.sortByLastSeen(): List {
- val list = toMutableList()
- list.sortWith(DatedObjectComparators.descComparator)
- return list
+ return this.sortedByDescending { it.lastSeenTs ?: 0 }
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/listeners/ProgressListener.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/listeners/ProgressListener.kt
index ad47260f86..d672434046 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/listeners/ProgressListener.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/listeners/ProgressListener.kt
@@ -21,6 +21,7 @@ package im.vector.matrix.android.api.listeners
*/
interface ProgressListener {
/**
+ * Will be invoked on the background thread, not in UI thread.
* @param progress from 0 to total by contract
* @param total
*/
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt
index 5bd219247c..c2fa7d2d32 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt
@@ -21,6 +21,7 @@ import androidx.lifecycle.LiveData
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.failure.GlobalError
import im.vector.matrix.android.api.pushrules.PushRuleService
+import im.vector.matrix.android.api.session.accountdata.AccountDataService
import im.vector.matrix.android.api.session.cache.CacheService
import im.vector.matrix.android.api.session.content.ContentUploadStateTracker
import im.vector.matrix.android.api.session.content.ContentUrlResolver
@@ -33,6 +34,7 @@ import im.vector.matrix.android.api.session.pushers.PushersService
import im.vector.matrix.android.api.session.room.RoomDirectoryService
import im.vector.matrix.android.api.session.room.RoomService
import im.vector.matrix.android.api.session.securestorage.SecureStorageService
+import im.vector.matrix.android.api.session.securestorage.SharedSecretStorageService
import im.vector.matrix.android.api.session.signout.SignOutService
import im.vector.matrix.android.api.session.sync.FilterService
import im.vector.matrix.android.api.session.sync.SyncState
@@ -47,7 +49,6 @@ interface Session :
RoomDirectoryService,
GroupService,
UserService,
- CryptoService,
CacheService,
SignOutService,
FilterService,
@@ -57,7 +58,8 @@ interface Session :
PushersService,
InitialSyncProgressService,
HomeServerCapabilitiesService,
- SecureStorageService {
+ SecureStorageService,
+ AccountDataService {
/**
* The params associated to the session
@@ -136,6 +138,11 @@ interface Session :
*/
fun contentUploadProgressTracker(): ContentUploadStateTracker
+ /**
+ * Returns the cryptoService associated with the session
+ */
+ fun cryptoService(): CryptoService
+
/**
* Add a listener to the session.
* @param listener the listener to add.
@@ -159,4 +166,6 @@ interface Session :
*/
fun onGlobalError(globalError: GlobalError)
}
+
+ val sharedSecretStorageService: SharedSecretStorageService
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/AccountDataService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/AccountDataService.kt
new file mode 100644
index 0000000000..ee13d1f097
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/accountdata/AccountDataService.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.api.session.accountdata
+
+import androidx.lifecycle.LiveData
+import im.vector.matrix.android.api.MatrixCallback
+import im.vector.matrix.android.api.session.events.model.Content
+import im.vector.matrix.android.api.util.Cancelable
+import im.vector.matrix.android.api.util.Optional
+import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
+
+interface AccountDataService {
+ /**
+ * Retrieve the account data with the provided type or null if not found
+ */
+ fun getAccountDataEvent(type: String): UserAccountDataEvent?
+
+ /**
+ * Observe the account data with the provided type
+ */
+ fun getLiveAccountDataEvent(type: String): LiveData>
+
+ /**
+ * Retrieve the account data with the provided types. The return list can have a different size that
+ * the size of the types set, because some AccountData may not exist.
+ * If an empty set is provided, all the AccountData are retrieved
+ */
+ fun getAccountDataEvents(types: Set): List
+
+ /**
+ * Observe the account data with the provided types. If an empty set is provided, all the AccountData are observed
+ */
+ fun getLiveAccountDataEvents(types: Set): LiveData>
+
+ /**
+ * Update the account data with the provided type and the provided account data content
+ */
+ fun updateAccountData(type: String, content: Content, callback: MatrixCallback? = null): Cancelable
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/content/ContentAttachmentData.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/content/ContentAttachmentData.kt
index 0d8ef2c52b..48dff4e56d 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/content/ContentAttachmentData.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/content/ContentAttachmentData.kt
@@ -29,6 +29,7 @@ data class ContentAttachmentData(
val width: Long? = 0,
val exifOrientation: Int = ExifInterface.ORIENTATION_UNDEFINED,
val name: String? = null,
+ val queryUri: String,
val path: String,
val mimeType: String?,
val type: Type
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/CryptoService.kt
index 46539d9029..1360924270 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/CryptoService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/CryptoService.kt
@@ -23,7 +23,7 @@ import im.vector.matrix.android.api.listeners.ProgressListener
import im.vector.matrix.android.api.session.crypto.crosssigning.CrossSigningService
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
import im.vector.matrix.android.api.session.crypto.keyshare.RoomKeysRequestListener
-import im.vector.matrix.android.api.session.crypto.sas.VerificationService
+import im.vector.matrix.android.api.session.crypto.verification.VerificationService
import im.vector.matrix.android.api.session.events.model.Content
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult
@@ -40,6 +40,12 @@ import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody
interface CryptoService {
+ fun verificationService(): VerificationService
+
+ fun crossSigningService(): CrossSigningService
+
+ fun keysBackupService(): KeysBackupService
+
fun setDeviceName(deviceId: String, deviceName: String, callback: MatrixCallback)
fun deleteDevice(deviceId: String, callback: MatrixCallback)
@@ -50,12 +56,6 @@ interface CryptoService {
fun isCryptoEnabled(): Boolean
- fun getVerificationService(): VerificationService
-
- fun getCrossSigningService(): CrossSigningService
-
- fun getKeysBackupService(): KeysBackupService
-
fun isRoomBlacklistUnverifiedDevices(roomId: String?): Boolean
fun setWarnOnUnknownDevices(warn: Boolean)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/crosssigning/CrossSigningService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/crosssigning/CrossSigningService.kt
index b7bc20a1dc..ff4745ef46 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/crosssigning/CrossSigningService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/crosssigning/CrossSigningService.kt
@@ -42,6 +42,10 @@ interface CrossSigningService {
fun initializeCrossSigning(authParams: UserPasswordAuth?,
callback: MatrixCallback? = null)
+ fun checkTrustFromPrivateKeys(masterKeyPrivateKey: String?,
+ uskKeyPrivateKey: String?,
+ sskPrivateKey: String?) : UserTrustResult
+
fun getUserCrossSigningKeys(otherUserId: String): MXCrossSigningInfo?
fun getLiveCrossSigningKeys(userId: String): LiveData>
@@ -53,11 +57,13 @@ interface CrossSigningService {
fun trustUser(otherUserId: String,
callback: MatrixCallback)
+ fun markMyMasterKeyAsTrusted()
+
/**
* Sign one of your devices and upload the signature
*/
- fun signDevice(deviceId: String,
- callback: MatrixCallback)
+ fun trustDevice(deviceId: String,
+ callback: MatrixCallback)
fun checkDeviceTrust(otherUserId: String,
otherDeviceId: String,
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/crosssigning/CrossSigningSsssSecretConstants.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/crosssigning/CrossSigningSsssSecretConstants.kt
new file mode 100644
index 0000000000..d46a724463
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/crosssigning/CrossSigningSsssSecretConstants.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.api.session.crypto.crosssigning
+
+const val MASTER_KEY_SSSS_NAME = "m.cross_signing.master"
+
+const val USER_SIGNING_KEY_SSSS_NAME = "m.cross_signing.user_signing"
+
+const val SELF_SIGNING_KEY_SSSS_NAME = "m.cross_signing.self_signing"
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/CancelCode.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/CancelCode.kt
similarity index 95%
rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/CancelCode.kt
rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/CancelCode.kt
index 79448de83f..35961b309f 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/CancelCode.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/CancelCode.kt
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-// TODO Rename package
-package im.vector.matrix.android.api.session.crypto.sas
+package im.vector.matrix.android.api.session.crypto.verification
enum class CancelCode(val value: String, val humanReadable: String) {
User("m.user", "the user cancelled the verification"),
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/EmojiRepresentation.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/EmojiRepresentation.kt
similarity index 92%
rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/EmojiRepresentation.kt
rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/EmojiRepresentation.kt
index 031610f0c6..9ee7c92788 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/EmojiRepresentation.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/EmojiRepresentation.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package im.vector.matrix.android.api.session.crypto.sas
+package im.vector.matrix.android.api.session.crypto.verification
import androidx.annotation.StringRes
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/IncomingSasVerificationTransaction.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/IncomingSasVerificationTransaction.kt
similarity index 93%
rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/IncomingSasVerificationTransaction.kt
rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/IncomingSasVerificationTransaction.kt
index 8e349416dc..e3ba3dc4c0 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/IncomingSasVerificationTransaction.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/IncomingSasVerificationTransaction.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package im.vector.matrix.android.api.session.crypto.sas
+package im.vector.matrix.android.api.session.crypto.verification
interface IncomingSasVerificationTransaction : SasVerificationTransaction {
val uxState: UxState
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/OutgoingSasVerificationTransaction.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/OutgoingSasVerificationTransaction.kt
similarity index 93%
rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/OutgoingSasVerificationTransaction.kt
rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/OutgoingSasVerificationTransaction.kt
index 7ab386295a..67e88f5648 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/OutgoingSasVerificationTransaction.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/OutgoingSasVerificationTransaction.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package im.vector.matrix.android.api.session.crypto.sas
+package im.vector.matrix.android.api.session.crypto.verification
interface OutgoingSasVerificationTransaction : SasVerificationTransaction {
val uxState: UxState
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/QrCodeVerificationTransaction.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/QrCodeVerificationTransaction.kt
similarity index 94%
rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/QrCodeVerificationTransaction.kt
rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/QrCodeVerificationTransaction.kt
index ef6462f854..516f7f0712 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/QrCodeVerificationTransaction.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/QrCodeVerificationTransaction.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package im.vector.matrix.android.api.session.crypto.sas
+package im.vector.matrix.android.api.session.crypto.verification
interface QrCodeVerificationTransaction : VerificationTransaction {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/SasMode.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/SasMode.kt
similarity index 91%
rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/SasMode.kt
rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/SasMode.kt
index f58485decd..c346a07228 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/SasMode.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/SasMode.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package im.vector.matrix.android.api.session.crypto.sas
+package im.vector.matrix.android.api.session.crypto.verification
object SasMode {
const val DECIMAL = "decimal"
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/SasVerificationTransaction.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/SasVerificationTransaction.kt
similarity index 94%
rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/SasVerificationTransaction.kt
rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/SasVerificationTransaction.kt
index 912e2b65e8..d1778f19a0 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/SasVerificationTransaction.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/SasVerificationTransaction.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package im.vector.matrix.android.api.session.crypto.sas
+package im.vector.matrix.android.api.session.crypto.verification
interface SasVerificationTransaction : VerificationTransaction {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationMethod.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/VerificationMethod.kt
similarity index 93%
rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationMethod.kt
rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/VerificationMethod.kt
index b8f0f23891..3cd3aee90d 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationMethod.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/VerificationMethod.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package im.vector.matrix.android.api.session.crypto.sas
+package im.vector.matrix.android.api.session.crypto.verification
/**
* Verification methods
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/VerificationService.kt
similarity index 98%
rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt
rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/VerificationService.kt
index 1b5f5d3dd6..d65bd7bb6a 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/VerificationService.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package im.vector.matrix.android.api.session.crypto.sas
+package im.vector.matrix.android.api.session.crypto.verification
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.session.events.model.LocalEcho
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationTransaction.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/VerificationTransaction.kt
similarity index 93%
rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationTransaction.kt
rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/VerificationTransaction.kt
index 6ed650b2ad..13aae70b5b 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationTransaction.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/VerificationTransaction.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package im.vector.matrix.android.api.session.crypto.sas
+package im.vector.matrix.android.api.session.crypto.verification
interface VerificationTransaction {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationTxState.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/VerificationTxState.kt
similarity index 96%
rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationTxState.kt
rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/VerificationTxState.kt
index b30dde2d4d..aaaf227187 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationTxState.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/verification/VerificationTxState.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package im.vector.matrix.android.api.session.crypto.sas
+package im.vector.matrix.android.api.session.crypto.verification
sealed class VerificationTxState {
// Uninitialized state
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/EventType.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/EventType.kt
index 8878930de0..9a3107a8ca 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/EventType.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/EventType.kt
@@ -66,6 +66,9 @@ object EventType {
const val ROOM_KEY_REQUEST = "m.room_key_request"
const val FORWARDED_ROOM_KEY = "m.forwarded_room_key"
+ const val REQUEST_SECRET = "m.secret.request"
+ const val SEND_SECRET = "m.secret.send"
+
// Interactive key verification
const val KEY_VERIFICATION_START = "m.key.verification.start"
const val KEY_VERIFICATION_ACCEPT = "m.key.verification.accept"
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/LocalEcho.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/LocalEcho.kt
index 1dbee475e0..67ae3b2d73 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/LocalEcho.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/LocalEcho.kt
@@ -20,7 +20,7 @@ import java.util.UUID
object LocalEcho {
- private const val PREFIX = "local."
+ private const val PREFIX = "\$local."
fun isLocalEchoId(eventId: String) = eventId.startsWith(PREFIX)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomDirectoryService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomDirectoryService.kt
index c0e413f83b..0273c789dd 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomDirectoryService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomDirectoryService.kt
@@ -35,9 +35,9 @@ interface RoomDirectoryService {
callback: MatrixCallback): Cancelable
/**
- * Join a room by id
+ * Join a room by id, or room alias
*/
- fun joinRoom(roomId: String,
+ fun joinRoom(roomIdOrAlias: String,
reason: String? = null,
callback: MatrixCallback): Cancelable
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomService.kt
index 9fec605bd9..93761dfd26 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/RoomService.kt
@@ -36,11 +36,11 @@ interface RoomService {
/**
* Join a room by id
- * @param roomId the roomId of the room to join
+ * @param roomIdOrAlias the roomId or the room alias of the room to join
* @param reason optional reason for joining the room
* @param viaServers the servers to attempt to join the room through. One of the servers must be participating in the room.
*/
- fun joinRoom(roomId: String,
+ fun joinRoom(roomIdOrAlias: String,
reason: String? = null,
viaServers: List = emptyList(),
callback: MatrixCallback): Cancelable
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/ReferencesAggregatedContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/ReferencesAggregatedContent.kt
index ae6e52a091..31a5694682 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/ReferencesAggregatedContent.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/ReferencesAggregatedContent.kt
@@ -17,6 +17,7 @@ package im.vector.matrix.android.api.session.room.model
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
+import im.vector.matrix.android.internal.session.room.VerificationState
/**
* Contains an aggregated summary info of the references.
@@ -26,6 +27,6 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class ReferencesAggregatedContent(
// Verification status info for m.key.verification.request msgType events
- @Json(name = "verif_sum") val verificationSummary: String
+ @Json(name = "verif_sum") val verificationState: VerificationState
// Add more fields for future summary info.
)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt
index 28c56125f1..6171b2633b 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt
@@ -45,7 +45,8 @@ data class RoomSummary constructor(
val versioningState: VersioningState = VersioningState.NONE,
val readMarkerId: String? = null,
val userDrafts: List = emptyList(),
- var isEncrypted: Boolean,
+ val isEncrypted: Boolean,
+ val inviterId: String? = null,
val typingRoomMemberIds: List = emptyList(),
val breadcrumbsIndex: Int = NOT_IN_BREADCRUMBS,
// TODO Plug it
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/create/CreateRoomParams.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/create/CreateRoomParams.kt
index b69c189f89..1abbe9ef3a 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/create/CreateRoomParams.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/create/CreateRoomParams.kt
@@ -17,6 +17,7 @@
package im.vector.matrix.android.api.session.room.model.create
import android.util.Patterns
+import androidx.annotation.CheckResult
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import im.vector.matrix.android.api.MatrixPatterns.isUserId
@@ -120,37 +121,53 @@ data class CreateRoomParams(
@Json(name = "power_level_content_override")
val powerLevelContentOverride: PowerLevelsContent? = null
) {
- /**
- * Set to true means that if cross-signing is enabled and we can get keys for every invited users,
- * the encryption will be enabled on the created room
- */
@Transient
internal var enableEncryptionIfInvitedUsersSupportIt: Boolean = false
private set
- fun enableEncryptionIfInvitedUsersSupportIt(): CreateRoomParams {
- enableEncryptionIfInvitedUsersSupportIt = true
+ /**
+ * After calling this method, when the room will be created, if cross-signing is enabled and we can get keys for every invited users,
+ * the encryption will be enabled on the created room
+ * @param value true to activate this behavior.
+ * @return this, to allow chaining methods
+ */
+ fun enableEncryptionIfInvitedUsersSupportIt(value: Boolean = true): CreateRoomParams {
+ enableEncryptionIfInvitedUsersSupportIt = value
return this
}
/**
* Add the crypto algorithm to the room creation parameters.
*
- * @param algorithm the algorithm
+ * @param enable true to enable encryption.
+ * @param algorithm the algorithm, default to [MXCRYPTO_ALGORITHM_MEGOLM], which is actually the only supported algorithm for the moment
+ * @return a modified copy of the CreateRoomParams object, or this if there is no modification
*/
- fun enableEncryptionWithAlgorithm(algorithm: String = MXCRYPTO_ALGORITHM_MEGOLM): CreateRoomParams {
+ @CheckResult
+ fun enableEncryptionWithAlgorithm(enable: Boolean = true,
+ algorithm: String = MXCRYPTO_ALGORITHM_MEGOLM): CreateRoomParams {
+ // Remove the existing value if any.
+ val newInitialStates = initialStates
+ ?.filter { it.type != EventType.STATE_ROOM_ENCRYPTION }
+
return if (algorithm == MXCRYPTO_ALGORITHM_MEGOLM) {
- val contentMap = mapOf("algorithm" to algorithm)
+ if (enable) {
+ val contentMap = mapOf("algorithm" to algorithm)
- val algoEvent = Event(
- type = EventType.STATE_ROOM_ENCRYPTION,
- stateKey = "",
- content = contentMap.toContent()
- )
+ val algoEvent = Event(
+ type = EventType.STATE_ROOM_ENCRYPTION,
+ stateKey = "",
+ content = contentMap.toContent()
+ )
- copy(
- initialStates = initialStates.orEmpty().filter { it.type != EventType.STATE_ROOM_ENCRYPTION } + algoEvent
- )
+ copy(
+ initialStates = newInitialStates.orEmpty() + algoEvent
+ )
+ } else {
+ return copy(
+ initialStates = newInitialStates
+ )
+ }
} else {
Timber.e("Unsupported algorithm: $algorithm")
this
@@ -161,7 +178,9 @@ data class CreateRoomParams(
* Force the history visibility in the room creation parameters.
*
* @param historyVisibility the expected history visibility, set null to remove any existing value.
+ * @return a modified copy of the CreateRoomParams object
*/
+ @CheckResult
fun setHistoryVisibility(historyVisibility: RoomHistoryVisibility?): CreateRoomParams {
// Remove the existing value if any.
val newInitialStates = initialStates
@@ -187,7 +206,9 @@ data class CreateRoomParams(
/**
* Mark as a direct message room.
+ * @return a modified copy of the CreateRoomParams object
*/
+ @CheckResult
fun setDirectMessage(): CreateRoomParams {
return copy(
preset = CreateRoomPreset.PRESET_TRUSTED_PRIVATE_CHAT,
@@ -195,20 +216,6 @@ data class CreateRoomParams(
)
}
- /**
- * @return the invite count
- */
- private fun getInviteCount(): Int {
- return invitedUserIds?.size ?: 0
- }
-
- /**
- * @return the pid invite count
- */
- private fun getInvite3PidCount(): Int {
- return invite3pids?.size ?: 0
- }
-
/**
* Tells if the created room can be a direct chat one.
*
@@ -217,7 +224,6 @@ data class CreateRoomParams(
fun isDirect(): Boolean {
return preset == CreateRoomPreset.PRESET_TRUSTED_PRIVATE_CHAT
&& isDirect == true
- && (1 == getInviteCount() || 1 == getInvite3PidCount())
}
/**
@@ -232,7 +238,9 @@ data class CreateRoomParams(
* ids might be a matrix id or an email address.
*
* @param ids the participant ids to add.
+ * @return a modified copy of the CreateRoomParams object
*/
+ @CheckResult
fun addParticipantIds(hsConfig: HomeServerConnectionConfig,
userId: String,
ids: List): CreateRoomParams {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/create/CreateRoomResponse.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/create/CreateRoomResponse.kt
index c437bcfbf1..da54b344a2 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/create/CreateRoomResponse.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/create/CreateRoomResponse.kt
@@ -21,5 +21,10 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
internal data class CreateRoomResponse(
- @Json(name = "room_id") var roomId: String? = null
+ /**
+ * Required. The created room's ID.
+ */
+ @Json(name = "room_id") val roomId: String
)
+
+internal typealias JoinRoomResponse = CreateRoomResponse
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageVerificationCancelContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageVerificationCancelContent.kt
index 651a25e175..9b7ca13df8 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageVerificationCancelContent.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageVerificationCancelContent.kt
@@ -17,7 +17,7 @@ package im.vector.matrix.android.api.session.room.model.message
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
-import im.vector.matrix.android.api.session.crypto.sas.CancelCode
+import im.vector.matrix.android.api.session.crypto.verification.CancelCode
import im.vector.matrix.android.api.session.events.model.RelationType
import im.vector.matrix.android.api.session.events.model.toContent
import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageVerificationStartContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageVerificationStartContent.kt
index 3031b213d9..a2a3940199 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageVerificationStartContent.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageVerificationStartContent.kt
@@ -17,7 +17,7 @@ package im.vector.matrix.android.api.session.room.model.message
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
-import im.vector.matrix.android.api.session.crypto.sas.SasMode
+import im.vector.matrix.android.api.session.crypto.verification.SasMode
import im.vector.matrix.android.api.session.events.model.toContent
import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent
import im.vector.matrix.android.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoom.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoom.kt
index 508cbb55b4..efe2debeab 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoom.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoom.kt
@@ -23,66 +23,71 @@ import com.squareup.moshi.JsonClass
*/
@JsonClass(generateAdapter = true)
data class PublicRoom(
-
/**
* Aliases of the room. May be empty.
*/
@Json(name = "aliases")
- var aliases: List? = null,
+ val aliases: List? = null,
/**
* The canonical alias of the room, if any.
*/
@Json(name = "canonical_alias")
- var canonicalAlias: String? = null,
+ val canonicalAlias: String? = null,
/**
* The name of the room, if any.
*/
@Json(name = "name")
- var name: String? = null,
+ val name: String? = null,
/**
* Required. The number of members joined to the room.
*/
@Json(name = "num_joined_members")
- var numJoinedMembers: Int = 0,
+ val numJoinedMembers: Int = 0,
/**
* Required. The ID of the room.
*/
@Json(name = "room_id")
- var roomId: String,
+ val roomId: String,
/**
* The topic of the room, if any.
*/
@Json(name = "topic")
- var topic: String? = null,
+ val topic: String? = null,
/**
* Required. Whether the room may be viewed by guest users without joining.
*/
@Json(name = "world_readable")
- var worldReadable: Boolean = false,
+ val worldReadable: Boolean = false,
/**
* Required. Whether guest users may join the room and participate in it. If they can,
* they will be subject to ordinary power level rules like any other user.
*/
@Json(name = "guest_can_join")
- var guestCanJoin: Boolean = false,
+ val guestCanJoin: Boolean = false,
/**
* The URL for the room's avatar, if one is set.
*/
@Json(name = "avatar_url")
- var avatarUrl: String? = null,
+ val avatarUrl: String? = null,
/**
* Undocumented item
*/
@Json(name = "m.federate")
- var isFederated: Boolean = false
-
-)
+ val isFederated: Boolean = false
+) {
+ /**
+ * Return the canonical alias, or the first alias from the list of aliases, or null
+ */
+ fun getPrimaryAlias(): String? {
+ return canonicalAlias ?: aliases?.firstOrNull()
+ }
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsFilter.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsFilter.kt
index b4de72e41a..c519d054f2 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsFilter.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsFilter.kt
@@ -27,5 +27,5 @@ data class PublicRoomsFilter(
* A string to search for in the room metadata, e.g. name, topic, canonical alias etc. (Optional).
*/
@Json(name = "generic_search_term")
- var searchTerm: String? = null
+ val searchTerm: String? = null
)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsParams.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsParams.kt
index e2af1c3ccb..467968cd2a 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsParams.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsParams.kt
@@ -28,30 +28,30 @@ data class PublicRoomsParams(
* Limit the number of results returned.
*/
@Json(name = "limit")
- var limit: Int? = null,
+ val limit: Int? = null,
/**
* A pagination token from a previous request, allowing clients to get the next (or previous) batch of rooms.
* The direction of pagination is specified solely by which token is supplied, rather than via an explicit flag.
*/
@Json(name = "since")
- var since: String? = null,
+ val since: String? = null,
/**
* Filter to apply to the results.
*/
@Json(name = "filter")
- var filter: PublicRoomsFilter? = null,
+ val filter: PublicRoomsFilter? = null,
/**
* Whether or not to include all known networks/protocols from application services on the homeserver. Defaults to false.
*/
@Json(name = "include_all_networks")
- var includeAllNetworks: Boolean = false,
+ val includeAllNetworks: Boolean = false,
/**
* The specific third party network/protocol to request from the homeserver. Can only be used if include_all_networks is false.
*/
@Json(name = "third_party_instance_id")
- var thirdPartyInstanceId: String? = null
+ val thirdPartyInstanceId: String? = null
)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsResponse.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsResponse.kt
index 3799d097fc..b83fa51491 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsResponse.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/roomdirectory/PublicRoomsResponse.kt
@@ -27,24 +27,24 @@ data class PublicRoomsResponse(
* A pagination token for the response. The absence of this token means there are no more results to fetch and the client should stop paginating.
*/
@Json(name = "next_batch")
- var nextBatch: String? = null,
+ val nextBatch: String? = null,
/**
* A pagination token that allows fetching previous results. The absence of this token means there are no results before this batch,
* i.e. this is the first batch.
*/
@Json(name = "prev_batch")
- var prevBatch: String? = null,
+ val prevBatch: String? = null,
/**
* A paginated chunk of public rooms.
*/
@Json(name = "chunk")
- var chunk: List? = null,
+ val chunk: List? = null,
/**
* An estimate on the total number of public rooms, if the server has an estimate.
*/
@Json(name = "total_room_count_estimate")
- var totalRoomCountEstimate: Int? = null
+ val totalRoomCountEstimate: Int? = null
)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/thirdparty/ThirdPartyProtocol.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/thirdparty/ThirdPartyProtocol.kt
index b066cff164..b4ed1f1a8e 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/thirdparty/ThirdPartyProtocol.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/thirdparty/ThirdPartyProtocol.kt
@@ -26,7 +26,7 @@ data class ThirdPartyProtocol(
* where higher groupings are ordered first. For example, the name of a network should be searched before the nickname of a user.
*/
@Json(name = "user_fields")
- var userFields: List? = null,
+ val userFields: List? = null,
/**
* Required. Fields which may be used to identify a third party location. These should be ordered to suggest the way that
@@ -34,15 +34,15 @@ data class ThirdPartyProtocol(
* searched before the name of a channel.
*/
@Json(name = "location_fields")
- var locationFields: List? = null,
+ val locationFields: List? = null,
/**
* Required. A content URI representing an icon for the third party protocol.
*
- * FIXDOC: This field was not present in legacy Riot, and it is sometimes sent by the server (no not Required?)
+ * FIXDOC: This field was not present in legacy Riot, and it is sometimes sent by the server (so not Required?)
*/
@Json(name = "icon")
- var icon: String? = null,
+ val icon: String? = null,
/**
* Required. The type definitions for the fields defined in the user_fields and location_fields. Each entry in those arrays MUST have an entry here.
@@ -51,12 +51,12 @@ data class ThirdPartyProtocol(
* May be an empty object if no fields are defined.
*/
@Json(name = "field_types")
- var fieldTypes: Map? = null,
+ val fieldTypes: Map? = null,
/**
* Required. A list of objects representing independent instances of configuration. For example, multiple networks on IRC
* if multiple are provided by the same application service.
*/
@Json(name = "instances")
- var instances: List? = null
+ val instances: List? = null
)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/thirdparty/ThirdPartyProtocolInstance.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/thirdparty/ThirdPartyProtocolInstance.kt
index 50f92356fb..f5d59f9282 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/thirdparty/ThirdPartyProtocolInstance.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/thirdparty/ThirdPartyProtocolInstance.kt
@@ -25,35 +25,35 @@ data class ThirdPartyProtocolInstance(
* Required. A human-readable description for the protocol, such as the name.
*/
@Json(name = "desc")
- var desc: String? = null,
+ val desc: String? = null,
/**
* An optional content URI representing the protocol. Overrides the one provided at the higher level Protocol object.
*/
@Json(name = "icon")
- var icon: String? = null,
+ val icon: String? = null,
/**
* Required. Preset values for fields the client may use to search by.
*/
@Json(name = "fields")
- var fields: Map? = null,
+ val fields: Map? = null,
/**
* Required. A unique identifier across all instances.
*/
@Json(name = "network_id")
- var networkId: String? = null,
+ val networkId: String? = null,
/**
* FIXDOC Not documented on matrix.org doc
*/
@Json(name = "instance_id")
- var instanceId: String? = null,
+ val instanceId: String? = null,
/**
* FIXDOC Not documented on matrix.org doc
*/
@Json(name = "bot_user_id")
- var botUserId: String? = null
+ val botUserId: String? = null
)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/tombstone/RoomTombstoneContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/tombstone/RoomTombstoneContent.kt
index 035e76d10f..4dfcdd86f5 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/tombstone/RoomTombstoneContent.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/tombstone/RoomTombstoneContent.kt
@@ -23,6 +23,13 @@ import com.squareup.moshi.JsonClass
*/
@JsonClass(generateAdapter = true)
data class RoomTombstoneContent(
+ /**
+ * Required. A server-defined message.
+ */
@Json(name = "body") val body: String? = null,
- @Json(name = "replacement_room") val replacementRoom: String?
+
+ /**
+ * Required. The new room the client should be visiting.
+ */
+ @Json(name = "replacement_room") val replacementRoomId: String?
)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/send/SendService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/send/SendService.kt
index e6c32193f4..afa3dda496 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/send/SendService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/send/SendService.kt
@@ -51,16 +51,26 @@ interface SendService {
/**
* Method to send a media asynchronously.
* @param attachment the media to send
+ * @param compressBeforeSending set to true to compress images before sending them
+ * @param roomIds set of roomIds to where the media will be sent. The current roomId will be add to this set if not present.
+ * It can be useful to send media to multiple room. It's safe to include the current roomId in this set
* @return a [Cancelable]
*/
- fun sendMedia(attachment: ContentAttachmentData): Cancelable
+ fun sendMedia(attachment: ContentAttachmentData,
+ compressBeforeSending: Boolean,
+ roomIds: Set): Cancelable
/**
* Method to send a list of media asynchronously.
* @param attachments the list of media to send
+ * @param compressBeforeSending set to true to compress images before sending them
+ * @param roomIds set of roomIds to where the media will be sent. The current roomId will be add to this set if not present.
+ * It can be useful to send media to multiple room. It's safe to include the current roomId in this set
* @return a [Cancelable]
*/
- fun sendMedias(attachments: List): Cancelable
+ fun sendMedias(attachments: List,
+ compressBeforeSending: Boolean,
+ roomIds: Set): Cancelable
/**
* Send a poll to the room.
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/Timeline.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/Timeline.kt
index 164afb3a60..eb4a9b59e4 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/Timeline.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/Timeline.kt
@@ -41,12 +41,12 @@ interface Timeline {
fun removeAllListeners()
/**
- * This should be called before any other method after creating the timeline. It ensures the underlying database is open
+ * This must be called before any other method after creating the timeline. It ensures the underlying database is open
*/
fun start()
/**
- * This should be called when you don't need the timeline. It ensures the underlying database get closed.
+ * This must be called when you don't need the timeline. It ensures the underlying database get closed.
*/
fun dispose()
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineService.kt
index 2b23ee40ca..a69127532e 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineService.kt
@@ -27,6 +27,9 @@ interface TimelineService {
/**
* Instantiate a [Timeline] with an optional initial eventId, to be used with permalink.
* You can also configure some settings with the [settings] param.
+ *
+ * Important: the returned Timeline has to be started
+ *
* @param eventId the optional initial eventId.
* @param settings settings to configure the timeline.
* @return the instantiated timeline
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/EncryptedSecretContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/EncryptedSecretContent.kt
new file mode 100644
index 0000000000..57fd652735
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/EncryptedSecretContent.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.api.session.securestorage
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+import im.vector.matrix.android.internal.di.MoshiProvider
+import im.vector.matrix.android.internal.session.user.accountdata.AccountDataContent
+
+/**
+ * The account_data will have an encrypted property that is a map from key ID to an object.
+ * The algorithm from the m.secret_storage.key.[key ID] data for the given key defines how the other properties are interpreted,
+ * though it's expected that most encryption schemes would have ciphertext and mac properties,
+ * where the ciphertext property is the unpadded base64-encoded ciphertext, and the mac is used to ensure the integrity of the data.
+ */
+@JsonClass(generateAdapter = true)
+data class EncryptedSecretContent(
+ /** unpadded base64-encoded ciphertext */
+ @Json(name = "ciphertext") val ciphertext: String? = null,
+ @Json(name = "mac") val mac: String? = null,
+ @Json(name = "ephemeral") val ephemeral: String? = null,
+ @Json(name = "iv") val initializationVector: String? = null
+) : AccountDataContent {
+ companion object {
+ /**
+ * Facility method to convert from object which must be comprised of maps, lists,
+ * strings, numbers, booleans and nulls.
+ */
+ fun fromJson(obj: Any?): EncryptedSecretContent? {
+ return MoshiProvider.providesMoshi()
+ .adapter(EncryptedSecretContent::class.java)
+ .fromJsonValue(obj)
+ }
+ }
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/IntegrityResult.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/IntegrityResult.kt
new file mode 100644
index 0000000000..70efa56c48
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/IntegrityResult.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.api.session.securestorage
+
+sealed class IntegrityResult {
+ data class Success(val passphraseBased: Boolean) : IntegrityResult()
+ data class Error(val cause: SharedSecretStorageError) : IntegrityResult()
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/KeyInfoResult.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/KeyInfoResult.kt
new file mode 100644
index 0000000000..940f5298ef
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/KeyInfoResult.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.api.session.securestorage
+
+sealed class KeyInfoResult {
+ data class Success(val keyInfo: KeyInfo) : KeyInfoResult()
+ data class Error(val error: SharedSecretStorageError) : KeyInfoResult()
+
+ fun isSuccess(): Boolean = this is Success
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/KeySigner.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/KeySigner.kt
new file mode 100644
index 0000000000..2cd7a74f31
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/KeySigner.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.api.session.securestorage
+
+interface KeySigner {
+ fun sign(canonicalJson: String): Map>?
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SecretStorageKeyContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SecretStorageKeyContent.kt
new file mode 100644
index 0000000000..129f4bab9d
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SecretStorageKeyContent.kt
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.api.session.securestorage
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+import im.vector.matrix.android.internal.di.MoshiProvider
+import im.vector.matrix.android.internal.util.JsonCanonicalizer
+
+/**
+ *
+ * The contents of the account data for the key will include an algorithm property, which indicates the encryption algorithm used, as well as a name property,
+ * which is a human-readable name.
+ * The contents will be signed as signed JSON using the user's master cross-signing key. Other properties depend on the encryption algorithm.
+ *
+ *
+ * "content": {
+ * "algorithm": "m.secret_storage.v1.curve25519-aes-sha2",
+ * "passphrase": {
+ * "algorithm": "m.pbkdf2",
+ * "iterations": 500000,
+ * "salt": "IrswcMWnYieBALCAOMBw9k93xSzlc2su"
+ * },
+ * "pubkey": "qql1q3IvBbwMU97zLnyh9HYW5x/zqTy5eoK1n+9fm1Y",
+ * "signatures": {
+ * "@valere35:matrix.org": {
+ * "ed25519:nOUQYiH9L8uKp5JajqiQyv+Loa3+lsdil7UBverz/Ko": "QtePmwfUL7+SHYRJT/HaTgF7gUFog1E/wtUCt0qc5aB8N+Sz5iCOvQ0KtaFHQ5SJzsBlYH8k7ejoBc0RcnU7BA"
+ * }
+ * }
+ * }
+ */
+
+data class KeyInfo(
+ val id: String,
+ val content: SecretStorageKeyContent
+)
+
+@JsonClass(generateAdapter = true)
+data class SecretStorageKeyContent(
+ /** Currently support m.secret_storage.v1.curve25519-aes-sha2 */
+ @Json(name = "algorithm") val algorithm: String? = null,
+ @Json(name = "name") val name: String? = null,
+ @Json(name = "passphrase") val passphrase: SsssPassphrase? = null,
+ @Json(name = "pubkey") val publicKey: String? = null,
+ @Json(name = "signatures") val signatures: Map>? = null
+) {
+
+ private fun signalableJSONDictionary(): Map {
+ return mutableMapOf().apply {
+ algorithm
+ ?.let { this["algorithm"] = it }
+ name
+ ?.let { this["name"] = it }
+ publicKey
+ ?.let { this["pubkey"] = it }
+ passphrase
+ ?.let { ssssPassphrase ->
+ this["passphrase"] = mapOf(
+ "algorithm" to ssssPassphrase.algorithm,
+ "iterations" to ssssPassphrase.iterations,
+ "salt" to ssssPassphrase.salt
+ )
+ }
+ }
+ }
+
+ fun canonicalSignable(): String {
+ return JsonCanonicalizer.getCanonicalJson(Map::class.java, signalableJSONDictionary())
+ }
+
+ companion object {
+ /**
+ * Facility method to convert from object which must be comprised of maps, lists,
+ * strings, numbers, booleans and nulls.
+ */
+ fun fromJson(obj: Any?): SecretStorageKeyContent? {
+ return MoshiProvider.providesMoshi()
+ .adapter(SecretStorageKeyContent::class.java)
+ .fromJsonValue(obj)
+ }
+ }
+}
+
+@JsonClass(generateAdapter = true)
+data class SsssPassphrase(
+ @Json(name = "algorithm") val algorithm: String?,
+ @Json(name = "iterations") val iterations: Int,
+ @Json(name = "salt") val salt: String?
+)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SharedSecretStorageError.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SharedSecretStorageError.kt
new file mode 100644
index 0000000000..abd12789a5
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SharedSecretStorageError.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.api.session.securestorage
+
+sealed class SharedSecretStorageError(message: String?) : Throwable(message) {
+ data class UnknownSecret(val secretName: String) : SharedSecretStorageError("Unknown Secret $secretName")
+ data class UnknownKey(val keyId: String) : SharedSecretStorageError("Unknown key $keyId")
+ data class UnknownAlgorithm(val keyId: String) : SharedSecretStorageError("Unknown algorithm $keyId")
+ data class UnsupportedAlgorithm(val algorithm: String) : SharedSecretStorageError("Unknown algorithm $algorithm")
+ data class SecretNotEncrypted(val secretName: String) : SharedSecretStorageError("Missing content for secret $secretName")
+ data class SecretNotEncryptedWithKey(val secretName: String, val keyId: String)
+ : SharedSecretStorageError("Missing content for secret $secretName with key $keyId")
+
+ object BadKeyFormat : SharedSecretStorageError("Bad Key Format")
+ object ParsingError : SharedSecretStorageError("parsing Error")
+ object BadMac : SharedSecretStorageError("Bad mac")
+ data class OtherError(val reason: Throwable) : SharedSecretStorageError(reason.localizedMessage)
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SharedSecretStorageService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SharedSecretStorageService.kt
new file mode 100644
index 0000000000..596d8d3e5d
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SharedSecretStorageService.kt
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.api.session.securestorage
+
+import im.vector.matrix.android.api.MatrixCallback
+import im.vector.matrix.android.api.listeners.ProgressListener
+
+/**
+ * Some features may require clients to store encrypted data on the server so that it can be shared securely between clients.
+ * Clients may also wish to securely send such data directly to each other.
+ * For example, key backups (MSC1219) can store the decryption key for the backups on the server, or cross-signing (MSC1756) can store the signing keys.
+ *
+ * https://github.com/matrix-org/matrix-doc/pull/1946
+ *
+ */
+
+interface SharedSecretStorageService {
+
+ /**
+ * Generates a SSSS key for encrypting secrets.
+ * Use the SsssKeyCreationInfo object returned by the callback to get more information about the created key (recovery key ...)
+ *
+ * @param keyId the ID of the key
+ * @param keyName a human readable name
+ * @param keySigner Used to add a signature to the key (client should check key signature before storing secret)
+ *
+ * @param callback Get key creation info
+ */
+ fun generateKey(keyId: String,
+ keyName: String,
+ keySigner: KeySigner?,
+ callback: MatrixCallback)
+
+ /**
+ * Generates a SSSS key using the given passphrase.
+ * Use the SsssKeyCreationInfo object returned by the callback to get more information about the created key (recovery key, salt, iteration ...)
+ *
+ * @param keyId the ID of the key
+ * @param keyName human readable key name
+ * @param passphrase The passphrase used to generate the key
+ * @param keySigner Used to add a signature to the key (client should check key signature before retrieving secret)
+ * @param progressListener The derivation of the passphrase may take long depending on the device, use this to report progress
+ *
+ * @param callback Get key creation info
+ */
+ fun generateKeyWithPassphrase(keyId: String,
+ keyName: String,
+ passphrase: String,
+ keySigner: KeySigner,
+ progressListener: ProgressListener?,
+ callback: MatrixCallback)
+
+ fun getKey(keyId: String): KeyInfoResult
+
+ /**
+ * A key can be marked as the "default" key by setting the user's account_data with event type m.secret_storage.default_key
+ * to an object that has the ID of the key as its key property.
+ * The default key will be used to encrypt all secrets that the user would expect to be available on all their clients.
+ * Unless the user specifies otherwise, clients will try to use the default key to decrypt secrets.
+ */
+ fun getDefaultKey(): KeyInfoResult
+
+ fun setDefaultKey(keyId: String, callback: MatrixCallback)
+
+ /**
+ * Check whether we have a key with a given ID.
+ *
+ * @param keyId The ID of the key to check
+ * @return Whether we have the key.
+ */
+ fun hasKey(keyId: String): Boolean
+
+ /**
+ * Store an encrypted secret on the server
+ * Clients MUST ensure that the key is trusted before using it to encrypt secrets.
+ *
+ * @param name The name of the secret
+ * @param secret The secret contents.
+ * @param keys The list of (ID,privateKey) of the keys to use to encrypt the secret.
+ */
+ fun storeSecret(name: String, secretBase64: String, keys: List, callback: MatrixCallback)
+
+ /**
+ * Use this call to determine which SSSSKeySpec to use for requesting secret
+ */
+ fun getAlgorithmsForSecret(name: String): List
+
+ /**
+ * Get an encrypted secret from the shared storage
+ *
+ * @param name The name of the secret
+ * @param keyId The id of the key that should be used to decrypt (null for default key)
+ * @param secretKey the secret key to use (@see #RawBytesKeySpec)
+ *
+ */
+ fun getSecret(name: String, keyId: String?, secretKey: SsssKeySpec, callback: MatrixCallback)
+
+ fun checkShouldBeAbleToAccessSecrets(secretNames: List, keyId: String?) : IntegrityResult
+
+ data class KeyRef(
+ val keyId: String?,
+ val keySpec: SsssKeySpec?
+ )
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SsssKeyCreationInfo.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SsssKeyCreationInfo.kt
new file mode 100644
index 0000000000..1d5522b8bf
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SsssKeyCreationInfo.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.api.session.securestorage
+
+data class SsssKeyCreationInfo(
+ val keyId: String = "",
+ var content: SecretStorageKeyContent?,
+ val recoveryKey: String = ""
+)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SsssKeySpec.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SsssKeySpec.kt
new file mode 100644
index 0000000000..1fe8fbb90d
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/securestorage/SsssKeySpec.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.api.session.securestorage
+
+import im.vector.matrix.android.api.listeners.ProgressListener
+import im.vector.matrix.android.internal.crypto.keysbackup.deriveKey
+import im.vector.matrix.android.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey
+
+/** Tag class */
+interface SsssKeySpec
+
+data class RawBytesKeySpec(
+ val privateKey: ByteArray
+) : SsssKeySpec {
+
+ companion object {
+
+ fun fromPassphrase(passphrase: String, salt: String, iterations: Int, progressListener: ProgressListener?): RawBytesKeySpec {
+ return RawBytesKeySpec(
+ privateKey = deriveKey(
+ passphrase,
+ salt,
+ iterations,
+ progressListener
+ )
+ )
+ }
+
+ fun fromRecoveryKey(recoveryKey: String): RawBytesKeySpec? {
+ return extractCurveKeyFromRecoveryKey(recoveryKey)?.let {
+ RawBytesKeySpec(
+ privateKey = it
+ )
+ }
+ }
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as RawBytesKeySpec
+
+ if (!privateKey.contentEquals(other.privateKey)) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int {
+ return privateKey.contentHashCode()
+ }
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/model/User.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/model/User.kt
index f569f5e47e..753c9b609c 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/model/User.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/model/User.kt
@@ -24,4 +24,9 @@ data class User(
val userId: String,
val displayName: String? = null,
val avatarUrl: String? = null
-)
+) {
+ /**
+ * Return the display name or the user id
+ */
+ fun getBestName() = displayName?.takeIf { it.isNotEmpty() } ?: userId
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/MatrixItem.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/MatrixItem.kt
index 5b3ca234ac..d5aa897c7d 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/MatrixItem.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/MatrixItem.kt
@@ -22,7 +22,7 @@ import im.vector.matrix.android.api.session.room.model.RoomMemberSummary
import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom
import im.vector.matrix.android.api.session.user.model.User
-import java.util.*
+import java.util.Locale
sealed class MatrixItem(
open val id: String,
@@ -143,8 +143,14 @@ sealed class MatrixItem(
* ========================================================================================== */
fun User.toMatrixItem() = MatrixItem.UserItem(userId, displayName, avatarUrl)
+
fun GroupSummary.toMatrixItem() = MatrixItem.GroupItem(groupId, displayName, avatarUrl)
+
fun RoomSummary.toMatrixItem() = MatrixItem.RoomItem(roomId, displayName, avatarUrl)
+
fun RoomSummary.toRoomAliasMatrixItem() = MatrixItem.RoomAliasItem(canonicalAlias ?: roomId, displayName, avatarUrl)
-fun PublicRoom.toMatrixItem() = MatrixItem.RoomItem(roomId, name, avatarUrl)
+
+// If no name is available, use room alias as Riot-Web does
+fun PublicRoom.toMatrixItem() = MatrixItem.RoomItem(roomId, name ?: getPrimaryAlias() ?: "", avatarUrl)
+
fun RoomMemberSummary.toMatrixItem() = MatrixItem.UserItem(userId, displayName, avatarUrl)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthAPI.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthAPI.kt
index 306a3846bc..2f03c99421 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthAPI.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthAPI.kt
@@ -22,10 +22,19 @@ import im.vector.matrix.android.internal.auth.data.LoginFlowResponse
import im.vector.matrix.android.internal.auth.data.PasswordLoginParams
import im.vector.matrix.android.internal.auth.data.RiotConfig
import im.vector.matrix.android.internal.auth.login.ResetPasswordMailConfirmed
-import im.vector.matrix.android.internal.auth.registration.*
+import im.vector.matrix.android.internal.auth.registration.AddThreePidRegistrationParams
+import im.vector.matrix.android.internal.auth.registration.AddThreePidRegistrationResponse
+import im.vector.matrix.android.internal.auth.registration.RegistrationParams
+import im.vector.matrix.android.internal.auth.registration.SuccessResult
+import im.vector.matrix.android.internal.auth.registration.ValidationCodeBody
import im.vector.matrix.android.internal.network.NetworkConstants
import retrofit2.Call
-import retrofit2.http.*
+import retrofit2.http.Body
+import retrofit2.http.GET
+import retrofit2.http.Headers
+import retrofit2.http.POST
+import retrofit2.http.Path
+import retrofit2.http.Url
/**
* The login REST API.
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticationService.kt
index d5dd7e2959..85c2cdbf3d 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticationService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticationService.kt
@@ -20,7 +20,13 @@ import android.net.Uri
import dagger.Lazy
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.auth.AuthenticationService
-import im.vector.matrix.android.api.auth.data.*
+import im.vector.matrix.android.api.auth.data.Credentials
+import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
+import im.vector.matrix.android.api.auth.data.LoginFlowResult
+import im.vector.matrix.android.api.auth.data.SessionParams
+import im.vector.matrix.android.api.auth.data.Versions
+import im.vector.matrix.android.api.auth.data.isLoginAndRegistrationSupportedBySdk
+import im.vector.matrix.android.api.auth.data.isSupportedBySdk
import im.vector.matrix.android.api.auth.login.LoginWizard
import im.vector.matrix.android.api.auth.registration.RegistrationWizard
import im.vector.matrix.android.api.failure.Failure
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/PendingSessionData.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/PendingSessionData.kt
index 0314491d3b..3241ea5917 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/PendingSessionData.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/PendingSessionData.kt
@@ -19,7 +19,7 @@ package im.vector.matrix.android.internal.auth.db
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
import im.vector.matrix.android.internal.auth.login.ResetPasswordData
import im.vector.matrix.android.internal.auth.registration.ThreePidData
-import java.util.*
+import java.util.UUID
/**
* This class holds all pending data when creating a session, either by login or by register
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/registration/RegistrationFlowResponse.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/registration/RegistrationFlowResponse.kt
index 2d3d25e538..7512454052 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/registration/RegistrationFlowResponse.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/registration/RegistrationFlowResponse.kt
@@ -32,20 +32,20 @@ data class RegistrationFlowResponse(
* The list of flows.
*/
@Json(name = "flows")
- var flows: List? = null,
+ val flows: List? = null,
/**
* The list of stages the client has completed successfully.
*/
@Json(name = "completed")
- var completedStages: List? = null,
+ val completedStages: List? = null,
/**
* The session identifier that the client must pass back to the home server, if one is provided,
* in subsequent attempts to authenticate in the same API call.
*/
@Json(name = "session")
- var session: String? = null,
+ val session: String? = null,
/**
* The information that the client will need to know in order to use a given type of authentication.
@@ -53,7 +53,7 @@ data class RegistrationFlowResponse(
* For example, the public key of reCAPTCHA stage could be given here.
*/
@Json(name = "params")
- var params: JsonDict? = null
+ val params: JsonDict? = null
/**
* WARNING,
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoConstants.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoConstants.kt
index a3b0a567fe..f82300548a 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoConstants.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoConstants.kt
@@ -31,6 +31,13 @@ const val MXCRYPTO_ALGORITHM_MEGOLM = "m.megolm.v1.aes-sha2"
*/
const val MXCRYPTO_ALGORITHM_MEGOLM_BACKUP = "m.megolm_backup.v1.curve25519-aes-sha2"
+/**
+ * Secured Shared Storage algorithm constant
+ */
+const val SSSS_ALGORITHM_CURVE25519_AES_SHA2 = "m.secret_storage.v1.curve25519-aes-sha2"
+/* Secrets are encrypted using AES-CTR-256 and MACed using HMAC-SHA-256. **/
+const val SSSS_ALGORITHM_AES_HMAC_SHA2 = "m.secret_storage.v1.aes-hmac-sha2"
+
// TODO Refacto: use this constants everywhere
const val ed25519 = "ed25519"
const val curve25519 = "curve25519"
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DefaultCryptoService.kt
index 26a35bd919..1db774fd2d 100755
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DefaultCryptoService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DefaultCryptoService.kt
@@ -49,7 +49,7 @@ import im.vector.matrix.android.internal.crypto.algorithms.megolm.MXMegolmEncryp
import im.vector.matrix.android.internal.crypto.algorithms.olm.MXOlmEncryptionFactory
import im.vector.matrix.android.internal.crypto.crosssigning.DefaultCrossSigningService
import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
-import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup
+import im.vector.matrix.android.internal.crypto.keysbackup.DefaultKeysBackupService
import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo
@@ -122,7 +122,7 @@ internal class DefaultCryptoService @Inject constructor(
// Device list manager
private val deviceListManager: DeviceListManager,
// The key backup service.
- private val keysBackup: KeysBackup,
+ private val keysBackupService: DefaultKeysBackupService,
//
private val objectSigner: ObjectSigner,
//
@@ -301,7 +301,7 @@ internal class DefaultCryptoService @Inject constructor(
uploadDeviceKeys()
oneTimeKeysUploader.maybeUploadOneTimeKeys()
outgoingRoomKeyRequestManager.start()
- keysBackup.checkAndStartKeysBackup()
+ keysBackupService.checkAndStartKeysBackup()
if (isInitialSync) {
// refresh the devices list for each known room members
deviceListManager.invalidateAllDeviceLists()
@@ -340,14 +340,14 @@ internal class DefaultCryptoService @Inject constructor(
/**
* @return the Keys backup Service
*/
- override fun getKeysBackupService() = keysBackup
+ override fun keysBackupService() = keysBackupService
/**
* @return the VerificationService
*/
- override fun getVerificationService() = verificationService
+ override fun verificationService() = verificationService
- override fun getCrossSigningService() = crossSigningService
+ override fun crossSigningService() = crossSigningService
/**
* A sync response has been received
@@ -721,7 +721,7 @@ internal class DefaultCryptoService @Inject constructor(
Timber.e("## onRoomKeyEvent() : Unable to handle keys for ${roomKeyContent.algorithm}")
return
}
- alg.onRoomKeyEvent(event, keysBackup)
+ alg.onRoomKeyEvent(event, keysBackupService)
}
/**
@@ -887,7 +887,7 @@ internal class DefaultCryptoService @Inject constructor(
throw Exception("Error")
}
- megolmSessionDataImporter.handle(importedSessions, true, uiHandler, progressListener)
+ megolmSessionDataImporter.handle(importedSessions, true, progressListener)
}
}.foldToCallback(callback)
}
@@ -1021,12 +1021,12 @@ internal class DefaultCryptoService @Inject constructor(
return
}
- val requestBody = RoomKeyRequestBody()
-
- requestBody.roomId = event.roomId
- requestBody.algorithm = wireContent["algorithm"]?.toString()
- requestBody.senderKey = wireContent["sender_key"]?.toString()
- requestBody.sessionId = wireContent["session_id"]?.toString()
+ val requestBody = RoomKeyRequestBody(
+ algorithm = wireContent["algorithm"]?.toString(),
+ roomId = event.roomId,
+ senderKey = wireContent["sender_key"]?.toString(),
+ sessionId = wireContent["session_id"]?.toString()
+ )
outgoingRoomKeyRequestManager.resendRoomKeyRequest(requestBody)
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequest.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequest.kt
index fe1f69f904..39b4678a27 100755
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequest.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequest.kt
@@ -25,54 +25,56 @@ import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyShareRequest
/**
* IncomingRoomKeyRequest class defines the incoming room keys request.
*/
-open class IncomingRoomKeyRequest {
- /**
- * The user id
- */
- var userId: String? = null
+data class IncomingRoomKeyRequest(
+ /**
+ * The user id
+ */
+ override val userId: String? = null,
- /**
- * The device id
- */
- var deviceId: String? = null
+ /**
+ * The device id
+ */
+ override val deviceId: String? = null,
- /**
- * The request id
- */
- var requestId: String? = null
+ /**
+ * The request id
+ */
+ override val requestId: String? = null,
- /**
- * The request body
- */
- var requestBody: RoomKeyRequestBody? = null
+ /**
+ * The request body
+ */
+ val requestBody: RoomKeyRequestBody? = null,
- /**
- * The runnable to call to accept to share the keys
- */
- @Transient
- var share: Runnable? = null
+ /**
+ * The runnable to call to accept to share the keys
+ */
+ @Transient
+ var share: Runnable? = null,
- /**
- * The runnable to call to ignore the key share request.
- */
- @Transient
- var ignore: Runnable? = null
-
- /**
- * Constructor
- *
- * @param event the event
- */
- constructor(event: Event) {
- userId = event.senderId
- val roomKeyShareRequest = event.getClearContent().toModel()!!
- deviceId = roomKeyShareRequest.requestingDeviceId
- requestId = roomKeyShareRequest.requestId
- requestBody = if (null != roomKeyShareRequest.body) roomKeyShareRequest.body else RoomKeyRequestBody()
+ /**
+ * The runnable to call to ignore the key share request.
+ */
+ @Transient
+ var ignore: Runnable? = null
+) : IncomingRoomKeyRequestCommon {
+ companion object {
+ /**
+ * Factory
+ *
+ * @param event the event
+ */
+ fun fromEvent(event: Event): IncomingRoomKeyRequest? {
+ return event.getClearContent()
+ .toModel()
+ ?.let {
+ IncomingRoomKeyRequest(
+ userId = event.senderId,
+ deviceId = it.requestingDeviceId,
+ requestId = it.requestId,
+ requestBody = it.body ?: RoomKeyRequestBody()
+ )
+ }
+ }
}
-
- /**
- * Constructor for object creation from crypto store
- */
- constructor()
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequestCancellation.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequestCancellation.kt
index 0b22a0e28b..6779936f3a 100755
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequestCancellation.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequestCancellation.kt
@@ -17,13 +17,44 @@
package im.vector.matrix.android.internal.crypto
import im.vector.matrix.android.api.session.events.model.Event
+import im.vector.matrix.android.api.session.events.model.toModel
+import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyShareCancellation
/**
* IncomingRoomKeyRequestCancellation describes the incoming room key cancellation.
*/
-class IncomingRoomKeyRequestCancellation(event: Event) : IncomingRoomKeyRequest(event) {
+data class IncomingRoomKeyRequestCancellation(
+ /**
+ * The user id
+ */
+ override val userId: String? = null,
- init {
- requestBody = null
+ /**
+ * The device id
+ */
+ override val deviceId: String? = null,
+
+ /**
+ * The request id
+ */
+ override val requestId: String? = null
+) : IncomingRoomKeyRequestCommon {
+ companion object {
+ /**
+ * Factory
+ *
+ * @param event the event
+ */
+ fun fromEvent(event: Event): IncomingRoomKeyRequestCancellation? {
+ return event.getClearContent()
+ .toModel()
+ ?.let {
+ IncomingRoomKeyRequestCancellation(
+ userId = event.senderId,
+ deviceId = it.requestingDeviceId,
+ requestId = it.requestId
+ )
+ }
+ }
}
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequestCommon.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequestCommon.kt
new file mode 100644
index 0000000000..a7b1c6b117
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequestCommon.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.internal.crypto
+
+interface IncomingRoomKeyRequestCommon {
+ /**
+ * The user id
+ */
+ val userId: String?
+
+ /**
+ * The device id
+ */
+ val deviceId: String?
+
+ /**
+ * The request id
+ */
+ val requestId: String?
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequestManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequestManager.kt
index 814d9d5a7c..92a117d64b 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequestManager.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequestManager.kt
@@ -19,7 +19,6 @@ package im.vector.matrix.android.internal.crypto
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.api.session.crypto.keyshare.RoomKeysRequestListener
import im.vector.matrix.android.api.session.events.model.Event
-import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyShare
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.session.SessionScope
@@ -51,11 +50,10 @@ internal class IncomingRoomKeyRequestManager @Inject constructor(
* @param event the announcement event.
*/
fun onRoomKeyRequestEvent(event: Event) {
- val roomKeyShare = event.getClearContent().toModel()
- when (roomKeyShare?.action) {
- RoomKeyShare.ACTION_SHARE_REQUEST -> receivedRoomKeyRequests.add(IncomingRoomKeyRequest(event))
- RoomKeyShare.ACTION_SHARE_CANCELLATION -> receivedRoomKeyRequestCancellations.add(IncomingRoomKeyRequestCancellation(event))
- else -> Timber.e("## onRoomKeyRequestEvent() : unsupported action ${roomKeyShare?.action}")
+ when (val roomKeyShareAction = event.getClearContent()?.get("action") as? String) {
+ RoomKeyShare.ACTION_SHARE_REQUEST -> IncomingRoomKeyRequest.fromEvent(event)?.let { receivedRoomKeyRequests.add(it) }
+ RoomKeyShare.ACTION_SHARE_CANCELLATION -> IncomingRoomKeyRequestCancellation.fromEvent(event)?.let { receivedRoomKeyRequestCancellations.add(it) }
+ else -> Timber.e("## onRoomKeyRequestEvent() : unsupported action $roomKeyShareAction")
}
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOlmDevice.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOlmDevice.kt
index 75a4ba5ed7..47ec85ec8c 100755
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOlmDevice.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOlmDevice.kt
@@ -29,7 +29,12 @@ import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.util.JsonCanonicalizer
import im.vector.matrix.android.internal.util.convertFromUTF8
import im.vector.matrix.android.internal.util.convertToUTF8
-import org.matrix.olm.*
+import org.matrix.olm.OlmAccount
+import org.matrix.olm.OlmException
+import org.matrix.olm.OlmMessage
+import org.matrix.olm.OlmOutboundGroupSession
+import org.matrix.olm.OlmSession
+import org.matrix.olm.OlmUtility
import timber.log.Timber
import java.net.URLEncoder
import javax.inject.Inject
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MegolmSessionData.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MegolmSessionData.kt
index 821ed0a553..d6dae1a865 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MegolmSessionData.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MegolmSessionData.kt
@@ -28,46 +28,46 @@ data class MegolmSessionData(
* The algorithm used.
*/
@Json(name = "algorithm")
- var algorithm: String? = null,
+ val algorithm: String? = null,
/**
* Unique id for the session.
*/
@Json(name = "session_id")
- var sessionId: String? = null,
+ val sessionId: String? = null,
/**
* Sender's Curve25519 device key.
*/
@Json(name = "sender_key")
- var senderKey: String? = null,
+ val senderKey: String? = null,
/**
* Room this session is used in.
*/
@Json(name = "room_id")
- var roomId: String? = null,
+ val roomId: String? = null,
/**
* Base64'ed key data.
*/
@Json(name = "session_key")
- var sessionKey: String? = null,
+ val sessionKey: String? = null,
/**
* Other keys the sender claims.
*/
@Json(name = "sender_claimed_keys")
- var senderClaimedKeys: Map? = null,
+ val senderClaimedKeys: Map? = null,
// This is a shortcut for sender_claimed_keys.get("ed25519")
// Keep it for compatibility reason.
@Json(name = "sender_claimed_ed25519_key")
- var senderClaimedEd25519Key: String? = null,
+ val senderClaimedEd25519Key: String? = null,
/**
* Devices which forwarded this session to us (normally empty).
*/
@Json(name = "forwarding_curve25519_key_chain")
- var forwardingCurve25519KeyChain: List? = null
+ val forwardingCurve25519KeyChain: List? = null
)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/OutgoingRoomKeyRequestManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/OutgoingRoomKeyRequestManager.kt
index 5320b84b0e..b59c93ba83 100755
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/OutgoingRoomKeyRequestManager.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/OutgoingRoomKeyRequestManager.kt
@@ -213,10 +213,11 @@ internal class OutgoingRoomKeyRequestManager @Inject constructor(
Timber.v("## sendOutgoingRoomKeyRequest() : Requesting keys " + request.requestBody
+ " from " + request.recipients + " id " + request.requestId)
- val requestMessage = RoomKeyShareRequest()
- requestMessage.requestingDeviceId = cryptoStore.getDeviceId()
- requestMessage.requestId = request.requestId
- requestMessage.body = request.requestBody
+ val requestMessage = RoomKeyShareRequest(
+ requestingDeviceId = cryptoStore.getDeviceId(),
+ requestId = request.requestId,
+ body = request.requestBody
+ )
sendMessageToDevices(requestMessage, request.recipients, request.requestId, object : MatrixCallback {
private fun onDone(state: OutgoingRoomKeyRequest.RequestState) {
@@ -253,9 +254,10 @@ internal class OutgoingRoomKeyRequestManager @Inject constructor(
+ " to " + request.recipients
+ " cancellation id " + request.cancellationTxnId)
- val roomKeyShareCancellation = RoomKeyShareCancellation()
- roomKeyShareCancellation.requestingDeviceId = cryptoStore.getDeviceId()
- roomKeyShareCancellation.requestId = request.cancellationTxnId
+ val roomKeyShareCancellation = RoomKeyShareCancellation(
+ requestingDeviceId = cryptoStore.getDeviceId(),
+ requestId = request.cancellationTxnId
+ )
sendMessageToDevices(roomKeyShareCancellation, request.recipients, request.cancellationTxnId, object : MatrixCallback {
private fun onDone() {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/MegolmSessionDataImporter.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/MegolmSessionDataImporter.kt
index 62b4f1b851..6f41116b90 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/MegolmSessionDataImporter.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/MegolmSessionDataImporter.kt
@@ -16,7 +16,6 @@
package im.vector.matrix.android.internal.crypto.actions
-import android.os.Handler
import androidx.annotation.WorkerThread
import im.vector.matrix.android.api.listeners.ProgressListener
import im.vector.matrix.android.internal.crypto.MXOlmDevice
@@ -46,7 +45,6 @@ internal class MegolmSessionDataImporter @Inject constructor(private val olmDevi
@WorkerThread
fun handle(megolmSessionsData: List,
fromBackup: Boolean,
- uiHandler: Handler,
progressListener: ProgressListener?): ImportRoomKeysResult {
val t0 = System.currentTimeMillis()
@@ -54,11 +52,7 @@ internal class MegolmSessionDataImporter @Inject constructor(private val olmDevi
var lastProgress = 0
var totalNumbersOfImportedKeys = 0
- if (progressListener != null) {
- uiHandler.post {
- progressListener.onProgress(0, 100)
- }
- }
+ progressListener?.onProgress(0, 100)
val olmInboundGroupSessionWrappers = olmDevice.importInboundGroupSessions(megolmSessionsData)
megolmSessionsData.forEachIndexed { cpt, megolmSessionData ->
@@ -72,12 +66,12 @@ internal class MegolmSessionDataImporter @Inject constructor(private val olmDevi
totalNumbersOfImportedKeys++
// cancel any outstanding room key requests for this session
- val roomKeyRequestBody = RoomKeyRequestBody()
-
- roomKeyRequestBody.algorithm = megolmSessionData.algorithm
- roomKeyRequestBody.roomId = megolmSessionData.roomId
- roomKeyRequestBody.senderKey = megolmSessionData.senderKey
- roomKeyRequestBody.sessionId = megolmSessionData.sessionId
+ val roomKeyRequestBody = RoomKeyRequestBody(
+ algorithm = megolmSessionData.algorithm,
+ roomId = megolmSessionData.roomId,
+ senderKey = megolmSessionData.senderKey,
+ sessionId = megolmSessionData.sessionId
+ )
outgoingRoomKeyRequestManager.cancelRoomKeyRequest(roomKeyRequestBody)
@@ -89,14 +83,12 @@ internal class MegolmSessionDataImporter @Inject constructor(private val olmDevi
}
if (progressListener != null) {
- uiHandler.post {
- val progress = 100 * cpt / totalNumbersOfKeys
+ val progress = 100 * (cpt + 1) / totalNumbersOfKeys
- if (lastProgress != progress) {
- lastProgress = progress
+ if (lastProgress != progress) {
+ lastProgress = progress
- progressListener.onProgress(progress, 100)
- }
+ progressListener.onProgress(progress, 100)
}
}
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/SetDeviceVerificationAction.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/SetDeviceVerificationAction.kt
index 8dad832617..d6538f041d 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/SetDeviceVerificationAction.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/SetDeviceVerificationAction.kt
@@ -17,7 +17,7 @@
package im.vector.matrix.android.internal.crypto.actions
import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
-import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup
+import im.vector.matrix.android.internal.crypto.keysbackup.DefaultKeysBackupService
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.di.UserId
import timber.log.Timber
@@ -26,7 +26,7 @@ import javax.inject.Inject
internal class SetDeviceVerificationAction @Inject constructor(
private val cryptoStore: IMXCryptoStore,
@UserId private val userId: String,
- private val keysBackup: KeysBackup) {
+ private val defaultKeysBackupService: DefaultKeysBackupService) {
fun handle(trustLevel: DeviceTrustLevel, userId: String, deviceId: String) {
val device = cryptoStore.getUserDevice(userId, deviceId)
@@ -42,7 +42,7 @@ internal class SetDeviceVerificationAction @Inject constructor(
// If one of the user's own devices is being marked as verified / unverified,
// check the key backup status, since whether or not we use this depends on
// whether it has a signature from a verified device
- keysBackup.checkAndStartKeysBackup()
+ defaultKeysBackupService.checkAndStartKeysBackup()
}
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/IMXDecrypting.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/IMXDecrypting.kt
index f63eaa93b3..e8fb6be6ff 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/IMXDecrypting.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/IMXDecrypting.kt
@@ -20,7 +20,7 @@ package im.vector.matrix.android.internal.crypto.algorithms
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.internal.crypto.IncomingRoomKeyRequest
import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult
-import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup
+import im.vector.matrix.android.internal.crypto.keysbackup.DefaultKeysBackupService
/**
* An interface for decrypting data
@@ -41,7 +41,7 @@ internal interface IMXDecrypting {
*
* @param event the key event.
*/
- fun onRoomKeyEvent(event: Event, keysBackup: KeysBackup) {}
+ fun onRoomKeyEvent(event: Event, defaultKeysBackupService: DefaultKeysBackupService) {}
/**
* Check if the some messages can be decrypted with a new session
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt
index 9121ce3fcb..90100fcc48 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt
@@ -30,7 +30,7 @@ import im.vector.matrix.android.internal.crypto.OutgoingRoomKeyRequestManager
import im.vector.matrix.android.internal.crypto.actions.EnsureOlmSessionsForDevicesAction
import im.vector.matrix.android.internal.crypto.actions.MessageEncrypter
import im.vector.matrix.android.internal.crypto.algorithms.IMXDecrypting
-import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup
+import im.vector.matrix.android.internal.crypto.keysbackup.DefaultKeysBackupService
import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
import im.vector.matrix.android.internal.crypto.model.event.EncryptedEventContent
import im.vector.matrix.android.internal.crypto.model.event.RoomKeyContent
@@ -163,12 +163,12 @@ internal class MXMegolmDecryption(private val userId: String,
recipients.add(senderMap)
}
- val requestBody = RoomKeyRequestBody()
-
- requestBody.roomId = event.roomId
- requestBody.algorithm = encryptedEventContent.algorithm
- requestBody.senderKey = encryptedEventContent.senderKey
- requestBody.sessionId = encryptedEventContent.sessionId
+ val requestBody = RoomKeyRequestBody(
+ roomId = event.roomId,
+ algorithm = encryptedEventContent.algorithm,
+ senderKey = encryptedEventContent.senderKey,
+ sessionId = encryptedEventContent.sessionId
+ )
outgoingRoomKeyRequestManager.sendRoomKeyRequest(requestBody, recipients)
}
@@ -198,7 +198,7 @@ internal class MXMegolmDecryption(private val userId: String,
*
* @param event the key event.
*/
- override fun onRoomKeyEvent(event: Event, keysBackup: KeysBackup) {
+ override fun onRoomKeyEvent(event: Event, defaultKeysBackupService: DefaultKeysBackupService) {
var exportFormat = false
val roomKeyContent = event.getClearContent().toModel() ?: return
@@ -262,14 +262,14 @@ internal class MXMegolmDecryption(private val userId: String,
exportFormat)
if (added) {
- keysBackup.maybeBackupKeys()
+ defaultKeysBackupService.maybeBackupKeys()
- val content = RoomKeyRequestBody()
-
- content.algorithm = roomKeyContent.algorithm
- content.roomId = roomKeyContent.roomId
- content.sessionId = roomKeyContent.sessionId
- content.senderKey = senderKey
+ val content = RoomKeyRequestBody(
+ algorithm = roomKeyContent.algorithm,
+ roomId = roomKeyContent.roomId,
+ sessionId = roomKeyContent.sessionId,
+ senderKey = senderKey
+ )
outgoingRoomKeyRequestManager.cancelRoomKeyRequest(content)
@@ -290,8 +290,8 @@ internal class MXMegolmDecryption(private val userId: String,
override fun hasKeysForKeyRequest(request: IncomingRoomKeyRequest): Boolean {
val roomId = request.requestBody?.roomId ?: return false
- val senderKey = request.requestBody?.senderKey ?: return false
- val sessionId = request.requestBody?.sessionId ?: return false
+ val senderKey = request.requestBody.senderKey ?: return false
+ val sessionId = request.requestBody.sessionId ?: return false
return olmDevice.hasInboundSessionKeys(roomId, senderKey, sessionId)
}
@@ -319,15 +319,14 @@ internal class MXMegolmDecryption(private val userId: String,
return@mapCatching
}
Timber.v("## shareKeysWithDevice() : sharing keys for session" +
- " ${body?.senderKey}|${body?.sessionId} with device $userId:$deviceId")
+ " ${body.senderKey}|${body.sessionId} with device $userId:$deviceId")
val payloadJson = mutableMapOf("type" to EventType.FORWARDED_ROOM_KEY)
- runCatching { olmDevice.getInboundGroupSession(body?.sessionId, body?.senderKey, body?.roomId) }
+ runCatching { olmDevice.getInboundGroupSession(body.sessionId, body.senderKey, body.roomId) }
.fold(
{
// TODO
- payloadJson["content"] = it.exportKeys()
- ?: ""
+ payloadJson["content"] = it.exportKeys() ?: ""
},
{
// TODO
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt
index ee35810763..a2d21c4f89 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt
@@ -28,7 +28,7 @@ import im.vector.matrix.android.internal.crypto.MXOlmDevice
import im.vector.matrix.android.internal.crypto.actions.EnsureOlmSessionsForDevicesAction
import im.vector.matrix.android.internal.crypto.actions.MessageEncrypter
import im.vector.matrix.android.internal.crypto.algorithms.IMXEncrypting
-import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup
+import im.vector.matrix.android.internal.crypto.keysbackup.DefaultKeysBackupService
import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
import im.vector.matrix.android.internal.crypto.repository.WarnOnUnknownDeviceRepository
@@ -42,7 +42,7 @@ internal class MXMegolmEncryption(
// The id of the room we will be sending to.
private var roomId: String,
private val olmDevice: MXOlmDevice,
- private val keysBackup: KeysBackup,
+ private val defaultKeysBackupService: DefaultKeysBackupService,
private val cryptoStore: IMXCryptoStore,
private val deviceListManager: DeviceListManager,
private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
@@ -85,7 +85,7 @@ internal class MXMegolmEncryption(
olmDevice.addInboundGroupSession(sessionId!!, olmDevice.getSessionKey(sessionId)!!, roomId, olmDevice.deviceCurve25519Key!!,
emptyList(), keysClaimedMap, false)
- keysBackup.maybeBackupKeys()
+ defaultKeysBackupService.maybeBackupKeys()
return MXOutboundSessionInfo(sessionId)
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryptionFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryptionFactory.kt
index dadd810a4b..e9fe902f1f 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryptionFactory.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryptionFactory.kt
@@ -21,7 +21,7 @@ import im.vector.matrix.android.internal.crypto.DeviceListManager
import im.vector.matrix.android.internal.crypto.MXOlmDevice
import im.vector.matrix.android.internal.crypto.actions.EnsureOlmSessionsForDevicesAction
import im.vector.matrix.android.internal.crypto.actions.MessageEncrypter
-import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup
+import im.vector.matrix.android.internal.crypto.keysbackup.DefaultKeysBackupService
import im.vector.matrix.android.internal.crypto.repository.WarnOnUnknownDeviceRepository
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask
@@ -29,7 +29,7 @@ import javax.inject.Inject
internal class MXMegolmEncryptionFactory @Inject constructor(
private val olmDevice: MXOlmDevice,
- private val keysBackup: KeysBackup,
+ private val defaultKeysBackupService: DefaultKeysBackupService,
private val cryptoStore: IMXCryptoStore,
private val deviceListManager: DeviceListManager,
private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
@@ -42,7 +42,7 @@ internal class MXMegolmEncryptionFactory @Inject constructor(
return MXMegolmEncryption(
roomId,
olmDevice,
- keysBackup,
+ defaultKeysBackupService,
cryptoStore,
deviceListManager,
ensureOlmSessionsForDevicesAction,
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/api/CryptoApi.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/api/CryptoApi.kt
index 4953d53ae0..93dae588aa 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/api/CryptoApi.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/api/CryptoApi.kt
@@ -16,10 +16,29 @@
*/
package im.vector.matrix.android.internal.crypto.api
-import im.vector.matrix.android.internal.crypto.model.rest.*
+import im.vector.matrix.android.internal.crypto.model.rest.DeleteDeviceParams
+import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
+import im.vector.matrix.android.internal.crypto.model.rest.DevicesListResponse
+import im.vector.matrix.android.internal.crypto.model.rest.KeyChangesResponse
+import im.vector.matrix.android.internal.crypto.model.rest.KeysClaimBody
+import im.vector.matrix.android.internal.crypto.model.rest.KeysClaimResponse
+import im.vector.matrix.android.internal.crypto.model.rest.KeysQueryBody
+import im.vector.matrix.android.internal.crypto.model.rest.KeysQueryResponse
+import im.vector.matrix.android.internal.crypto.model.rest.KeysUploadBody
+import im.vector.matrix.android.internal.crypto.model.rest.KeysUploadResponse
+import im.vector.matrix.android.internal.crypto.model.rest.SendToDeviceBody
+import im.vector.matrix.android.internal.crypto.model.rest.SignatureUploadResponse
+import im.vector.matrix.android.internal.crypto.model.rest.UpdateDeviceInfoBody
+import im.vector.matrix.android.internal.crypto.model.rest.UploadSigningKeysBody
import im.vector.matrix.android.internal.network.NetworkConstants
import retrofit2.Call
-import retrofit2.http.*
+import retrofit2.http.Body
+import retrofit2.http.GET
+import retrofit2.http.HTTP
+import retrofit2.http.POST
+import retrofit2.http.PUT
+import retrofit2.http.Path
+import retrofit2.http.Query
internal interface CryptoApi {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ComputeTrustTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ComputeTrustTask.kt
index 207dc0b928..841de92130 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ComputeTrustTask.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ComputeTrustTask.kt
@@ -20,6 +20,8 @@ import im.vector.matrix.android.api.extensions.orFalse
import im.vector.matrix.android.api.session.crypto.crosssigning.MXCrossSigningInfo
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
import im.vector.matrix.android.internal.task.Task
+import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
+import kotlinx.coroutines.withContext
import javax.inject.Inject
internal interface ComputeTrustTask : Task {
@@ -29,14 +31,15 @@ internal interface ComputeTrustTask : Task getUserCrossSigningKeys(userId)?.isTrusted() == true }
- return if (allTrustedUserIds.isEmpty()) {
+ if (allTrustedUserIds.isEmpty()) {
RoomEncryptionTrustLevel.Default
} else {
// If one of the verified user as an untrusted device -> warning
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/DefaultCrossSigningService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/DefaultCrossSigningService.kt
index 7fc3c0a549..a29f27ddd6 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/DefaultCrossSigningService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/DefaultCrossSigningService.kt
@@ -88,7 +88,8 @@ internal class DefaultCrossSigningService @Inject constructor(
Timber.i("## CrossSigning - Loading master key success")
} else {
Timber.w("## CrossSigning - Public master key does not match the private key")
- // TODO untrust
+ pkSigning.releaseSigning()
+ // TODO untrust?
}
}
privateKeysInfo.user
@@ -100,7 +101,8 @@ internal class DefaultCrossSigningService @Inject constructor(
Timber.i("## CrossSigning - Loading User Signing key success")
} else {
Timber.w("## CrossSigning - Public User key does not match the private key")
- // TODO untrust
+ pkSigning.releaseSigning()
+ // TODO untrust?
}
}
privateKeysInfo.selfSigned
@@ -112,7 +114,8 @@ internal class DefaultCrossSigningService @Inject constructor(
Timber.i("## CrossSigning - Loading Self Signing key success")
} else {
Timber.w("## CrossSigning - Public Self Signing key does not match the private key")
- // TODO untrust
+ pkSigning.releaseSigning()
+ // TODO untrust?
}
}
}
@@ -224,16 +227,18 @@ internal class DefaultCrossSigningService @Inject constructor(
val myDevice = myDeviceInfoHolder.get().myDevice
val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, myDevice.signalableJSONDictionary())
val signedDevice = selfSigningPkOlm.sign(canonicalJson)
- val updateSignatures = (myDevice.signatures?.toMutableMap() ?: HashMap()).also {
- it[userId] = (it[userId]
- ?: HashMap()) + mapOf("ed25519:$sskPublicKey" to signedDevice)
- }
+ val updateSignatures = (myDevice.signatures?.toMutableMap() ?: HashMap())
+ .also {
+ it[userId] = (it[userId]
+ ?: HashMap()) + mapOf("ed25519:$sskPublicKey" to signedDevice)
+ }
myDevice.copy(signatures = updateSignatures).let {
uploadSignatureQueryBuilder.withDeviceInfo(it)
}
// sign MSK with device key (migration) and upload signatures
- olmDevice.signMessage(JsonCanonicalizer.getCanonicalJson(Map::class.java, mskCrossSigningKeyInfo.signalableJSONDictionary()))?.let { sign ->
+ val message = JsonCanonicalizer.getCanonicalJson(Map::class.java, mskCrossSigningKeyInfo.signalableJSONDictionary())
+ olmDevice.signMessage(message)?.let { sign ->
val mskUpdatedSignatures = (mskCrossSigningKeyInfo.signatures?.toMutableMap()
?: HashMap()).also {
it[userId] = (it[userId]
@@ -292,6 +297,80 @@ internal class DefaultCrossSigningService @Inject constructor(
cryptoStore.clearOtherUserTrust()
}
+ override fun checkTrustFromPrivateKeys(masterKeyPrivateKey: String?,
+ uskKeyPrivateKey: String?,
+ sskPrivateKey: String?
+ ): UserTrustResult {
+ val mxCrossSigningInfo = getMyCrossSigningKeys() ?: return UserTrustResult.CrossSigningNotConfigured(userId)
+
+ var masterKeyIsTrusted = false
+ var userKeyIsTrusted = false
+ var selfSignedKeyIsTrusted = false
+
+ masterKeyPrivateKey?.fromBase64NoPadding()
+ ?.let { privateKeySeed ->
+ val pkSigning = OlmPkSigning()
+ try {
+ if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.masterKey()?.unpaddedBase64PublicKey) {
+ masterPkSigning?.releaseSigning()
+ masterPkSigning = pkSigning
+ masterKeyIsTrusted = true
+ Timber.i("## CrossSigning - Loading master key success")
+ } else {
+ pkSigning.releaseSigning()
+ }
+ } catch (failure: Throwable) {
+ pkSigning.releaseSigning()
+ }
+ }
+
+ uskKeyPrivateKey?.fromBase64NoPadding()
+ ?.let { privateKeySeed ->
+ val pkSigning = OlmPkSigning()
+ try {
+ if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.userKey()?.unpaddedBase64PublicKey) {
+ userPkSigning?.releaseSigning()
+ userPkSigning = pkSigning
+ userKeyIsTrusted = true
+ Timber.i("## CrossSigning - Loading master key success")
+ } else {
+ pkSigning.releaseSigning()
+ }
+ } catch (failure: Throwable) {
+ pkSigning.releaseSigning()
+ }
+ }
+
+ sskPrivateKey?.fromBase64NoPadding()
+ ?.let { privateKeySeed ->
+ val pkSigning = OlmPkSigning()
+ try {
+ if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.selfSigningKey()?.unpaddedBase64PublicKey) {
+ selfSigningPkSigning?.releaseSigning()
+ selfSigningPkSigning = pkSigning
+ selfSignedKeyIsTrusted = true
+ Timber.i("## CrossSigning - Loading master key success")
+ } else {
+ pkSigning.releaseSigning()
+ }
+ } catch (failure: Throwable) {
+ pkSigning.releaseSigning()
+ }
+ }
+
+ if (!masterKeyIsTrusted || !userKeyIsTrusted || !selfSignedKeyIsTrusted) {
+ return UserTrustResult.KeysNotTrusted(mxCrossSigningInfo)
+ } else {
+ cryptoStore.markMyMasterKeyAsLocallyTrusted(true)
+ val checkSelfTrust = checkSelfTrust()
+ if (checkSelfTrust.isVerified()) {
+ cryptoStore.storePrivateKeysInfo(masterKeyPrivateKey, uskKeyPrivateKey, sskPrivateKey)
+ setUserKeysAsTrusted(userId, true)
+ }
+ return checkSelfTrust
+ }
+ }
+
/**
*
* ┏━━━━━━━━┓ ┏━━━━━━━━┓
@@ -374,7 +453,9 @@ internal class DefaultCrossSigningService @Inject constructor(
?.fromBase64NoPadding()
var isMaterKeyTrusted = false
- if (masterPrivateKey != null) {
+ if (myMasterKey.trustLevel?.locallyVerified == true) {
+ isMaterKeyTrusted = true
+ } else if (masterPrivateKey != null) {
// Check if private match public
var olmPkSigning: OlmPkSigning? = null
try {
@@ -507,7 +588,12 @@ internal class DefaultCrossSigningService @Inject constructor(
}.executeBy(taskExecutor)
}
- override fun signDevice(deviceId: String, callback: MatrixCallback) {
+ override fun markMyMasterKeyAsTrusted() {
+ cryptoStore.markMyMasterKeyAsLocallyTrusted(true)
+ checkSelfTrust()
+ }
+
+ override fun trustDevice(deviceId: String, callback: MatrixCallback) {
// This device should be yours
val device = cryptoStore.getUserDevice(userId, deviceId)
if (device == null) {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ShieldTrustUpdater.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ShieldTrustUpdater.kt
index 5bc6e2df0f..c4c49a5940 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ShieldTrustUpdater.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ShieldTrustUpdater.kt
@@ -18,16 +18,19 @@ package im.vector.matrix.android.internal.crypto.crosssigning
import im.vector.matrix.android.internal.database.model.RoomMemberSummaryEntity
import im.vector.matrix.android.internal.database.model.RoomMemberSummaryEntityFields
import im.vector.matrix.android.internal.database.query.where
-import im.vector.matrix.android.internal.di.CryptoDatabase
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater
import im.vector.matrix.android.internal.task.TaskExecutor
+import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import im.vector.matrix.android.internal.util.createBackgroundHandler
import io.realm.Realm
import io.realm.RealmConfiguration
import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
+import timber.log.Timber
+import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference
import javax.inject.Inject
@@ -35,7 +38,7 @@ internal class ShieldTrustUpdater @Inject constructor(
private val eventBus: EventBus,
private val computeTrustTask: ComputeTrustTask,
private val taskExecutor: TaskExecutor,
- @CryptoDatabase private val cryptoRealmConfiguration: RealmConfiguration,
+ private val coroutineDispatchers: MatrixCoroutineDispatchers,
@SessionDatabase private val sessionRealmConfiguration: RealmConfiguration,
private val roomSummaryUpdater: RoomSummaryUpdater
) {
@@ -44,51 +47,41 @@ internal class ShieldTrustUpdater @Inject constructor(
private val BACKGROUND_HANDLER = createBackgroundHandler("SHIELD_CRYPTO_DB_THREAD")
}
- private val backgroundCryptoRealm = AtomicReference()
private val backgroundSessionRealm = AtomicReference()
-// private var cryptoDevicesResult: RealmResults? = null
-
-// private val cryptoDeviceChangeListener = object : OrderedRealmCollectionChangeListener> {
-// override fun onChange(t: RealmResults, changeSet: OrderedCollectionChangeSet) {
-// val grouped = t.groupBy { it.userId }
-// onCryptoDevicesChange(grouped.keys.mapNotNull { it })
-// }
-// }
+ private val isStarted = AtomicBoolean()
fun start() {
- eventBus.register(this)
- BACKGROUND_HANDLER.post {
- val cryptoRealm = Realm.getInstance(cryptoRealmConfiguration)
- backgroundCryptoRealm.set(cryptoRealm)
-// cryptoDevicesResult = cryptoRealm.where().findAll()
-// cryptoDevicesResult?.addChangeListener(cryptoDeviceChangeListener)
-
- backgroundSessionRealm.set(Realm.getInstance(sessionRealmConfiguration))
+ if (isStarted.compareAndSet(false, true)) {
+ eventBus.register(this)
+ BACKGROUND_HANDLER.post {
+ backgroundSessionRealm.set(Realm.getInstance(sessionRealmConfiguration))
+ }
}
}
fun stop() {
- eventBus.unregister(this)
- BACKGROUND_HANDLER.post {
- // cryptoDevicesResult?.removeAllChangeListeners()
- backgroundCryptoRealm.getAndSet(null).also {
- it?.close()
- }
- backgroundSessionRealm.getAndSet(null).also {
- it?.close()
+ if (isStarted.compareAndSet(true, false)) {
+ eventBus.unregister(this)
+ BACKGROUND_HANDLER.post {
+ backgroundSessionRealm.getAndSet(null).also {
+ it?.close()
+ }
}
}
}
@Subscribe
fun onRoomMemberChange(update: SessionToCryptoRoomMembersUpdate) {
- taskExecutor.executorScope.launch {
+ if (!isStarted.get()) {
+ return
+ }
+ taskExecutor.executorScope.launch(coroutineDispatchers.crypto) {
val updatedTrust = computeTrustTask.execute(ComputeTrustTask.Params(update.userIds))
// We need to send that back to session base
BACKGROUND_HANDLER.post {
- backgroundSessionRealm.get().executeTransaction { realm ->
+ backgroundSessionRealm.get()?.executeTransaction { realm ->
roomSummaryUpdater.updateShieldTrust(realm, update.roomId, updatedTrust)
}
}
@@ -97,34 +90,47 @@ internal class ShieldTrustUpdater @Inject constructor(
@Subscribe
fun onTrustUpdate(update: CryptoToSessionUserTrustChange) {
+ if (!isStarted.get()) {
+ return
+ }
+
onCryptoDevicesChange(update.userIds)
}
private fun onCryptoDevicesChange(users: List) {
BACKGROUND_HANDLER.post {
- val impactedRoomsId = backgroundSessionRealm.get().where(RoomMemberSummaryEntity::class.java)
- .`in`(RoomMemberSummaryEntityFields.USER_ID, users.toTypedArray())
- .findAll()
- .map { it.roomId }
- .distinct()
+ val impactedRoomsId = backgroundSessionRealm.get()?.where(RoomMemberSummaryEntity::class.java)
+ ?.`in`(RoomMemberSummaryEntityFields.USER_ID, users.toTypedArray())
+ ?.findAll()
+ ?.map { it.roomId }
+ ?.distinct()
val map = HashMap>()
- impactedRoomsId.forEach { roomId ->
- RoomMemberSummaryEntity.where(backgroundSessionRealm.get(), roomId)
- .findAll()
- .let { results ->
- map[roomId] = results.map { it.userId }
- }
+ impactedRoomsId?.forEach { roomId ->
+ backgroundSessionRealm.get()?.let { realm ->
+ RoomMemberSummaryEntity.where(realm, roomId)
+ .findAll()
+ .let { results ->
+ map[roomId] = results.map { it.userId }
+ }
+ }
}
map.forEach { entry ->
val roomId = entry.key
val userList = entry.value
taskExecutor.executorScope.launch {
- val updatedTrust = computeTrustTask.execute(ComputeTrustTask.Params(userList))
- BACKGROUND_HANDLER.post {
- backgroundSessionRealm.get().executeTransaction { realm ->
- roomSummaryUpdater.updateShieldTrust(realm, roomId, updatedTrust)
+ withContext(coroutineDispatchers.crypto) {
+ try {
+ // Can throw if the crypto database has been closed in between, in this case log and ignore?
+ val updatedTrust = computeTrustTask.execute(ComputeTrustTask.Params(userList))
+ BACKGROUND_HANDLER.post {
+ backgroundSessionRealm.get()?.executeTransaction { realm ->
+ roomSummaryUpdater.updateShieldTrust(realm, roomId, updatedTrust)
+ }
+ }
+ } catch (failure: Throwable) {
+ Timber.e(failure)
}
}
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackup.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/DefaultKeysBackupService.kt
similarity index 89%
rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackup.kt
rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/DefaultKeysBackupService.kt
index 7906005046..3ec5a2f979 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackup.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/DefaultKeysBackupService.kt
@@ -40,8 +40,28 @@ import im.vector.matrix.android.internal.crypto.keysbackup.model.KeysBackupVersi
import im.vector.matrix.android.internal.crypto.keysbackup.model.KeysBackupVersionTrustSignature
import im.vector.matrix.android.internal.crypto.keysbackup.model.MegolmBackupAuthData
import im.vector.matrix.android.internal.crypto.keysbackup.model.MegolmBackupCreationInfo
-import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.*
-import im.vector.matrix.android.internal.crypto.keysbackup.tasks.*
+import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.BackupKeysResult
+import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody
+import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeyBackupData
+import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysBackupData
+import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersion
+import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersionResult
+import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.RoomKeysBackupData
+import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.UpdateKeysBackupVersionBody
+import im.vector.matrix.android.internal.crypto.keysbackup.tasks.CreateKeysBackupVersionTask
+import im.vector.matrix.android.internal.crypto.keysbackup.tasks.DeleteBackupTask
+import im.vector.matrix.android.internal.crypto.keysbackup.tasks.DeleteRoomSessionDataTask
+import im.vector.matrix.android.internal.crypto.keysbackup.tasks.DeleteRoomSessionsDataTask
+import im.vector.matrix.android.internal.crypto.keysbackup.tasks.DeleteSessionsDataTask
+import im.vector.matrix.android.internal.crypto.keysbackup.tasks.GetKeysBackupLastVersionTask
+import im.vector.matrix.android.internal.crypto.keysbackup.tasks.GetKeysBackupVersionTask
+import im.vector.matrix.android.internal.crypto.keysbackup.tasks.GetRoomSessionDataTask
+import im.vector.matrix.android.internal.crypto.keysbackup.tasks.GetRoomSessionsDataTask
+import im.vector.matrix.android.internal.crypto.keysbackup.tasks.GetSessionsDataTask
+import im.vector.matrix.android.internal.crypto.keysbackup.tasks.StoreRoomSessionDataTask
+import im.vector.matrix.android.internal.crypto.keysbackup.tasks.StoreRoomSessionsDataTask
+import im.vector.matrix.android.internal.crypto.keysbackup.tasks.StoreSessionsDataTask
+import im.vector.matrix.android.internal.crypto.keysbackup.tasks.UpdateKeysBackupVersionTask
import im.vector.matrix.android.internal.crypto.keysbackup.util.computeRecoveryKey
import im.vector.matrix.android.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey
import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
@@ -60,6 +80,7 @@ import im.vector.matrix.android.internal.util.JsonCanonicalizer
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import im.vector.matrix.android.internal.util.awaitCallback
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.matrix.olm.OlmException
@@ -72,12 +93,11 @@ import javax.inject.Inject
import kotlin.random.Random
/**
- * A KeysBackup class instance manage incremental backup of e2e keys (megolm keys)
+ * A DefaultKeysBackupService class instance manage incremental backup of e2e keys (megolm keys)
* to the user's homeserver.
*/
-
@SessionScope
-internal class KeysBackup @Inject constructor(
+internal class DefaultKeysBackupService @Inject constructor(
@UserId private val userId: String,
private val credentials: Credentials,
private val cryptoStore: IMXCryptoStore,
@@ -148,9 +168,7 @@ internal class KeysBackup @Inject constructor(
runCatching {
withContext(coroutineDispatchers.crypto) {
val olmPkDecryption = OlmPkDecryption()
- val megolmBackupAuthData = MegolmBackupAuthData()
-
- if (password != null) {
+ val megolmBackupAuthData = if (password != null) {
// Generate a private key from the password
val backgroundProgressListener = if (progressListener == null) {
null
@@ -169,25 +187,30 @@ internal class KeysBackup @Inject constructor(
}
val generatePrivateKeyResult = generatePrivateKeyWithPassword(password, backgroundProgressListener)
- megolmBackupAuthData.publicKey = olmPkDecryption.setPrivateKey(generatePrivateKeyResult.privateKey)
- megolmBackupAuthData.privateKeySalt = generatePrivateKeyResult.salt
- megolmBackupAuthData.privateKeyIterations = generatePrivateKeyResult.iterations
+ MegolmBackupAuthData(
+ publicKey = olmPkDecryption.setPrivateKey(generatePrivateKeyResult.privateKey),
+ privateKeySalt = generatePrivateKeyResult.salt,
+ privateKeyIterations = generatePrivateKeyResult.iterations
+ )
} else {
val publicKey = olmPkDecryption.generateKey()
- megolmBackupAuthData.publicKey = publicKey
+ MegolmBackupAuthData(
+ publicKey = publicKey
+ )
}
val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, megolmBackupAuthData.signalableJSONDictionary())
- megolmBackupAuthData.signatures = objectSigner.signObject(canonicalJson)
+ val signedMegolmBackupAuthData = megolmBackupAuthData.copy(
+ signatures = objectSigner.signObject(canonicalJson)
+ )
- val megolmBackupCreationInfo = MegolmBackupCreationInfo()
- megolmBackupCreationInfo.algorithm = MXCRYPTO_ALGORITHM_MEGOLM_BACKUP
- megolmBackupCreationInfo.authData = megolmBackupAuthData
- megolmBackupCreationInfo.recoveryKey = computeRecoveryKey(olmPkDecryption.privateKey())
-
- megolmBackupCreationInfo
+ MegolmBackupCreationInfo(
+ algorithm = MXCRYPTO_ALGORITHM_MEGOLM_BACKUP,
+ authData = signedMegolmBackupAuthData,
+ recoveryKey = computeRecoveryKey(olmPkDecryption.privateKey())
+ )
}
}.foldToCallback(callback)
}
@@ -195,11 +218,12 @@ internal class KeysBackup @Inject constructor(
override fun createKeysBackupVersion(keysBackupCreationInfo: MegolmBackupCreationInfo,
callback: MatrixCallback) {
- val createKeysBackupVersionBody = CreateKeysBackupVersionBody()
- createKeysBackupVersionBody.algorithm = keysBackupCreationInfo.algorithm
@Suppress("UNCHECKED_CAST")
- createKeysBackupVersionBody.authData = MoshiProvider.providesMoshi().adapter(Map::class.java)
- .fromJson(keysBackupCreationInfo.authData?.toJsonString() ?: "") as JsonDict?
+ val createKeysBackupVersionBody = CreateKeysBackupVersionBody(
+ algorithm = keysBackupCreationInfo.algorithm,
+ authData = MoshiProvider.providesMoshi().adapter(Map::class.java)
+ .fromJson(keysBackupCreationInfo.authData?.toJsonString() ?: "") as JsonDict?
+ )
keysBackupStateManager.state = KeysBackupState.Enabling
@@ -210,14 +234,14 @@ internal class KeysBackup @Inject constructor(
// Reset backup markers.
cryptoStore.resetBackupMarkers()
- val keyBackupVersion = KeysVersionResult()
- keyBackupVersion.algorithm = createKeysBackupVersionBody.algorithm
- keyBackupVersion.authData = createKeysBackupVersionBody.authData
- keyBackupVersion.version = data.version
-
- // We can consider that the server does not have keys yet
- keyBackupVersion.count = 0
- keyBackupVersion.hash = null
+ val keyBackupVersion = KeysVersionResult(
+ algorithm = createKeysBackupVersionBody.algorithm,
+ authData = createKeysBackupVersionBody.authData,
+ version = data.version,
+ // We can consider that the server does not have keys yet
+ count = 0,
+ hash = null
+ )
enableKeysBackup(keyBackupVersion)
@@ -387,7 +411,7 @@ internal class KeysBackup @Inject constructor(
return keysBackupVersionTrust
}
- val mySigs = authData.signatures?.get(userId)
+ val mySigs = authData.signatures[userId]
if (mySigs.isNullOrEmpty()) {
Timber.v("getKeysBackupTrust: Ignoring key backup because it lacks any signatures from this user")
return keysBackupVersionTrust
@@ -450,8 +474,7 @@ internal class KeysBackup @Inject constructor(
cryptoCoroutineScope.launch(coroutineDispatchers.main) {
val updateKeysBackupVersionBody = withContext(coroutineDispatchers.crypto) {
// Get current signatures, or create an empty set
- val myUserSignatures = authData.signatures?.get(userId)?.toMutableMap()
- ?: HashMap()
+ val myUserSignatures = authData.signatures?.get(userId)?.toMutableMap() ?: HashMap()
if (trust) {
// Add current device signature
@@ -468,24 +491,23 @@ internal class KeysBackup @Inject constructor(
}
// Create an updated version of KeysVersionResult
- val updateKeysBackupVersionBody = UpdateKeysBackupVersionBody(keysBackupVersion.version!!)
-
- updateKeysBackupVersionBody.algorithm = keysBackupVersion.algorithm
-
val newMegolmBackupAuthData = authData.copy()
val newSignatures = newMegolmBackupAuthData.signatures!!.toMutableMap()
newSignatures[userId] = myUserSignatures
- newMegolmBackupAuthData.signatures = newSignatures
+ val newMegolmBackupAuthDataWithNewSignature = newMegolmBackupAuthData.copy(
+ signatures = newSignatures
+ )
val moshi = MoshiProvider.providesMoshi()
val adapter = moshi.adapter(Map::class.java)
@Suppress("UNCHECKED_CAST")
- updateKeysBackupVersionBody.authData = adapter.fromJson(newMegolmBackupAuthData.toJsonString()) as Map?
-
- updateKeysBackupVersionBody
+ UpdateKeysBackupVersionBody(
+ algorithm = keysBackupVersion.algorithm,
+ authData = adapter.fromJson(newMegolmBackupAuthDataWithNewSignature.toJsonString()) as Map?,
+ version = keysBackupVersion.version!!)
}
// And send it to the homeserver
@@ -494,13 +516,13 @@ internal class KeysBackup @Inject constructor(
this.callback = object : MatrixCallback {
override fun onSuccess(data: Unit) {
// Relaunch the state machine on this updated backup version
- val newKeysBackupVersion = KeysVersionResult()
-
- newKeysBackupVersion.version = keysBackupVersion.version
- newKeysBackupVersion.algorithm = keysBackupVersion.algorithm
- newKeysBackupVersion.count = keysBackupVersion.count
- newKeysBackupVersion.hash = keysBackupVersion.hash
- newKeysBackupVersion.authData = updateKeysBackupVersionBody.authData
+ val newKeysBackupVersion = KeysVersionResult(
+ algorithm = keysBackupVersion.algorithm,
+ authData = updateKeysBackupVersionBody.authData,
+ version = keysBackupVersion.version,
+ hash = keysBackupVersion.hash,
+ count = keysBackupVersion.count
+ )
checkAndStartWithKeysBackupVersion(newKeysBackupVersion)
@@ -673,7 +695,7 @@ internal class KeysBackup @Inject constructor(
null
}
- val result = megolmSessionDataImporter.handle(sessionsData, !backUp, uiHandler, progressListener)
+ val result = megolmSessionDataImporter.handle(sessionsData, !backUp, progressListener)
// Do not back up the key if it comes from a backup recovery
if (backUp) {
@@ -788,7 +810,10 @@ internal class KeysBackup @Inject constructor(
// new key is sent
val delayInMs = Random.nextLong(KEY_BACKUP_WAITING_TIME_TO_SEND_KEY_BACKUP_MILLIS)
- uiHandler.postDelayed({ backupKeys() }, delayInMs)
+ cryptoCoroutineScope.launch {
+ delay(delayInMs)
+ uiHandler.post { backupKeys() }
+ }
}
else -> {
Timber.v("maybeBackupKeys: Skip it because state: $state")
@@ -1005,7 +1030,7 @@ internal class KeysBackup @Inject constructor(
}
// Extract the recovery key from the passphrase
- val data = retrievePrivateKeyWithPassword(password, authData.privateKeySalt!!, authData.privateKeyIterations!!, progressListener)
+ val data = retrievePrivateKeyWithPassword(password, authData.privateKeySalt, authData.privateKeyIterations, progressListener)
return computeRecoveryKey(data)
}
@@ -1159,14 +1184,16 @@ internal class KeysBackup @Inject constructor(
// Gather data to send to the homeserver
// roomId -> sessionId -> MXKeyBackupData
- val keysBackupData = KeysBackupData()
- keysBackupData.roomIdToRoomKeysBackupData = HashMap()
+ val keysBackupData = KeysBackupData(
+ roomIdToRoomKeysBackupData = HashMap()
+ )
for (olmInboundGroupSessionWrapper in olmInboundGroupSessionWrappers) {
val keyBackupData = encryptGroupSession(olmInboundGroupSessionWrapper)
if (keysBackupData.roomIdToRoomKeysBackupData[olmInboundGroupSessionWrapper.roomId] == null) {
- val roomKeysBackupData = RoomKeysBackupData()
- roomKeysBackupData.sessionIdToKeyBackupData = HashMap()
+ val roomKeysBackupData = RoomKeysBackupData(
+ sessionIdToKeyBackupData = HashMap()
+ )
keysBackupData.roomIdToRoomKeysBackupData[olmInboundGroupSessionWrapper.roomId!!] = roomKeysBackupData
}
@@ -1282,24 +1309,21 @@ internal class KeysBackup @Inject constructor(
}
// Build backup data for that key
- val keyBackupData = KeyBackupData()
- try {
- keyBackupData.firstMessageIndex = olmInboundGroupSessionWrapper.olmInboundGroupSession!!.firstKnownIndex
- } catch (e: OlmException) {
- Timber.e(e, "OlmException")
- }
+ return KeyBackupData(
+ firstMessageIndex = try {
+ olmInboundGroupSessionWrapper.olmInboundGroupSession!!.firstKnownIndex
+ } catch (e: OlmException) {
+ Timber.e(e, "OlmException")
+ 0L
+ },
+ forwardedCount = olmInboundGroupSessionWrapper.forwardingCurve25519KeyChain!!.size,
+ isVerified = device?.isVerified == true,
- keyBackupData.forwardedCount = olmInboundGroupSessionWrapper.forwardingCurve25519KeyChain!!.size
- keyBackupData.isVerified = device?.isVerified == true
-
- val data = mapOf(
- "ciphertext" to encryptedSessionBackupData!!.mCipherText,
- "mac" to encryptedSessionBackupData.mMac,
- "ephemeral" to encryptedSessionBackupData.mEphemeralKey)
-
- keyBackupData.sessionData = data
-
- return keyBackupData
+ sessionData = mapOf(
+ "ciphertext" to encryptedSessionBackupData!!.mCipherText,
+ "mac" to encryptedSessionBackupData.mMac,
+ "ephemeral" to encryptedSessionBackupData.mEphemeralKey)
+ )
}
@VisibleForTesting
@@ -1331,8 +1355,10 @@ internal class KeysBackup @Inject constructor(
}
if (sessionBackupData != null) {
- sessionBackupData.sessionId = sessionId
- sessionBackupData.roomId = roomId
+ sessionBackupData = sessionBackupData.copy(
+ sessionId = sessionId,
+ roomId = roomId
+ )
}
}
@@ -1351,11 +1377,12 @@ internal class KeysBackup @Inject constructor(
@VisibleForTesting
fun createFakeKeysBackupVersion(keysBackupCreationInfo: MegolmBackupCreationInfo,
callback: MatrixCallback) {
- val createKeysBackupVersionBody = CreateKeysBackupVersionBody()
- createKeysBackupVersionBody.algorithm = keysBackupCreationInfo.algorithm
@Suppress("UNCHECKED_CAST")
- createKeysBackupVersionBody.authData = MoshiProvider.providesMoshi().adapter(Map::class.java)
- .fromJson(keysBackupCreationInfo.authData?.toJsonString() ?: "") as JsonDict?
+ val createKeysBackupVersionBody = CreateKeysBackupVersionBody(
+ algorithm = keysBackupCreationInfo.algorithm,
+ authData = MoshiProvider.providesMoshi().adapter(Map::class.java)
+ .fromJson(keysBackupCreationInfo.authData?.toJsonString() ?: "") as JsonDict?
+ )
createKeysBackupVersionTask
.configureWith(createKeysBackupVersionBody) {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupPassword.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupPassword.kt
index 344ba61277..2429c1e658 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupPassword.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupPassword.kt
@@ -83,10 +83,10 @@ fun retrievePrivateKeyWithPassword(password: String,
* @return a private key.
*/
@WorkerThread
-private fun deriveKey(password: String,
- salt: String,
- iterations: Int,
- progressListener: ProgressListener?): ByteArray {
+fun deriveKey(password: String,
+ salt: String,
+ iterations: Int,
+ progressListener: ProgressListener?): ByteArray {
// Note: copied and adapted from MXMegolmExportEncryption
val t0 = System.currentTimeMillis()
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/api/RoomKeysApi.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/api/RoomKeysApi.kt
index f5d89fb5eb..beaee58a3e 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/api/RoomKeysApi.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/api/RoomKeysApi.kt
@@ -16,10 +16,23 @@
package im.vector.matrix.android.internal.crypto.keysbackup.api
-import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.*
+import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.BackupKeysResult
+import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody
+import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeyBackupData
+import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysBackupData
+import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersion
+import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersionResult
+import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.RoomKeysBackupData
+import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.UpdateKeysBackupVersionBody
import im.vector.matrix.android.internal.network.NetworkConstants
import retrofit2.Call
-import retrofit2.http.*
+import retrofit2.http.Body
+import retrofit2.http.DELETE
+import retrofit2.http.GET
+import retrofit2.http.POST
+import retrofit2.http.PUT
+import retrofit2.http.Path
+import retrofit2.http.Query
/**
* Ref: https://github.com/uhoreg/matrix-doc/blob/e2e_backup/proposals/1219-storing-megolm-keys-serverside.md
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/MegolmBackupAuthData.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/MegolmBackupAuthData.kt
index 442b1f081c..48015a98dd 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/MegolmBackupAuthData.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/MegolmBackupAuthData.kt
@@ -30,26 +30,27 @@ data class MegolmBackupAuthData(
* The curve25519 public key used to encrypt the backups.
*/
@Json(name = "public_key")
- var publicKey: String = "",
+ val publicKey: String = "",
/**
* In case of a backup created from a password, the salt associated with the backup
* private key.
*/
@Json(name = "private_key_salt")
- var privateKeySalt: String? = null,
+ val privateKeySalt: String? = null,
/**
* In case of a backup created from a password, the number of key derivations.
*/
@Json(name = "private_key_iterations")
- var privateKeyIterations: Int? = null,
+ val privateKeyIterations: Int? = null,
/**
* Signatures of the public key.
* userId -> (deviceSignKeyId -> signature)
*/
- var signatures: Map>? = null
+ @Json(name = "signatures")
+ val signatures: Map>? = null
) {
fun toJsonString(): String {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/MegolmBackupCreationInfo.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/MegolmBackupCreationInfo.kt
index a08ba9ba96..b329fa44c9 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/MegolmBackupCreationInfo.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/MegolmBackupCreationInfo.kt
@@ -19,20 +19,19 @@ package im.vector.matrix.android.internal.crypto.keysbackup.model
/**
* Data retrieved from Olm library. algorithm and authData will be send to the homeserver, and recoveryKey will be displayed to the user
*/
-class MegolmBackupCreationInfo {
+data class MegolmBackupCreationInfo(
+ /**
+ * The algorithm used for storing backups [org.matrix.androidsdk.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP].
+ */
+ val algorithm: String = "",
- /**
- * The algorithm used for storing backups [org.matrix.androidsdk.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP].
- */
- var algorithm: String = ""
+ /**
+ * Authentication data.
+ */
+ val authData: MegolmBackupAuthData? = null,
- /**
- * Authentication data.
- */
- var authData: MegolmBackupAuthData? = null
-
- /**
- * The Base58 recovery key.
- */
- var recoveryKey: String = ""
-}
+ /**
+ * The Base58 recovery key.
+ */
+ val recoveryKey: String = ""
+)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/CreateKeysBackupVersionBody.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/CreateKeysBackupVersionBody.kt
index 5efbc6d017..3b267280e5 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/CreateKeysBackupVersionBody.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/CreateKeysBackupVersionBody.kt
@@ -16,7 +16,21 @@
package im.vector.matrix.android.internal.crypto.keysbackup.model.rest
+import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
+import im.vector.matrix.android.api.util.JsonDict
@JsonClass(generateAdapter = true)
-class CreateKeysBackupVersionBody : KeysAlgorithmAndData()
+data class CreateKeysBackupVersionBody(
+ /**
+ * The algorithm used for storing backups. Currently, only "m.megolm_backup.v1.curve25519-aes-sha2" is defined
+ */
+ @Json(name = "algorithm")
+ override val algorithm: String? = null,
+
+ /**
+ * algorithm-dependent data, for "m.megolm_backup.v1.curve25519-aes-sha2" see [im.vector.matrix.android.internal.crypto.keysbackup.MegolmBackupAuthData]
+ */
+ @Json(name = "auth_data")
+ override val authData: JsonDict? = null
+) : KeysAlgorithmAndData
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeyBackupData.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeyBackupData.kt
index f172d45ffd..b2d10687aa 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeyBackupData.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeyBackupData.kt
@@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.crypto.keysbackup.model.rest
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import im.vector.matrix.android.internal.di.MoshiProvider
+import im.vector.matrix.android.internal.network.parsing.ForceToBoolean
/**
* Backup data for one key.
@@ -29,25 +30,27 @@ data class KeyBackupData(
* Required. The index of the first message in the session that the key can decrypt.
*/
@Json(name = "first_message_index")
- var firstMessageIndex: Long = 0,
+ val firstMessageIndex: Long = 0,
/**
* Required. The number of times this key has been forwarded.
*/
@Json(name = "forwarded_count")
- var forwardedCount: Int = 0,
+ val forwardedCount: Int = 0,
/**
* Whether the device backing up the key has verified the device that the key is from.
+ * Force to boolean because of https://github.com/matrix-org/synapse/issues/6977
*/
+ @ForceToBoolean
@Json(name = "is_verified")
- var isVerified: Boolean = false,
+ val isVerified: Boolean = false,
/**
* Algorithm-dependent data.
*/
@Json(name = "session_data")
- var sessionData: Map? = null
+ val sessionData: Map? = null
) {
fun toJsonString(): String {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeysAlgorithmAndData.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeysAlgorithmAndData.kt
index 6fba833589..81ca6586a3 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeysAlgorithmAndData.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeysAlgorithmAndData.kt
@@ -16,7 +16,6 @@
package im.vector.matrix.android.internal.crypto.keysbackup.model.rest
-import com.squareup.moshi.Json
import im.vector.matrix.android.api.util.JsonDict
import im.vector.matrix.android.internal.crypto.keysbackup.model.MegolmBackupAuthData
import im.vector.matrix.android.internal.di.MoshiProvider
@@ -38,19 +37,17 @@ import im.vector.matrix.android.internal.di.MoshiProvider
* }
*
*/
-open class KeysAlgorithmAndData {
+interface KeysAlgorithmAndData {
/**
* The algorithm used for storing backups. Currently, only "m.megolm_backup.v1.curve25519-aes-sha2" is defined
*/
- @Json(name = "algorithm")
- var algorithm: String? = null
+ val algorithm: String?
/**
* algorithm-dependent data, for "m.megolm_backup.v1.curve25519-aes-sha2" see [im.vector.matrix.android.internal.crypto.keysbackup.MegolmBackupAuthData]
*/
- @Json(name = "auth_data")
- var authData: JsonDict? = null
+ val authData: JsonDict?
/**
* Facility method to convert authData to a MegolmBackupAuthData object
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeysBackupData.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeysBackupData.kt
index 2f4165d8ab..240c79fd1e 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeysBackupData.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeysBackupData.kt
@@ -24,9 +24,7 @@ import com.squareup.moshi.JsonClass
*/
@JsonClass(generateAdapter = true)
data class KeysBackupData(
-
// the keys are the room IDs, and the values are RoomKeysBackupData
@Json(name = "rooms")
- var roomIdToRoomKeysBackupData: MutableMap = HashMap()
-
+ val roomIdToRoomKeysBackupData: MutableMap = HashMap()
)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeysVersionResult.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeysVersionResult.kt
index 4510cdd773..0addd1491e 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeysVersionResult.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/KeysVersionResult.kt
@@ -16,16 +16,33 @@
package im.vector.matrix.android.internal.crypto.keysbackup.model.rest
+import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
+import im.vector.matrix.android.api.util.JsonDict
@JsonClass(generateAdapter = true)
data class KeysVersionResult(
+ /**
+ * The algorithm used for storing backups. Currently, only "m.megolm_backup.v1.curve25519-aes-sha2" is defined
+ */
+ @Json(name = "algorithm")
+ override val algorithm: String? = null,
+
+ /**
+ * algorithm-dependent data, for "m.megolm_backup.v1.curve25519-aes-sha2" see [im.vector.matrix.android.internal.crypto.keysbackup.MegolmBackupAuthData]
+ */
+ @Json(name = "auth_data")
+ override val authData: JsonDict? = null,
+
// the backup version
- var version: String? = null,
+ @Json(name = "version")
+ val version: String? = null,
// The hash value which is an opaque string representing stored keys in the backup
- var hash: String? = null,
+ @Json(name = "hash")
+ val hash: String? = null,
// The number of keys stored in the backup.
- var count: Int? = null
-) : KeysAlgorithmAndData()
+ @Json(name = "count")
+ val count: Int? = null
+) : KeysAlgorithmAndData
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/RoomKeysBackupData.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/RoomKeysBackupData.kt
index 5d69f63538..f3c218baca 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/RoomKeysBackupData.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/RoomKeysBackupData.kt
@@ -24,8 +24,7 @@ import com.squareup.moshi.JsonClass
*/
@JsonClass(generateAdapter = true)
data class RoomKeysBackupData(
-
// the keys are the session IDs, and the values are KeyBackupData
@Json(name = "sessions")
- var sessionIdToKeyBackupData: MutableMap = HashMap()
+ val sessionIdToKeyBackupData: MutableMap = HashMap()
)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/UpdateKeysBackupVersionBody.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/UpdateKeysBackupVersionBody.kt
index cb8ba5e26c..9d88af20ef 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/UpdateKeysBackupVersionBody.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/model/rest/UpdateKeysBackupVersionBody.kt
@@ -16,10 +16,25 @@
package im.vector.matrix.android.internal.crypto.keysbackup.model.rest
+import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
+import im.vector.matrix.android.api.util.JsonDict
@JsonClass(generateAdapter = true)
data class UpdateKeysBackupVersionBody(
+ /**
+ * The algorithm used for storing backups. Currently, only "m.megolm_backup.v1.curve25519-aes-sha2" is defined
+ */
+ @Json(name = "algorithm")
+ override val algorithm: String? = null,
+
+ /**
+ * algorithm-dependent data, for "m.megolm_backup.v1.curve25519-aes-sha2" see [im.vector.matrix.android.internal.crypto.keysbackup.MegolmBackupAuthData]
+ */
+ @Json(name = "auth_data")
+ override val authData: JsonDict? = null,
+
// the backup version, mandatory
+ @Json(name = "version")
val version: String
-) : KeysAlgorithmAndData()
+) : KeysAlgorithmAndData
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoDeviceInfo.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoDeviceInfo.kt
index 8f6d64221c..e3e8f3de27 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoDeviceInfo.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoDeviceInfo.kt
@@ -28,10 +28,6 @@ data class CryptoDeviceInfo(
override val keys: Map? = null,
override val signatures: Map>? = null,
val unsigned: JsonDict? = null,
-
- // TODO how to store if this device is verified by a user SSK, or is legacy trusted?
- // I need to know if it is trusted via cross signing (Trusted because bob verified it)
-
var trustLevel: DeviceTrustLevel? = null,
var isBlocked: Boolean = false
) : CryptoInfo {
@@ -75,19 +71,6 @@ data class CryptoDeviceInfo(
keys?.let { map["keys"] = it }
return map
}
-//
-// /**
-// * @return a dictionary of the parameters
-// */
-// fun toDeviceKeys(): DeviceKeys {
-// return DeviceKeys(
-// userId = userId,
-// deviceId = deviceId,
-// algorithms = algorithms!!,
-// keys = keys!!,
-// signatures = signatures!!
-// )
-// }
}
internal fun CryptoDeviceInfo.toRest(): RestDeviceInfo {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXDeviceInfo.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXDeviceInfo.kt
index cc9b3bff74..ae53694a0f 100755
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXDeviceInfo.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXDeviceInfo.kt
@@ -26,48 +26,47 @@ import java.io.Serializable
@JsonClass(generateAdapter = true)
data class MXDeviceInfo(
-
/**
* The id of this device.
*/
@Json(name = "device_id")
- var deviceId: String,
+ val deviceId: String,
/**
* the user id
*/
@Json(name = "user_id")
- var userId: String,
+ val userId: String,
/**
* The list of algorithms supported by this device.
*/
@Json(name = "algorithms")
- var algorithms: List? = null,
+ val algorithms: List? = null,
/**
* A map from ":" to "".
*/
@Json(name = "keys")
- var keys: Map? = null,
+ val keys: Map? = null,
/**
* The signature of this MXDeviceInfo.
* A map from "" to a map from ":" to ""
*/
@Json(name = "signatures")
- var signatures: Map>? = null,
+ val signatures: Map>? = null,
/*
* Additional data from the home server.
*/
@Json(name = "unsigned")
- var unsigned: JsonDict? = null,
+ val unsigned: JsonDict? = null,
/**
* Verification state of this device.
*/
- var verified: Int = DEVICE_VERIFICATION_UNKNOWN
+ val verified: Int = DEVICE_VERIFICATION_UNKNOWN
) : Serializable {
/**
* Tells if the device is unknown
@@ -137,11 +136,11 @@ data class MXDeviceInfo(
map["user_id"] = userId
if (null != algorithms) {
- map["algorithms"] = algorithms!!
+ map["algorithms"] = algorithms
}
if (null != keys) {
- map["keys"] = keys!!
+ map["keys"] = keys
}
return map
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/OlmInboundGroupSessionWrapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/OlmInboundGroupSessionWrapper.kt
index 361b8bc205..cf1a3b237a 100755
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/OlmInboundGroupSessionWrapper.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/OlmInboundGroupSessionWrapper.kt
@@ -116,16 +116,16 @@ class OlmInboundGroupSessionWrapper : Serializable {
return null
}
- MegolmSessionData().also {
- it.senderClaimedEd25519Key = keysClaimed?.get("ed25519")
- it.forwardingCurve25519KeyChain = ArrayList(forwardingCurve25519KeyChain!!)
- it.senderKey = senderKey
- it.senderClaimedKeys = keysClaimed
- it.roomId = roomId
- it.sessionId = olmInboundGroupSession!!.sessionIdentifier()
- it.sessionKey = olmInboundGroupSession!!.export(olmInboundGroupSession!!.firstKnownIndex)
- it.algorithm = MXCRYPTO_ALGORITHM_MEGOLM
- }
+ MegolmSessionData(
+ senderClaimedEd25519Key = keysClaimed?.get("ed25519"),
+ forwardingCurve25519KeyChain = ArrayList(forwardingCurve25519KeyChain!!),
+ senderKey = senderKey,
+ senderClaimedKeys = keysClaimed,
+ roomId = roomId,
+ sessionId = olmInboundGroupSession!!.sessionIdentifier(),
+ sessionKey = olmInboundGroupSession!!.export(olmInboundGroupSession!!.firstKnownIndex),
+ algorithm = MXCRYPTO_ALGORITHM_MEGOLM
+ )
} catch (e: Exception) {
Timber.e(e, "## export() : senderKey $senderKey failed")
null
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/EncryptionEventContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/EncryptionEventContent.kt
index 6de50f84c2..05e97da68d 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/EncryptionEventContent.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/EncryptionEventContent.kt
@@ -23,22 +23,21 @@ import com.squareup.moshi.JsonClass
*/
@JsonClass(generateAdapter = true)
data class EncryptionEventContent(
-
/**
* Required. The encryption algorithm to be used to encrypt messages sent in this room. Must be 'm.megolm.v1.aes-sha2'.
*/
@Json(name = "algorithm")
- var algorithm: String,
+ val algorithm: String,
/**
* How long the session should be used before changing it. 604800000 (a week) is the recommended default.
*/
@Json(name = "rotation_period_ms")
- var rotationPeriodMs: Long? = null,
+ val rotationPeriodMs: Long? = null,
/**
* How many messages should be sent before changing the session. 100 is the recommended default.
*/
@Json(name = "rotation_period_msgs")
- var rotationPeriodMsgs: Long? = null
+ val rotationPeriodMsgs: Long? = null
)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/NewDeviceContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/NewDeviceContent.kt
index a6777a4f12..62fe4293e7 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/NewDeviceContent.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/NewDeviceContent.kt
@@ -20,12 +20,11 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class NewDeviceContent(
-
// the device id
@Json(name = "device_id")
- var deviceId: String? = null,
+ val deviceId: String? = null,
// the room ids list
@Json(name = "rooms")
- var rooms: List? = null
+ val rooms: List? = null
)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/OlmEventContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/OlmEventContent.kt
index 7ac0b075be..2b2b49120a 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/OlmEventContent.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/OlmEventContent.kt
@@ -27,11 +27,11 @@ data class OlmEventContent(
*
*/
@Json(name = "ciphertext")
- var ciphertext: Map? = null,
+ val ciphertext: Map? = null,
/**
* the sender key
*/
@Json(name = "sender_key")
- var senderKey: String? = null
+ val senderKey: String? = null
)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/DeviceInfo.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/DeviceInfo.kt
index 1289ef3d92..b058fac082 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/DeviceInfo.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/DeviceInfo.kt
@@ -30,31 +30,31 @@ data class DeviceInfo(
* The owner user id (not documented and useless but the homeserver sent it. You should not need it)
*/
@Json(name = "user_id")
- var user_id: String? = null,
+ val user_id: String? = null,
/**
* The device id
*/
@Json(name = "device_id")
- var deviceId: String? = null,
+ val deviceId: String? = null,
/**
* The device display name
*/
@Json(name = "display_name")
- var displayName: String? = null,
+ val displayName: String? = null,
/**
* The last time this device has been seen.
*/
@Json(name = "last_seen_ts")
- var lastSeenTs: Long? = null,
+ val lastSeenTs: Long? = null,
/**
* The last ip address
*/
@Json(name = "last_seen_ip")
- var lastSeenIp: String? = null
+ val lastSeenIp: String? = null
) : DatedObject {
override val date: Long
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/DevicesListResponse.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/DevicesListResponse.kt
index 9b50b486dc..2bf3d06299 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/DevicesListResponse.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/DevicesListResponse.kt
@@ -24,5 +24,5 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class DevicesListResponse(
@Json(name = "devices")
- var devices: List? = null
+ val devices: List? = null
)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/EncryptedFileInfo.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/EncryptedFileInfo.kt
index 5e09b20c91..93e8b4d211 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/EncryptedFileInfo.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/EncryptedFileInfo.kt
@@ -27,38 +27,38 @@ data class EncryptedFileInfo(
* Required. The URL to the file.
*/
@Json(name = "url")
- var url: String? = null,
+ val url: String? = null,
/**
* Not documented
*/
@Json(name = "mimetype")
- var mimetype: String? = null,
+ val mimetype: String? = null,
/**
* Required. A JSON Web Key object.
*/
@Json(name = "key")
- var key: EncryptedFileKey? = null,
+ val key: EncryptedFileKey? = null,
/**
* Required. The Initialisation Vector used by AES-CTR, encoded as unpadded base64.
*/
@Json(name = "iv")
- var iv: String? = null,
+ val iv: String? = null,
/**
* Required. A map from an algorithm name to a hash of the ciphertext, encoded as unpadded base64.
* Clients should support the SHA-256 hash, which uses the key "sha256".
*/
@Json(name = "hashes")
- var hashes: Map? = null,
+ val hashes: Map? = null,
/**
* Required. Version of the encrypted attachments protocol. Must be "v2".
*/
@Json(name = "v")
- var v: String? = null
+ val v: String? = null
) {
/**
* Check what the spec tells us
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/EncryptedFileKey.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/EncryptedFileKey.kt
index 799819ceee..fa5885de49 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/EncryptedFileKey.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/EncryptedFileKey.kt
@@ -24,31 +24,31 @@ data class EncryptedFileKey(
* Required. Algorithm. Must be "A256CTR".
*/
@Json(name = "alg")
- var alg: String? = null,
+ val alg: String? = null,
/**
* Required. Extractable. Must be true. This is a W3C extension.
*/
@Json(name = "ext")
- var ext: Boolean? = null,
+ val ext: Boolean? = null,
/**
* Required. Key operations. Must at least contain "encrypt" and "decrypt".
*/
@Json(name = "key_ops")
- var key_ops: List? = null,
+ val key_ops: List? = null,
/**
* Required. Key type. Must be "oct".
*/
@Json(name = "kty")
- var kty: String? = null,
+ val kty: String? = null,
/**
* Required. The key, encoded as urlsafe unpadded base64.
*/
@Json(name = "k")
- var k: String? = null
+ val k: String? = null
) {
/**
* Check what the spec tells us
@@ -62,7 +62,7 @@ data class EncryptedFileKey(
return false
}
- if (key_ops?.contains("encrypt") != true || key_ops?.contains("decrypt") != true) {
+ if (key_ops?.contains("encrypt") != true || !key_ops.contains("decrypt")) {
return false
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/EncryptedMessage.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/EncryptedMessage.kt
index c546cd04c4..e3ada0c0ab 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/EncryptedMessage.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/EncryptedMessage.kt
@@ -21,11 +21,12 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class EncryptedMessage(
- var algorithm: String? = null,
+ @Json(name = "algorithm")
+ val algorithm: String? = null,
@Json(name = "sender_key")
- var senderKey: String? = null,
+ val senderKey: String? = null,
@Json(name = "ciphertext")
- var cipherText: Map? = null
+ val cipherText: Map? = null
) : SendToDeviceObject
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyChangesResponse.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyChangesResponse.kt
index 12d27a023f..3af7d7c8c5 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyChangesResponse.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyChangesResponse.kt
@@ -25,9 +25,9 @@ import com.squareup.moshi.JsonClass
internal data class KeyChangesResponse(
// list of user ids which have new devices
@Json(name = "changed")
- var changed: List? = null,
+ val changed: List? = null,
// List of user ids who are no more tracked.
@Json(name = "left")
- var left: List? = null
+ val left: List? = null
)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationCancel.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationCancel.kt
index d1ae09cc37..dcf08531c8 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationCancel.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationCancel.kt
@@ -17,7 +17,7 @@ package im.vector.matrix.android.internal.crypto.model.rest
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
-import im.vector.matrix.android.api.session.crypto.sas.CancelCode
+import im.vector.matrix.android.api.session.crypto.verification.CancelCode
import im.vector.matrix.android.internal.crypto.verification.VerificationInfoCancel
/**
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationDone.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationDone.kt
index c0a72d29db..bdce77b31d 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationDone.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationDone.kt
@@ -24,7 +24,7 @@ import im.vector.matrix.android.internal.crypto.verification.VerificationInfoDon
*/
@JsonClass(generateAdapter = true)
internal data class KeyVerificationDone(
- @Json(name = "transaction_id") override var transactionID: String? = null
+ @Json(name = "transaction_id") override val transactionID: String? = null
) : SendToDeviceObject, VerificationInfoDone {
override fun toSendToDeviceObject() = this
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationKey.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationKey.kt
index 9a190e1e15..4f90f8db8c 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationKey.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationKey.kt
@@ -17,8 +17,8 @@ package im.vector.matrix.android.internal.crypto.model.rest
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
-import im.vector.matrix.android.internal.crypto.verification.VerificationInfoKeyFactory
import im.vector.matrix.android.internal.crypto.verification.VerificationInfoKey
+import im.vector.matrix.android.internal.crypto.verification.VerificationInfoKeyFactory
/**
* Sent by both devices to send their ephemeral Curve25519 public key to the other device.
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationRequest.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationRequest.kt
index 5bd09658b5..fcddb5c3d4 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationRequest.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationRequest.kt
@@ -27,7 +27,7 @@ internal data class KeyVerificationRequest(
@Json(name = "from_device") override val fromDevice: String?,
@Json(name = "methods") override val methods: List,
@Json(name = "timestamp") override val timestamp: Long?,
- @Json(name = "transaction_id") override var transactionID: String? = null
+ @Json(name = "transaction_id") override val transactionID: String? = null
) : SendToDeviceObject, VerificationInfoRequest {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationStart.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationStart.kt
index 9e4b7b773e..c6a64fc2c8 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationStart.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeyVerificationStart.kt
@@ -17,7 +17,7 @@ package im.vector.matrix.android.internal.crypto.model.rest
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
-import im.vector.matrix.android.api.session.crypto.sas.SasMode
+import im.vector.matrix.android.api.session.crypto.verification.SasMode
import im.vector.matrix.android.internal.crypto.verification.SASDefaultVerificationTransaction
import im.vector.matrix.android.internal.crypto.verification.VerificationInfoStart
import im.vector.matrix.android.internal.util.JsonCanonicalizer
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysClaimBody.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysClaimBody.kt
index 38f6615dad..26ee1ebe38 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysClaimBody.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysClaimBody.kt
@@ -24,16 +24,15 @@ import com.squareup.moshi.JsonClass
*/
@JsonClass(generateAdapter = true)
internal data class KeysClaimBody(
-
/**
* The time (in milliseconds) to wait when downloading keys from remote servers. 10 seconds is the recommended default.
*/
@Json(name = "timeout")
- var timeout: Int? = null,
+ val timeout: Int? = null,
/**
* Required. The keys to be claimed. A map from user ID, to a map from device ID to algorithm name.
*/
@Json(name = "one_time_keys")
- var oneTimeKeys: Map>
+ val oneTimeKeys: Map>
)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysClaimResponse.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysClaimResponse.kt
index 59567ba77a..3483873fbb 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysClaimResponse.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysClaimResponse.kt
@@ -24,11 +24,10 @@ import com.squareup.moshi.JsonClass
*/
@JsonClass(generateAdapter = true)
internal data class KeysClaimResponse(
-
/**
* The requested keys ordered by device by user.
* TODO Type does not match spec, should be Map
*/
@Json(name = "one_time_keys")
- var oneTimeKeys: Map>>>? = null
+ val oneTimeKeys: Map>>>? = null
)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysQueryBody.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysQueryBody.kt
index 3dca696fcd..da2dd781dd 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysQueryBody.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysQueryBody.kt
@@ -25,12 +25,11 @@ import com.squareup.moshi.JsonClass
*/
@JsonClass(generateAdapter = true)
internal data class KeysQueryBody(
-
/**
* The time (in milliseconds) to wait when downloading keys from remote servers. 10 seconds is the recommended default.
*/
@Json(name = "timeout")
- var timeout: Int? = null,
+ val timeout: Int? = null,
/**
* Required. The keys to be downloaded.
@@ -45,6 +44,5 @@ internal data class KeysQueryBody(
* by the notification in that sync.
*/
@Json(name = "token")
- var token: String? = null
-
+ val token: String? = null
)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysUploadResponse.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysUploadResponse.kt
index 38360fa1cd..cd71749acf 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysUploadResponse.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysUploadResponse.kt
@@ -23,13 +23,11 @@ import com.squareup.moshi.JsonClass
*/
@JsonClass(generateAdapter = true)
internal data class KeysUploadResponse(
-
/**
* The count per algorithm as returned by the home server: a map (algorithm to count).
*/
@Json(name = "one_time_key_counts")
- var oneTimeKeyCounts: Map