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
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.roomSummaryQueryParams
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.awaitCallback
import org.matrix.android.sdk.api.util.toBase64NoPadding
@ -361,19 +361,19 @@ class CryptoTestHelper(val testHelper: CommonTestHelper) {
ssssService.storeSecret(
MASTER_KEY_SSSS_NAME,
session.cryptoService().crossSigningService().getCrossSigningPrivateKeys()!!.master!!,
listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec))
listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec))
)
ssssService.storeSecret(
SELF_SIGNING_KEY_SSSS_NAME,
session.cryptoService().crossSigningService().getCrossSigningPrivateKeys()!!.selfSigned!!,
listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec))
listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec))
)
ssssService.storeSecret(
USER_SIGNING_KEY_SSSS_NAME,
session.cryptoService().crossSigningService().getCrossSigningPrivateKeys()!!.user!!,
listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec))
listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec))
)
// set up megolm backup
@ -390,7 +390,7 @@ class CryptoTestHelper(val testHelper: CommonTestHelper) {
ssssService.storeSecret(
KEYBACKUP_SECRET_SSSS_NAME,
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)
assertFalse(keysBackup.isEnabled)
assertFalse(keysBackup.isEnabled())
val megolmBackupCreationInfo = testHelper.doSync<MegolmBackupCreationInfo> {
keysBackup.prepareKeysBackupVersion(null, null, it)
@ -141,13 +141,13 @@ class KeysBackupTest : InstrumentedTest {
val stateObserver = StateObserver(keysBackup)
assertFalse(keysBackup.isEnabled)
assertFalse(keysBackup.isEnabled())
val megolmBackupCreationInfo = testHelper.doSync<MegolmBackupCreationInfo> {
keysBackup.prepareKeysBackupVersion(null, null, it)
}
assertFalse(keysBackup.isEnabled)
assertFalse(keysBackup.isEnabled())
// Create the version
val version = testHelper.doSync<KeysVersion> {
@ -155,7 +155,7 @@ class KeysBackupTest : InstrumentedTest {
}
// Backup must be enable now
assertTrue(keysBackup.isEnabled)
assertTrue(keysBackup.isEnabled())
// Check that it's signed with MSK
val versionResult = testHelper.doSync<KeysVersionResult?> {
@ -425,8 +425,8 @@ class KeysBackupTest : InstrumentedTest {
// - The new device must see the previous backup as not trusted
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled())
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState())
// - Trust the backup from the new device
testHelper.doSync<Unit> {
@ -442,7 +442,7 @@ class KeysBackupTest : InstrumentedTest {
// - Backup must be enabled on the new device, on the same 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
val keysVersionResult = testHelper.doSync<KeysBackupLastVersionResult> {
@ -485,8 +485,8 @@ class KeysBackupTest : InstrumentedTest {
// - The new device must see the previous backup as not trusted
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled())
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState())
// - Trust the backup from the new device with the recovery key
testHelper.doSync<Unit> {
@ -502,7 +502,7 @@ class KeysBackupTest : InstrumentedTest {
// - Backup must be enabled on the new device, on the same 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
val keysVersionResult = testHelper.doSync<KeysBackupLastVersionResult> {
@ -543,8 +543,8 @@ class KeysBackupTest : InstrumentedTest {
// - The new device must see the previous backup as not trusted
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled())
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState())
// - Try to trust the backup from the new device with a wrong recovery key
val latch = CountDownLatch(1)
@ -557,8 +557,8 @@ class KeysBackupTest : InstrumentedTest {
// - The new device must still see the previous backup as not trusted
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled())
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState())
stateObserver.stopAndCheckStates(null)
}
@ -587,8 +587,8 @@ class KeysBackupTest : InstrumentedTest {
// - The new device must see the previous backup as not trusted
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled())
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState())
// - Trust the backup from the new device with the password
testHelper.doSync<Unit> {
@ -604,7 +604,7 @@ class KeysBackupTest : InstrumentedTest {
// - Backup must be enabled on the new device, on the same 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
val keysVersionResult = testHelper.doSync<KeysBackupLastVersionResult> {
@ -648,8 +648,8 @@ class KeysBackupTest : InstrumentedTest {
// - The new device must see the previous backup as not trusted
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled())
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState())
// - Try to trust the backup from the new device with a wrong password
val latch = CountDownLatch(1)
@ -662,8 +662,8 @@ class KeysBackupTest : InstrumentedTest {
// - The new device must still see the previous backup as not trusted
assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion)
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled)
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state)
assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled())
assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState())
stateObserver.stopAndCheckStates(null)
}
@ -915,7 +915,7 @@ class KeysBackupTest : InstrumentedTest {
val stateObserver = StateObserver(keysBackup)
assertFalse(keysBackup.isEnabled)
assertFalse(keysBackup.isEnabled())
// Wait for keys backup to be finished
val latch0 = CountDownLatch(1)
@ -939,7 +939,7 @@ class KeysBackupTest : InstrumentedTest {
// - Make alice back up her keys to her homeserver
keysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup)
assertTrue(keysBackup.isEnabled)
assertTrue(keysBackup.isEnabled())
testHelper.await(latch0)
@ -958,8 +958,8 @@ class KeysBackupTest : InstrumentedTest {
testHelper.await(latch2)
// -> That must fail and her backup state must be WrongBackUpVersion
assertEquals(KeysBackupState.WrongBackUpVersion, keysBackup.state)
assertFalse(keysBackup.isEnabled)
assertEquals(KeysBackupState.WrongBackUpVersion, keysBackup.getState())
assertFalse(keysBackup.isEnabled())
stateObserver.stopAndCheckStates(null)
}
@ -1012,7 +1012,7 @@ class KeysBackupTest : InstrumentedTest {
// - Try to backup all in aliceSession2, it must fail
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)
@ -1031,8 +1031,8 @@ class KeysBackupTest : InstrumentedTest {
assertFalse(isSuccessful)
// Backup state must be NotTrusted
assertEquals("Backup state must be NotTrusted", KeysBackupState.NotTrusted, keysBackup2.state)
assertFalse("Backup should not be enabled", keysBackup2.isEnabled)
assertEquals("Backup state must be NotTrusted", KeysBackupState.NotTrusted, keysBackup2.getState())
assertFalse("Backup should not be enabled", keysBackup2.isEnabled())
// - Validate the old device from the new one
aliceSession2.cryptoService().setDeviceVerification(
@ -1046,7 +1046,7 @@ class KeysBackupTest : InstrumentedTest {
keysBackup2.addListener(object : KeysBackupStateListener {
override fun onStateChange(newState: KeysBackupState) {
// Check the backup completes
if (keysBackup2.state == KeysBackupState.ReadyToBackUp) {
if (keysBackup2.getState() == KeysBackupState.ReadyToBackUp) {
// Remove itself from the list of listeners
keysBackup2.removeListener(this)
@ -1064,7 +1064,7 @@ class KeysBackupTest : InstrumentedTest {
}
// -> It must success
assertTrue(aliceSession2.cryptoService().keysBackupService().isEnabled)
assertTrue(aliceSession2.cryptoService().keysBackupService().isEnabled())
stateObserver.stopAndCheckStates(null)
stateObserver2.stopAndCheckStates(null)
@ -1085,17 +1085,17 @@ class KeysBackupTest : InstrumentedTest {
val stateObserver = StateObserver(keysBackup)
assertFalse(keysBackup.isEnabled)
assertFalse(keysBackup.isEnabled())
val keyBackupCreationInfo = keysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup)
assertTrue(keysBackup.isEnabled)
assertTrue(keysBackup.isEnabled())
// Delete the backup
testHelper.doSync<Unit> { keysBackup.deleteBackup(keyBackupCreationInfo.version, it) }
// Backup is now disabled
assertFalse(keysBackup.isEnabled)
assertFalse(keysBackup.isEnabled())
stateObserver.stopAndCheckStates(null)
}

View file

@ -106,7 +106,7 @@ internal class KeysBackupTestHelper(
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
val keysVersion = testHelper.doSync<KeysVersion> {
@ -116,7 +116,7 @@ internal class KeysBackupTestHelper(
Assert.assertNotNull("Key backup version should not be null", keysVersion.version)
// Backup must be enable now
Assert.assertTrue(keysBackup.isEnabled)
Assert.assertTrue(keysBackup.isEnabled())
stateObserver.stopAndCheckStates(null)
return PrepareKeysBackupDataResult(megolmBackupCreationInfo, keysVersion.version)
@ -128,7 +128,7 @@ internal class KeysBackupTestHelper(
*/
fun waitForKeysBackupToBeInState(session: Session, state: KeysBackupState) {
// If already in the wanted state, return
if (session.cryptoService().keysBackupService().state == state) {
if (session.cryptoService().keysBackupService().getState() == state) {
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.accountdata.UserAccountDataEvent
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.RawBytesKeySpec
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.SharedSecretStorageService
import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo
import org.matrix.android.sdk.api.util.Optional
import org.matrix.android.sdk.api.util.toBase64NoPadding
@ -122,7 +122,7 @@ class QuadSTests : InstrumentedTest {
aliceSession.sharedSecretStorageService().storeSecret(
"secret.of.life",
clearSecret,
listOf(SharedSecretStorageService.KeyRef(null, keySpec)) // default key
listOf(KeyRef(null, keySpec)) // default key
)
}
@ -185,8 +185,8 @@ class QuadSTests : InstrumentedTest {
"my.secret",
mySecretText.toByteArray().toBase64NoPadding(),
listOf(
SharedSecretStorageService.KeyRef(keyId1, RawBytesKeySpec.fromRecoveryKey(key1Info.recoveryKey)),
SharedSecretStorageService.KeyRef(keyId2, RawBytesKeySpec.fromRecoveryKey(key2Info.recoveryKey))
KeyRef(keyId1, RawBytesKeySpec.fromRecoveryKey(key1Info.recoveryKey)),
KeyRef(keyId2, RawBytesKeySpec.fromRecoveryKey(key2Info.recoveryKey))
)
)
}
@ -232,7 +232,7 @@ class QuadSTests : InstrumentedTest {
aliceSession.sharedSecretStorageService().storeSecret(
"my.secret",
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.
*/
val isRegistrationStarted: Boolean
fun isRegistrationStarted(): Boolean
/**
* 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
// 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 {
/**
* The registration is successful, the [Session] is provided.
*/
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()
}
/**
* Information about the missing and completed [Stage].
*/
data class FlowResult(
/**
* List of missing stages.
*/
val missingStages: List<Stage>,
/**
* List of completed stages.
*/
val completedStages: List<Stage>
)

View file

@ -109,14 +109,14 @@ interface RegistrationWizard {
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
*/
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.
*/
val isRegistrationStarted: Boolean
fun isRegistrationStarted(): Boolean
}

View file

@ -16,25 +16,40 @@
package org.matrix.android.sdk.api.auth.registration
/**
* Registration stages.
*/
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)
// m.login.email.identity
/**
* m.login.email.identity stage.
*/
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)
// 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)
// Undocumented yet: m.login.terms
/**
* Undocumented yet: m.login.terms stage.
*/
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)
}

View file

@ -17,13 +17,19 @@
package org.matrix.android.sdk.api.cache
sealed class CacheStrategy {
// Data is always fetched from the server
/**
* Data is always fetched from the server.
*/
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()
// 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()
}

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()))
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 RegistrationFlowError(val registrationFlowResponse: RegistrationFlowResponse) : Failure(RuntimeException(registrationFlowResponse.toString()))

View file

@ -168,8 +168,6 @@ interface KeysBackupService {
password: String,
callback: MatrixCallback<Unit>)
fun onSecretKeyGossip(secret: String)
/**
* 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>)
val keysBackupVersion: KeysVersionResult?
val currentBackupVersion: String?
val isEnabled: Boolean
val isStucked: Boolean
val state: KeysBackupState
get() = keysBackupVersion?.version
fun isEnabled(): Boolean
fun isStuck(): Boolean
fun getState(): KeysBackupState
// For gossiping
fun saveBackupRecoveryKey(recoveryKey: String?, version: String?)

View file

@ -51,33 +51,51 @@ package org.matrix.android.sdk.api.session.crypto.keysbackup
* </pre>
*/
enum class KeysBackupState {
// Need to check the current backup version on the homeserver
/**
* Need to check the current backup version on the homeserver.
*/
Unknown,
// Checking if backup is enabled on homeserver
/**
* Checking if backup is enabled on homeserver.
*/
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,
// Backup from this device is not enabled
/**
* Backup from this device is not enabled.
*/
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
// Use [KeysBackup.getKeysBackupTrust()] to get trust details.
// Consequently, the backup from this device is not enabled.
/**
* 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.
* Use [KeysBackup.getKeysBackupTrust()] to get trust details.
* Consequently, the backup from this device is not enabled.
*/
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,
// Backup is enabled and ready to send backup to the homeserver
/**
* Backup is enabled and ready to send backup to the homeserver.
*/
ReadyToBackUp,
// e2e keys are going to be sent to the homeserver
/**
* e2e keys are going to be sent to the homeserver.
*/
WillBackUp,
// e2e keys are being sent to the homeserver
/**
* e2e keys are being sent to the homeserver.
*/
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.
*/
enum class RoomEncryptionTrustLevel {
// No one in the room has been verified -> Black shield
/**
* No one in the room has been verified -> Black shield.
*/
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,
// 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,
// e2e is active but with an unsupported algorithm
/**
* e2e is active but with an unsupported algorithm.
*/
E2EWithUnsupportedAlgorithm
}

View file

@ -20,12 +20,18 @@ package org.matrix.android.sdk.api.session.crypto.verification
* Verification methods.
*/
enum class VerificationMethod {
// Use it when your application supports the SAS verification method
/**
* Use it when your application supports the SAS verification method.
*/
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,
// 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
}

View file

@ -17,10 +17,14 @@
package org.matrix.android.sdk.api.session.crypto.verification
sealed class VerificationTxState {
// Uninitialized state
/**
* Uninitialized state.
*/
object None : VerificationTxState()
// Specific for SAS
/**
* Specific for SAS.
*/
abstract class VerificationSasTxState : VerificationTxState()
object SendingStart : VerificationSasTxState()
@ -38,18 +42,26 @@ sealed class VerificationTxState {
object MacSent : VerificationSasTxState()
object Verifying : VerificationSasTxState()
// Specific for QR code
/**
* Specific for QR code.
*/
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 WaitingOtherReciprocateConfirm : VerificationQrTxState()
// Terminal states
/**
* Terminal states.
*/
abstract class TerminalTxState : VerificationTxState()
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()
}

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.
*/
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
enum class SendState {
/**
* The state is unknown.
*/
UNKNOWN,
// the event has not been sent
/**
* The event has not been sent.
*/
UNSENT,
// the event is encrypting
/**
* The event is encrypting.
*/
ENCRYPTING,
// the event is currently sending
/**
* The event is currently sending.
*/
SENDING,
// the event has been sent
/**
* The event has been sent.
*/
SENT,
// the event has been received from server
/**
* The event has been received from server.
*/
SYNCED,
// The event failed to be sent
/**
* The event failed to be sent.
*/
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;
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
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.
*/
enum class ThreadNotificationState {
// There are no new message
/**
* There are no new message.
*/
NO_NEW_MESSAGE,
// There is at least one new message
/**
* There is at least one 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;
}

View file

@ -323,8 +323,7 @@ internal class DefaultAuthenticationService @Inject constructor(
}
}
override val isRegistrationStarted: Boolean
get() = currentRegistrationWizard?.isRegistrationStarted == true
override fun isRegistrationStarted() = currentRegistrationWizard?.isRegistrationStarted() == true
override fun getLoginWizard(): LoginWizard {
return currentLoginWizard

View file

@ -49,20 +49,18 @@ internal class DefaultRegistrationWizard(
private val validateCodeTask: ValidateCodeTask = DefaultValidateCodeTask(authAPI)
private val registerCustomTask: RegisterCustomTask = DefaultRegisterCustomTask(authAPI)
override val currentThreePid: String?
get() {
return when (val threePid = pendingSessionData.currentThreePidData?.threePid) {
is RegisterThreePid.Email -> threePid.email
is RegisterThreePid.Msisdn -> {
// Take formatted msisdn if provided by the server
pendingSessionData.currentThreePidData?.addThreePidRegistrationResponse?.formattedMsisdn?.takeIf { it.isNotBlank() } ?: threePid.msisdn
}
null -> null
override fun getCurrentThreePid(): String? {
return when (val threePid = pendingSessionData.currentThreePidData?.threePid) {
is RegisterThreePid.Email -> threePid.email
is RegisterThreePid.Msisdn -> {
// Take formatted msisdn if provided by the server
pendingSessionData.currentThreePidData?.addThreePidRegistrationResponse?.formattedMsisdn?.takeIf { it.isNotBlank() } ?: threePid.msisdn
}
null -> null
}
}
override val isRegistrationStarted: Boolean
get() = pendingSessionData.isRegistrationStarted
override fun isRegistrationStarted() = pendingSessionData.isRegistrationStarted
override suspend fun getRegistrationFlow(): RegistrationResult {
val params = RegistrationParams()

View file

@ -137,17 +137,11 @@ internal class DefaultKeysBackupService @Inject constructor(
private var keysBackupStateListener: KeysBackupStateListener? = null
override val isEnabled: Boolean
get() = keysBackupStateManager.isEnabled
override fun isEnabled(): Boolean = keysBackupStateManager.isEnabled
override val isStucked: Boolean
get() = keysBackupStateManager.isStucked
override fun isStuck(): Boolean = keysBackupStateManager.isStuck
override val state: KeysBackupState
get() = keysBackupStateManager.state
override val currentBackupVersion: String?
get() = keysBackupVersion?.version
override fun getState(): KeysBackupState = keysBackupStateManager.state
override fun addListener(listener: KeysBackupStateListener) {
keysBackupStateManager.addListener(listener)
@ -291,7 +285,7 @@ internal class DefaultKeysBackupService @Inject constructor(
this.callback = object : MatrixCallback<Unit> {
private fun eventuallyRestartBackup() {
// Do not stay in KeysBackupState.Unknown but check what is available on the homeserver
if (state == KeysBackupState.Unknown) {
if (getState() == KeysBackupState.Unknown) {
checkAndStartKeysBackup()
}
}
@ -347,7 +341,7 @@ internal class DefaultKeysBackupService @Inject constructor(
override fun backupAllGroupSessions(progressListener: ProgressListener?,
callback: MatrixCallback<Unit>?) {
if (!isEnabled || backupOlmPkEncryption == null || keysBackupVersion == null) {
if (!isEnabled() || backupOlmPkEncryption == null || keysBackupVersion == null) {
callback?.onFailure(Throwable("Backup not enabled"))
return
}
@ -383,7 +377,7 @@ internal class DefaultKeysBackupService @Inject constructor(
}
// If backup is finished, notify the main listener
if (state === KeysBackupState.ReadyToBackUp) {
if (getState() === KeysBackupState.ReadyToBackUp) {
backupAllGroupSessionsCallback?.onSuccess(Unit)
resetBackupAllGroupSessionsListeners()
}
@ -628,7 +622,7 @@ internal class DefaultKeysBackupService @Inject constructor(
}
}
override fun onSecretKeyGossip(secret: String) {
fun onSecretKeyGossip(secret: String) {
Timber.i("## CrossSigning - onSecretKeyGossip")
cryptoCoroutineScope.launch(coroutineDispatchers.io) {
@ -915,12 +909,12 @@ internal class DefaultKeysBackupService @Inject constructor(
*/
fun maybeBackupKeys() {
when {
isStucked -> {
isStuck() -> {
// 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.
checkAndStartKeysBackup()
}
state == KeysBackupState.ReadyToBackUp -> {
getState() == KeysBackupState.ReadyToBackUp -> {
keysBackupStateManager.state = KeysBackupState.WillBackUp
// Wait between 0 and 10 seconds, to avoid backup requests from
@ -933,8 +927,8 @@ internal class DefaultKeysBackupService @Inject constructor(
uiHandler.post { backupKeys() }
}
}
else -> {
Timber.v("maybeBackupKeys: Skip it because state: $state")
else -> {
Timber.v("maybeBackupKeys: Skip it because state: ${getState()}")
}
}
}
@ -1018,9 +1012,9 @@ internal class DefaultKeysBackupService @Inject constructor(
}
override fun checkAndStartKeysBackup() {
if (!isStucked) {
if (!isStuck()) {
// 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
}
@ -1259,16 +1253,16 @@ internal class DefaultKeysBackupService @Inject constructor(
Timber.v("backupKeys")
// 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")
backupAllGroupSessionsCallback?.onFailure(IllegalStateException("Invalid configuration"))
resetBackupAllGroupSessionsListeners()
return
}
if (state === KeysBackupState.BackingUp) {
if (getState() === KeysBackupState.BackingUp) {
// Do nothing if we are already backing up
Timber.v("backupKeys: Invalid state: $state")
Timber.v("backupKeys: Invalid state: ${getState()}")
return
}

View file

@ -49,7 +49,7 @@ internal class KeysBackupStateManager(private val uiHandler: Handler) {
state == KeysBackupState.BackingUp
// True if unknown or bad state
val isStucked: Boolean
val isStuck: Boolean
get() = state == KeysBackupState.Unknown ||
state == KeysBackupState.Disabled ||
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.KeyInfo
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.RawBytesKeySpec
import org.matrix.android.sdk.api.session.securestorage.SecretStorageKeyContent
@ -157,7 +158,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
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) {
val encryptedContents = HashMap<String, EncryptedSecretContent>()
keys.forEach {

View file

@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.session.pushers
import androidx.lifecycle.LiveData
import androidx.work.BackoffPolicy
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.PushersService
import org.matrix.android.sdk.internal.database.mapper.asDomain
@ -58,15 +59,15 @@ internal class DefaultPushersService @Inject constructor(
.executeBy(taskExecutor)
}
override fun enqueueAddHttpPusher(httpPusher: PushersService.HttpPusher): UUID {
override fun enqueueAddHttpPusher(httpPusher: HttpPusher): UUID {
return enqueueAddPusher(httpPusher.toJsonPusher())
}
override suspend fun addHttpPusher(httpPusher: PushersService.HttpPusher) {
override suspend fun addHttpPusher(httpPusher: HttpPusher) {
addPusherTask.execute(AddPusherTask.Params(httpPusher.toJsonPusher()))
}
private fun PushersService.HttpPusher.toJsonPusher() = JsonPusher(
private fun HttpPusher.toJsonPusher() = JsonPusher(
pushKey = pushkey,
kind = "http",
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().canCrossSign())
assert(uiSession.cryptoService().crossSigningService().allPrivateKeysKnown())
assert(uiSession.cryptoService().keysBackupService().isEnabled)
assert(uiSession.cryptoService().keysBackupService().isEnabled())
assert(uiSession.cryptoService().keysBackupService().currentBackupVersion != null)
assert(uiSession.sharedSecretStorageService().isRecoverySetup())
assert(uiSession.sharedSecretStorageService().isMegolmKeyInBackup())

View file

@ -66,7 +66,7 @@ fun Session.startSyncing(context: Context) {
*/
fun Session.hasUnsavedKeys(): Boolean {
return cryptoService().inboundGroupSessionsCount(false) > 0 &&
cryptoService().keysBackupService().state != KeysBackupState.ReadyToBackUp
cryptoService().keysBackupService().getState() != KeysBackupState.ReadyToBackUp
}
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.LocaleProvider
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 javax.inject.Inject
import kotlin.math.abs
@ -55,7 +55,7 @@ class PushersManager @Inject constructor(
currentSession.pushersService().addHttpPusher(createHttpPusher(pushKey))
}
private fun createHttpPusher(pushKey: String) = PushersService.HttpPusher(
private fun createHttpPusher(pushKey: String) = HttpPusher(
pushKey,
stringProvider.getString(R.string.pusher_app_id),
profileTag = DEFAULT_PUSHER_FILE_TAG + "_" + abs(activeSessionHolder.getActiveSession().myUserId.hashCode()),

View file

@ -60,7 +60,7 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS
init {
setState {
this.copy(
keysBackupState = keysBackupService.state,
keysBackupState = keysBackupService.getState(),
keysBackupVersion = keysBackupService.keysBackupVersion
)
}
@ -206,7 +206,7 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS
}
fun canExit(): Boolean {
val currentBackupState = keysBackupService.state
val currentBackupState = keysBackupService.getState()
return currentBackupState == KeysBackupState.Unknown ||
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.KeyInfo
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.SharedSecretStorageService
import org.matrix.android.sdk.api.util.toBase64NoPadding
import org.matrix.android.sdk.flow.flow
import timber.log.Timber
@ -283,7 +283,7 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
session.sharedSecretStorageService().storeSecret(
name = name,
secretBase64 = value,
keys = listOf(SharedSecretStorageService.KeyRef(keyInfo.id, keySpec))
keys = listOf(KeyRef(keyInfo.id, keySpec))
)
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.extractCurveKeyFromRecoveryKey
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.SharedSecretStorageService
import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo
import org.matrix.android.sdk.api.util.awaitCallback
import org.matrix.android.sdk.api.util.toBase64NoPadding
@ -142,7 +142,7 @@ class BackupToQuadSMigrationTask @Inject constructor(
quadS.storeSecret(
KEYBACKUP_SECRET_SSSS_NAME,
curveKey.toBase64NoPadding(),
listOf(SharedSecretStorageService.KeyRef(info.keyId, info.keySpec))
listOf(KeyRef(info.keyId, info.keySpec))
)
// 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.toKeysVersionResult
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.SsssKeySpec
import org.matrix.android.sdk.api.util.awaitCallback
@ -183,7 +183,7 @@ class BootstrapCrossSigningTask @Inject constructor(
ssssService.storeSecret(
MASTER_KEY_SSSS_NAME,
mskPrivateKey,
listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec))
listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec))
)
params.progressListener?.onProgress(
WaitingViewData(
@ -195,7 +195,7 @@ class BootstrapCrossSigningTask @Inject constructor(
ssssService.storeSecret(
USER_SIGNING_KEY_SSSS_NAME,
uskPrivateKey,
listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec))
listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec))
)
params.progressListener?.onProgress(
WaitingViewData(
@ -206,7 +206,7 @@ class BootstrapCrossSigningTask @Inject constructor(
ssssService.storeSecret(
SELF_SIGNING_KEY_SSSS_NAME,
sskPrivateKey,
listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec))
listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec))
)
} catch (failure: Failure) {
Timber.e("## BootstrapCrossSigningTask: Creating 4S - Failed to store keys <${failure.localizedMessage}>")
@ -258,7 +258,7 @@ class BootstrapCrossSigningTask @Inject constructor(
ssssService.storeSecret(
KEYBACKUP_SECRET_SSSS_NAME,
secret,
listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec))
listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec))
)
}
} else {
@ -275,7 +275,7 @@ class BootstrapCrossSigningTask @Inject constructor(
ssssService.storeSecret(
KEYBACKUP_SECRET_SSSS_NAME,
secret,
listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec))
listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec))
)
}
} else {

View file

@ -401,8 +401,8 @@ class MessageActionsViewModel @AssistedInject constructor(
if (vectorPreferences.developerMode()) {
if (timelineEvent.isEncrypted() && timelineEvent.root.mCryptoError != null) {
val keysBackupService = session.cryptoService().keysBackupService()
if (keysBackupService.state == KeysBackupState.NotTrusted ||
(keysBackupService.state == KeysBackupState.ReadyToBackUp &&
if (keysBackupService.getState() == KeysBackupState.NotTrusted ||
(keysBackupService.getState() == KeysBackupState.ReadyToBackUp &&
keysBackupService.canRestoreKeys())
) {
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()
val currentThreePid: String?
get() = registrationWizard?.currentThreePid
get() = registrationWizard?.getCurrentThreePid()
// True when login and password has been sent with success to the homeserver
val isRegistrationStarted: Boolean
get() = authenticationService.isRegistrationStarted
get() = authenticationService.isRegistrationStarted()
private val registrationWizard: RegistrationWizard?
get() = authenticationService.getRegistrationWizard()
@ -455,7 +455,7 @@ class LoginViewModel @AssistedInject constructor(
// If there is a pending email validation continue on this step
try {
if (registrationWizard?.isRegistrationStarted == true) {
if (registrationWizard?.isRegistrationStarted() == true) {
currentThreePid?.let {
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()
val currentThreePid: String?
get() = registrationWizard?.currentThreePid
get() = registrationWizard?.getCurrentThreePid()
// True when login and password has been sent with success to the homeserver
val isRegistrationStarted: Boolean
get() = authenticationService.isRegistrationStarted
get() = authenticationService.isRegistrationStarted()
private val registrationWizard: RegistrationWizard?
get() = authenticationService.getRegistrationWizard()
@ -420,7 +420,7 @@ class LoginViewModel2 @AssistedInject constructor(
// If there is a pending email validation continue on this step
try {
if (registrationWizard?.isRegistrationStarted == true) {
if (registrationWizard?.isRegistrationStarted() == true) {
currentThreePid?.let {
handle(LoginAction2.PostViewEvent(LoginViewEvents2.OnSendEmailSuccess(it)))
}

View file

@ -116,11 +116,11 @@ class OnboardingViewModel @AssistedInject constructor(
get() = authenticationService.getRegistrationWizard()
val currentThreePid: String?
get() = registrationWizard.currentThreePid
get() = registrationWizard.getCurrentThreePid()
// True when login and password has been sent with success to the homeserver
val isRegistrationStarted: Boolean
get() = authenticationService.isRegistrationStarted
get() = authenticationService.isRegistrationStarted()
private val loginWizard: LoginWizard?
get() = authenticationService.getLoginWizard()
@ -425,7 +425,7 @@ class OnboardingViewModel @AssistedInject constructor(
// If there is a pending email validation continue on this step
try {
if (registrationWizard.isRegistrationStarted) {
if (registrationWizard.isRegistrationStarted()) {
currentThreePid?.let {
handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnSendEmailSuccess(it)))
}

View file

@ -81,7 +81,7 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS
init {
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 liveCrossSigningInfo = session.flow().liveCrossSigningInfo(session.myUserId)
val liveCrossSigningPrivateKeys = session.flow().liveCrossSigningPrivateKeys()
@ -116,7 +116,7 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS
}
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) {
viewModelScope.launch {
keyBackupFlow.tryEmit(session.cryptoService().keysBackupService().state)
keyBackupFlow.tryEmit(session.cryptoService().keysBackupService().getState())
}
keysBackupState.value = newState
}

View file

@ -76,7 +76,7 @@ class SignoutCheckViewModel @AssistedInject constructor(
val quad4SIsSetup = session.sharedSecretStorageService().isRecoverySetup()
val allKeysKnown = session.cryptoService().crossSigningService().allPrivateKeysKnown()
val backupState = session.cryptoService().keysBackupService().state
val backupState = session.cryptoService().keysBackupService().getState()
setState {
copy(
userId = session.myUserId,

View file

@ -33,7 +33,7 @@ class FakeAuthenticationService : AuthenticationService by mockk() {
}
fun givenRegistrationStarted(started: Boolean) {
every { isRegistrationStarted } returns started
every { isRegistrationStarted() } returns started
}
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.session.securestorage.IntegrityResult
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.SharedSecretStorageError
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService
@ -56,7 +57,7 @@ class FakeSharedSecretStorageService : SharedSecretStorageService {
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")
}