forked from GitHub-Mirror/riotX-android
commit
51879845f2
@ -223,13 +223,17 @@ internal abstract class SASVerificationTransaction(
|
|||||||
cancel(CancelCode.MismatchedKeys)
|
cancel(CancelCode.MismatchedKeys)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val verifiedDevices = ArrayList<String>()
|
||||||
|
|
||||||
//cannot be empty because it has been validated
|
//cannot be empty because it has been validated
|
||||||
theirMac!!.mac!!.keys.forEach {
|
theirMac!!.mac!!.keys.forEach {
|
||||||
val keyIDNoPrefix = if (it.startsWith("ed25519:")) it.substring("ed25519:".length) else it
|
val keyIDNoPrefix = if (it.startsWith("ed25519:")) it.substring("ed25519:".length) else it
|
||||||
val otherDeviceKey = otherUserKnownDevices?.get(keyIDNoPrefix)?.fingerprint()
|
val otherDeviceKey = otherUserKnownDevices?.get(keyIDNoPrefix)?.fingerprint()
|
||||||
if (otherDeviceKey == null) {
|
if (otherDeviceKey == null) {
|
||||||
cancel(CancelCode.MismatchedKeys)
|
Timber.e("Verification: Could not find device $keyIDNoPrefix to verify")
|
||||||
return
|
//just ignore and continue
|
||||||
|
return@forEach
|
||||||
}
|
}
|
||||||
val mac = macUsingAgreedMethod(otherDeviceKey, baseInfo + it)
|
val mac = macUsingAgreedMethod(otherDeviceKey, baseInfo + it)
|
||||||
if (mac != theirMac?.mac?.get(it)) {
|
if (mac != theirMac?.mac?.get(it)) {
|
||||||
@ -237,13 +241,21 @@ internal abstract class SASVerificationTransaction(
|
|||||||
cancel(CancelCode.MismatchedKeys)
|
cancel(CancelCode.MismatchedKeys)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
verifiedDevices.add(keyIDNoPrefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
setDeviceVerified(
|
// if none of the keys could be verified, then error because the app
|
||||||
otherDeviceId ?: "",
|
// should be informed about that
|
||||||
otherUserId)
|
if (verifiedDevices.isEmpty()) {
|
||||||
|
Timber.e("Verification: No devices verified")
|
||||||
|
cancel(CancelCode.MismatchedKeys)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
state = SasVerificationTxState.Verified
|
//TODO what if the otherDevice is not in this list? and should we
|
||||||
|
verifiedDevices.forEach {
|
||||||
|
setDeviceVerified(it, otherUserId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setDeviceVerified(deviceId: String, userId: String) {
|
private fun setDeviceVerified(deviceId: String, userId: String) {
|
||||||
|
@ -22,7 +22,6 @@ import androidx.core.view.isVisible
|
|||||||
import androidx.fragment.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.lifecycle.ViewModelProviders
|
||||||
import im.vector.fragments.keysbackup.setup.KeysBackupSetupSharedViewModel
|
|
||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.dialogs.ExportKeysDialog
|
import im.vector.riotredesign.core.dialogs.ExportKeysDialog
|
||||||
@ -67,19 +66,19 @@ class KeysBackupSetupActivity : SimpleFragmentActivity() {
|
|||||||
|
|
||||||
viewModel.navigateEvent.observeEvent(this) { uxStateEvent ->
|
viewModel.navigateEvent.observeEvent(this) { uxStateEvent ->
|
||||||
when (uxStateEvent) {
|
when (uxStateEvent) {
|
||||||
KeysBackupSetupSharedViewModel.NAVIGATE_TO_STEP_2 -> {
|
KeysBackupSetupSharedViewModel.NAVIGATE_TO_STEP_2 -> {
|
||||||
supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
|
supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
|
||||||
supportFragmentManager.beginTransaction()
|
supportFragmentManager.beginTransaction()
|
||||||
.replace(R.id.container, KeysBackupSetupStep2Fragment.newInstance())
|
.replace(R.id.container, KeysBackupSetupStep2Fragment.newInstance())
|
||||||
.commit()
|
.commit()
|
||||||
}
|
}
|
||||||
KeysBackupSetupSharedViewModel.NAVIGATE_TO_STEP_3 -> {
|
KeysBackupSetupSharedViewModel.NAVIGATE_TO_STEP_3 -> {
|
||||||
supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
|
supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
|
||||||
supportFragmentManager.beginTransaction()
|
supportFragmentManager.beginTransaction()
|
||||||
.replace(R.id.container, KeysBackupSetupStep3Fragment.newInstance())
|
.replace(R.id.container, KeysBackupSetupStep3Fragment.newInstance())
|
||||||
.commit()
|
.commit()
|
||||||
}
|
}
|
||||||
KeysBackupSetupSharedViewModel.NAVIGATE_FINISH -> {
|
KeysBackupSetupSharedViewModel.NAVIGATE_FINISH -> {
|
||||||
val resultIntent = Intent()
|
val resultIntent = Intent()
|
||||||
viewModel.keysVersion.value?.version?.let {
|
viewModel.keysVersion.value?.version?.let {
|
||||||
resultIntent.putExtra(KEYS_VERSION, it)
|
resultIntent.putExtra(KEYS_VERSION, it)
|
||||||
@ -87,7 +86,18 @@ class KeysBackupSetupActivity : SimpleFragmentActivity() {
|
|||||||
setResult(RESULT_OK, resultIntent)
|
setResult(RESULT_OK, resultIntent)
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
KeysBackupSetupSharedViewModel.NAVIGATE_MANUAL_EXPORT -> {
|
KeysBackupSetupSharedViewModel.NAVIGATE_PROMPT_REPLACE -> {
|
||||||
|
AlertDialog.Builder(this)
|
||||||
|
.setTitle(R.string.keys_backup_setup_override_backup_prompt_tile)
|
||||||
|
.setMessage(R.string.keys_backup_setup_override_backup_prompt_description)
|
||||||
|
.setPositiveButton(R.string.keys_backup_setup_override_replace) { _, _ ->
|
||||||
|
viewModel.forceCreateKeyBackup(this)
|
||||||
|
}.setNegativeButton(R.string.keys_backup_setup_override_stop) { _, _ ->
|
||||||
|
viewModel.stopAndKeepAfterDetectingExistingOnServer()
|
||||||
|
}
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
KeysBackupSetupSharedViewModel.NAVIGATE_MANUAL_EXPORT -> {
|
||||||
exportKeysManually()
|
exportKeysManually()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package im.vector.fragments.keysbackup.setup
|
package im.vector.riotredesign.features.crypto.keysbackup.setup
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
@ -26,6 +26,7 @@ import im.vector.matrix.android.api.session.Session
|
|||||||
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
|
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
|
||||||
import im.vector.matrix.android.internal.crypto.keysbackup.model.MegolmBackupCreationInfo
|
import im.vector.matrix.android.internal.crypto.keysbackup.model.MegolmBackupCreationInfo
|
||||||
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersion
|
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersion
|
||||||
|
import im.vector.matrix.android.internal.crypto.keysbackup.model.rest.KeysVersionResult
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.platform.WaitingViewData
|
import im.vector.riotredesign.core.platform.WaitingViewData
|
||||||
import im.vector.riotredesign.core.utils.LiveEvent
|
import im.vector.riotredesign.core.utils.LiveEvent
|
||||||
@ -39,6 +40,7 @@ class KeysBackupSetupSharedViewModel : ViewModel() {
|
|||||||
companion object {
|
companion object {
|
||||||
const val NAVIGATE_TO_STEP_2 = "NAVIGATE_TO_STEP_2"
|
const val NAVIGATE_TO_STEP_2 = "NAVIGATE_TO_STEP_2"
|
||||||
const val NAVIGATE_TO_STEP_3 = "NAVIGATE_TO_STEP_3"
|
const val NAVIGATE_TO_STEP_3 = "NAVIGATE_TO_STEP_3"
|
||||||
|
const val NAVIGATE_PROMPT_REPLACE = "NAVIGATE_PROMPT_REPLACE"
|
||||||
const val NAVIGATE_FINISH = "NAVIGATE_FINISH"
|
const val NAVIGATE_FINISH = "NAVIGATE_FINISH"
|
||||||
const val NAVIGATE_MANUAL_EXPORT = "NAVIGATE_MANUAL_EXPORT"
|
const val NAVIGATE_MANUAL_EXPORT = "NAVIGATE_MANUAL_EXPORT"
|
||||||
}
|
}
|
||||||
@ -123,15 +125,8 @@ class KeysBackupSetupSharedViewModel : ViewModel() {
|
|||||||
megolmBackupCreationInfo = data
|
megolmBackupCreationInfo = data
|
||||||
copyHasBeenMade = false
|
copyHasBeenMade = false
|
||||||
|
|
||||||
val keyBackup = session?.getKeysBackupService()
|
val keyBackup = session.getKeysBackupService()
|
||||||
if (keyBackup != null) {
|
createKeysBackup(context, keyBackup)
|
||||||
createKeysBackup(context, keyBackup)
|
|
||||||
} else {
|
|
||||||
loadingStatus.value = null
|
|
||||||
|
|
||||||
isCreatingBackupVersion.value = false
|
|
||||||
prepareRecoverFailError.value = Exception()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(failure: Throwable) {
|
override fun onFailure(failure: Throwable) {
|
||||||
@ -149,18 +144,32 @@ class KeysBackupSetupSharedViewModel : ViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createKeysBackup(context: Context, keysBackup: KeysBackupService) {
|
fun forceCreateKeyBackup(context: Context) {
|
||||||
|
val keyBackup = session.getKeysBackupService()
|
||||||
|
createKeysBackup(context, keyBackup, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stopAndKeepAfterDetectingExistingOnServer() {
|
||||||
|
loadingStatus.value = null
|
||||||
|
navigateEvent.value = LiveEvent(NAVIGATE_FINISH)
|
||||||
|
session.getKeysBackupService().checkAndStartKeysBackup()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createKeysBackup(context: Context, keysBackup: KeysBackupService, forceOverride: Boolean = false) {
|
||||||
loadingStatus.value = WaitingViewData(context.getString(R.string.keys_backup_setup_creating_backup), isIndeterminate = true)
|
loadingStatus.value = WaitingViewData(context.getString(R.string.keys_backup_setup_creating_backup), isIndeterminate = true)
|
||||||
|
|
||||||
creatingBackupError.value = null
|
creatingBackupError.value = null
|
||||||
keysBackup.createKeysBackupVersion(megolmBackupCreationInfo!!, object : MatrixCallback<KeysVersion> {
|
|
||||||
|
|
||||||
override fun onSuccess(data: KeysVersion) {
|
keysBackup.getCurrentVersion(object : MatrixCallback<KeysVersionResult?> {
|
||||||
loadingStatus.value = null
|
override fun onSuccess(data: KeysVersionResult?) {
|
||||||
|
if (data?.version.isNullOrBlank() || forceOverride) {
|
||||||
isCreatingBackupVersion.value = false
|
processOnCreate()
|
||||||
keysVersion.value = data
|
} else {
|
||||||
navigateEvent.value = LiveEvent(NAVIGATE_TO_STEP_3)
|
loadingStatus.value = null
|
||||||
|
// we should prompt
|
||||||
|
isCreatingBackupVersion.value = false
|
||||||
|
navigateEvent.value = LiveEvent(NAVIGATE_PROMPT_REPLACE)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(failure: Throwable) {
|
override fun onFailure(failure: Throwable) {
|
||||||
@ -170,7 +179,26 @@ class KeysBackupSetupSharedViewModel : ViewModel() {
|
|||||||
isCreatingBackupVersion.value = false
|
isCreatingBackupVersion.value = false
|
||||||
creatingBackupError.value = failure
|
creatingBackupError.value = failure
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun processOnCreate() {
|
||||||
|
keysBackup.createKeysBackupVersion(megolmBackupCreationInfo!!, object : MatrixCallback<KeysVersion> {
|
||||||
|
override fun onSuccess(data: KeysVersion) {
|
||||||
|
loadingStatus.value = null
|
||||||
|
|
||||||
|
isCreatingBackupVersion.value = false
|
||||||
|
keysVersion.value = data
|
||||||
|
navigateEvent.value = LiveEvent(NAVIGATE_TO_STEP_3)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(failure: Throwable) {
|
||||||
|
Timber.e(failure, "## createKeyBackupVersion")
|
||||||
|
loadingStatus.value = null
|
||||||
|
|
||||||
|
isCreatingBackupVersion.value = false
|
||||||
|
creatingBackupError.value = failure
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -24,7 +24,6 @@ import androidx.lifecycle.Observer
|
|||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.lifecycle.ViewModelProviders
|
||||||
import butterknife.BindView
|
import butterknife.BindView
|
||||||
import butterknife.OnClick
|
import butterknife.OnClick
|
||||||
import im.vector.fragments.keysbackup.setup.KeysBackupSetupSharedViewModel
|
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||||
import im.vector.riotredesign.core.utils.LiveEvent
|
import im.vector.riotredesign.core.utils.LiveEvent
|
||||||
|
@ -30,7 +30,6 @@ import butterknife.OnClick
|
|||||||
import butterknife.OnTextChanged
|
import butterknife.OnTextChanged
|
||||||
import com.google.android.material.textfield.TextInputLayout
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
import com.nulabinc.zxcvbn.Zxcvbn
|
import com.nulabinc.zxcvbn.Zxcvbn
|
||||||
import im.vector.fragments.keysbackup.setup.KeysBackupSetupSharedViewModel
|
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.extensions.showPassword
|
import im.vector.riotredesign.core.extensions.showPassword
|
||||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||||
|
@ -29,7 +29,6 @@ import arrow.core.Try
|
|||||||
import butterknife.BindView
|
import butterknife.BindView
|
||||||
import butterknife.OnClick
|
import butterknife.OnClick
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
import im.vector.fragments.keysbackup.setup.KeysBackupSetupSharedViewModel
|
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.files.addEntryToDownloadManager
|
import im.vector.riotredesign.core.files.addEntryToDownloadManager
|
||||||
import im.vector.riotredesign.core.files.writeToFile
|
import im.vector.riotredesign.core.files.writeToFile
|
||||||
|
@ -46,6 +46,8 @@ import kotlinx.android.synthetic.main.activity_home.*
|
|||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
import org.koin.android.scope.ext.android.bindScope
|
import org.koin.android.scope.ext.android.bindScope
|
||||||
import org.koin.android.scope.ext.android.getOrCreateScope
|
import org.koin.android.scope.ext.android.getOrCreateScope
|
||||||
|
import im.vector.riotredesign.features.workers.signout.SignOutViewModel
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
|
class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||||
@ -130,6 +132,9 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
|
|||||||
.setNegativeButton(R.string.no) { _, _ -> BugReporter.deleteCrashFile(this) }
|
.setNegativeButton(R.string.no) { _, _ -> BugReporter.deleteCrashFile(this) }
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Force remote backup state update to update the banner if needed
|
||||||
|
ViewModelProviders.of(this).get(SignOutViewModel::class.java).refreshRemoteStateIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun configure(toolbar: Toolbar) {
|
override fun configure(toolbar: Toolbar) {
|
||||||
|
@ -81,6 +81,12 @@ class SignOutViewModel : ViewModel(), KeysBackupStateListener {
|
|||||||
keysBackupState.value = newState
|
keysBackupState.value = newState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun refreshRemoteStateIfNeeded() {
|
||||||
|
if (keysBackupState.value == KeysBackupState.Disabled) {
|
||||||
|
mxSession?.getKeysBackupService()?.checkAndStartKeysBackup()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
/**
|
/**
|
||||||
* The backup check on logout flow has to be displayed if there are keys in the store, and the keys backup state is not Ready
|
* The backup check on logout flow has to be displayed if there are keys in the store, and the keys backup state is not Ready
|
||||||
|
Loading…
Reference in New Issue
Block a user