Code review
This commit is contained in:
parent
e0eede1150
commit
f99eca8014
@ -124,9 +124,9 @@ class RxSession(private val session: Session) {
|
||||
}
|
||||
|
||||
fun liveAccountData(filter: List<String>): Observable<List<UserAccountDataEvent>> {
|
||||
return session.getLiveAccountData(filter).asObservable()
|
||||
return session.getLiveAccountDataEvents(filter).asObservable()
|
||||
.startWithCallable {
|
||||
session.getAccountData(filter)
|
||||
session.getAccountDataEvents(filter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.session.securestorage.Curve25519AesSha2KeySpec
|
||||
import im.vector.matrix.android.api.session.securestorage.EncryptedSecretContent
|
||||
import im.vector.matrix.android.api.session.securestorage.KeySigner
|
||||
import im.vector.matrix.android.api.session.securestorage.SSSSKeyCreationInfo
|
||||
import im.vector.matrix.android.api.session.securestorage.SsssKeyCreationInfo
|
||||
import im.vector.matrix.android.api.session.securestorage.SecretStorageKeyContent
|
||||
import im.vector.matrix.android.api.util.Optional
|
||||
import im.vector.matrix.android.common.CommonTestHelper
|
||||
@ -33,8 +33,9 @@ import im.vector.matrix.android.common.CryptoTestHelper
|
||||
import im.vector.matrix.android.common.SessionTestParams
|
||||
import im.vector.matrix.android.common.TestConstants
|
||||
import im.vector.matrix.android.common.TestMatrixCallback
|
||||
import im.vector.matrix.android.internal.crypto.SSSS_ALGORITHM_CURVE25519_AES_SHA2
|
||||
import im.vector.matrix.android.internal.crypto.crosssigning.toBase64NoPadding
|
||||
import im.vector.matrix.android.internal.crypto.secrets.DefaultSharedSecretStorage
|
||||
import im.vector.matrix.android.internal.crypto.secrets.DefaultSharedSecretStorageService
|
||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
@ -74,8 +75,8 @@ class QuadSTests : InstrumentedTest {
|
||||
val TEST_KEY_ID = "my.test.Key"
|
||||
|
||||
quadS.generateKey(TEST_KEY_ID, "Test Key", emptyKeySigner,
|
||||
object : MatrixCallback<SSSSKeyCreationInfo> {
|
||||
override fun onSuccess(data: SSSSKeyCreationInfo) {
|
||||
object : MatrixCallback<SsssKeyCreationInfo> {
|
||||
override fun onSuccess(data: SsssKeyCreationInfo) {
|
||||
recoveryKey = data.recoveryKey
|
||||
aliceLatch.countDown()
|
||||
}
|
||||
@ -93,7 +94,7 @@ class QuadSTests : InstrumentedTest {
|
||||
var accountData: UserAccountDataEvent? = null
|
||||
|
||||
val liveAccountData = runBlocking(Dispatchers.Main) {
|
||||
aliceSession.getLiveAccountData("m.secret_storage.key.$TEST_KEY_ID")
|
||||
aliceSession.getLiveAccountDataEvent("m.secret_storage.key.$TEST_KEY_ID")
|
||||
}
|
||||
val accountDataObserver = Observer<Optional<UserAccountDataEvent>?> { t ->
|
||||
if (t?.getOrNull()?.type == "m.secret_storage.key.$TEST_KEY_ID") {
|
||||
@ -108,13 +109,13 @@ class QuadSTests : InstrumentedTest {
|
||||
Assert.assertNotNull("Key should be stored in account data", accountData)
|
||||
val parsed = SecretStorageKeyContent.fromJson(accountData!!.content)
|
||||
Assert.assertNotNull("Key Content cannot be parsed", parsed)
|
||||
Assert.assertEquals("Unexpected Algorithm", DefaultSharedSecretStorage.ALGORITHM_CURVE25519_AES_SHA2, parsed!!.algorithm)
|
||||
Assert.assertEquals("Unexpected Algorithm", SSSS_ALGORITHM_CURVE25519_AES_SHA2, parsed!!.algorithm)
|
||||
Assert.assertEquals("Unexpected key name", "Test Key", parsed.name)
|
||||
Assert.assertNull("Key was not generated from passphrase", parsed.passphrase)
|
||||
Assert.assertNotNull("Pubkey should be defined", parsed.publicKey)
|
||||
|
||||
val privateKeySpec = Curve25519AesSha2KeySpec.fromRecoveryKey(recoveryKey!!)
|
||||
DefaultSharedSecretStorage.withOlmDecryption { olmPkDecryption ->
|
||||
DefaultSharedSecretStorageService.withOlmDecryption { olmPkDecryption ->
|
||||
val pubKey = olmPkDecryption.setPrivateKey(privateKeySpec!!.privateKey)
|
||||
Assert.assertEquals("Unexpected Public Key", pubKey, parsed.publicKey)
|
||||
}
|
||||
@ -126,10 +127,10 @@ class QuadSTests : InstrumentedTest {
|
||||
val defaultDataLock = CountDownLatch(1)
|
||||
|
||||
val liveDefAccountData = runBlocking(Dispatchers.Main) {
|
||||
aliceSession.getLiveAccountData(DefaultSharedSecretStorage.DEFAULT_KEY_ID)
|
||||
aliceSession.getLiveAccountDataEvent(DefaultSharedSecretStorageService.DEFAULT_KEY_ID)
|
||||
}
|
||||
val accountDefDataObserver = Observer<Optional<UserAccountDataEvent>?> { t ->
|
||||
if (t?.getOrNull()?.type == DefaultSharedSecretStorage.DEFAULT_KEY_ID) {
|
||||
if (t?.getOrNull()?.type == DefaultSharedSecretStorageService.DEFAULT_KEY_ID) {
|
||||
defaultKeyAccountData = t.getOrNull()!!
|
||||
defaultDataLock.countDown()
|
||||
}
|
||||
@ -247,7 +248,7 @@ class QuadSTests : InstrumentedTest {
|
||||
)
|
||||
mTestHelper.await(storeLatch)
|
||||
|
||||
val accountDataEvent = aliceSession.getAccountData("my.secret")
|
||||
val accountDataEvent = aliceSession.getAccountDataEvent("my.secret")
|
||||
val encryptedContent = accountDataEvent?.content?.get("encrypted") as? Map<*, *>
|
||||
|
||||
Assert.assertEquals("Content should contains two encryptions", 2, encryptedContent?.keys?.size ?: 0)
|
||||
@ -334,7 +335,7 @@ class QuadSTests : InstrumentedTest {
|
||||
var accountData: UserAccountDataEvent? = null
|
||||
|
||||
val liveAccountData = runBlocking(Dispatchers.Main) {
|
||||
session.getLiveAccountData(type)
|
||||
session.getLiveAccountDataEvent(type)
|
||||
}
|
||||
val accountDataObserver = Observer<Optional<UserAccountDataEvent>?> { t ->
|
||||
if (t?.getOrNull()?.type == type) {
|
||||
@ -350,7 +351,7 @@ class QuadSTests : InstrumentedTest {
|
||||
return accountData!!
|
||||
}
|
||||
|
||||
private fun generatedSecret(session: Session, keyId: String, asDefault: Boolean = true): SSSSKeyCreationInfo {
|
||||
private fun generatedSecret(session: Session, keyId: String, asDefault: Boolean = true): SsssKeyCreationInfo {
|
||||
val quadS = session.sharedSecretStorageService
|
||||
|
||||
val emptyKeySigner = object : KeySigner {
|
||||
@ -359,13 +360,13 @@ class QuadSTests : InstrumentedTest {
|
||||
}
|
||||
}
|
||||
|
||||
var creationInfo: SSSSKeyCreationInfo? = null
|
||||
var creationInfo: SsssKeyCreationInfo? = null
|
||||
|
||||
val generateLatch = CountDownLatch(1)
|
||||
|
||||
quadS.generateKey(keyId, keyId, emptyKeySigner,
|
||||
object : MatrixCallback<SSSSKeyCreationInfo> {
|
||||
override fun onSuccess(data: SSSSKeyCreationInfo) {
|
||||
object : MatrixCallback<SsssKeyCreationInfo> {
|
||||
override fun onSuccess(data: SsssKeyCreationInfo) {
|
||||
creationInfo = data
|
||||
generateLatch.countDown()
|
||||
}
|
||||
@ -385,13 +386,13 @@ class QuadSTests : InstrumentedTest {
|
||||
val setDefaultLatch = CountDownLatch(1)
|
||||
quadS.setDefaultKey(keyId, TestMatrixCallback(setDefaultLatch))
|
||||
mTestHelper.await(setDefaultLatch)
|
||||
assertAccountData(session, DefaultSharedSecretStorage.DEFAULT_KEY_ID)
|
||||
assertAccountData(session, DefaultSharedSecretStorageService.DEFAULT_KEY_ID)
|
||||
}
|
||||
|
||||
return creationInfo!!
|
||||
}
|
||||
|
||||
private fun generatedSecretFromPassphrase(session: Session, passphrase: String, keyId: String, asDefault: Boolean = true): SSSSKeyCreationInfo {
|
||||
private fun generatedSecretFromPassphrase(session: Session, passphrase: String, keyId: String, asDefault: Boolean = true): SsssKeyCreationInfo {
|
||||
val quadS = session.sharedSecretStorageService
|
||||
|
||||
val emptyKeySigner = object : KeySigner {
|
||||
@ -400,7 +401,7 @@ class QuadSTests : InstrumentedTest {
|
||||
}
|
||||
}
|
||||
|
||||
var creationInfo: SSSSKeyCreationInfo? = null
|
||||
var creationInfo: SsssKeyCreationInfo? = null
|
||||
|
||||
val generateLatch = CountDownLatch(1)
|
||||
|
||||
@ -408,8 +409,8 @@ class QuadSTests : InstrumentedTest {
|
||||
passphrase,
|
||||
emptyKeySigner,
|
||||
null,
|
||||
object : MatrixCallback<SSSSKeyCreationInfo> {
|
||||
override fun onSuccess(data: SSSSKeyCreationInfo) {
|
||||
object : MatrixCallback<SsssKeyCreationInfo> {
|
||||
override fun onSuccess(data: SsssKeyCreationInfo) {
|
||||
creationInfo = data
|
||||
generateLatch.countDown()
|
||||
}
|
||||
@ -429,7 +430,7 @@ class QuadSTests : InstrumentedTest {
|
||||
val setDefaultLatch = CountDownLatch(1)
|
||||
quadS.setDefaultKey(keyId, TestMatrixCallback(setDefaultLatch))
|
||||
mTestHelper.await(setDefaultLatch)
|
||||
assertAccountData(session, DefaultSharedSecretStorage.DEFAULT_KEY_ID)
|
||||
assertAccountData(session, DefaultSharedSecretStorageService.DEFAULT_KEY_ID)
|
||||
}
|
||||
|
||||
return creationInfo!!
|
||||
|
@ -24,13 +24,13 @@ import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAcco
|
||||
|
||||
interface AccountDataService {
|
||||
|
||||
fun getAccountData(type: String): UserAccountDataEvent?
|
||||
fun getAccountDataEvent(type: String): UserAccountDataEvent?
|
||||
|
||||
fun getLiveAccountData(type: String): LiveData<Optional<UserAccountDataEvent>>
|
||||
fun getLiveAccountDataEvent(type: String): LiveData<Optional<UserAccountDataEvent>>
|
||||
|
||||
fun getAccountData(filterType: List<String>): List<UserAccountDataEvent>
|
||||
fun getAccountDataEvents(filterType: List<String>): List<UserAccountDataEvent>
|
||||
|
||||
fun getLiveAccountData(filterType: List<String>): LiveData<List<UserAccountDataEvent>>
|
||||
fun getLiveAccountDataEvents(filterType: List<String>): LiveData<List<UserAccountDataEvent>>
|
||||
|
||||
fun updateAccountData(type: String, content: Content, callback: MatrixCallback<Unit>? = null)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
* Copyright 2020 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -31,26 +31,38 @@ import im.vector.matrix.android.api.listeners.ProgressListener
|
||||
interface SharedSecretStorageService {
|
||||
|
||||
/**
|
||||
* Add a key for encrypting secrets.
|
||||
* Generates a SSSS key for encrypting secrets.
|
||||
* Use the SsssKeyCreationInfo object returned by the callback to get more information about the created key (recovery key ...)
|
||||
*
|
||||
* @param algorithm the algorithm used by the key.
|
||||
* @param opts the options for the algorithm. The properties used
|
||||
* depend on the algorithm given.
|
||||
* @param keyId the ID of the key
|
||||
* @param keyName a human readable name
|
||||
* @param keySigner Used to add a signature to the key (client should check key signature before storing secret)
|
||||
*
|
||||
* @return {string} the ID of the key
|
||||
* @param callback Get key creation info
|
||||
*/
|
||||
fun generateKey(keyId: String,
|
||||
keyName: String,
|
||||
keySigner: KeySigner,
|
||||
callback: MatrixCallback<SSSSKeyCreationInfo>)
|
||||
callback: MatrixCallback<SsssKeyCreationInfo>)
|
||||
|
||||
/**
|
||||
* Generates a SSSS key using the given passphrase.
|
||||
* Use the SsssKeyCreationInfo object returned by the callback to get more information about the created key (recovery key, salt, iteration ...)
|
||||
*
|
||||
* @param keyId the ID of the key
|
||||
* @param keyName human readable key name
|
||||
* @param passphrase The passphrase used to generate the key
|
||||
* @param keySigner Used to add a signature to the key (client should check key signature before retrieving secret)
|
||||
* @param progressListener The derivation of the passphrase may take long depending on the device, use this to report progress
|
||||
*
|
||||
* @param callback Get key creation info
|
||||
*/
|
||||
fun generateKeyWithPassphrase(keyId: String,
|
||||
keyName: String,
|
||||
passphrase: String,
|
||||
keySigner: KeySigner,
|
||||
progressListener: ProgressListener?,
|
||||
callback: MatrixCallback<SSSSKeyCreationInfo>)
|
||||
callback: MatrixCallback<SsssKeyCreationInfo>)
|
||||
|
||||
fun getKey(keyId: String): KeyInfoResult
|
||||
|
||||
@ -92,11 +104,9 @@ interface SharedSecretStorageService {
|
||||
*
|
||||
* @param name The name of the secret
|
||||
* @param keyId The id of the key that should be used to decrypt (null for default key)
|
||||
* @param privateKey the passphrase/secret
|
||||
* @param secretKey the secret key to use (@see #Curve25519AesSha2KeySpec)
|
||||
*
|
||||
* @return The decrypted value
|
||||
*/
|
||||
@Throws
|
||||
|
||||
fun getSecret(name: String, keyId: String?, secretKey: SSSSKeySpec, callback: MatrixCallback<String>)
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package im.vector.matrix.android.api.session.securestorage
|
||||
|
||||
data class SSSSKeyCreationInfo(
|
||||
data class SsssKeyCreationInfo(
|
||||
val keyId: String = "",
|
||||
var content: SecretStorageKeyContent?,
|
||||
val recoveryKey: String = ""
|
@ -31,6 +31,11 @@ const val MXCRYPTO_ALGORITHM_MEGOLM = "m.megolm.v1.aes-sha2"
|
||||
*/
|
||||
const val MXCRYPTO_ALGORITHM_MEGOLM_BACKUP = "m.megolm_backup.v1.curve25519-aes-sha2"
|
||||
|
||||
/**
|
||||
* Secured Shared Storage algorithm constant
|
||||
*/
|
||||
const val SSSS_ALGORITHM_CURVE25519_AES_SHA2 = "m.secret_storage.v1.curve25519-aes-sha2"
|
||||
|
||||
// TODO Refacto: use this constants everywhere
|
||||
const val ed25519 = "ed25519"
|
||||
const val curve25519 = "curve25519"
|
||||
|
@ -25,12 +25,13 @@ import im.vector.matrix.android.api.session.securestorage.EncryptedSecretContent
|
||||
import im.vector.matrix.android.api.session.securestorage.KeyInfo
|
||||
import im.vector.matrix.android.api.session.securestorage.KeyInfoResult
|
||||
import im.vector.matrix.android.api.session.securestorage.KeySigner
|
||||
import im.vector.matrix.android.api.session.securestorage.SSSSKeyCreationInfo
|
||||
import im.vector.matrix.android.api.session.securestorage.SsssKeyCreationInfo
|
||||
import im.vector.matrix.android.api.session.securestorage.SSSSKeySpec
|
||||
import im.vector.matrix.android.api.session.securestorage.SSSSPassphrase
|
||||
import im.vector.matrix.android.api.session.securestorage.SecretStorageKeyContent
|
||||
import im.vector.matrix.android.api.session.securestorage.SharedSecretStorageError
|
||||
import im.vector.matrix.android.api.session.securestorage.SharedSecretStorageService
|
||||
import im.vector.matrix.android.internal.crypto.SSSS_ALGORITHM_CURVE25519_AES_SHA2
|
||||
import im.vector.matrix.android.internal.crypto.keysbackup.generatePrivateKeyWithPassword
|
||||
import im.vector.matrix.android.internal.crypto.keysbackup.util.computeRecoveryKey
|
||||
import im.vector.matrix.android.internal.extensions.foldToCallback
|
||||
@ -42,7 +43,7 @@ import org.matrix.olm.OlmPkEncryption
|
||||
import org.matrix.olm.OlmPkMessage
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DefaultSharedSecretStorage @Inject constructor(
|
||||
internal class DefaultSharedSecretStorageService @Inject constructor(
|
||||
private val accountDataService: AccountDataService,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val cryptoCoroutineScope: CoroutineScope
|
||||
@ -51,7 +52,7 @@ internal class DefaultSharedSecretStorage @Inject constructor(
|
||||
override fun generateKey(keyId: String,
|
||||
keyName: String,
|
||||
keySigner: KeySigner,
|
||||
callback: MatrixCallback<SSSSKeyCreationInfo>) {
|
||||
callback: MatrixCallback<SsssKeyCreationInfo>) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.main) {
|
||||
val pkDecryption = OlmPkDecryption()
|
||||
val pubKey: String
|
||||
@ -69,7 +70,7 @@ internal class DefaultSharedSecretStorage @Inject constructor(
|
||||
|
||||
val storageKeyContent = SecretStorageKeyContent(
|
||||
name = keyName,
|
||||
algorithm = ALGORITHM_CURVE25519_AES_SHA2,
|
||||
algorithm = SSSS_ALGORITHM_CURVE25519_AES_SHA2,
|
||||
passphrase = null,
|
||||
publicKey = pubKey
|
||||
)
|
||||
@ -89,7 +90,7 @@ internal class DefaultSharedSecretStorage @Inject constructor(
|
||||
}
|
||||
|
||||
override fun onSuccess(data: Unit) {
|
||||
callback.onSuccess(SSSSKeyCreationInfo(
|
||||
callback.onSuccess(SsssKeyCreationInfo(
|
||||
keyId = keyId,
|
||||
content = storageKeyContent,
|
||||
recoveryKey = computeRecoveryKey(privateKey)
|
||||
@ -105,7 +106,7 @@ internal class DefaultSharedSecretStorage @Inject constructor(
|
||||
passphrase: String,
|
||||
keySigner: KeySigner,
|
||||
progressListener: ProgressListener?,
|
||||
callback: MatrixCallback<SSSSKeyCreationInfo>) {
|
||||
callback: MatrixCallback<SsssKeyCreationInfo>) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.main) {
|
||||
val privatePart = generatePrivateKeyWithPassword(passphrase, progressListener)
|
||||
|
||||
@ -122,7 +123,7 @@ internal class DefaultSharedSecretStorage @Inject constructor(
|
||||
}
|
||||
|
||||
val storageKeyContent = SecretStorageKeyContent(
|
||||
algorithm = ALGORITHM_CURVE25519_AES_SHA2,
|
||||
algorithm = SSSS_ALGORITHM_CURVE25519_AES_SHA2,
|
||||
passphrase = SSSSPassphrase(algorithm = "m.pbkdf2", iterations = privatePart.iterations, salt = privatePart.salt),
|
||||
publicKey = pubKey
|
||||
)
|
||||
@ -142,7 +143,7 @@ internal class DefaultSharedSecretStorage @Inject constructor(
|
||||
}
|
||||
|
||||
override fun onSuccess(data: Unit) {
|
||||
callback.onSuccess(SSSSKeyCreationInfo(
|
||||
callback.onSuccess(SsssKeyCreationInfo(
|
||||
keyId = keyId,
|
||||
content = storageKeyContent,
|
||||
recoveryKey = computeRecoveryKey(privatePart.privateKey)
|
||||
@ -154,11 +155,11 @@ internal class DefaultSharedSecretStorage @Inject constructor(
|
||||
}
|
||||
|
||||
override fun hasKey(keyId: String): Boolean {
|
||||
return accountDataService.getAccountData("$KEY_ID_BASE.$keyId") != null
|
||||
return accountDataService.getAccountDataEvent("$KEY_ID_BASE.$keyId") != null
|
||||
}
|
||||
|
||||
override fun getKey(keyId: String): KeyInfoResult {
|
||||
val accountData = accountDataService.getAccountData("$KEY_ID_BASE.$keyId")
|
||||
val accountData = accountDataService.getAccountDataEvent("$KEY_ID_BASE.$keyId")
|
||||
?: return KeyInfoResult.Error(SharedSecretStorageError.UnknownKey(keyId))
|
||||
return SecretStorageKeyContent.fromJson(accountData.content)?.let {
|
||||
KeyInfoResult.Success(
|
||||
@ -180,7 +181,7 @@ internal class DefaultSharedSecretStorage @Inject constructor(
|
||||
}
|
||||
|
||||
override fun getDefaultKey(): KeyInfoResult {
|
||||
val accountData = accountDataService.getAccountData(DEFAULT_KEY_ID)
|
||||
val accountData = accountDataService.getAccountDataEvent(DEFAULT_KEY_ID)
|
||||
?: return KeyInfoResult.Error(SharedSecretStorageError.UnknownKey(DEFAULT_KEY_ID))
|
||||
val keyId = accountData.content["key"] as? String
|
||||
?: return KeyInfoResult.Error(SharedSecretStorageError.UnknownKey(DEFAULT_KEY_ID))
|
||||
@ -196,7 +197,7 @@ internal class DefaultSharedSecretStorage @Inject constructor(
|
||||
val key = getDefaultKey()
|
||||
when (key) {
|
||||
is KeyInfoResult.Success -> {
|
||||
if (key.keyInfo.content.algorithm == ALGORITHM_CURVE25519_AES_SHA2) {
|
||||
if (key.keyInfo.content.algorithm == SSSS_ALGORITHM_CURVE25519_AES_SHA2) {
|
||||
withOlmEncryption { olmEncrypt ->
|
||||
olmEncrypt.setRecipientKey(key.keyInfo.content.publicKey)
|
||||
val encryptedResult = olmEncrypt.encrypt(secretBase64)
|
||||
@ -224,7 +225,7 @@ internal class DefaultSharedSecretStorage @Inject constructor(
|
||||
val key = getKey(keyId)
|
||||
when (key) {
|
||||
is KeyInfoResult.Success -> {
|
||||
if (key.keyInfo.content.algorithm == ALGORITHM_CURVE25519_AES_SHA2) {
|
||||
if (key.keyInfo.content.algorithm == SSSS_ALGORITHM_CURVE25519_AES_SHA2) {
|
||||
withOlmEncryption { olmEncrypt ->
|
||||
olmEncrypt.setRecipientKey(key.keyInfo.content.publicKey)
|
||||
val encryptedResult = olmEncrypt.encrypt(secretBase64)
|
||||
@ -264,7 +265,7 @@ internal class DefaultSharedSecretStorage @Inject constructor(
|
||||
}
|
||||
|
||||
override fun getAlgorithmsForSecret(name: String): List<KeyInfoResult> {
|
||||
val accountData = accountDataService.getAccountData(name)
|
||||
val accountData = accountDataService.getAccountDataEvent(name)
|
||||
?: return listOf(KeyInfoResult.Error(SharedSecretStorageError.UnknownSecret(name)))
|
||||
val encryptedContent = accountData.content[ENCRYPTED] as? Map<*, *>
|
||||
?: return listOf(KeyInfoResult.Error(SharedSecretStorageError.SecretNotEncrypted(name)))
|
||||
@ -279,7 +280,7 @@ internal class DefaultSharedSecretStorage @Inject constructor(
|
||||
}
|
||||
|
||||
override fun getSecret(name: String, keyId: String?, secretKey: SSSSKeySpec, callback: MatrixCallback<String>) {
|
||||
val accountData = accountDataService.getAccountData(name) ?: return Unit.also {
|
||||
val accountData = accountDataService.getAccountDataEvent(name) ?: return Unit.also {
|
||||
callback.onFailure(SharedSecretStorageError.UnknownSecret(name))
|
||||
}
|
||||
val encryptedContent = accountData.content[ENCRYPTED] as? Map<*, *> ?: return Unit.also {
|
||||
@ -299,7 +300,7 @@ internal class DefaultSharedSecretStorage @Inject constructor(
|
||||
}
|
||||
|
||||
val algorithm = key.keyInfo.content
|
||||
if (ALGORITHM_CURVE25519_AES_SHA2 == algorithm.algorithm) {
|
||||
if (SSSS_ALGORITHM_CURVE25519_AES_SHA2 == algorithm.algorithm) {
|
||||
val keySpec = secretKey as? Curve25519AesSha2KeySpec ?: return Unit.also {
|
||||
callback.onFailure(SharedSecretStorageError.BadKeyFormat)
|
||||
}
|
||||
@ -332,8 +333,6 @@ internal class DefaultSharedSecretStorage @Inject constructor(
|
||||
const val ENCRYPTED = "encrypted"
|
||||
const val DEFAULT_KEY_ID = "m.secret_storage.default_key"
|
||||
|
||||
const val ALGORITHM_CURVE25519_AES_SHA2 = "m.secret_storage.v1.curve25519-aes-sha2"
|
||||
|
||||
fun withOlmEncryption(block: (OlmPkEncryption) -> Unit) {
|
||||
val olmPkEncryption = OlmPkEncryption()
|
||||
try {
|
@ -20,9 +20,10 @@ import io.realm.RealmObject
|
||||
import io.realm.annotations.Index
|
||||
|
||||
/**
|
||||
* Clients can store custom config data for their account on their homeserver.
|
||||
* Clients can store custom config data for their account on their HomeServer.
|
||||
* This account data will be synced between different devices and can persist across installations on a particular device.
|
||||
* Users may only view the account data for their own accountThe account_data may be either global or scoped to a particular rooms.
|
||||
* Users may only view the account data for their own account.
|
||||
* The account_data may be either global or scoped to a particular rooms.
|
||||
*/
|
||||
internal open class UserAccountDataEntity(
|
||||
@Index var type: String? = null,
|
||||
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.network.parsing
|
||||
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.squareup.moshi.Moshi
|
||||
import java.lang.reflect.Type
|
||||
|
||||
class AccountDataJsonAdapterFactory<UserAccountData> : JsonAdapter.Factory {
|
||||
|
||||
override fun create(type: Type, annotations: MutableSet<out Annotation>, moshi: Moshi): JsonAdapter<*>? {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
@ -36,7 +36,7 @@ import im.vector.matrix.android.api.session.accountdata.AccountDataService
|
||||
import im.vector.matrix.android.api.session.homeserver.HomeServerCapabilitiesService
|
||||
import im.vector.matrix.android.api.session.securestorage.SecureStorageService
|
||||
import im.vector.matrix.android.api.session.securestorage.SharedSecretStorageService
|
||||
import im.vector.matrix.android.internal.crypto.secrets.DefaultSharedSecretStorage
|
||||
import im.vector.matrix.android.internal.crypto.secrets.DefaultSharedSecretStorageService
|
||||
import im.vector.matrix.android.internal.crypto.verification.VerificationMessageLiveObserver
|
||||
import im.vector.matrix.android.internal.database.LiveEntityObserver
|
||||
import im.vector.matrix.android.internal.database.SessionRealmConfigurationFactory
|
||||
@ -269,8 +269,8 @@ internal abstract class SessionModule {
|
||||
abstract fun bindHomeServerCapabilitiesService(homeServerCapabilitiesService: DefaultHomeServerCapabilitiesService): HomeServerCapabilitiesService
|
||||
|
||||
@Binds
|
||||
abstract fun bindAccountDataServiceService(accountDataService: DefaultAccountDataService): AccountDataService
|
||||
abstract fun bindAccountDataService(accountDataService: DefaultAccountDataService): AccountDataService
|
||||
|
||||
@Binds
|
||||
abstract fun bindSharedSecuredSecretStorageService(service: DefaultSharedSecretStorage): SharedSecretStorageService
|
||||
abstract fun bindSharedSecretStorageService(service: DefaultSharedSecretStorageService): SharedSecretStorageService
|
||||
}
|
||||
|
@ -46,17 +46,17 @@ internal class DefaultAccountDataService @Inject constructor(
|
||||
private val moshi = MoshiProvider.providesMoshi()
|
||||
private val adapter = moshi.adapter<Map<String, Any>>(JSON_DICT_PARAMETERIZED_TYPE)
|
||||
|
||||
override fun getAccountData(type: String): UserAccountDataEvent? {
|
||||
return getAccountData(listOf(type)).firstOrNull()
|
||||
override fun getAccountDataEvent(type: String): UserAccountDataEvent? {
|
||||
return getAccountDataEvents(listOf(type)).firstOrNull()
|
||||
}
|
||||
|
||||
override fun getLiveAccountData(type: String): LiveData<Optional<UserAccountDataEvent>> {
|
||||
return Transformations.map(getLiveAccountData(listOf(type))) {
|
||||
override fun getLiveAccountDataEvent(type: String): LiveData<Optional<UserAccountDataEvent>> {
|
||||
return Transformations.map(getLiveAccountDataEvents(listOf(type))) {
|
||||
it.firstOrNull()?.toOptional()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getAccountData(filterType: List<String>): List<UserAccountDataEvent> {
|
||||
override fun getAccountDataEvents(filterType: List<String>): List<UserAccountDataEvent> {
|
||||
return monarchy.fetchAllCopiedSync { realm ->
|
||||
realm.where(UserAccountDataEntity::class.java)
|
||||
.apply {
|
||||
@ -74,7 +74,7 @@ internal class DefaultAccountDataService @Inject constructor(
|
||||
} ?: emptyList()
|
||||
}
|
||||
|
||||
override fun getLiveAccountData(filterType: List<String>): LiveData<List<UserAccountDataEvent>> {
|
||||
override fun getLiveAccountDataEvents(filterType: List<String>): LiveData<List<UserAccountDataEvent>> {
|
||||
return monarchy.findAllMappedWithChanges({ realm ->
|
||||
realm.where(UserAccountDataEntity::class.java)
|
||||
.apply {
|
||||
|
@ -24,6 +24,7 @@ import im.vector.matrix.android.internal.di.MoshiProvider
|
||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
|
||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.extensions.cleanup
|
||||
import im.vector.riotx.core.extensions.configureWith
|
||||
import im.vector.riotx.core.platform.VectorBaseActivity
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
@ -58,6 +59,12 @@ class AccountDataFragment @Inject constructor(
|
||||
epoxyController.interactionListener = this
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
recyclerView.cleanup()
|
||||
epoxyController.interactionListener = null
|
||||
}
|
||||
|
||||
override fun didTap(data: UserAccountData) {
|
||||
val fb = data as? UserAccountDataEvent ?: return
|
||||
val jsonString = MoshiProvider.providesMoshi()
|
||||
|
Loading…
x
Reference in New Issue
Block a user