mirror of
https://github.com/element-hq/element-android
synced 2024-11-24 02:15:35 +03:00
Merge pull request #5952 from vector-im/feature/bma/sdk_user_story
Sdk user story
This commit is contained in:
commit
ae94f45f34
54 changed files with 667 additions and 241 deletions
4
changelog.d/5952.sdk
Normal file
4
changelog.d/5952.sdk
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
- Some `val` have been changed to `fun` to increase their visibility in the generated documentation. Just add `()` if you were using them.
|
||||||
|
- `KeysBackupService.state` has been replaced by `KeysBackupService.getState()`
|
||||||
|
- `KeysBackupService.isStucked` has been replaced by `KeysBackupService.isStuck()`
|
||||||
|
- SDK documentation improved
|
|
@ -1,3 +1,7 @@
|
||||||
|
# Package org.matrix.android.sdk.userstories
|
||||||
|
|
||||||
|
This package contains some user stories (**Us** prefix) of the SDK usage. You will find example of what it is possible to do with the SDK and the API which can be used to do it.
|
||||||
|
|
||||||
# Package org.matrix.android.sdk.api
|
# Package org.matrix.android.sdk.api
|
||||||
|
|
||||||
This is the root package of the API exposed by this SDK.
|
This is the root package of the API exposed by this SDK.
|
||||||
|
|
|
@ -58,7 +58,7 @@ import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
|
||||||
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
|
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
|
||||||
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
||||||
import org.matrix.android.sdk.api.session.securestorage.EmptyKeySigner
|
import org.matrix.android.sdk.api.session.securestorage.EmptyKeySigner
|
||||||
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService
|
import org.matrix.android.sdk.api.session.securestorage.KeyRef
|
||||||
import org.matrix.android.sdk.api.util.Optional
|
import org.matrix.android.sdk.api.util.Optional
|
||||||
import org.matrix.android.sdk.api.util.awaitCallback
|
import org.matrix.android.sdk.api.util.awaitCallback
|
||||||
import org.matrix.android.sdk.api.util.toBase64NoPadding
|
import org.matrix.android.sdk.api.util.toBase64NoPadding
|
||||||
|
@ -361,19 +361,19 @@ class CryptoTestHelper(val testHelper: CommonTestHelper) {
|
||||||
ssssService.storeSecret(
|
ssssService.storeSecret(
|
||||||
MASTER_KEY_SSSS_NAME,
|
MASTER_KEY_SSSS_NAME,
|
||||||
session.cryptoService().crossSigningService().getCrossSigningPrivateKeys()!!.master!!,
|
session.cryptoService().crossSigningService().getCrossSigningPrivateKeys()!!.master!!,
|
||||||
listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec))
|
listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec))
|
||||||
)
|
)
|
||||||
|
|
||||||
ssssService.storeSecret(
|
ssssService.storeSecret(
|
||||||
SELF_SIGNING_KEY_SSSS_NAME,
|
SELF_SIGNING_KEY_SSSS_NAME,
|
||||||
session.cryptoService().crossSigningService().getCrossSigningPrivateKeys()!!.selfSigned!!,
|
session.cryptoService().crossSigningService().getCrossSigningPrivateKeys()!!.selfSigned!!,
|
||||||
listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec))
|
listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec))
|
||||||
)
|
)
|
||||||
|
|
||||||
ssssService.storeSecret(
|
ssssService.storeSecret(
|
||||||
USER_SIGNING_KEY_SSSS_NAME,
|
USER_SIGNING_KEY_SSSS_NAME,
|
||||||
session.cryptoService().crossSigningService().getCrossSigningPrivateKeys()!!.user!!,
|
session.cryptoService().crossSigningService().getCrossSigningPrivateKeys()!!.user!!,
|
||||||
listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec))
|
listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec))
|
||||||
)
|
)
|
||||||
|
|
||||||
// set up megolm backup
|
// set up megolm backup
|
||||||
|
@ -390,7 +390,7 @@ class CryptoTestHelper(val testHelper: CommonTestHelper) {
|
||||||
ssssService.storeSecret(
|
ssssService.storeSecret(
|
||||||
KEYBACKUP_SECRET_SSSS_NAME,
|
KEYBACKUP_SECRET_SSSS_NAME,
|
||||||
secret,
|
secret,
|
||||||
listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec))
|
listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
|
|
||||||
val stateObserver = StateObserver(keysBackup)
|
val stateObserver = StateObserver(keysBackup)
|
||||||
|
|
||||||
assertFalse(keysBackup.isEnabled)
|
assertFalse(keysBackup.isEnabled())
|
||||||
|
|
||||||
val megolmBackupCreationInfo = testHelper.doSync<MegolmBackupCreationInfo> {
|
val megolmBackupCreationInfo = testHelper.doSync<MegolmBackupCreationInfo> {
|
||||||
keysBackup.prepareKeysBackupVersion(null, null, it)
|
keysBackup.prepareKeysBackupVersion(null, null, it)
|
||||||
|
@ -141,13 +141,13 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
|
|
||||||
val stateObserver = StateObserver(keysBackup)
|
val stateObserver = StateObserver(keysBackup)
|
||||||
|
|
||||||
assertFalse(keysBackup.isEnabled)
|
assertFalse(keysBackup.isEnabled())
|
||||||
|
|
||||||
val megolmBackupCreationInfo = testHelper.doSync<MegolmBackupCreationInfo> {
|
val megolmBackupCreationInfo = testHelper.doSync<MegolmBackupCreationInfo> {
|
||||||
keysBackup.prepareKeysBackupVersion(null, null, it)
|
keysBackup.prepareKeysBackupVersion(null, null, it)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertFalse(keysBackup.isEnabled)
|
assertFalse(keysBackup.isEnabled())
|
||||||
|
|
||||||
// Create the version
|
// Create the version
|
||||||
val version = testHelper.doSync<KeysVersion> {
|
val version = testHelper.doSync<KeysVersion> {
|
||||||
|
@ -155,7 +155,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backup must be enable now
|
// Backup must be enable now
|
||||||
assertTrue(keysBackup.isEnabled)
|
assertTrue(keysBackup.isEnabled())
|
||||||
|
|
||||||
// Check that it's signed with MSK
|
// Check that it's signed with MSK
|
||||||
val versionResult = testHelper.doSync<KeysVersionResult?> {
|
val versionResult = testHelper.doSync<KeysVersionResult?> {
|
||||||
|
@ -425,8 +425,8 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
|
|
||||||
// - The new device must see the previous backup as not trusted
|
// - The new device must see the previous backup as not trusted
|
||||||
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
||||||
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled())
|
||||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
|
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState())
|
||||||
|
|
||||||
// - Trust the backup from the new device
|
// - Trust the backup from the new device
|
||||||
testHelper.doSync<Unit> {
|
testHelper.doSync<Unit> {
|
||||||
|
@ -442,7 +442,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
|
|
||||||
// - Backup must be enabled on the new device, on the same version
|
// - Backup must be enabled on the new device, on the same version
|
||||||
assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion?.version)
|
assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion?.version)
|
||||||
assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled())
|
||||||
|
|
||||||
// - Retrieve the last version from the server
|
// - Retrieve the last version from the server
|
||||||
val keysVersionResult = testHelper.doSync<KeysBackupLastVersionResult> {
|
val keysVersionResult = testHelper.doSync<KeysBackupLastVersionResult> {
|
||||||
|
@ -485,8 +485,8 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
|
|
||||||
// - The new device must see the previous backup as not trusted
|
// - The new device must see the previous backup as not trusted
|
||||||
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
||||||
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled())
|
||||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
|
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState())
|
||||||
|
|
||||||
// - Trust the backup from the new device with the recovery key
|
// - Trust the backup from the new device with the recovery key
|
||||||
testHelper.doSync<Unit> {
|
testHelper.doSync<Unit> {
|
||||||
|
@ -502,7 +502,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
|
|
||||||
// - Backup must be enabled on the new device, on the same version
|
// - Backup must be enabled on the new device, on the same version
|
||||||
assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion?.version)
|
assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion?.version)
|
||||||
assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled())
|
||||||
|
|
||||||
// - Retrieve the last version from the server
|
// - Retrieve the last version from the server
|
||||||
val keysVersionResult = testHelper.doSync<KeysBackupLastVersionResult> {
|
val keysVersionResult = testHelper.doSync<KeysBackupLastVersionResult> {
|
||||||
|
@ -543,8 +543,8 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
|
|
||||||
// - The new device must see the previous backup as not trusted
|
// - The new device must see the previous backup as not trusted
|
||||||
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
||||||
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled())
|
||||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
|
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState())
|
||||||
|
|
||||||
// - Try to trust the backup from the new device with a wrong recovery key
|
// - Try to trust the backup from the new device with a wrong recovery key
|
||||||
val latch = CountDownLatch(1)
|
val latch = CountDownLatch(1)
|
||||||
|
@ -557,8 +557,8 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
|
|
||||||
// - The new device must still see the previous backup as not trusted
|
// - The new device must still see the previous backup as not trusted
|
||||||
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
||||||
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled())
|
||||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
|
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState())
|
||||||
|
|
||||||
stateObserver.stopAndCheckStates(null)
|
stateObserver.stopAndCheckStates(null)
|
||||||
}
|
}
|
||||||
|
@ -587,8 +587,8 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
|
|
||||||
// - The new device must see the previous backup as not trusted
|
// - The new device must see the previous backup as not trusted
|
||||||
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
||||||
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled())
|
||||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
|
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState())
|
||||||
|
|
||||||
// - Trust the backup from the new device with the password
|
// - Trust the backup from the new device with the password
|
||||||
testHelper.doSync<Unit> {
|
testHelper.doSync<Unit> {
|
||||||
|
@ -604,7 +604,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
|
|
||||||
// - Backup must be enabled on the new device, on the same version
|
// - Backup must be enabled on the new device, on the same version
|
||||||
assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion?.version)
|
assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion?.version)
|
||||||
assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled())
|
||||||
|
|
||||||
// - Retrieve the last version from the server
|
// - Retrieve the last version from the server
|
||||||
val keysVersionResult = testHelper.doSync<KeysBackupLastVersionResult> {
|
val keysVersionResult = testHelper.doSync<KeysBackupLastVersionResult> {
|
||||||
|
@ -648,8 +648,8 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
|
|
||||||
// - The new device must see the previous backup as not trusted
|
// - The new device must see the previous backup as not trusted
|
||||||
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
||||||
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled())
|
||||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
|
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState())
|
||||||
|
|
||||||
// - Try to trust the backup from the new device with a wrong password
|
// - Try to trust the backup from the new device with a wrong password
|
||||||
val latch = CountDownLatch(1)
|
val latch = CountDownLatch(1)
|
||||||
|
@ -662,8 +662,8 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
|
|
||||||
// - The new device must still see the previous backup as not trusted
|
// - The new device must still see the previous backup as not trusted
|
||||||
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
|
||||||
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
|
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled())
|
||||||
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
|
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState())
|
||||||
|
|
||||||
stateObserver.stopAndCheckStates(null)
|
stateObserver.stopAndCheckStates(null)
|
||||||
}
|
}
|
||||||
|
@ -915,7 +915,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
|
|
||||||
val stateObserver = StateObserver(keysBackup)
|
val stateObserver = StateObserver(keysBackup)
|
||||||
|
|
||||||
assertFalse(keysBackup.isEnabled)
|
assertFalse(keysBackup.isEnabled())
|
||||||
|
|
||||||
// Wait for keys backup to be finished
|
// Wait for keys backup to be finished
|
||||||
val latch0 = CountDownLatch(1)
|
val latch0 = CountDownLatch(1)
|
||||||
|
@ -939,7 +939,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
// - Make alice back up her keys to her homeserver
|
// - Make alice back up her keys to her homeserver
|
||||||
keysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup)
|
keysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup)
|
||||||
|
|
||||||
assertTrue(keysBackup.isEnabled)
|
assertTrue(keysBackup.isEnabled())
|
||||||
|
|
||||||
testHelper.await(latch0)
|
testHelper.await(latch0)
|
||||||
|
|
||||||
|
@ -958,8 +958,8 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
testHelper.await(latch2)
|
testHelper.await(latch2)
|
||||||
|
|
||||||
// -> That must fail and her backup state must be WrongBackUpVersion
|
// -> That must fail and her backup state must be WrongBackUpVersion
|
||||||
assertEquals(KeysBackupState.WrongBackUpVersion, keysBackup.state)
|
assertEquals(KeysBackupState.WrongBackUpVersion, keysBackup.getState())
|
||||||
assertFalse(keysBackup.isEnabled)
|
assertFalse(keysBackup.isEnabled())
|
||||||
|
|
||||||
stateObserver.stopAndCheckStates(null)
|
stateObserver.stopAndCheckStates(null)
|
||||||
}
|
}
|
||||||
|
@ -1012,7 +1012,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
// - Try to backup all in aliceSession2, it must fail
|
// - Try to backup all in aliceSession2, it must fail
|
||||||
val keysBackup2 = aliceSession2.cryptoService().keysBackupService()
|
val keysBackup2 = aliceSession2.cryptoService().keysBackupService()
|
||||||
|
|
||||||
assertFalse("Backup should not be enabled", keysBackup2.isEnabled)
|
assertFalse("Backup should not be enabled", keysBackup2.isEnabled())
|
||||||
|
|
||||||
val stateObserver2 = StateObserver(keysBackup2)
|
val stateObserver2 = StateObserver(keysBackup2)
|
||||||
|
|
||||||
|
@ -1031,8 +1031,8 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
assertFalse(isSuccessful)
|
assertFalse(isSuccessful)
|
||||||
|
|
||||||
// Backup state must be NotTrusted
|
// Backup state must be NotTrusted
|
||||||
assertEquals("Backup state must be NotTrusted", KeysBackupState.NotTrusted, keysBackup2.state)
|
assertEquals("Backup state must be NotTrusted", KeysBackupState.NotTrusted, keysBackup2.getState())
|
||||||
assertFalse("Backup should not be enabled", keysBackup2.isEnabled)
|
assertFalse("Backup should not be enabled", keysBackup2.isEnabled())
|
||||||
|
|
||||||
// - Validate the old device from the new one
|
// - Validate the old device from the new one
|
||||||
aliceSession2.cryptoService().setDeviceVerification(
|
aliceSession2.cryptoService().setDeviceVerification(
|
||||||
|
@ -1046,7 +1046,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
keysBackup2.addListener(object : KeysBackupStateListener {
|
keysBackup2.addListener(object : KeysBackupStateListener {
|
||||||
override fun onStateChange(newState: KeysBackupState) {
|
override fun onStateChange(newState: KeysBackupState) {
|
||||||
// Check the backup completes
|
// Check the backup completes
|
||||||
if (keysBackup2.state == KeysBackupState.ReadyToBackUp) {
|
if (keysBackup2.getState() == KeysBackupState.ReadyToBackUp) {
|
||||||
// Remove itself from the list of listeners
|
// Remove itself from the list of listeners
|
||||||
keysBackup2.removeListener(this)
|
keysBackup2.removeListener(this)
|
||||||
|
|
||||||
|
@ -1064,7 +1064,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// -> It must success
|
// -> It must success
|
||||||
assertTrue(aliceSession2.cryptoService().keysBackupService().isEnabled)
|
assertTrue(aliceSession2.cryptoService().keysBackupService().isEnabled())
|
||||||
|
|
||||||
stateObserver.stopAndCheckStates(null)
|
stateObserver.stopAndCheckStates(null)
|
||||||
stateObserver2.stopAndCheckStates(null)
|
stateObserver2.stopAndCheckStates(null)
|
||||||
|
@ -1085,17 +1085,17 @@ class KeysBackupTest : InstrumentedTest {
|
||||||
|
|
||||||
val stateObserver = StateObserver(keysBackup)
|
val stateObserver = StateObserver(keysBackup)
|
||||||
|
|
||||||
assertFalse(keysBackup.isEnabled)
|
assertFalse(keysBackup.isEnabled())
|
||||||
|
|
||||||
val keyBackupCreationInfo = keysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup)
|
val keyBackupCreationInfo = keysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup)
|
||||||
|
|
||||||
assertTrue(keysBackup.isEnabled)
|
assertTrue(keysBackup.isEnabled())
|
||||||
|
|
||||||
// Delete the backup
|
// Delete the backup
|
||||||
testHelper.doSync<Unit> { keysBackup.deleteBackup(keyBackupCreationInfo.version, it) }
|
testHelper.doSync<Unit> { keysBackup.deleteBackup(keyBackupCreationInfo.version, it) }
|
||||||
|
|
||||||
// Backup is now disabled
|
// Backup is now disabled
|
||||||
assertFalse(keysBackup.isEnabled)
|
assertFalse(keysBackup.isEnabled())
|
||||||
|
|
||||||
stateObserver.stopAndCheckStates(null)
|
stateObserver.stopAndCheckStates(null)
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ internal class KeysBackupTestHelper(
|
||||||
|
|
||||||
Assert.assertNotNull(megolmBackupCreationInfo)
|
Assert.assertNotNull(megolmBackupCreationInfo)
|
||||||
|
|
||||||
Assert.assertFalse("Key backup should not be enabled before creation", keysBackup.isEnabled)
|
Assert.assertFalse("Key backup should not be enabled before creation", keysBackup.isEnabled())
|
||||||
|
|
||||||
// Create the version
|
// Create the version
|
||||||
val keysVersion = testHelper.doSync<KeysVersion> {
|
val keysVersion = testHelper.doSync<KeysVersion> {
|
||||||
|
@ -116,7 +116,7 @@ internal class KeysBackupTestHelper(
|
||||||
Assert.assertNotNull("Key backup version should not be null", keysVersion.version)
|
Assert.assertNotNull("Key backup version should not be null", keysVersion.version)
|
||||||
|
|
||||||
// Backup must be enable now
|
// Backup must be enable now
|
||||||
Assert.assertTrue(keysBackup.isEnabled)
|
Assert.assertTrue(keysBackup.isEnabled())
|
||||||
|
|
||||||
stateObserver.stopAndCheckStates(null)
|
stateObserver.stopAndCheckStates(null)
|
||||||
return PrepareKeysBackupDataResult(megolmBackupCreationInfo, keysVersion.version)
|
return PrepareKeysBackupDataResult(megolmBackupCreationInfo, keysVersion.version)
|
||||||
|
@ -128,7 +128,7 @@ internal class KeysBackupTestHelper(
|
||||||
*/
|
*/
|
||||||
fun waitForKeysBackupToBeInState(session: Session, state: KeysBackupState) {
|
fun waitForKeysBackupToBeInState(session: Session, state: KeysBackupState) {
|
||||||
// If already in the wanted state, return
|
// If already in the wanted state, return
|
||||||
if (session.cryptoService().keysBackupService().state == state) {
|
if (session.cryptoService().keysBackupService().getState() == state) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,11 +31,11 @@ import org.matrix.android.sdk.api.crypto.SSSS_ALGORITHM_AES_HMAC_SHA2
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent
|
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent
|
||||||
import org.matrix.android.sdk.api.session.securestorage.EncryptedSecretContent
|
import org.matrix.android.sdk.api.session.securestorage.EncryptedSecretContent
|
||||||
|
import org.matrix.android.sdk.api.session.securestorage.KeyRef
|
||||||
import org.matrix.android.sdk.api.session.securestorage.KeySigner
|
import org.matrix.android.sdk.api.session.securestorage.KeySigner
|
||||||
import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec
|
import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec
|
||||||
import org.matrix.android.sdk.api.session.securestorage.SecretStorageKeyContent
|
import org.matrix.android.sdk.api.session.securestorage.SecretStorageKeyContent
|
||||||
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageError
|
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageError
|
||||||
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService
|
|
||||||
import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo
|
import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo
|
||||||
import org.matrix.android.sdk.api.util.Optional
|
import org.matrix.android.sdk.api.util.Optional
|
||||||
import org.matrix.android.sdk.api.util.toBase64NoPadding
|
import org.matrix.android.sdk.api.util.toBase64NoPadding
|
||||||
|
@ -122,7 +122,7 @@ class QuadSTests : InstrumentedTest {
|
||||||
aliceSession.sharedSecretStorageService().storeSecret(
|
aliceSession.sharedSecretStorageService().storeSecret(
|
||||||
"secret.of.life",
|
"secret.of.life",
|
||||||
clearSecret,
|
clearSecret,
|
||||||
listOf(SharedSecretStorageService.KeyRef(null, keySpec)) // default key
|
listOf(KeyRef(null, keySpec)) // default key
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,8 +185,8 @@ class QuadSTests : InstrumentedTest {
|
||||||
"my.secret",
|
"my.secret",
|
||||||
mySecretText.toByteArray().toBase64NoPadding(),
|
mySecretText.toByteArray().toBase64NoPadding(),
|
||||||
listOf(
|
listOf(
|
||||||
SharedSecretStorageService.KeyRef(keyId1, RawBytesKeySpec.fromRecoveryKey(key1Info.recoveryKey)),
|
KeyRef(keyId1, RawBytesKeySpec.fromRecoveryKey(key1Info.recoveryKey)),
|
||||||
SharedSecretStorageService.KeyRef(keyId2, RawBytesKeySpec.fromRecoveryKey(key2Info.recoveryKey))
|
KeyRef(keyId2, RawBytesKeySpec.fromRecoveryKey(key2Info.recoveryKey))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,7 @@ class QuadSTests : InstrumentedTest {
|
||||||
aliceSession.sharedSecretStorageService().storeSecret(
|
aliceSession.sharedSecretStorageService().storeSecret(
|
||||||
"my.secret",
|
"my.secret",
|
||||||
mySecretText.toByteArray().toBase64NoPadding(),
|
mySecretText.toByteArray().toBase64NoPadding(),
|
||||||
listOf(SharedSecretStorageService.KeyRef(keyId1, RawBytesKeySpec.fromRecoveryKey(key1Info.recoveryKey)))
|
listOf(KeyRef(keyId1, RawBytesKeySpec.fromRecoveryKey(key1Info.recoveryKey)))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ interface AuthenticationService {
|
||||||
/**
|
/**
|
||||||
* True when login and password has been sent with success to the homeserver.
|
* True when login and password has been sent with success to the homeserver.
|
||||||
*/
|
*/
|
||||||
val isRegistrationStarted: Boolean
|
fun isRegistrationStarted(): Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel pending login or pending registration.
|
* Cancel pending login or pending registration.
|
||||||
|
|
|
@ -18,13 +18,31 @@ package org.matrix.android.sdk.api.auth.registration
|
||||||
|
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
|
|
||||||
// Either a session or an object containing data about registration stages
|
/**
|
||||||
|
* Either a session or an object containing data about registration stages.
|
||||||
|
*/
|
||||||
sealed class RegistrationResult {
|
sealed class RegistrationResult {
|
||||||
|
/**
|
||||||
|
* The registration is successful, the [Session] is provided.
|
||||||
|
*/
|
||||||
data class Success(val session: Session) : RegistrationResult()
|
data class Success(val session: Session) : RegistrationResult()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The registration still miss some steps. See [FlowResult] to know the details.
|
||||||
|
*/
|
||||||
data class FlowResponse(val flowResult: FlowResult) : RegistrationResult()
|
data class FlowResponse(val flowResult: FlowResult) : RegistrationResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about the missing and completed [Stage].
|
||||||
|
*/
|
||||||
data class FlowResult(
|
data class FlowResult(
|
||||||
|
/**
|
||||||
|
* List of missing stages.
|
||||||
|
*/
|
||||||
val missingStages: List<Stage>,
|
val missingStages: List<Stage>,
|
||||||
|
/**
|
||||||
|
* List of completed stages.
|
||||||
|
*/
|
||||||
val completedStages: List<Stage>
|
val completedStages: List<Stage>
|
||||||
)
|
)
|
||||||
|
|
|
@ -109,14 +109,14 @@ interface RegistrationWizard {
|
||||||
suspend fun checkIfEmailHasBeenValidated(delayMillis: Long): RegistrationResult
|
suspend fun checkIfEmailHasBeenValidated(delayMillis: Long): RegistrationResult
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the current ThreePid, waiting for validation. The SDK will store it in database, so it can be
|
* Returns the current ThreePid, waiting for validation. The SDK will store it in database, so it can be
|
||||||
* restored even if the app has been killed during the registration
|
* restored even if the app has been killed during the registration
|
||||||
*/
|
*/
|
||||||
val currentThreePid: String?
|
fun getCurrentThreePid(): String?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True when login and password have been sent with success to the homeserver, i.e. [createAccount] has been
|
* Return true when login and password have been sent with success to the homeserver, i.e. [createAccount] has been
|
||||||
* called successfully.
|
* called successfully.
|
||||||
*/
|
*/
|
||||||
val isRegistrationStarted: Boolean
|
fun isRegistrationStarted(): Boolean
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,25 +16,40 @@
|
||||||
|
|
||||||
package org.matrix.android.sdk.api.auth.registration
|
package org.matrix.android.sdk.api.auth.registration
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registration stages.
|
||||||
|
*/
|
||||||
sealed class Stage(open val mandatory: Boolean) {
|
sealed class Stage(open val mandatory: Boolean) {
|
||||||
|
|
||||||
// m.login.recaptcha
|
/**
|
||||||
|
* m.login.recaptcha stage.
|
||||||
|
*/
|
||||||
data class ReCaptcha(override val mandatory: Boolean, val publicKey: String) : Stage(mandatory)
|
data class ReCaptcha(override val mandatory: Boolean, val publicKey: String) : Stage(mandatory)
|
||||||
|
|
||||||
// m.login.email.identity
|
/**
|
||||||
|
* m.login.email.identity stage.
|
||||||
|
*/
|
||||||
data class Email(override val mandatory: Boolean) : Stage(mandatory)
|
data class Email(override val mandatory: Boolean) : Stage(mandatory)
|
||||||
|
|
||||||
// m.login.msisdn
|
/**
|
||||||
|
* m.login.msisdn stage.
|
||||||
|
*/
|
||||||
data class Msisdn(override val mandatory: Boolean) : Stage(mandatory)
|
data class Msisdn(override val mandatory: Boolean) : Stage(mandatory)
|
||||||
|
|
||||||
// m.login.dummy, can be mandatory if there is no other stages. In this case the account cannot be created by just sending a username
|
/**
|
||||||
// and a password, the dummy stage has to be done
|
* m.login.dummy, can be mandatory if there is no other stages. In this case the account cannot be created by just sending a username
|
||||||
|
* and a password, the dummy stage has to be done.
|
||||||
|
*/
|
||||||
data class Dummy(override val mandatory: Boolean) : Stage(mandatory)
|
data class Dummy(override val mandatory: Boolean) : Stage(mandatory)
|
||||||
|
|
||||||
// Undocumented yet: m.login.terms
|
/**
|
||||||
|
* Undocumented yet: m.login.terms stage.
|
||||||
|
*/
|
||||||
data class Terms(override val mandatory: Boolean, val policies: TermPolicies) : Stage(mandatory)
|
data class Terms(override val mandatory: Boolean, val policies: TermPolicies) : Stage(mandatory)
|
||||||
|
|
||||||
// For unknown stages
|
/**
|
||||||
|
* For unknown stages.
|
||||||
|
*/
|
||||||
data class Other(override val mandatory: Boolean, val type: String, val params: Map<*, *>?) : Stage(mandatory)
|
data class Other(override val mandatory: Boolean, val type: String, val params: Map<*, *>?) : Stage(mandatory)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,13 +17,19 @@
|
||||||
package org.matrix.android.sdk.api.cache
|
package org.matrix.android.sdk.api.cache
|
||||||
|
|
||||||
sealed class CacheStrategy {
|
sealed class CacheStrategy {
|
||||||
// Data is always fetched from the server
|
/**
|
||||||
|
* Data is always fetched from the server.
|
||||||
|
*/
|
||||||
object NoCache : CacheStrategy()
|
object NoCache : CacheStrategy()
|
||||||
|
|
||||||
// Once data is retrieved, it is stored for the provided amount of time.
|
/**
|
||||||
// In case of error, and if strict is set to false, the cache can be returned if available
|
* Once data is retrieved, it is stored for the provided amount of time.
|
||||||
|
* In case of error, and if strict is set to false, the cache can be returned if available
|
||||||
|
*/
|
||||||
data class TtlCache(val validityDurationInMillis: Long, val strict: Boolean) : CacheStrategy()
|
data class TtlCache(val validityDurationInMillis: Long, val strict: Boolean) : CacheStrategy()
|
||||||
|
|
||||||
// Once retrieved, the data is stored in cache and will be always get from the cache
|
/**
|
||||||
|
* Once retrieved, the data is stored in cache and will be always get from the cache.
|
||||||
|
*/
|
||||||
object InfiniteCache : CacheStrategy()
|
object InfiniteCache : CacheStrategy()
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,9 @@ sealed class Failure(cause: Throwable? = null) : Throwable(cause = cause) {
|
||||||
data class ServerError(val error: MatrixError, val httpCode: Int) : Failure(RuntimeException(error.toString()))
|
data class ServerError(val error: MatrixError, val httpCode: Int) : Failure(RuntimeException(error.toString()))
|
||||||
object SuccessError : Failure(RuntimeException(RuntimeException("SuccessResult is false")))
|
object SuccessError : Failure(RuntimeException(RuntimeException("SuccessResult is false")))
|
||||||
|
|
||||||
// When server send an error, but it cannot be interpreted as a MatrixError
|
/**
|
||||||
|
* When server send an error, but it cannot be interpreted as a MatrixError.
|
||||||
|
*/
|
||||||
data class OtherServerError(val errorBody: String, val httpCode: Int) : Failure(RuntimeException("HTTP $httpCode: $errorBody"))
|
data class OtherServerError(val errorBody: String, val httpCode: Int) : Failure(RuntimeException("HTTP $httpCode: $errorBody"))
|
||||||
|
|
||||||
data class RegistrationFlowError(val registrationFlowResponse: RegistrationFlowResponse) : Failure(RuntimeException(registrationFlowResponse.toString()))
|
data class RegistrationFlowError(val registrationFlowResponse: RegistrationFlowResponse) : Failure(RuntimeException(registrationFlowResponse.toString()))
|
||||||
|
|
|
@ -168,8 +168,6 @@ interface KeysBackupService {
|
||||||
password: String,
|
password: String,
|
||||||
callback: MatrixCallback<Unit>)
|
callback: MatrixCallback<Unit>)
|
||||||
|
|
||||||
fun onSecretKeyGossip(secret: String)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restore a backup with a recovery key from a given backup version stored on the homeserver.
|
* Restore a backup with a recovery key from a given backup version stored on the homeserver.
|
||||||
*
|
*
|
||||||
|
@ -204,10 +202,13 @@ interface KeysBackupService {
|
||||||
callback: MatrixCallback<ImportRoomKeysResult>)
|
callback: MatrixCallback<ImportRoomKeysResult>)
|
||||||
|
|
||||||
val keysBackupVersion: KeysVersionResult?
|
val keysBackupVersion: KeysVersionResult?
|
||||||
|
|
||||||
val currentBackupVersion: String?
|
val currentBackupVersion: String?
|
||||||
val isEnabled: Boolean
|
get() = keysBackupVersion?.version
|
||||||
val isStucked: Boolean
|
|
||||||
val state: KeysBackupState
|
fun isEnabled(): Boolean
|
||||||
|
fun isStuck(): Boolean
|
||||||
|
fun getState(): KeysBackupState
|
||||||
|
|
||||||
// For gossiping
|
// For gossiping
|
||||||
fun saveBackupRecoveryKey(recoveryKey: String?, version: String?)
|
fun saveBackupRecoveryKey(recoveryKey: String?, version: String?)
|
||||||
|
|
|
@ -51,33 +51,51 @@ package org.matrix.android.sdk.api.session.crypto.keysbackup
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
enum class KeysBackupState {
|
enum class KeysBackupState {
|
||||||
// Need to check the current backup version on the homeserver
|
/**
|
||||||
|
* Need to check the current backup version on the homeserver.
|
||||||
|
*/
|
||||||
Unknown,
|
Unknown,
|
||||||
|
|
||||||
// Checking if backup is enabled on homeserver
|
/**
|
||||||
|
* Checking if backup is enabled on homeserver.
|
||||||
|
*/
|
||||||
CheckingBackUpOnHomeserver,
|
CheckingBackUpOnHomeserver,
|
||||||
|
|
||||||
// Backup has been stopped because a new backup version has been detected on the homeserver
|
/**
|
||||||
|
* Backup has been stopped because a new backup version has been detected on the homeserver.
|
||||||
|
*/
|
||||||
WrongBackUpVersion,
|
WrongBackUpVersion,
|
||||||
|
|
||||||
// Backup from this device is not enabled
|
/**
|
||||||
|
* Backup from this device is not enabled.
|
||||||
|
*/
|
||||||
Disabled,
|
Disabled,
|
||||||
|
|
||||||
// There is a backup available on the homeserver but it is not trusted.
|
/**
|
||||||
// It is not trusted because the signature is invalid or the device that created it is not verified
|
* There is a backup available on the homeserver but it is not trusted.
|
||||||
// Use [KeysBackup.getKeysBackupTrust()] to get trust details.
|
* It is not trusted because the signature is invalid or the device that created it is not verified.
|
||||||
// Consequently, the backup from this device is not enabled.
|
* Use [KeysBackup.getKeysBackupTrust()] to get trust details.
|
||||||
|
* Consequently, the backup from this device is not enabled.
|
||||||
|
*/
|
||||||
NotTrusted,
|
NotTrusted,
|
||||||
|
|
||||||
// Backup is being enabled: the backup version is being created on the homeserver
|
/**
|
||||||
|
* Backup is being enabled: the backup version is being created on the homeserver.
|
||||||
|
*/
|
||||||
Enabling,
|
Enabling,
|
||||||
|
|
||||||
// Backup is enabled and ready to send backup to the homeserver
|
/**
|
||||||
|
* Backup is enabled and ready to send backup to the homeserver.
|
||||||
|
*/
|
||||||
ReadyToBackUp,
|
ReadyToBackUp,
|
||||||
|
|
||||||
// e2e keys are going to be sent to the homeserver
|
/**
|
||||||
|
* e2e keys are going to be sent to the homeserver.
|
||||||
|
*/
|
||||||
WillBackUp,
|
WillBackUp,
|
||||||
|
|
||||||
// e2e keys are being sent to the homeserver
|
/**
|
||||||
|
* e2e keys are being sent to the homeserver.
|
||||||
|
*/
|
||||||
BackingUp
|
BackingUp
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,15 +20,23 @@ package org.matrix.android.sdk.api.session.crypto.model
|
||||||
* RoomEncryptionTrustLevel represents the trust level in an encrypted room.
|
* RoomEncryptionTrustLevel represents the trust level in an encrypted room.
|
||||||
*/
|
*/
|
||||||
enum class RoomEncryptionTrustLevel {
|
enum class RoomEncryptionTrustLevel {
|
||||||
// No one in the room has been verified -> Black shield
|
/**
|
||||||
|
* No one in the room has been verified -> Black shield.
|
||||||
|
*/
|
||||||
Default,
|
Default,
|
||||||
|
|
||||||
// There are one or more device un-verified -> the app should display a red shield
|
/**
|
||||||
|
* There are one or more device un-verified -> the app should display a red shield.
|
||||||
|
*/
|
||||||
Warning,
|
Warning,
|
||||||
|
|
||||||
// All devices in the room are verified -> the app should display a green shield
|
/**
|
||||||
|
* All devices in the room are verified -> the app should display a green shield.
|
||||||
|
*/
|
||||||
Trusted,
|
Trusted,
|
||||||
|
|
||||||
// e2e is active but with an unsupported algorithm
|
/**
|
||||||
|
* e2e is active but with an unsupported algorithm.
|
||||||
|
*/
|
||||||
E2EWithUnsupportedAlgorithm
|
E2EWithUnsupportedAlgorithm
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,18 @@ package org.matrix.android.sdk.api.session.crypto.verification
|
||||||
* Verification methods.
|
* Verification methods.
|
||||||
*/
|
*/
|
||||||
enum class VerificationMethod {
|
enum class VerificationMethod {
|
||||||
// Use it when your application supports the SAS verification method
|
/**
|
||||||
|
* Use it when your application supports the SAS verification method.
|
||||||
|
*/
|
||||||
SAS,
|
SAS,
|
||||||
|
|
||||||
// Use it if your application is able to display QR codes
|
/**
|
||||||
|
* Use it if your application is able to display QR codes.
|
||||||
|
*/
|
||||||
QR_CODE_SHOW,
|
QR_CODE_SHOW,
|
||||||
|
|
||||||
// Use it if your application is able to scan QR codes
|
/**
|
||||||
|
* Use it if your application is able to scan QR codes.
|
||||||
|
*/
|
||||||
QR_CODE_SCAN
|
QR_CODE_SCAN
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,14 @@
|
||||||
package org.matrix.android.sdk.api.session.crypto.verification
|
package org.matrix.android.sdk.api.session.crypto.verification
|
||||||
|
|
||||||
sealed class VerificationTxState {
|
sealed class VerificationTxState {
|
||||||
// Uninitialized state
|
/**
|
||||||
|
* Uninitialized state.
|
||||||
|
*/
|
||||||
object None : VerificationTxState()
|
object None : VerificationTxState()
|
||||||
|
|
||||||
// Specific for SAS
|
/**
|
||||||
|
* Specific for SAS.
|
||||||
|
*/
|
||||||
abstract class VerificationSasTxState : VerificationTxState()
|
abstract class VerificationSasTxState : VerificationTxState()
|
||||||
|
|
||||||
object SendingStart : VerificationSasTxState()
|
object SendingStart : VerificationSasTxState()
|
||||||
|
@ -38,18 +42,26 @@ sealed class VerificationTxState {
|
||||||
object MacSent : VerificationSasTxState()
|
object MacSent : VerificationSasTxState()
|
||||||
object Verifying : VerificationSasTxState()
|
object Verifying : VerificationSasTxState()
|
||||||
|
|
||||||
// Specific for QR code
|
/**
|
||||||
|
* Specific for QR code.
|
||||||
|
*/
|
||||||
abstract class VerificationQrTxState : VerificationTxState()
|
abstract class VerificationQrTxState : VerificationTxState()
|
||||||
|
|
||||||
// Will be used to ask the user if the other user has correctly scanned
|
/**
|
||||||
|
* Will be used to ask the user if the other user has correctly scanned.
|
||||||
|
*/
|
||||||
object QrScannedByOther : VerificationQrTxState()
|
object QrScannedByOther : VerificationQrTxState()
|
||||||
object WaitingOtherReciprocateConfirm : VerificationQrTxState()
|
object WaitingOtherReciprocateConfirm : VerificationQrTxState()
|
||||||
|
|
||||||
// Terminal states
|
/**
|
||||||
|
* Terminal states.
|
||||||
|
*/
|
||||||
abstract class TerminalTxState : VerificationTxState()
|
abstract class TerminalTxState : VerificationTxState()
|
||||||
|
|
||||||
object Verified : TerminalTxState()
|
object Verified : TerminalTxState()
|
||||||
|
|
||||||
// Cancelled by me or by other
|
/**
|
||||||
|
* Cancelled by me or by other.
|
||||||
|
*/
|
||||||
data class Cancelled(val cancelCode: CancelCode, val byMe: Boolean) : TerminalTxState()
|
data class Cancelled(val cancelCode: CancelCode, val byMe: Boolean) : TerminalTxState()
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* 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 org.matrix.android.sdk.api.session.pushers
|
||||||
|
|
||||||
|
data class HttpPusher(
|
||||||
|
/**
|
||||||
|
* This is a unique identifier for this pusher. The value you should use for
|
||||||
|
* this is the routing or destination address information for the notification,
|
||||||
|
* for example, the APNS token for APNS or the Registration ID for GCM. If your
|
||||||
|
* notification client has no such concept, use any unique identifier. Max length, 512 chars.
|
||||||
|
*/
|
||||||
|
val pushkey: String,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The application id
|
||||||
|
* This is a reverse-DNS style identifier for the application. It is recommended
|
||||||
|
* that this end with the platform, such that different platform versions get
|
||||||
|
* different app identifiers. Max length, 64 chars.
|
||||||
|
*/
|
||||||
|
val appId: String,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This string determines which set of device specific rules this pusher executes.
|
||||||
|
*/
|
||||||
|
val profileTag: String,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The preferred language for receiving notifications (e.g. "en" or "en-US").
|
||||||
|
*/
|
||||||
|
val lang: String,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A human readable string that will allow the user to identify what application owns this pusher.
|
||||||
|
*/
|
||||||
|
val appDisplayName: String,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A human readable string that will allow the user to identify what device owns this pusher.
|
||||||
|
*/
|
||||||
|
val deviceDisplayName: String,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URL to use to send notifications to. MUST be an HTTPS URL with a path of /_matrix/push/v1/notify.
|
||||||
|
*/
|
||||||
|
val url: String,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If true, the homeserver should add another pusher with the given pushkey and App ID in addition
|
||||||
|
* to any others with different user IDs. Otherwise, the homeserver must remove any other pushers
|
||||||
|
* with the same App ID and pushkey for different users.
|
||||||
|
*/
|
||||||
|
val append: Boolean,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* true to limit the push content to only id and not message content
|
||||||
|
* Ref: https://matrix.org/docs/spec/push_gateway/r0.1.1#homeserver-behaviour
|
||||||
|
*/
|
||||||
|
val withEventIdOnly: Boolean
|
||||||
|
)
|
|
@ -107,61 +107,4 @@ interface PushersService {
|
||||||
* Get the current pushers.
|
* Get the current pushers.
|
||||||
*/
|
*/
|
||||||
fun getPushers(): List<Pusher>
|
fun getPushers(): List<Pusher>
|
||||||
|
|
||||||
data class HttpPusher(
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a unique identifier for this pusher. The value you should use for
|
|
||||||
* this is the routing or destination address information for the notification,
|
|
||||||
* for example, the APNS token for APNS or the Registration ID for GCM. If your
|
|
||||||
* notification client has no such concept, use any unique identifier. Max length, 512 chars.
|
|
||||||
*/
|
|
||||||
val pushkey: String,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The application id
|
|
||||||
* This is a reverse-DNS style identifier for the application. It is recommended
|
|
||||||
* that this end with the platform, such that different platform versions get
|
|
||||||
* different app identifiers. Max length, 64 chars.
|
|
||||||
*/
|
|
||||||
val appId: String,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This string determines which set of device specific rules this pusher executes.
|
|
||||||
*/
|
|
||||||
val profileTag: String,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The preferred language for receiving notifications (e.g. "en" or "en-US").
|
|
||||||
*/
|
|
||||||
val lang: String,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A human readable string that will allow the user to identify what application owns this pusher.
|
|
||||||
*/
|
|
||||||
val appDisplayName: String,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A human readable string that will allow the user to identify what device owns this pusher.
|
|
||||||
*/
|
|
||||||
val deviceDisplayName: String,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The URL to use to send notifications to. MUST be an HTTPS URL with a path of /_matrix/push/v1/notify.
|
|
||||||
*/
|
|
||||||
val url: String,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If true, the homeserver should add another pusher with the given pushkey and App ID in addition
|
|
||||||
* to any others with different user IDs. Otherwise, the homeserver must remove any other pushers
|
|
||||||
* with the same App ID and pushkey for different users.
|
|
||||||
*/
|
|
||||||
val append: Boolean,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* true to limit the push content to only id and not message content
|
|
||||||
* Ref: https://matrix.org/docs/spec/push_gateway/r0.1.1#homeserver-behaviour
|
|
||||||
*/
|
|
||||||
val withEventIdOnly: Boolean
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,27 +17,44 @@
|
||||||
package org.matrix.android.sdk.api.session.room.send
|
package org.matrix.android.sdk.api.session.room.send
|
||||||
|
|
||||||
enum class SendState {
|
enum class SendState {
|
||||||
|
/**
|
||||||
|
* The state is unknown.
|
||||||
|
*/
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
|
|
||||||
// the event has not been sent
|
/**
|
||||||
|
* The event has not been sent.
|
||||||
|
*/
|
||||||
UNSENT,
|
UNSENT,
|
||||||
|
|
||||||
// the event is encrypting
|
/**
|
||||||
|
* The event is encrypting.
|
||||||
|
*/
|
||||||
ENCRYPTING,
|
ENCRYPTING,
|
||||||
|
|
||||||
// the event is currently sending
|
/**
|
||||||
|
* The event is currently sending.
|
||||||
|
*/
|
||||||
SENDING,
|
SENDING,
|
||||||
|
|
||||||
// the event has been sent
|
/**
|
||||||
|
* The event has been sent.
|
||||||
|
*/
|
||||||
SENT,
|
SENT,
|
||||||
|
|
||||||
// the event has been received from server
|
/**
|
||||||
|
* The event has been received from server.
|
||||||
|
*/
|
||||||
SYNCED,
|
SYNCED,
|
||||||
|
|
||||||
// The event failed to be sent
|
/**
|
||||||
|
* The event failed to be sent.
|
||||||
|
*/
|
||||||
UNDELIVERED,
|
UNDELIVERED,
|
||||||
|
|
||||||
// the event failed to be sent because some unknown devices have been found while encrypting it
|
/**
|
||||||
|
* The event failed to be sent because some unknown devices have been found while encrypting it.
|
||||||
|
*/
|
||||||
FAILED_UNKNOWN_DEVICES;
|
FAILED_UNKNOWN_DEVICES;
|
||||||
|
|
||||||
internal companion object {
|
internal companion object {
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* 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 org.matrix.android.sdk.api.session.securestorage
|
||||||
|
|
||||||
|
data class KeyRef(
|
||||||
|
val keyId: String?,
|
||||||
|
val keySpec: SsssKeySpec?
|
||||||
|
)
|
|
@ -132,9 +132,4 @@ interface SharedSecretStorageService {
|
||||||
fun checkShouldBeAbleToAccessSecrets(secretNames: List<String>, keyId: String?): IntegrityResult
|
fun checkShouldBeAbleToAccessSecrets(secretNames: List<String>, keyId: String?): IntegrityResult
|
||||||
|
|
||||||
suspend fun requestSecret(name: String, myOtherDeviceId: String)
|
suspend fun requestSecret(name: String, myOtherDeviceId: String)
|
||||||
|
|
||||||
data class KeyRef(
|
|
||||||
val keyId: String?,
|
|
||||||
val keySpec: SsssKeySpec?
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,14 +20,19 @@ package org.matrix.android.sdk.api.session.threads
|
||||||
* This class defines the state of a thread notification.
|
* This class defines the state of a thread notification.
|
||||||
*/
|
*/
|
||||||
enum class ThreadNotificationState {
|
enum class ThreadNotificationState {
|
||||||
|
/**
|
||||||
// There are no new message
|
* There are no new message.
|
||||||
|
*/
|
||||||
NO_NEW_MESSAGE,
|
NO_NEW_MESSAGE,
|
||||||
|
|
||||||
// There is at least one new message
|
/**
|
||||||
|
* There is at least one new message.
|
||||||
|
*/
|
||||||
NEW_MESSAGE,
|
NEW_MESSAGE,
|
||||||
|
|
||||||
// The is at least one new message that should be highlighted
|
/**
|
||||||
// ex. "Hello @aris.kotsomitopoulos"
|
* The is at least one new message that should be highlighted.
|
||||||
|
* ex. "Hello @aris.kotsomitopoulos"
|
||||||
|
*/
|
||||||
NEW_HIGHLIGHTED_MESSAGE;
|
NEW_HIGHLIGHTED_MESSAGE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,8 +323,7 @@ internal class DefaultAuthenticationService @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val isRegistrationStarted: Boolean
|
override fun isRegistrationStarted() = currentRegistrationWizard?.isRegistrationStarted() == true
|
||||||
get() = currentRegistrationWizard?.isRegistrationStarted == true
|
|
||||||
|
|
||||||
override fun getLoginWizard(): LoginWizard {
|
override fun getLoginWizard(): LoginWizard {
|
||||||
return currentLoginWizard
|
return currentLoginWizard
|
||||||
|
|
|
@ -49,8 +49,7 @@ internal class DefaultRegistrationWizard(
|
||||||
private val validateCodeTask: ValidateCodeTask = DefaultValidateCodeTask(authAPI)
|
private val validateCodeTask: ValidateCodeTask = DefaultValidateCodeTask(authAPI)
|
||||||
private val registerCustomTask: RegisterCustomTask = DefaultRegisterCustomTask(authAPI)
|
private val registerCustomTask: RegisterCustomTask = DefaultRegisterCustomTask(authAPI)
|
||||||
|
|
||||||
override val currentThreePid: String?
|
override fun getCurrentThreePid(): String? {
|
||||||
get() {
|
|
||||||
return when (val threePid = pendingSessionData.currentThreePidData?.threePid) {
|
return when (val threePid = pendingSessionData.currentThreePidData?.threePid) {
|
||||||
is RegisterThreePid.Email -> threePid.email
|
is RegisterThreePid.Email -> threePid.email
|
||||||
is RegisterThreePid.Msisdn -> {
|
is RegisterThreePid.Msisdn -> {
|
||||||
|
@ -61,8 +60,7 @@ internal class DefaultRegistrationWizard(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val isRegistrationStarted: Boolean
|
override fun isRegistrationStarted() = pendingSessionData.isRegistrationStarted
|
||||||
get() = pendingSessionData.isRegistrationStarted
|
|
||||||
|
|
||||||
override suspend fun getRegistrationFlow(): RegistrationResult {
|
override suspend fun getRegistrationFlow(): RegistrationResult {
|
||||||
val params = RegistrationParams()
|
val params = RegistrationParams()
|
||||||
|
|
|
@ -137,17 +137,11 @@ internal class DefaultKeysBackupService @Inject constructor(
|
||||||
|
|
||||||
private var keysBackupStateListener: KeysBackupStateListener? = null
|
private var keysBackupStateListener: KeysBackupStateListener? = null
|
||||||
|
|
||||||
override val isEnabled: Boolean
|
override fun isEnabled(): Boolean = keysBackupStateManager.isEnabled
|
||||||
get() = keysBackupStateManager.isEnabled
|
|
||||||
|
|
||||||
override val isStucked: Boolean
|
override fun isStuck(): Boolean = keysBackupStateManager.isStuck
|
||||||
get() = keysBackupStateManager.isStucked
|
|
||||||
|
|
||||||
override val state: KeysBackupState
|
override fun getState(): KeysBackupState = keysBackupStateManager.state
|
||||||
get() = keysBackupStateManager.state
|
|
||||||
|
|
||||||
override val currentBackupVersion: String?
|
|
||||||
get() = keysBackupVersion?.version
|
|
||||||
|
|
||||||
override fun addListener(listener: KeysBackupStateListener) {
|
override fun addListener(listener: KeysBackupStateListener) {
|
||||||
keysBackupStateManager.addListener(listener)
|
keysBackupStateManager.addListener(listener)
|
||||||
|
@ -291,7 +285,7 @@ internal class DefaultKeysBackupService @Inject constructor(
|
||||||
this.callback = object : MatrixCallback<Unit> {
|
this.callback = object : MatrixCallback<Unit> {
|
||||||
private fun eventuallyRestartBackup() {
|
private fun eventuallyRestartBackup() {
|
||||||
// Do not stay in KeysBackupState.Unknown but check what is available on the homeserver
|
// Do not stay in KeysBackupState.Unknown but check what is available on the homeserver
|
||||||
if (state == KeysBackupState.Unknown) {
|
if (getState() == KeysBackupState.Unknown) {
|
||||||
checkAndStartKeysBackup()
|
checkAndStartKeysBackup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,7 +341,7 @@ internal class DefaultKeysBackupService @Inject constructor(
|
||||||
|
|
||||||
override fun backupAllGroupSessions(progressListener: ProgressListener?,
|
override fun backupAllGroupSessions(progressListener: ProgressListener?,
|
||||||
callback: MatrixCallback<Unit>?) {
|
callback: MatrixCallback<Unit>?) {
|
||||||
if (!isEnabled || backupOlmPkEncryption == null || keysBackupVersion == null) {
|
if (!isEnabled() || backupOlmPkEncryption == null || keysBackupVersion == null) {
|
||||||
callback?.onFailure(Throwable("Backup not enabled"))
|
callback?.onFailure(Throwable("Backup not enabled"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -383,7 +377,7 @@ internal class DefaultKeysBackupService @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
// If backup is finished, notify the main listener
|
// If backup is finished, notify the main listener
|
||||||
if (state === KeysBackupState.ReadyToBackUp) {
|
if (getState() === KeysBackupState.ReadyToBackUp) {
|
||||||
backupAllGroupSessionsCallback?.onSuccess(Unit)
|
backupAllGroupSessionsCallback?.onSuccess(Unit)
|
||||||
resetBackupAllGroupSessionsListeners()
|
resetBackupAllGroupSessionsListeners()
|
||||||
}
|
}
|
||||||
|
@ -628,7 +622,7 @@ internal class DefaultKeysBackupService @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSecretKeyGossip(secret: String) {
|
fun onSecretKeyGossip(secret: String) {
|
||||||
Timber.i("## CrossSigning - onSecretKeyGossip")
|
Timber.i("## CrossSigning - onSecretKeyGossip")
|
||||||
|
|
||||||
cryptoCoroutineScope.launch(coroutineDispatchers.io) {
|
cryptoCoroutineScope.launch(coroutineDispatchers.io) {
|
||||||
|
@ -915,12 +909,12 @@ internal class DefaultKeysBackupService @Inject constructor(
|
||||||
*/
|
*/
|
||||||
fun maybeBackupKeys() {
|
fun maybeBackupKeys() {
|
||||||
when {
|
when {
|
||||||
isStucked -> {
|
isStuck() -> {
|
||||||
// If not already done, or in error case, check for a valid backup version on the homeserver.
|
// If not already done, or in error case, check for a valid backup version on the homeserver.
|
||||||
// If there is one, maybeBackupKeys will be called again.
|
// If there is one, maybeBackupKeys will be called again.
|
||||||
checkAndStartKeysBackup()
|
checkAndStartKeysBackup()
|
||||||
}
|
}
|
||||||
state == KeysBackupState.ReadyToBackUp -> {
|
getState() == KeysBackupState.ReadyToBackUp -> {
|
||||||
keysBackupStateManager.state = KeysBackupState.WillBackUp
|
keysBackupStateManager.state = KeysBackupState.WillBackUp
|
||||||
|
|
||||||
// Wait between 0 and 10 seconds, to avoid backup requests from
|
// Wait between 0 and 10 seconds, to avoid backup requests from
|
||||||
|
@ -934,7 +928,7 @@ internal class DefaultKeysBackupService @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
Timber.v("maybeBackupKeys: Skip it because state: $state")
|
Timber.v("maybeBackupKeys: Skip it because state: ${getState()}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1018,9 +1012,9 @@ internal class DefaultKeysBackupService @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun checkAndStartKeysBackup() {
|
override fun checkAndStartKeysBackup() {
|
||||||
if (!isStucked) {
|
if (!isStuck()) {
|
||||||
// Try to start or restart the backup only if it is in unknown or bad state
|
// Try to start or restart the backup only if it is in unknown or bad state
|
||||||
Timber.w("checkAndStartKeysBackup: invalid state: $state")
|
Timber.w("checkAndStartKeysBackup: invalid state: ${getState()}")
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1259,16 +1253,16 @@ internal class DefaultKeysBackupService @Inject constructor(
|
||||||
Timber.v("backupKeys")
|
Timber.v("backupKeys")
|
||||||
|
|
||||||
// Sanity check, as this method can be called after a delay, the state may have change during the delay
|
// Sanity check, as this method can be called after a delay, the state may have change during the delay
|
||||||
if (!isEnabled || backupOlmPkEncryption == null || keysBackupVersion == null) {
|
if (!isEnabled() || backupOlmPkEncryption == null || keysBackupVersion == null) {
|
||||||
Timber.v("backupKeys: Invalid configuration")
|
Timber.v("backupKeys: Invalid configuration")
|
||||||
backupAllGroupSessionsCallback?.onFailure(IllegalStateException("Invalid configuration"))
|
backupAllGroupSessionsCallback?.onFailure(IllegalStateException("Invalid configuration"))
|
||||||
resetBackupAllGroupSessionsListeners()
|
resetBackupAllGroupSessionsListeners()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state === KeysBackupState.BackingUp) {
|
if (getState() === KeysBackupState.BackingUp) {
|
||||||
// Do nothing if we are already backing up
|
// Do nothing if we are already backing up
|
||||||
Timber.v("backupKeys: Invalid state: $state")
|
Timber.v("backupKeys: Invalid state: ${getState()}")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ internal class KeysBackupStateManager(private val uiHandler: Handler) {
|
||||||
state == KeysBackupState.BackingUp
|
state == KeysBackupState.BackingUp
|
||||||
|
|
||||||
// True if unknown or bad state
|
// True if unknown or bad state
|
||||||
val isStucked: Boolean
|
val isStuck: Boolean
|
||||||
get() = state == KeysBackupState.Unknown ||
|
get() = state == KeysBackupState.Unknown ||
|
||||||
state == KeysBackupState.Disabled ||
|
state == KeysBackupState.Disabled ||
|
||||||
state == KeysBackupState.WrongBackUpVersion ||
|
state == KeysBackupState.WrongBackUpVersion ||
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.matrix.android.sdk.api.session.securestorage.EncryptedSecretContent
|
||||||
import org.matrix.android.sdk.api.session.securestorage.IntegrityResult
|
import org.matrix.android.sdk.api.session.securestorage.IntegrityResult
|
||||||
import org.matrix.android.sdk.api.session.securestorage.KeyInfo
|
import org.matrix.android.sdk.api.session.securestorage.KeyInfo
|
||||||
import org.matrix.android.sdk.api.session.securestorage.KeyInfoResult
|
import org.matrix.android.sdk.api.session.securestorage.KeyInfoResult
|
||||||
|
import org.matrix.android.sdk.api.session.securestorage.KeyRef
|
||||||
import org.matrix.android.sdk.api.session.securestorage.KeySigner
|
import org.matrix.android.sdk.api.session.securestorage.KeySigner
|
||||||
import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec
|
import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec
|
||||||
import org.matrix.android.sdk.api.session.securestorage.SecretStorageKeyContent
|
import org.matrix.android.sdk.api.session.securestorage.SecretStorageKeyContent
|
||||||
|
@ -157,7 +158,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
|
||||||
return getKey(keyId)
|
return getKey(keyId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun storeSecret(name: String, secretBase64: String, keys: List<SharedSecretStorageService.KeyRef>) {
|
override suspend fun storeSecret(name: String, secretBase64: String, keys: List<KeyRef>) {
|
||||||
withContext(cryptoCoroutineScope.coroutineContext + coroutineDispatchers.computation) {
|
withContext(cryptoCoroutineScope.coroutineContext + coroutineDispatchers.computation) {
|
||||||
val encryptedContents = HashMap<String, EncryptedSecretContent>()
|
val encryptedContents = HashMap<String, EncryptedSecretContent>()
|
||||||
keys.forEach {
|
keys.forEach {
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.session.pushers
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.work.BackoffPolicy
|
import androidx.work.BackoffPolicy
|
||||||
import com.zhuinden.monarchy.Monarchy
|
import com.zhuinden.monarchy.Monarchy
|
||||||
|
import org.matrix.android.sdk.api.session.pushers.HttpPusher
|
||||||
import org.matrix.android.sdk.api.session.pushers.Pusher
|
import org.matrix.android.sdk.api.session.pushers.Pusher
|
||||||
import org.matrix.android.sdk.api.session.pushers.PushersService
|
import org.matrix.android.sdk.api.session.pushers.PushersService
|
||||||
import org.matrix.android.sdk.internal.database.mapper.asDomain
|
import org.matrix.android.sdk.internal.database.mapper.asDomain
|
||||||
|
@ -58,15 +59,15 @@ internal class DefaultPushersService @Inject constructor(
|
||||||
.executeBy(taskExecutor)
|
.executeBy(taskExecutor)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun enqueueAddHttpPusher(httpPusher: PushersService.HttpPusher): UUID {
|
override fun enqueueAddHttpPusher(httpPusher: HttpPusher): UUID {
|
||||||
return enqueueAddPusher(httpPusher.toJsonPusher())
|
return enqueueAddPusher(httpPusher.toJsonPusher())
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun addHttpPusher(httpPusher: PushersService.HttpPusher) {
|
override suspend fun addHttpPusher(httpPusher: HttpPusher) {
|
||||||
addPusherTask.execute(AddPusherTask.Params(httpPusher.toJsonPusher()))
|
addPusherTask.execute(AddPusherTask.Params(httpPusher.toJsonPusher()))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun PushersService.HttpPusher.toJsonPusher() = JsonPusher(
|
private fun HttpPusher.toJsonPusher() = JsonPusher(
|
||||||
pushKey = pushkey,
|
pushKey = pushkey,
|
||||||
kind = "http",
|
kind = "http",
|
||||||
appId = appId,
|
appId = appId,
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("unused")
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.userstories
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ### Title
|
||||||
|
* Init a Matrix object.
|
||||||
|
*
|
||||||
|
* ### Required APIs:
|
||||||
|
* - [org.matrix.android.sdk.api.Matrix] constructor
|
||||||
|
*/
|
||||||
|
class Us000InitMatrix private constructor()
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("unused")
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.userstories
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ### Title
|
||||||
|
* Sign in to an existing account.
|
||||||
|
*
|
||||||
|
* #### Required APIs:
|
||||||
|
* - [org.matrix.android.sdk.api.Matrix.authenticationService]
|
||||||
|
* - [org.matrix.android.sdk.api.auth.AuthenticationService.getLoginFlow]
|
||||||
|
* - [org.matrix.android.sdk.api.auth.AuthenticationService.getLoginWizard]
|
||||||
|
* - [org.matrix.android.sdk.api.auth.login.LoginWizard.login]
|
||||||
|
*/
|
||||||
|
class Us100SignIn private constructor()
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("unused")
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.userstories
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ### Title
|
||||||
|
* Verify a Session after a Sign in.
|
||||||
|
*
|
||||||
|
* #### Required APIs:
|
||||||
|
* - TODO
|
||||||
|
*/
|
||||||
|
class Us150VerifySession private constructor()
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("unused")
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.userstories
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ### Title
|
||||||
|
* Sign out.
|
||||||
|
*
|
||||||
|
* #### Required APIs:
|
||||||
|
* - TODO
|
||||||
|
*/
|
||||||
|
class Us190SignOut private constructor()
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("unused")
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.userstories
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ### Title
|
||||||
|
* Get the Room list.
|
||||||
|
*
|
||||||
|
* #### Required APIs:
|
||||||
|
* - TODO
|
||||||
|
*/
|
||||||
|
class Us200RoomList private constructor()
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("unused")
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.userstories
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ### Title
|
||||||
|
* Display a Room timeline, and navigate backward and forward.
|
||||||
|
*
|
||||||
|
* #### Required APIs:
|
||||||
|
* - TODO
|
||||||
|
*/
|
||||||
|
class Us300RoomTimeline private constructor()
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("unused")
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.userstories
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ### Title
|
||||||
|
* Display a Room timeline at a specific point.
|
||||||
|
*
|
||||||
|
* #### Required APIs:
|
||||||
|
* - TODO
|
||||||
|
*/
|
||||||
|
class Us350RoomTimelineFromPermalink private constructor()
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("unused")
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.userstories
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ### Title
|
||||||
|
* Send content to a room, including monitoring the sending state.
|
||||||
|
*
|
||||||
|
* #### Required APIs:
|
||||||
|
* - TODO
|
||||||
|
*/
|
||||||
|
class Us400RoomSendContent private constructor()
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("unused")
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.userstories
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ### Title
|
||||||
|
* Get notified when new Events are received.
|
||||||
|
*
|
||||||
|
* #### Required APIs:
|
||||||
|
* - TODO
|
||||||
|
*/
|
||||||
|
class Us500Notification private constructor()
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("unused")
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.userstories
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ### Title
|
||||||
|
* Manage the sync with the server.
|
||||||
|
*
|
||||||
|
* #### Required APIs:
|
||||||
|
* - TODO
|
||||||
|
*/
|
||||||
|
class Us600SyncWithTheServer private constructor()
|
|
@ -165,7 +165,7 @@ class SecurityBootstrapTest : VerificationTestBase() {
|
||||||
assert(uiSession.cryptoService().crossSigningService().isCrossSigningInitialized())
|
assert(uiSession.cryptoService().crossSigningService().isCrossSigningInitialized())
|
||||||
assert(uiSession.cryptoService().crossSigningService().canCrossSign())
|
assert(uiSession.cryptoService().crossSigningService().canCrossSign())
|
||||||
assert(uiSession.cryptoService().crossSigningService().allPrivateKeysKnown())
|
assert(uiSession.cryptoService().crossSigningService().allPrivateKeysKnown())
|
||||||
assert(uiSession.cryptoService().keysBackupService().isEnabled)
|
assert(uiSession.cryptoService().keysBackupService().isEnabled())
|
||||||
assert(uiSession.cryptoService().keysBackupService().currentBackupVersion != null)
|
assert(uiSession.cryptoService().keysBackupService().currentBackupVersion != null)
|
||||||
assert(uiSession.sharedSecretStorageService().isRecoverySetup())
|
assert(uiSession.sharedSecretStorageService().isRecoverySetup())
|
||||||
assert(uiSession.sharedSecretStorageService().isMegolmKeyInBackup())
|
assert(uiSession.sharedSecretStorageService().isMegolmKeyInBackup())
|
||||||
|
|
|
@ -66,7 +66,7 @@ fun Session.startSyncing(context: Context) {
|
||||||
*/
|
*/
|
||||||
fun Session.hasUnsavedKeys(): Boolean {
|
fun Session.hasUnsavedKeys(): Boolean {
|
||||||
return cryptoService().inboundGroupSessionsCount(false) > 0 &&
|
return cryptoService().inboundGroupSessionsCount(false) > 0 &&
|
||||||
cryptoService().keysBackupService().state != KeysBackupState.ReadyToBackUp
|
cryptoService().keysBackupService().getState() != KeysBackupState.ReadyToBackUp
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Session.cannotLogoutSafely(): Boolean {
|
fun Session.cannotLogoutSafely(): Boolean {
|
||||||
|
|
|
@ -21,7 +21,7 @@ import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.resources.AppNameProvider
|
import im.vector.app.core.resources.AppNameProvider
|
||||||
import im.vector.app.core.resources.LocaleProvider
|
import im.vector.app.core.resources.LocaleProvider
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import org.matrix.android.sdk.api.session.pushers.PushersService
|
import org.matrix.android.sdk.api.session.pushers.HttpPusher
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
@ -55,7 +55,7 @@ class PushersManager @Inject constructor(
|
||||||
currentSession.pushersService().addHttpPusher(createHttpPusher(pushKey))
|
currentSession.pushersService().addHttpPusher(createHttpPusher(pushKey))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createHttpPusher(pushKey: String) = PushersService.HttpPusher(
|
private fun createHttpPusher(pushKey: String) = HttpPusher(
|
||||||
pushKey,
|
pushKey,
|
||||||
stringProvider.getString(R.string.pusher_app_id),
|
stringProvider.getString(R.string.pusher_app_id),
|
||||||
profileTag = DEFAULT_PUSHER_FILE_TAG + "_" + abs(activeSessionHolder.getActiveSession().myUserId.hashCode()),
|
profileTag = DEFAULT_PUSHER_FILE_TAG + "_" + abs(activeSessionHolder.getActiveSession().myUserId.hashCode()),
|
||||||
|
|
|
@ -60,7 +60,7 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS
|
||||||
init {
|
init {
|
||||||
setState {
|
setState {
|
||||||
this.copy(
|
this.copy(
|
||||||
keysBackupState = keysBackupService.state,
|
keysBackupState = keysBackupService.getState(),
|
||||||
keysBackupVersion = keysBackupService.keysBackupVersion
|
keysBackupVersion = keysBackupService.keysBackupVersion
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -206,7 +206,7 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS
|
||||||
}
|
}
|
||||||
|
|
||||||
fun canExit(): Boolean {
|
fun canExit(): Boolean {
|
||||||
val currentBackupState = keysBackupService.state
|
val currentBackupState = keysBackupService.getState()
|
||||||
|
|
||||||
return currentBackupState == KeysBackupState.Unknown ||
|
return currentBackupState == KeysBackupState.Unknown ||
|
||||||
currentBackupState == KeysBackupState.CheckingBackUpOnHomeserver
|
currentBackupState == KeysBackupState.CheckingBackUpOnHomeserver
|
||||||
|
|
|
@ -41,8 +41,8 @@ import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.securestorage.IntegrityResult
|
import org.matrix.android.sdk.api.session.securestorage.IntegrityResult
|
||||||
import org.matrix.android.sdk.api.session.securestorage.KeyInfo
|
import org.matrix.android.sdk.api.session.securestorage.KeyInfo
|
||||||
import org.matrix.android.sdk.api.session.securestorage.KeyInfoResult
|
import org.matrix.android.sdk.api.session.securestorage.KeyInfoResult
|
||||||
|
import org.matrix.android.sdk.api.session.securestorage.KeyRef
|
||||||
import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec
|
import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec
|
||||||
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService
|
|
||||||
import org.matrix.android.sdk.api.util.toBase64NoPadding
|
import org.matrix.android.sdk.api.util.toBase64NoPadding
|
||||||
import org.matrix.android.sdk.flow.flow
|
import org.matrix.android.sdk.flow.flow
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
@ -283,7 +283,7 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
|
||||||
session.sharedSecretStorageService().storeSecret(
|
session.sharedSecretStorageService().storeSecret(
|
||||||
name = name,
|
name = name,
|
||||||
secretBase64 = value,
|
secretBase64 = value,
|
||||||
keys = listOf(SharedSecretStorageService.KeyRef(keyInfo.id, keySpec))
|
keys = listOf(KeyRef(keyInfo.id, keySpec))
|
||||||
)
|
)
|
||||||
decryptedSecretMap[name] = value
|
decryptedSecretMap[name] = value
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,8 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_S
|
||||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.computeRecoveryKey
|
import org.matrix.android.sdk.api.session.crypto.keysbackup.computeRecoveryKey
|
||||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromRecoveryKey
|
import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromRecoveryKey
|
||||||
import org.matrix.android.sdk.api.session.securestorage.EmptyKeySigner
|
import org.matrix.android.sdk.api.session.securestorage.EmptyKeySigner
|
||||||
|
import org.matrix.android.sdk.api.session.securestorage.KeyRef
|
||||||
import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec
|
import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec
|
||||||
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService
|
|
||||||
import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo
|
import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo
|
||||||
import org.matrix.android.sdk.api.util.awaitCallback
|
import org.matrix.android.sdk.api.util.awaitCallback
|
||||||
import org.matrix.android.sdk.api.util.toBase64NoPadding
|
import org.matrix.android.sdk.api.util.toBase64NoPadding
|
||||||
|
@ -142,7 +142,7 @@ class BackupToQuadSMigrationTask @Inject constructor(
|
||||||
quadS.storeSecret(
|
quadS.storeSecret(
|
||||||
KEYBACKUP_SECRET_SSSS_NAME,
|
KEYBACKUP_SECRET_SSSS_NAME,
|
||||||
curveKey.toBase64NoPadding(),
|
curveKey.toBase64NoPadding(),
|
||||||
listOf(SharedSecretStorageService.KeyRef(info.keyId, info.keySpec))
|
listOf(KeyRef(info.keyId, info.keySpec))
|
||||||
)
|
)
|
||||||
|
|
||||||
// save for gossiping
|
// save for gossiping
|
||||||
|
|
|
@ -34,7 +34,7 @@ import org.matrix.android.sdk.api.session.crypto.keysbackup.MegolmBackupCreation
|
||||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromRecoveryKey
|
import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromRecoveryKey
|
||||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.toKeysVersionResult
|
import org.matrix.android.sdk.api.session.crypto.keysbackup.toKeysVersionResult
|
||||||
import org.matrix.android.sdk.api.session.securestorage.EmptyKeySigner
|
import org.matrix.android.sdk.api.session.securestorage.EmptyKeySigner
|
||||||
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService
|
import org.matrix.android.sdk.api.session.securestorage.KeyRef
|
||||||
import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo
|
import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo
|
||||||
import org.matrix.android.sdk.api.session.securestorage.SsssKeySpec
|
import org.matrix.android.sdk.api.session.securestorage.SsssKeySpec
|
||||||
import org.matrix.android.sdk.api.util.awaitCallback
|
import org.matrix.android.sdk.api.util.awaitCallback
|
||||||
|
@ -183,7 +183,7 @@ class BootstrapCrossSigningTask @Inject constructor(
|
||||||
ssssService.storeSecret(
|
ssssService.storeSecret(
|
||||||
MASTER_KEY_SSSS_NAME,
|
MASTER_KEY_SSSS_NAME,
|
||||||
mskPrivateKey,
|
mskPrivateKey,
|
||||||
listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec))
|
listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec))
|
||||||
)
|
)
|
||||||
params.progressListener?.onProgress(
|
params.progressListener?.onProgress(
|
||||||
WaitingViewData(
|
WaitingViewData(
|
||||||
|
@ -195,7 +195,7 @@ class BootstrapCrossSigningTask @Inject constructor(
|
||||||
ssssService.storeSecret(
|
ssssService.storeSecret(
|
||||||
USER_SIGNING_KEY_SSSS_NAME,
|
USER_SIGNING_KEY_SSSS_NAME,
|
||||||
uskPrivateKey,
|
uskPrivateKey,
|
||||||
listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec))
|
listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec))
|
||||||
)
|
)
|
||||||
params.progressListener?.onProgress(
|
params.progressListener?.onProgress(
|
||||||
WaitingViewData(
|
WaitingViewData(
|
||||||
|
@ -206,7 +206,7 @@ class BootstrapCrossSigningTask @Inject constructor(
|
||||||
ssssService.storeSecret(
|
ssssService.storeSecret(
|
||||||
SELF_SIGNING_KEY_SSSS_NAME,
|
SELF_SIGNING_KEY_SSSS_NAME,
|
||||||
sskPrivateKey,
|
sskPrivateKey,
|
||||||
listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec))
|
listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec))
|
||||||
)
|
)
|
||||||
} catch (failure: Failure) {
|
} catch (failure: Failure) {
|
||||||
Timber.e("## BootstrapCrossSigningTask: Creating 4S - Failed to store keys <${failure.localizedMessage}>")
|
Timber.e("## BootstrapCrossSigningTask: Creating 4S - Failed to store keys <${failure.localizedMessage}>")
|
||||||
|
@ -258,7 +258,7 @@ class BootstrapCrossSigningTask @Inject constructor(
|
||||||
ssssService.storeSecret(
|
ssssService.storeSecret(
|
||||||
KEYBACKUP_SECRET_SSSS_NAME,
|
KEYBACKUP_SECRET_SSSS_NAME,
|
||||||
secret,
|
secret,
|
||||||
listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec))
|
listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -275,7 +275,7 @@ class BootstrapCrossSigningTask @Inject constructor(
|
||||||
ssssService.storeSecret(
|
ssssService.storeSecret(
|
||||||
KEYBACKUP_SECRET_SSSS_NAME,
|
KEYBACKUP_SECRET_SSSS_NAME,
|
||||||
secret,
|
secret,
|
||||||
listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec))
|
listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -401,8 +401,8 @@ class MessageActionsViewModel @AssistedInject constructor(
|
||||||
if (vectorPreferences.developerMode()) {
|
if (vectorPreferences.developerMode()) {
|
||||||
if (timelineEvent.isEncrypted() && timelineEvent.root.mCryptoError != null) {
|
if (timelineEvent.isEncrypted() && timelineEvent.root.mCryptoError != null) {
|
||||||
val keysBackupService = session.cryptoService().keysBackupService()
|
val keysBackupService = session.cryptoService().keysBackupService()
|
||||||
if (keysBackupService.state == KeysBackupState.NotTrusted ||
|
if (keysBackupService.getState() == KeysBackupState.NotTrusted ||
|
||||||
(keysBackupService.state == KeysBackupState.ReadyToBackUp &&
|
(keysBackupService.getState() == KeysBackupState.ReadyToBackUp &&
|
||||||
keysBackupService.canRestoreKeys())
|
keysBackupService.canRestoreKeys())
|
||||||
) {
|
) {
|
||||||
add(EventSharedAction.UseKeyBackup)
|
add(EventSharedAction.UseKeyBackup)
|
||||||
|
|
|
@ -91,11 +91,11 @@ class LoginViewModel @AssistedInject constructor(
|
||||||
private val matrixOrgUrl = stringProvider.getString(R.string.matrix_org_server_url).ensureTrailingSlash()
|
private val matrixOrgUrl = stringProvider.getString(R.string.matrix_org_server_url).ensureTrailingSlash()
|
||||||
|
|
||||||
val currentThreePid: String?
|
val currentThreePid: String?
|
||||||
get() = registrationWizard?.currentThreePid
|
get() = registrationWizard?.getCurrentThreePid()
|
||||||
|
|
||||||
// True when login and password has been sent with success to the homeserver
|
// True when login and password has been sent with success to the homeserver
|
||||||
val isRegistrationStarted: Boolean
|
val isRegistrationStarted: Boolean
|
||||||
get() = authenticationService.isRegistrationStarted
|
get() = authenticationService.isRegistrationStarted()
|
||||||
|
|
||||||
private val registrationWizard: RegistrationWizard?
|
private val registrationWizard: RegistrationWizard?
|
||||||
get() = authenticationService.getRegistrationWizard()
|
get() = authenticationService.getRegistrationWizard()
|
||||||
|
@ -455,7 +455,7 @@ class LoginViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
// If there is a pending email validation continue on this step
|
// If there is a pending email validation continue on this step
|
||||||
try {
|
try {
|
||||||
if (registrationWizard?.isRegistrationStarted == true) {
|
if (registrationWizard?.isRegistrationStarted() == true) {
|
||||||
currentThreePid?.let {
|
currentThreePid?.let {
|
||||||
handle(LoginAction.PostViewEvent(LoginViewEvents.OnSendEmailSuccess(it)))
|
handle(LoginAction.PostViewEvent(LoginViewEvents.OnSendEmailSuccess(it)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,11 +92,11 @@ class LoginViewModel2 @AssistedInject constructor(
|
||||||
private val matrixOrgUrl = stringProvider.getString(R.string.matrix_org_server_url).ensureTrailingSlash()
|
private val matrixOrgUrl = stringProvider.getString(R.string.matrix_org_server_url).ensureTrailingSlash()
|
||||||
|
|
||||||
val currentThreePid: String?
|
val currentThreePid: String?
|
||||||
get() = registrationWizard?.currentThreePid
|
get() = registrationWizard?.getCurrentThreePid()
|
||||||
|
|
||||||
// True when login and password has been sent with success to the homeserver
|
// True when login and password has been sent with success to the homeserver
|
||||||
val isRegistrationStarted: Boolean
|
val isRegistrationStarted: Boolean
|
||||||
get() = authenticationService.isRegistrationStarted
|
get() = authenticationService.isRegistrationStarted()
|
||||||
|
|
||||||
private val registrationWizard: RegistrationWizard?
|
private val registrationWizard: RegistrationWizard?
|
||||||
get() = authenticationService.getRegistrationWizard()
|
get() = authenticationService.getRegistrationWizard()
|
||||||
|
@ -420,7 +420,7 @@ class LoginViewModel2 @AssistedInject constructor(
|
||||||
|
|
||||||
// If there is a pending email validation continue on this step
|
// If there is a pending email validation continue on this step
|
||||||
try {
|
try {
|
||||||
if (registrationWizard?.isRegistrationStarted == true) {
|
if (registrationWizard?.isRegistrationStarted() == true) {
|
||||||
currentThreePid?.let {
|
currentThreePid?.let {
|
||||||
handle(LoginAction2.PostViewEvent(LoginViewEvents2.OnSendEmailSuccess(it)))
|
handle(LoginAction2.PostViewEvent(LoginViewEvents2.OnSendEmailSuccess(it)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,11 +116,11 @@ class OnboardingViewModel @AssistedInject constructor(
|
||||||
get() = authenticationService.getRegistrationWizard()
|
get() = authenticationService.getRegistrationWizard()
|
||||||
|
|
||||||
val currentThreePid: String?
|
val currentThreePid: String?
|
||||||
get() = registrationWizard.currentThreePid
|
get() = registrationWizard.getCurrentThreePid()
|
||||||
|
|
||||||
// True when login and password has been sent with success to the homeserver
|
// True when login and password has been sent with success to the homeserver
|
||||||
val isRegistrationStarted: Boolean
|
val isRegistrationStarted: Boolean
|
||||||
get() = authenticationService.isRegistrationStarted
|
get() = authenticationService.isRegistrationStarted()
|
||||||
|
|
||||||
private val loginWizard: LoginWizard?
|
private val loginWizard: LoginWizard?
|
||||||
get() = authenticationService.getLoginWizard()
|
get() = authenticationService.getLoginWizard()
|
||||||
|
@ -425,7 +425,7 @@ class OnboardingViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
// If there is a pending email validation continue on this step
|
// If there is a pending email validation continue on this step
|
||||||
try {
|
try {
|
||||||
if (registrationWizard.isRegistrationStarted) {
|
if (registrationWizard.isRegistrationStarted()) {
|
||||||
currentThreePid?.let {
|
currentThreePid?.let {
|
||||||
handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnSendEmailSuccess(it)))
|
handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnSendEmailSuccess(it)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS
|
||||||
|
|
||||||
init {
|
init {
|
||||||
session.cryptoService().keysBackupService().addListener(this)
|
session.cryptoService().keysBackupService().addListener(this)
|
||||||
keysBackupState.value = session.cryptoService().keysBackupService().state
|
keysBackupState.value = session.cryptoService().keysBackupService().getState()
|
||||||
val liveUserAccountData = session.flow().liveUserAccountData(setOf(MASTER_KEY_SSSS_NAME, USER_SIGNING_KEY_SSSS_NAME, SELF_SIGNING_KEY_SSSS_NAME))
|
val liveUserAccountData = session.flow().liveUserAccountData(setOf(MASTER_KEY_SSSS_NAME, USER_SIGNING_KEY_SSSS_NAME, SELF_SIGNING_KEY_SSSS_NAME))
|
||||||
val liveCrossSigningInfo = session.flow().liveCrossSigningInfo(session.myUserId)
|
val liveCrossSigningInfo = session.flow().liveCrossSigningInfo(session.myUserId)
|
||||||
val liveCrossSigningPrivateKeys = session.flow().liveCrossSigningPrivateKeys()
|
val liveCrossSigningPrivateKeys = session.flow().liveCrossSigningPrivateKeys()
|
||||||
|
@ -116,7 +116,7 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
keyBackupFlow.tryEmit(session.cryptoService().keysBackupService().state)
|
keyBackupFlow.tryEmit(session.cryptoService().keysBackupService().getState())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS
|
||||||
|
|
||||||
override fun onStateChange(newState: KeysBackupState) {
|
override fun onStateChange(newState: KeysBackupState) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
keyBackupFlow.tryEmit(session.cryptoService().keysBackupService().state)
|
keyBackupFlow.tryEmit(session.cryptoService().keysBackupService().getState())
|
||||||
}
|
}
|
||||||
keysBackupState.value = newState
|
keysBackupState.value = newState
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ class SignoutCheckViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
val quad4SIsSetup = session.sharedSecretStorageService().isRecoverySetup()
|
val quad4SIsSetup = session.sharedSecretStorageService().isRecoverySetup()
|
||||||
val allKeysKnown = session.cryptoService().crossSigningService().allPrivateKeysKnown()
|
val allKeysKnown = session.cryptoService().crossSigningService().allPrivateKeysKnown()
|
||||||
val backupState = session.cryptoService().keysBackupService().state
|
val backupState = session.cryptoService().keysBackupService().getState()
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
userId = session.myUserId,
|
userId = session.myUserId,
|
||||||
|
|
|
@ -33,7 +33,7 @@ class FakeAuthenticationService : AuthenticationService by mockk() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun givenRegistrationStarted(started: Boolean) {
|
fun givenRegistrationStarted(started: Boolean) {
|
||||||
every { isRegistrationStarted } returns started
|
every { isRegistrationStarted() } returns started
|
||||||
}
|
}
|
||||||
|
|
||||||
fun givenLoginFlow(config: HomeServerConnectionConfig, result: LoginFlowResult) {
|
fun givenLoginFlow(config: HomeServerConnectionConfig, result: LoginFlowResult) {
|
||||||
|
|
|
@ -19,6 +19,7 @@ package im.vector.app.test.fakes
|
||||||
import org.matrix.android.sdk.api.listeners.ProgressListener
|
import org.matrix.android.sdk.api.listeners.ProgressListener
|
||||||
import org.matrix.android.sdk.api.session.securestorage.IntegrityResult
|
import org.matrix.android.sdk.api.session.securestorage.IntegrityResult
|
||||||
import org.matrix.android.sdk.api.session.securestorage.KeyInfoResult
|
import org.matrix.android.sdk.api.session.securestorage.KeyInfoResult
|
||||||
|
import org.matrix.android.sdk.api.session.securestorage.KeyRef
|
||||||
import org.matrix.android.sdk.api.session.securestorage.KeySigner
|
import org.matrix.android.sdk.api.session.securestorage.KeySigner
|
||||||
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageError
|
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageError
|
||||||
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService
|
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService
|
||||||
|
@ -56,7 +57,7 @@ class FakeSharedSecretStorageService : SharedSecretStorageService {
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun storeSecret(name: String, secretBase64: String, keys: List<SharedSecretStorageService.KeyRef>) {
|
override suspend fun storeSecret(name: String, secretBase64: String, keys: List<KeyRef>) {
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue