Merge pull request #5952 from vector-im/feature/bma/sdk_user_story

Sdk user story
This commit is contained in:
Benoit Marty 2022-05-30 18:30:56 +02:00 committed by GitHub
commit ae94f45f34
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
54 changed files with 667 additions and 241 deletions

4
changelog.d/5952.sdk Normal file
View 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

View file

@ -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.

View file

@ -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))
) )
} }
} }

View file

@ -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)
} }

View file

@ -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
} }

View file

@ -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)))
) )
} }

View file

@ -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.

View file

@ -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>
) )

View file

@ -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
} }

View file

@ -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)
} }

View file

@ -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()
} }

View file

@ -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()))

View file

@ -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?)

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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()
} }

View file

@ -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
)

View file

@ -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
)
} }

View file

@ -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 {

View file

@ -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?
)

View file

@ -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?
)
} }

View file

@ -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;
} }

View file

@ -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

View file

@ -49,20 +49,18 @@ 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 -> { // Take formatted msisdn if provided by the server
// Take formatted msisdn if provided by the server pendingSessionData.currentThreePidData?.addThreePidRegistrationResponse?.formattedMsisdn?.takeIf { it.isNotBlank() } ?: threePid.msisdn
pendingSessionData.currentThreePidData?.addThreePidRegistrationResponse?.formattedMsisdn?.takeIf { it.isNotBlank() } ?: threePid.msisdn
}
null -> null
} }
null -> null
} }
}
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()

View file

@ -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
@ -933,8 +927,8 @@ internal class DefaultKeysBackupService @Inject constructor(
uiHandler.post { backupKeys() } uiHandler.post { backupKeys() }
} }
} }
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
} }

View file

@ -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 ||

View file

@ -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 {

View file

@ -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,

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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())

View file

@ -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 {

View file

@ -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()),

View file

@ -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

View file

@ -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
} }

View file

@ -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

View file

@ -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 {

View file

@ -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)

View file

@ -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)))
} }

View file

@ -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)))
} }

View file

@ -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)))
} }

View file

@ -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
} }

View file

@ -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,

View file

@ -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) {

View file

@ -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")
} }