Introducing some reusable usecases
This commit is contained in:
parent
412fda27af
commit
ca70eddaf5
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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.app.features.settings.devices
|
||||
|
||||
/**
|
||||
* Used to hold some info about the cross signing of the current Session.
|
||||
*/
|
||||
data class CurrentSessionCrossSigningInfo(
|
||||
val deviceId: String?,
|
||||
val isCrossSigningInitialized: Boolean,
|
||||
val isCrossSigningVerified: Boolean,
|
||||
)
|
|
@ -101,6 +101,8 @@ class DevicesViewModel @AssistedInject constructor(
|
|||
private val stringProvider: StringProvider,
|
||||
private val matrix: Matrix,
|
||||
private val checkIfSessionIsInactiveUseCase: CheckIfSessionIsInactiveUseCase,
|
||||
getCurrentSessionCrossSigningInfoUseCase: GetCurrentSessionCrossSigningInfoUseCase,
|
||||
private val getEncryptionTrustLevelForDeviceUseCase: GetEncryptionTrustLevelForDeviceUseCase,
|
||||
) : VectorViewModel<DevicesViewState, DevicesAction, DevicesViewEvents>(initialState), VerificationService.Listener {
|
||||
|
||||
var uiaContinuation: Continuation<UIABaseAuth>? = null
|
||||
|
@ -116,8 +118,9 @@ class DevicesViewModel @AssistedInject constructor(
|
|||
private val refreshSource = PublishDataSource<Unit>()
|
||||
|
||||
init {
|
||||
val hasAccountCrossSigning = session.cryptoService().crossSigningService().isCrossSigningInitialized()
|
||||
val accountCrossSigningIsTrusted = session.cryptoService().crossSigningService().isCrossSigningVerified()
|
||||
val currentSessionCrossSigningInfo = getCurrentSessionCrossSigningInfoUseCase.execute()
|
||||
val hasAccountCrossSigning = currentSessionCrossSigningInfo.isCrossSigningInitialized
|
||||
val accountCrossSigningIsTrusted = currentSessionCrossSigningInfo.isCrossSigningVerified
|
||||
|
||||
setState {
|
||||
copy(
|
||||
|
@ -143,12 +146,7 @@ class DevicesViewModel @AssistedInject constructor(
|
|||
.sortedByDescending { it.lastSeenTs }
|
||||
.map { deviceInfo ->
|
||||
val cryptoDeviceInfo = cryptoList.firstOrNull { it.deviceId == deviceInfo.deviceId }
|
||||
val trustLevelForShield = computeTrustLevelForShield(
|
||||
currentSessionCrossTrusted = accountCrossSigningIsTrusted,
|
||||
legacyMode = !hasAccountCrossSigning,
|
||||
deviceTrustLevel = cryptoDeviceInfo?.trustLevel,
|
||||
isCurrentDevice = deviceInfo.deviceId == session.sessionParams.deviceId
|
||||
)
|
||||
val trustLevelForShield = getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo)
|
||||
val isInactive = checkIfSessionIsInactiveUseCase.execute(deviceInfo.lastSeenTs ?: 0)
|
||||
DeviceFullInfo(deviceInfo, cryptoDeviceInfo, trustLevelForShield, isInactive)
|
||||
}
|
||||
|
@ -268,20 +266,6 @@ class DevicesViewModel @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun computeTrustLevelForShield(
|
||||
currentSessionCrossTrusted: Boolean,
|
||||
legacyMode: Boolean,
|
||||
deviceTrustLevel: DeviceTrustLevel?,
|
||||
isCurrentDevice: Boolean,
|
||||
): RoomEncryptionTrustLevel {
|
||||
return TrustUtils.shieldForTrust(
|
||||
currentDevice = isCurrentDevice,
|
||||
trustMSK = currentSessionCrossTrusted,
|
||||
legacyMode = legacyMode,
|
||||
deviceTrustLevel = deviceTrustLevel
|
||||
)
|
||||
}
|
||||
|
||||
private fun handleInteractiveVerification(action: DevicesAction.VerifyMyDevice) {
|
||||
val txID = session.cryptoService()
|
||||
.verificationService()
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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.app.features.settings.devices
|
||||
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
import javax.inject.Inject
|
||||
|
||||
// TODO add unit tests
|
||||
class GetCurrentSessionCrossSigningInfoUseCase @Inject constructor(
|
||||
private val activeSessionHolder: ActiveSessionHolder,
|
||||
) {
|
||||
|
||||
fun execute(): CurrentSessionCrossSigningInfo {
|
||||
val session = activeSessionHolder.getActiveSession()
|
||||
val isCrossSigningInitialized = session.cryptoService().crossSigningService().isCrossSigningInitialized()
|
||||
val isCrossSigningVerified = session.cryptoService().crossSigningService().isCrossSigningVerified()
|
||||
return CurrentSessionCrossSigningInfo(
|
||||
deviceId = session.sessionParams.deviceId,
|
||||
isCrossSigningInitialized = isCrossSigningInitialized,
|
||||
isCrossSigningVerified = isCrossSigningVerified
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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.app.features.settings.devices
|
||||
|
||||
import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
|
||||
import javax.inject.Inject
|
||||
|
||||
// TODO add unit tests
|
||||
class GetEncryptionTrustLevelForCurrentDeviceUseCase @Inject constructor() {
|
||||
|
||||
fun execute(trustMSK: Boolean, legacyMode: Boolean): RoomEncryptionTrustLevel {
|
||||
return if (legacyMode) {
|
||||
// In legacy, current session is always trusted
|
||||
RoomEncryptionTrustLevel.Trusted
|
||||
} else {
|
||||
// If current session doesn't trust MSK, show red shield for current device
|
||||
if (trustMSK) {
|
||||
RoomEncryptionTrustLevel.Trusted
|
||||
} else {
|
||||
RoomEncryptionTrustLevel.Warning
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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.app.features.settings.devices
|
||||
|
||||
import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
|
||||
import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
|
||||
import javax.inject.Inject
|
||||
|
||||
// TODO add unit tests
|
||||
class GetEncryptionTrustLevelForDeviceUseCase @Inject constructor(
|
||||
private val getEncryptionTrustLevelForCurrentDeviceUseCase: GetEncryptionTrustLevelForCurrentDeviceUseCase,
|
||||
private val getEncryptionTrustLevelForOtherDeviceUseCase: GetEncryptionTrustLevelForOtherDeviceUseCase,
|
||||
) {
|
||||
|
||||
fun execute(currentSessionCrossSigningInfo: CurrentSessionCrossSigningInfo, cryptoDeviceInfo: CryptoDeviceInfo?): RoomEncryptionTrustLevel {
|
||||
val legacyMode = !currentSessionCrossSigningInfo.isCrossSigningInitialized
|
||||
val trustMSK = currentSessionCrossSigningInfo.isCrossSigningVerified
|
||||
val isCurrentDevice = !cryptoDeviceInfo?.deviceId.isNullOrEmpty() && cryptoDeviceInfo?.deviceId == currentSessionCrossSigningInfo.deviceId
|
||||
val deviceTrustLevel = cryptoDeviceInfo?.trustLevel
|
||||
|
||||
return when {
|
||||
isCurrentDevice -> getEncryptionTrustLevelForCurrentDeviceUseCase.execute(trustMSK, legacyMode)
|
||||
else -> getEncryptionTrustLevelForOtherDeviceUseCase.execute(trustMSK, legacyMode, deviceTrustLevel)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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.app.features.settings.devices
|
||||
|
||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel
|
||||
import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
|
||||
import javax.inject.Inject
|
||||
|
||||
// TODO add unit tests
|
||||
class GetEncryptionTrustLevelForOtherDeviceUseCase @Inject constructor() {
|
||||
|
||||
fun execute(trustMSK: Boolean, legacyMode: Boolean, deviceTrustLevel: DeviceTrustLevel?): RoomEncryptionTrustLevel {
|
||||
return if (legacyMode) {
|
||||
// use local trust
|
||||
if (deviceTrustLevel?.locallyVerified == true) {
|
||||
RoomEncryptionTrustLevel.Trusted
|
||||
} else {
|
||||
RoomEncryptionTrustLevel.Warning
|
||||
}
|
||||
} else {
|
||||
if (trustMSK) {
|
||||
// use cross sign trust, put locally trusted in black
|
||||
when {
|
||||
deviceTrustLevel?.crossSigningVerified == true -> RoomEncryptionTrustLevel.Trusted
|
||||
deviceTrustLevel?.locallyVerified == true -> RoomEncryptionTrustLevel.Default
|
||||
else -> RoomEncryptionTrustLevel.Warning
|
||||
}
|
||||
} else {
|
||||
// The current session is untrusted, so displays others in black
|
||||
// as we can't know the cross-signing state
|
||||
RoomEncryptionTrustLevel.Default
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ package im.vector.app.features.settings.devices
|
|||
import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel
|
||||
import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
|
||||
|
||||
// TODO Replace usage by the use case GetEncryptionTrustLevelForDeviceUseCase
|
||||
object TrustUtils {
|
||||
|
||||
fun shieldForTrust(
|
||||
|
|
|
@ -19,6 +19,8 @@ package im.vector.app.features.settings.devices.v2.overview
|
|||
import androidx.lifecycle.asFlow
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
import im.vector.app.features.settings.devices.DeviceFullInfo
|
||||
import im.vector.app.features.settings.devices.GetCurrentSessionCrossSigningInfoUseCase
|
||||
import im.vector.app.features.settings.devices.GetEncryptionTrustLevelForDeviceUseCase
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
|
@ -26,12 +28,16 @@ import org.matrix.android.sdk.api.util.Optional
|
|||
import org.matrix.android.sdk.api.util.toOptional
|
||||
import javax.inject.Inject
|
||||
|
||||
// TODO update unit test
|
||||
class GetDeviceFullInfoUseCase @Inject constructor(
|
||||
private val activeSessionHolder: ActiveSessionHolder,
|
||||
private val getCurrentSessionCrossSigningInfoUseCase: GetCurrentSessionCrossSigningInfoUseCase,
|
||||
private val getEncryptionTrustLevelForDeviceUseCase: GetEncryptionTrustLevelForDeviceUseCase,
|
||||
) {
|
||||
|
||||
fun execute(deviceId: String): Flow<Optional<DeviceFullInfo>> {
|
||||
return activeSessionHolder.getSafeActiveSession()?.let { session ->
|
||||
val currentSessionCrossSigningInfo = getCurrentSessionCrossSigningInfoUseCase.execute()
|
||||
combine(
|
||||
session.cryptoService().getMyDevicesInfoLive(deviceId).asFlow(),
|
||||
session.cryptoService().getLiveCryptoDeviceInfoWithId(deviceId).asFlow()
|
||||
|
@ -39,9 +45,11 @@ class GetDeviceFullInfoUseCase @Inject constructor(
|
|||
val info = deviceInfo.getOrNull()
|
||||
val cryptoInfo = cryptoDeviceInfo.getOrNull()
|
||||
val fullInfo = if (info != null && cryptoInfo != null) {
|
||||
val roomEncryptionTrustLevel = getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoInfo)
|
||||
DeviceFullInfo(
|
||||
deviceInfo = info,
|
||||
cryptoDeviceInfo = cryptoInfo
|
||||
cryptoDeviceInfo = cryptoInfo,
|
||||
trustLevelForShield = roomEncryptionTrustLevel
|
||||
)
|
||||
} else {
|
||||
null
|
||||
|
|
Loading…
Reference in New Issue