Suspend API: handle verification service
This commit is contained in:
parent
e121007d20
commit
0590258d54
|
@ -36,7 +36,7 @@ interface VerificationService {
|
||||||
/**
|
/**
|
||||||
* Mark this device as verified manually
|
* Mark this device as verified manually
|
||||||
*/
|
*/
|
||||||
fun markedLocallyAsManuallyVerified(userId: String, deviceID: String)
|
suspend fun markedLocallyAsManuallyVerified(userId: String, deviceID: String)
|
||||||
|
|
||||||
fun getExistingTransaction(otherUserId: String, tid: String): VerificationTransaction?
|
fun getExistingTransaction(otherUserId: String, tid: String): VerificationTransaction?
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ interface VerificationService {
|
||||||
|
|
||||||
fun getExistingVerificationRequestInRoom(roomId: String, tid: String?): PendingVerificationRequest?
|
fun getExistingVerificationRequestInRoom(roomId: String, tid: String?): PendingVerificationRequest?
|
||||||
|
|
||||||
fun beginKeyVerification(method: VerificationMethod,
|
suspend fun beginKeyVerification(method: VerificationMethod,
|
||||||
otherUserId: String,
|
otherUserId: String,
|
||||||
otherDeviceId: String,
|
otherDeviceId: String,
|
||||||
transactionId: String?): String?
|
transactionId: String?): String?
|
||||||
|
@ -54,27 +54,27 @@ interface VerificationService {
|
||||||
/**
|
/**
|
||||||
* Request key verification with another user via room events (instead of the to-device API)
|
* Request key verification with another user via room events (instead of the to-device API)
|
||||||
*/
|
*/
|
||||||
fun requestKeyVerificationInDMs(methods: List<VerificationMethod>,
|
suspend fun requestKeyVerificationInDMs(methods: List<VerificationMethod>,
|
||||||
otherUserId: String,
|
otherUserId: String,
|
||||||
roomId: String,
|
roomId: String,
|
||||||
localId: String? = LocalEcho.createLocalEchoId()): PendingVerificationRequest
|
localId: String? = LocalEcho.createLocalEchoId()): PendingVerificationRequest
|
||||||
|
|
||||||
fun cancelVerificationRequest(request: PendingVerificationRequest)
|
suspend fun cancelVerificationRequest(request: PendingVerificationRequest)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request a key verification from another user using toDevice events.
|
* Request a key verification from another user using toDevice events.
|
||||||
*/
|
*/
|
||||||
fun requestKeyVerification(methods: List<VerificationMethod>,
|
suspend fun requestKeyVerification(methods: List<VerificationMethod>,
|
||||||
otherUserId: String,
|
otherUserId: String,
|
||||||
otherDevices: List<String>?): PendingVerificationRequest
|
otherDevices: List<String>?): PendingVerificationRequest
|
||||||
|
|
||||||
fun declineVerificationRequestInDMs(otherUserId: String,
|
suspend fun declineVerificationRequestInDMs(otherUserId: String,
|
||||||
transactionId: String,
|
transactionId: String,
|
||||||
roomId: String)
|
roomId: String)
|
||||||
|
|
||||||
// Only SAS method is supported for the moment
|
// Only SAS method is supported for the moment
|
||||||
// TODO Parameter otherDeviceId should be removed in this case
|
// TODO Parameter otherDeviceId should be removed in this case
|
||||||
fun beginKeyVerificationInDMs(method: VerificationMethod,
|
suspend fun beginKeyVerificationInDMs(method: VerificationMethod,
|
||||||
transactionId: String,
|
transactionId: String,
|
||||||
roomId: String,
|
roomId: String,
|
||||||
otherUserId: String,
|
otherUserId: String,
|
||||||
|
@ -83,7 +83,7 @@ interface VerificationService {
|
||||||
/**
|
/**
|
||||||
* Returns false if the request is unknown
|
* Returns false if the request is unknown
|
||||||
*/
|
*/
|
||||||
fun readyPendingVerificationInDMs(methods: List<VerificationMethod>,
|
suspend fun readyPendingVerificationInDMs(methods: List<VerificationMethod>,
|
||||||
otherUserId: String,
|
otherUserId: String,
|
||||||
roomId: String,
|
roomId: String,
|
||||||
transactionId: String): Boolean
|
transactionId: String): Boolean
|
||||||
|
@ -91,7 +91,7 @@ interface VerificationService {
|
||||||
/**
|
/**
|
||||||
* Returns false if the request is unknown
|
* Returns false if the request is unknown
|
||||||
*/
|
*/
|
||||||
fun readyPendingVerification(methods: List<VerificationMethod>,
|
suspend fun readyPendingVerification(methods: List<VerificationMethod>,
|
||||||
otherUserId: String,
|
otherUserId: String,
|
||||||
transactionId: String): Boolean
|
transactionId: String): Boolean
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.crypto.verification
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest
|
import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
||||||
|
@ -162,12 +161,10 @@ internal class RustVerificationService @Inject constructor(private val olmMachin
|
||||||
this.dispatcher.removeListener(listener)
|
this.dispatcher.removeListener(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) {
|
override suspend fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) {
|
||||||
// TODO this doesn't seem to be used anymore?
|
// TODO this doesn't seem to be used anymore?
|
||||||
runBlocking {
|
val device = olmMachine.getDevice(userId, deviceID)
|
||||||
val device = olmMachine.getDevice(userId, deviceID)
|
device?.markAsTrusted()
|
||||||
device?.markAsTrusted()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPotentiallyInterestingEventRoomFailToDecrypt(event: Event) {
|
override fun onPotentiallyInterestingEventRoomFailToDecrypt(event: Event) {
|
||||||
|
@ -224,13 +221,13 @@ internal class RustVerificationService @Inject constructor(private val olmMachin
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun requestKeyVerification(
|
override suspend fun requestKeyVerification(
|
||||||
methods: List<VerificationMethod>,
|
methods: List<VerificationMethod>,
|
||||||
otherUserId: String,
|
otherUserId: String,
|
||||||
otherDevices: List<String>?
|
otherDevices: List<String>?
|
||||||
): PendingVerificationRequest {
|
): PendingVerificationRequest {
|
||||||
val verification = when (val identity = runBlocking { olmMachine.getIdentity(otherUserId) }) {
|
val verification = when (val identity = olmMachine.getIdentity(otherUserId)) {
|
||||||
is OwnUserIdentity -> runBlocking { identity.requestVerification(methods) }
|
is OwnUserIdentity -> identity.requestVerification(methods)
|
||||||
is UserIdentity -> throw IllegalArgumentException("This method doesn't support verification of other users devices")
|
is UserIdentity -> throw IllegalArgumentException("This method doesn't support verification of other users devices")
|
||||||
null -> throw IllegalArgumentException("Cross signing has not been bootstrapped for our own user")
|
null -> throw IllegalArgumentException("Cross signing has not been bootstrapped for our own user")
|
||||||
}
|
}
|
||||||
|
@ -238,15 +235,15 @@ internal class RustVerificationService @Inject constructor(private val olmMachin
|
||||||
return verification.toPendingVerificationRequest()
|
return verification.toPendingVerificationRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun requestKeyVerificationInDMs(
|
override suspend fun requestKeyVerificationInDMs(
|
||||||
methods: List<VerificationMethod>,
|
methods: List<VerificationMethod>,
|
||||||
otherUserId: String,
|
otherUserId: String,
|
||||||
roomId: String,
|
roomId: String,
|
||||||
localId: String?
|
localId: String?
|
||||||
): PendingVerificationRequest {
|
): PendingVerificationRequest {
|
||||||
Timber.i("## SAS Requesting verification to user: $otherUserId in room $roomId")
|
Timber.i("## SAS Requesting verification to user: $otherUserId in room $roomId")
|
||||||
val verification = when (val identity = runBlocking { olmMachine.getIdentity(otherUserId) }) {
|
val verification = when (val identity = olmMachine.getIdentity(otherUserId)) {
|
||||||
is UserIdentity -> runBlocking { identity.requestVerification(methods, roomId, localId!!) }
|
is UserIdentity -> identity.requestVerification(methods, roomId, localId!!)
|
||||||
is OwnUserIdentity -> throw IllegalArgumentException("This method doesn't support verification of our own user")
|
is OwnUserIdentity -> throw IllegalArgumentException("This method doesn't support verification of our own user")
|
||||||
null -> throw IllegalArgumentException("The user that we wish to verify doesn't support cross signing")
|
null -> throw IllegalArgumentException("The user that we wish to verify doesn't support cross signing")
|
||||||
}
|
}
|
||||||
|
@ -254,7 +251,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin
|
||||||
return verification.toPendingVerificationRequest()
|
return verification.toPendingVerificationRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun readyPendingVerification(
|
override suspend fun readyPendingVerification(
|
||||||
methods: List<VerificationMethod>,
|
methods: List<VerificationMethod>,
|
||||||
otherUserId: String,
|
otherUserId: String,
|
||||||
transactionId: String
|
transactionId: String
|
||||||
|
@ -262,7 +259,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin
|
||||||
val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId)
|
val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId)
|
||||||
|
|
||||||
return if (request != null) {
|
return if (request != null) {
|
||||||
runBlocking { request.acceptWithMethods(methods) }
|
request.acceptWithMethods(methods)
|
||||||
|
|
||||||
if (request.isReady()) {
|
if (request.isReady()) {
|
||||||
val qrcode = request.startQrVerification()
|
val qrcode = request.startQrVerification()
|
||||||
|
@ -280,7 +277,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun readyPendingVerificationInDMs(
|
override suspend fun readyPendingVerificationInDMs(
|
||||||
methods: List<VerificationMethod>,
|
methods: List<VerificationMethod>,
|
||||||
otherUserId: String,
|
otherUserId: String,
|
||||||
roomId: String,
|
roomId: String,
|
||||||
|
@ -289,7 +286,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin
|
||||||
return readyPendingVerification(methods, otherUserId, transactionId)
|
return readyPendingVerification(methods, otherUserId, transactionId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun beginKeyVerification(
|
override suspend fun beginKeyVerification(
|
||||||
method: VerificationMethod,
|
method: VerificationMethod,
|
||||||
otherUserId: String,
|
otherUserId: String,
|
||||||
otherDeviceId: String,
|
otherDeviceId: String,
|
||||||
|
@ -299,15 +296,13 @@ internal class RustVerificationService @Inject constructor(private val olmMachin
|
||||||
if (transactionId != null) {
|
if (transactionId != null) {
|
||||||
val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId)
|
val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId)
|
||||||
|
|
||||||
runBlocking {
|
val sas = request?.startSasVerification()
|
||||||
val sas = request?.startSasVerification()
|
|
||||||
|
|
||||||
if (sas != null) {
|
if (sas != null) {
|
||||||
dispatcher.dispatchTxAdded(sas)
|
dispatcher.dispatchTxAdded(sas)
|
||||||
sas.transactionId
|
sas.transactionId
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// This starts the short SAS flow, the one that doesn't start with
|
// This starts the short SAS flow, the one that doesn't start with
|
||||||
|
@ -315,14 +310,12 @@ internal class RustVerificationService @Inject constructor(private val olmMachin
|
||||||
// be wise do do so as well
|
// be wise do do so as well
|
||||||
// DeviceListBottomSheetViewModel triggers this, interestingly the method that
|
// DeviceListBottomSheetViewModel triggers this, interestingly the method that
|
||||||
// triggers this is called `manuallyVerify()`
|
// triggers this is called `manuallyVerify()`
|
||||||
runBlocking {
|
val verification = olmMachine.getDevice(otherUserId, otherDeviceId)?.startVerification()
|
||||||
val verification = olmMachine.getDevice(otherUserId, otherDeviceId)?.startVerification()
|
if (verification != null) {
|
||||||
if (verification != null) {
|
dispatcher.dispatchTxAdded(verification)
|
||||||
dispatcher.dispatchTxAdded(verification)
|
verification.transactionId
|
||||||
verification.transactionId
|
} else {
|
||||||
} else {
|
null
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -330,7 +323,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun beginKeyVerificationInDMs(
|
override suspend fun beginKeyVerificationInDMs(
|
||||||
method: VerificationMethod,
|
method: VerificationMethod,
|
||||||
transactionId: String,
|
transactionId: String,
|
||||||
roomId: String,
|
roomId: String,
|
||||||
|
@ -343,19 +336,19 @@ internal class RustVerificationService @Inject constructor(private val olmMachin
|
||||||
return transactionId
|
return transactionId
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cancelVerificationRequest(request: PendingVerificationRequest) {
|
override suspend fun cancelVerificationRequest(request: PendingVerificationRequest) {
|
||||||
val verificationRequest = request.transactionId?.let {
|
val verificationRequest = request.transactionId?.let {
|
||||||
this.olmMachine.getVerificationRequest(request.otherUserId, it)
|
this.olmMachine.getVerificationRequest(request.otherUserId, it)
|
||||||
}
|
}
|
||||||
runBlocking { verificationRequest?.cancel() }
|
verificationRequest?.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun declineVerificationRequestInDMs(
|
override suspend fun declineVerificationRequestInDMs(
|
||||||
otherUserId: String,
|
otherUserId: String,
|
||||||
transactionId: String,
|
transactionId: String,
|
||||||
roomId: String
|
roomId: String
|
||||||
) {
|
) {
|
||||||
val verificationRequest = this.olmMachine.getVerificationRequest(otherUserId, transactionId)
|
val verificationRequest = this.olmMachine.getVerificationRequest(otherUserId, transactionId)
|
||||||
runBlocking { verificationRequest?.cancel() }
|
verificationRequest?.cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,10 +149,12 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
|
||||||
// as we are going to reset, we'd better cancel all outgoing requests
|
// as we are going to reset, we'd better cancel all outgoing requests
|
||||||
// if not they could be accepted in the middle of the reset process
|
// if not they could be accepted in the middle of the reset process
|
||||||
// and cause strange use cases
|
// and cause strange use cases
|
||||||
session.cryptoService().verificationService().getExistingVerificationRequests(session.myUserId).forEach {
|
viewModelScope.launch {
|
||||||
session.cryptoService().verificationService().cancelVerificationRequest(it)
|
session.cryptoService().verificationService().getExistingVerificationRequests(session.myUserId).forEach {
|
||||||
|
session.cryptoService().verificationService().cancelVerificationRequest(it)
|
||||||
|
}
|
||||||
|
_viewEvents.post(SharedSecureStorageViewEvent.ShowResetBottomSheet)
|
||||||
}
|
}
|
||||||
_viewEvents.post(SharedSecureStorageViewEvent.ShowResetBottomSheet)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleResetAll() {
|
private fun handleResetAll() {
|
||||||
|
|
|
@ -24,6 +24,8 @@ import im.vector.app.features.home.room.detail.RoomDetailActivity
|
||||||
import im.vector.app.features.home.room.detail.arguments.TimelineArgs
|
import im.vector.app.features.home.room.detail.arguments.TimelineArgs
|
||||||
import im.vector.app.features.popup.PopupAlertManager
|
import im.vector.app.features.popup.PopupAlertManager
|
||||||
import im.vector.app.features.popup.VerificationVectorAlert
|
import im.vector.app.features.popup.VerificationVectorAlert
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest
|
import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
||||||
|
@ -42,7 +44,8 @@ import javax.inject.Singleton
|
||||||
class IncomingVerificationRequestHandler @Inject constructor(
|
class IncomingVerificationRequestHandler @Inject constructor(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private var avatarRenderer: Provider<AvatarRenderer>,
|
private var avatarRenderer: Provider<AvatarRenderer>,
|
||||||
private val popupAlertManager: PopupAlertManager) : VerificationService.Listener {
|
private val popupAlertManager: PopupAlertManager,
|
||||||
|
private val coroutineScope: CoroutineScope) : VerificationService.Listener {
|
||||||
|
|
||||||
private var session: Session? = null
|
private var session: Session? = null
|
||||||
|
|
||||||
|
@ -61,7 +64,7 @@ class IncomingVerificationRequestHandler @Inject constructor(
|
||||||
// TODO maybe check also if
|
// TODO maybe check also if
|
||||||
val uid = "kvr_${tx.transactionId}"
|
val uid = "kvr_${tx.transactionId}"
|
||||||
when (tx.state) {
|
when (tx.state) {
|
||||||
is VerificationTxState.OnStarted -> {
|
is VerificationTxState.OnStarted -> {
|
||||||
// Add a notification for every incoming request
|
// Add a notification for every incoming request
|
||||||
val user = session?.getUser(tx.otherUserId)
|
val user = session?.getUser(tx.otherUserId)
|
||||||
val name = user?.toMatrixItem()?.getBestName() ?: tx.otherUserId
|
val name = user?.toMatrixItem()?.getBestName() ?: tx.otherUserId
|
||||||
|
@ -161,10 +164,12 @@ class IncomingVerificationRequestHandler @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dismissedAction = Runnable {
|
dismissedAction = Runnable {
|
||||||
session?.cryptoService()?.verificationService()?.declineVerificationRequestInDMs(pr.otherUserId,
|
coroutineScope.launch {
|
||||||
pr.transactionId ?: "",
|
session?.cryptoService()?.verificationService()?.declineVerificationRequestInDMs(pr.otherUserId,
|
||||||
pr.roomId ?: ""
|
pr.transactionId ?: "",
|
||||||
)
|
pr.roomId ?: ""
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
colorAttribute = R.attr.vctr_notice_secondary
|
colorAttribute = R.attr.vctr_notice_secondary
|
||||||
// 5mn expiration
|
// 5mn expiration
|
||||||
|
|
|
@ -152,13 +152,15 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (autoReady) {
|
if (autoReady) {
|
||||||
// TODO, can I be here in DM mode? in this case should test if roomID is null?
|
viewModelScope.launch {
|
||||||
session.cryptoService().verificationService()
|
// TODO, can I be here in DM mode? in this case should test if roomID is null?
|
||||||
.readyPendingVerification(
|
session.cryptoService().verificationService()
|
||||||
supportedVerificationMethodsProvider.provide(),
|
.readyPendingVerification(
|
||||||
pr!!.otherUserId,
|
supportedVerificationMethodsProvider.provide(),
|
||||||
pr.transactionId ?: ""
|
pr!!.otherUserId,
|
||||||
)
|
pr.transactionId ?: ""
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,14 +194,16 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun cancelAllPendingVerifications(state: VerificationBottomSheetViewState) {
|
private fun cancelAllPendingVerifications(state: VerificationBottomSheetViewState) {
|
||||||
session.cryptoService()
|
viewModelScope.launch {
|
||||||
.verificationService().getExistingVerificationRequest(state.otherUserMxItem?.id ?: "", state.transactionId)?.let {
|
session.cryptoService()
|
||||||
session.cryptoService().verificationService().cancelVerificationRequest(it)
|
.verificationService().getExistingVerificationRequest(state.otherUserMxItem?.id ?: "", state.transactionId)?.let {
|
||||||
}
|
session.cryptoService().verificationService().cancelVerificationRequest(it)
|
||||||
session.cryptoService()
|
}
|
||||||
.verificationService()
|
session.cryptoService()
|
||||||
.getExistingTransaction(state.otherUserMxItem?.id ?: "", state.transactionId ?: "")
|
.verificationService()
|
||||||
?.cancel(CancelCode.User)
|
.getExistingTransaction(state.otherUserMxItem?.id ?: "", state.transactionId ?: "")
|
||||||
|
?.cancel(CancelCode.User)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun continueFromCancel() {
|
fun continueFromCancel() {
|
||||||
|
@ -232,74 +236,29 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
when (action) {
|
when (action) {
|
||||||
is VerificationAction.RequestVerificationByDM -> {
|
is VerificationAction.RequestVerificationByDM -> {
|
||||||
if (roomId == null) {
|
handleRequestVerificationByDM(roomId, otherUserId)
|
||||||
val localId = LocalEcho.createLocalEchoId()
|
|
||||||
setState {
|
|
||||||
copy(
|
|
||||||
pendingLocalId = localId,
|
|
||||||
pendingRequest = Loading()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
viewModelScope.launch {
|
|
||||||
val result = runCatching { session.createDirectRoom(otherUserId) }
|
|
||||||
result.fold(
|
|
||||||
{ data ->
|
|
||||||
setState {
|
|
||||||
copy(
|
|
||||||
roomId = data,
|
|
||||||
pendingRequest = Success(
|
|
||||||
session
|
|
||||||
.cryptoService()
|
|
||||||
.verificationService()
|
|
||||||
.requestKeyVerificationInDMs(
|
|
||||||
supportedVerificationMethodsProvider.provide(),
|
|
||||||
otherUserId,
|
|
||||||
data,
|
|
||||||
pendingLocalId
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ failure ->
|
|
||||||
setState {
|
|
||||||
copy(pendingRequest = Fail(failure))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setState {
|
|
||||||
copy(
|
|
||||||
pendingRequest = Success(session
|
|
||||||
.cryptoService()
|
|
||||||
.verificationService()
|
|
||||||
.requestKeyVerificationInDMs(supportedVerificationMethodsProvider.provide(), otherUserId, roomId)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Unit
|
|
||||||
}
|
}
|
||||||
is VerificationAction.StartSASVerification -> {
|
is VerificationAction.StartSASVerification -> {
|
||||||
val request = session.cryptoService().verificationService().getExistingVerificationRequest(otherUserId, action.pendingRequestTransactionId)
|
val request = session.cryptoService().verificationService().getExistingVerificationRequest(otherUserId, action.pendingRequestTransactionId)
|
||||||
?: return@withState
|
?: return@withState
|
||||||
val otherDevice = if (request.isIncoming) request.requestInfo?.fromDevice else request.readyInfo?.fromDevice
|
val otherDevice = if (request.isIncoming) request.requestInfo?.fromDevice else request.readyInfo?.fromDevice
|
||||||
if (roomId == null) {
|
viewModelScope.launch {
|
||||||
session.cryptoService().verificationService().beginKeyVerification(
|
if (roomId == null) {
|
||||||
VerificationMethod.SAS,
|
session.cryptoService().verificationService().beginKeyVerification(
|
||||||
otherUserId = request.otherUserId,
|
VerificationMethod.SAS,
|
||||||
otherDeviceId = otherDevice ?: "",
|
otherUserId = request.otherUserId,
|
||||||
transactionId = action.pendingRequestTransactionId
|
otherDeviceId = otherDevice ?: "",
|
||||||
)
|
transactionId = action.pendingRequestTransactionId
|
||||||
} else {
|
)
|
||||||
session.cryptoService().verificationService().beginKeyVerificationInDMs(
|
} else {
|
||||||
VerificationMethod.SAS,
|
session.cryptoService().verificationService().beginKeyVerificationInDMs(
|
||||||
transactionId = action.pendingRequestTransactionId,
|
VerificationMethod.SAS,
|
||||||
roomId = roomId,
|
transactionId = action.pendingRequestTransactionId,
|
||||||
otherUserId = request.otherUserId,
|
roomId = roomId,
|
||||||
otherDeviceId = otherDevice ?: ""
|
otherUserId = request.otherUserId,
|
||||||
)
|
otherDeviceId = otherDevice ?: ""
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Unit
|
Unit
|
||||||
}
|
}
|
||||||
|
@ -365,6 +324,50 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
||||||
}.exhaustive
|
}.exhaustive
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handleRequestVerificationByDM(roomId: String?, otherUserId: String) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
if (roomId == null) {
|
||||||
|
val localId = LocalEcho.createLocalEchoId()
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
pendingLocalId = localId,
|
||||||
|
pendingRequest = Loading()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
val dmRoomId = session.createDirectRoom(otherUserId)
|
||||||
|
val pendingRequest = session
|
||||||
|
.cryptoService()
|
||||||
|
.verificationService()
|
||||||
|
.requestKeyVerificationInDMs(
|
||||||
|
supportedVerificationMethodsProvider.provide(),
|
||||||
|
otherUserId,
|
||||||
|
dmRoomId,
|
||||||
|
localId
|
||||||
|
)
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
roomId = dmRoomId,
|
||||||
|
pendingRequest = Success(pendingRequest)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} catch (failure: Throwable) {
|
||||||
|
setState {
|
||||||
|
copy(pendingRequest = Fail(failure))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val pendingRequest = session
|
||||||
|
.cryptoService()
|
||||||
|
.verificationService()
|
||||||
|
.requestKeyVerificationInDMs(supportedVerificationMethodsProvider.provide(), otherUserId, roomId)
|
||||||
|
setState {
|
||||||
|
copy(pendingRequest = Success(pendingRequest))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun handleSecretBackFromSSSS(action: VerificationAction.GotResultFromSsss) {
|
private fun handleSecretBackFromSSSS(action: VerificationAction.GotResultFromSsss) {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
|
@ -514,12 +517,14 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
||||||
if (!pr.isReady) {
|
if (!pr.isReady) {
|
||||||
// auto ready in this case, as we are waiting
|
// auto ready in this case, as we are waiting
|
||||||
// TODO, can I be here in DM mode? in this case should test if roomID is null?
|
// TODO, can I be here in DM mode? in this case should test if roomID is null?
|
||||||
session.cryptoService().verificationService()
|
viewModelScope.launch {
|
||||||
.readyPendingVerification(
|
session.cryptoService().verificationService()
|
||||||
supportedVerificationMethodsProvider.provide(),
|
.readyPendingVerification(
|
||||||
pr.otherUserId,
|
supportedVerificationMethodsProvider.provide(),
|
||||||
pr.transactionId ?: ""
|
pr.otherUserId,
|
||||||
)
|
pr.transactionId ?: ""
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use this one!
|
// Use this one!
|
||||||
|
|
|
@ -994,22 +994,26 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
private fun handleAcceptVerification(action: RoomDetailAction.AcceptVerificationRequest) {
|
private fun handleAcceptVerification(action: RoomDetailAction.AcceptVerificationRequest) {
|
||||||
Timber.v("## SAS handleAcceptVerification ${action.otherUserId}, roomId:${room.roomId}, txId:${action.transactionId}")
|
Timber.v("## SAS handleAcceptVerification ${action.otherUserId}, roomId:${room.roomId}, txId:${action.transactionId}")
|
||||||
if (session.cryptoService().verificationService().readyPendingVerificationInDMs(
|
viewModelScope.launch {
|
||||||
supportedVerificationMethodsProvider.provide(),
|
if (session.cryptoService().verificationService().readyPendingVerificationInDMs(
|
||||||
action.otherUserId,
|
supportedVerificationMethodsProvider.provide(),
|
||||||
room.roomId,
|
action.otherUserId,
|
||||||
action.transactionId)) {
|
room.roomId,
|
||||||
_viewEvents.post(RoomDetailViewEvents.ActionSuccess(action))
|
action.transactionId)) {
|
||||||
} else {
|
_viewEvents.post(RoomDetailViewEvents.ActionSuccess(action))
|
||||||
// TODO
|
} else {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleDeclineVerification(action: RoomDetailAction.DeclineVerificationRequest) {
|
private fun handleDeclineVerification(action: RoomDetailAction.DeclineVerificationRequest) {
|
||||||
session.cryptoService().verificationService().declineVerificationRequestInDMs(
|
viewModelScope.launch {
|
||||||
action.otherUserId,
|
session.cryptoService().verificationService().declineVerificationRequestInDMs(
|
||||||
action.transactionId,
|
action.otherUserId,
|
||||||
room.roomId)
|
action.transactionId,
|
||||||
|
room.roomId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleRequestVerification(action: RoomDetailAction.RequestVerification) {
|
private fun handleRequestVerification(action: RoomDetailAction.RequestVerification) {
|
||||||
|
|
|
@ -100,6 +100,8 @@ import im.vector.app.features.terms.ReviewTermsActivity
|
||||||
import im.vector.app.features.widgets.WidgetActivity
|
import im.vector.app.features.widgets.WidgetActivity
|
||||||
import im.vector.app.features.widgets.WidgetArgsBuilder
|
import im.vector.app.features.widgets.WidgetArgsBuilder
|
||||||
import im.vector.app.space
|
import im.vector.app.space
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction
|
import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction
|
||||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkData
|
import org.matrix.android.sdk.api.session.permalinks.PermalinkData
|
||||||
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom
|
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom
|
||||||
|
@ -116,7 +118,8 @@ class DefaultNavigator @Inject constructor(
|
||||||
private val widgetArgsBuilder: WidgetArgsBuilder,
|
private val widgetArgsBuilder: WidgetArgsBuilder,
|
||||||
private val appStateHandler: AppStateHandler,
|
private val appStateHandler: AppStateHandler,
|
||||||
private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider,
|
private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider,
|
||||||
private val features: VectorFeatures
|
private val features: VectorFeatures,
|
||||||
|
private val coroutineScope: CoroutineScope
|
||||||
) : Navigator {
|
) : Navigator {
|
||||||
|
|
||||||
override fun openLogin(context: Context, loginConfig: LoginConfig?, flags: Int) {
|
override fun openLogin(context: Context, loginConfig: LoginConfig?, flags: Int) {
|
||||||
|
@ -210,38 +213,42 @@ class DefaultNavigator @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun requestSessionVerification(context: Context, otherSessionId: String) {
|
override fun requestSessionVerification(context: Context, otherSessionId: String) {
|
||||||
val session = sessionHolder.getSafeActiveSession() ?: return
|
coroutineScope.launch {
|
||||||
val pr = session.cryptoService().verificationService().requestKeyVerification(
|
val session = sessionHolder.getSafeActiveSession() ?: return@launch
|
||||||
supportedVerificationMethodsProvider.provide(),
|
val pr = session.cryptoService().verificationService().requestKeyVerification(
|
||||||
session.myUserId,
|
supportedVerificationMethodsProvider.provide(),
|
||||||
listOf(otherSessionId)
|
session.myUserId,
|
||||||
)
|
listOf(otherSessionId)
|
||||||
if (context is AppCompatActivity) {
|
)
|
||||||
VerificationBottomSheet.withArgs(
|
if (context is AppCompatActivity) {
|
||||||
roomId = null,
|
VerificationBottomSheet.withArgs(
|
||||||
otherUserId = session.myUserId,
|
roomId = null,
|
||||||
transactionId = pr.transactionId
|
otherUserId = session.myUserId,
|
||||||
).show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG)
|
transactionId = pr.transactionId
|
||||||
|
).show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun requestSelfSessionVerification(context: Context) {
|
override fun requestSelfSessionVerification(context: Context) {
|
||||||
val session = sessionHolder.getSafeActiveSession() ?: return
|
coroutineScope.launch {
|
||||||
val otherSessions = session.cryptoService()
|
val session = sessionHolder.getSafeActiveSession() ?: return@launch
|
||||||
.getCryptoDeviceInfo(session.myUserId)
|
val otherSessions = session.cryptoService()
|
||||||
.filter { it.deviceId != session.sessionParams.deviceId }
|
.getCryptoDeviceInfo(session.myUserId)
|
||||||
.map { it.deviceId }
|
.filter { it.deviceId != session.sessionParams.deviceId }
|
||||||
if (context is AppCompatActivity) {
|
.map { it.deviceId }
|
||||||
if (otherSessions.isNotEmpty()) {
|
if (context is AppCompatActivity) {
|
||||||
val pr = session.cryptoService().verificationService().requestKeyVerification(
|
if (otherSessions.isNotEmpty()) {
|
||||||
supportedVerificationMethodsProvider.provide(),
|
val pr = session.cryptoService().verificationService().requestKeyVerification(
|
||||||
session.myUserId,
|
supportedVerificationMethodsProvider.provide(),
|
||||||
otherSessions)
|
session.myUserId,
|
||||||
VerificationBottomSheet.forSelfVerification(session, pr.transactionId ?: pr.localId)
|
otherSessions)
|
||||||
.show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG)
|
VerificationBottomSheet.forSelfVerification(session, pr.transactionId ?: pr.localId)
|
||||||
} else {
|
.show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG)
|
||||||
VerificationBottomSheet.forSelfVerification(session)
|
} else {
|
||||||
.show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG)
|
VerificationBottomSheet.forSelfVerification(session)
|
||||||
|
.show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import im.vector.app.core.di.SingletonEntryPoint
|
||||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
import im.vector.app.core.extensions.exhaustive
|
import im.vector.app.core.extensions.exhaustive
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo
|
import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
||||||
|
@ -124,8 +125,14 @@ class DeviceListBottomSheetViewModel @AssistedInject constructor(@Assisted priva
|
||||||
|
|
||||||
private fun manuallyVerify(action: DeviceListAction.ManuallyVerify) {
|
private fun manuallyVerify(action: DeviceListAction.ManuallyVerify) {
|
||||||
if (!initialState.allowDeviceAction) return
|
if (!initialState.allowDeviceAction) return
|
||||||
session.cryptoService().verificationService().beginKeyVerification(VerificationMethod.SAS, initialState.userId, action.deviceId, null)?.let { txID ->
|
viewModelScope.launch {
|
||||||
_viewEvents.post(DeviceListBottomSheetViewEvents.Verify(initialState.userId, txID))
|
session.cryptoService().verificationService().beginKeyVerification(
|
||||||
|
method = VerificationMethod.SAS,
|
||||||
|
otherUserId = initialState.userId,
|
||||||
|
otherDeviceId = action.deviceId,
|
||||||
|
transactionId = null)?.let { txID ->
|
||||||
|
_viewEvents.post(DeviceListBottomSheetViewEvents.Verify(initialState.userId, txID))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,13 +240,15 @@ class DevicesViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleInteractiveVerification(action: DevicesAction.VerifyMyDevice) {
|
private fun handleInteractiveVerification(action: DevicesAction.VerifyMyDevice) {
|
||||||
val txID = session.cryptoService()
|
viewModelScope.launch {
|
||||||
.verificationService()
|
val txID = session.cryptoService()
|
||||||
.beginKeyVerification(VerificationMethod.SAS, session.myUserId, action.deviceId, null)
|
.verificationService()
|
||||||
_viewEvents.post(DevicesViewEvents.ShowVerifyDevice(
|
.beginKeyVerification(VerificationMethod.SAS, session.myUserId, action.deviceId, null)
|
||||||
session.myUserId,
|
_viewEvents.post(DevicesViewEvents.ShowVerifyDevice(
|
||||||
txID
|
session.myUserId,
|
||||||
))
|
txID
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleShowDeviceCryptoInfo(action: DevicesAction.VerifyMyDeviceManually) = withState { state ->
|
private fun handleShowDeviceCryptoInfo(action: DevicesAction.VerifyMyDeviceManually) = withState { state ->
|
||||||
|
|
Loading…
Reference in New Issue