diff --git a/changelog.d/7143.wip b/changelog.d/7143.wip new file mode 100644 index 0000000000..588f7fb255 --- /dev/null +++ b/changelog.d/7143.wip @@ -0,0 +1 @@ +[Device management] Verify another session diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt index 30e7727860..d30d6ee270 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt @@ -34,8 +34,8 @@ import im.vector.app.core.resources.StringProvider import im.vector.app.core.utils.PublishDataSource import im.vector.app.features.auth.ReAuthActivity import im.vector.app.features.login.ReAuthHelper -import im.vector.app.features.settings.devices.v2.GetEncryptionTrustLevelForDeviceUseCase import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase +import im.vector.app.features.settings.devices.v2.verification.GetEncryptionTrustLevelForDeviceUseCase import im.vector.lib.core.utils.flow.throttleFirst import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.combine diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/GetCurrentSessionCrossSigningInfoUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/GetCurrentSessionCrossSigningInfoUseCase.kt index 8b58bd0536..a27c30379b 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/GetCurrentSessionCrossSigningInfoUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/GetCurrentSessionCrossSigningInfoUseCase.kt @@ -17,7 +17,7 @@ package im.vector.app.features.settings.devices import im.vector.app.core.di.ActiveSessionHolder -import im.vector.app.features.settings.devices.v2.CurrentSessionCrossSigningInfo +import im.vector.app.features.settings.devices.v2.verification.CurrentSessionCrossSigningInfo import javax.inject.Inject class GetCurrentSessionCrossSigningInfoUseCase @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewModel.kt index 96d169bf02..f1fe582e44 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewModel.kt @@ -26,6 +26,7 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType import im.vector.app.features.settings.devices.v2.verification.CheckIfCurrentSessionCanBeVerifiedUseCase +import im.vector.app.features.settings.devices.v2.verification.GetCurrentSessionCrossSigningInfoUseCase import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewState.kt index 3fc061daa4..e8bed35e24 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewState.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewState.kt @@ -19,6 +19,7 @@ package im.vector.app.features.settings.devices.v2 import com.airbnb.mvrx.Async import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.Uninitialized +import im.vector.app.features.settings.devices.v2.verification.CurrentSessionCrossSigningInfo data class DevicesViewState( val currentSessionCrossSigningInfo: CurrentSessionCrossSigningInfo = CurrentSessionCrossSigningInfo(), diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCase.kt index 3c0d3a5e56..ae38ba3d3f 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCase.kt @@ -20,6 +20,9 @@ import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType import im.vector.app.features.settings.devices.v2.filter.FilterDevicesUseCase import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase +import im.vector.app.features.settings.devices.v2.verification.CurrentSessionCrossSigningInfo +import im.vector.app.features.settings.devices.v2.verification.GetCurrentSessionCrossSigningInfoUseCase +import im.vector.app.features.settings.devices.v2.verification.GetEncryptionTrustLevelForDeviceUseCase import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt index 38bc0cb5d8..340a4f3c3a 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt @@ -62,6 +62,7 @@ class SessionInfoView @JvmOverloads constructor( sessionInfoViewState.deviceFullInfo.roomEncryptionTrustLevel, sessionInfoViewState.isCurrentSession, sessionInfoViewState.isLearnMoreLinkVisible, + sessionInfoViewState.isVerifyButtonVisible, ) renderDeviceLastSeenDetails( sessionInfoViewState.deviceFullInfo.isInactive, @@ -78,12 +79,13 @@ class SessionInfoView @JvmOverloads constructor( encryptionTrustLevel: RoomEncryptionTrustLevel, isCurrentSession: Boolean, hasLearnMoreLink: Boolean, + isVerifyButtonVisible: Boolean, ) { views.sessionInfoVerificationStatusImageView.render(encryptionTrustLevel) if (encryptionTrustLevel == RoomEncryptionTrustLevel.Trusted) { renderCrossSigningVerified(isCurrentSession) } else { - renderCrossSigningUnverified(isCurrentSession) + renderCrossSigningUnverified(isCurrentSession, isVerifyButtonVisible) } if (hasLearnMoreLink) { appendLearnMoreToVerificationStatus() @@ -120,7 +122,7 @@ class SessionInfoView @JvmOverloads constructor( views.sessionInfoVerifySessionButton.isVisible = false } - private fun renderCrossSigningUnverified(isCurrentSession: Boolean) { + private fun renderCrossSigningUnverified(isCurrentSession: Boolean, isVerifyButtonVisible: Boolean) { views.sessionInfoVerificationStatusTextView.text = context.getString(R.string.device_manager_verification_status_unverified) views.sessionInfoVerificationStatusTextView.setTextColor(ThemeUtils.getColor(context, R.attr.colorError)) val statusResId = if (isCurrentSession) { @@ -129,7 +131,7 @@ class SessionInfoView @JvmOverloads constructor( R.string.device_manager_verification_status_detail_other_session_unverified } views.sessionInfoVerificationStatusDetailTextView.text = context.getString(statusResId) - views.sessionInfoVerifySessionButton.isVisible = true + views.sessionInfoVerifySessionButton.isVisible = isVerifyButtonVisible } // TODO. We don't have this info yet. Update later accordingly. diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoViewState.kt index 60e1234820..287bb956f5 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoViewState.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoViewState.kt @@ -21,6 +21,7 @@ import im.vector.app.features.settings.devices.v2.DeviceFullInfo data class SessionInfoViewState( val isCurrentSession: Boolean, val deviceFullInfo: DeviceFullInfo, + val isVerifyButtonVisible: Boolean = true, val isDetailsButtonVisible: Boolean = true, val isLearnMoreLinkVisible: Boolean = false, val isLastSeenDetailsVisible: Boolean = false, diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt index 5a8106f2fd..8b343f5f90 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt @@ -19,9 +19,9 @@ 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.v2.DeviceFullInfo -import im.vector.app.features.settings.devices.v2.GetCurrentSessionCrossSigningInfoUseCase -import im.vector.app.features.settings.devices.v2.GetEncryptionTrustLevelForDeviceUseCase import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase +import im.vector.app.features.settings.devices.v2.verification.GetCurrentSessionCrossSigningInfoUseCase +import im.vector.app.features.settings.devices.v2.verification.GetEncryptionTrustLevelForDeviceUseCase import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.emptyFlow diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt index 4c83408fe7..73991c5f20 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt @@ -35,7 +35,6 @@ import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.DrawableProvider import im.vector.app.databinding.FragmentSessionOverviewBinding import im.vector.app.features.crypto.recover.SetupMode -import im.vector.app.features.settings.devices.v2.DeviceFullInfo import im.vector.app.features.settings.devices.v2.list.SessionInfoViewState import javax.inject.Inject @@ -82,9 +81,12 @@ class SessionOverviewFragment : private fun observeViewEvents() { viewModel.observeViewEvents { when (it) { - is SessionOverviewViewEvent.SelfVerification -> { + is SessionOverviewViewEvent.ShowVerifyCurrentSession -> { navigator.requestSelfSessionVerification(requireActivity()) } + is SessionOverviewViewEvent.ShowVerifyOtherSession -> { + navigator.requestSessionVerification(requireActivity(), it.deviceId) + } is SessionOverviewViewEvent.PromptResetSecrets -> { navigator.open4SSetup(requireActivity(), SetupMode.PASSPHRASE_AND_NEEDED_SECRETS_RESET) } @@ -104,11 +106,7 @@ class SessionOverviewFragment : override fun invalidate() = withState(viewModel) { state -> updateToolbar(state.isCurrentSession) updateEntryDetails(state.deviceId) - if (state.deviceInfo is Success) { - renderSessionInfo(state.isCurrentSession, state.deviceInfo.invoke()) - } else { - hideSessionInfo() - } + updateSessionInfo(state) } private fun updateToolbar(isCurrentSession: Boolean) { @@ -124,16 +122,22 @@ class SessionOverviewFragment : } } - private fun renderSessionInfo(isCurrentSession: Boolean, deviceFullInfo: DeviceFullInfo) { - views.sessionOverviewInfo.isVisible = true - val viewState = SessionInfoViewState( - isCurrentSession = isCurrentSession, - deviceFullInfo = deviceFullInfo, - isDetailsButtonVisible = false, - isLearnMoreLinkVisible = true, - isLastSeenDetailsVisible = true, - ) - views.sessionOverviewInfo.render(viewState, dateFormatter, drawableProvider, colorProvider) + private fun updateSessionInfo(viewState: SessionOverviewViewState) { + if (viewState.deviceInfo is Success) { + views.sessionOverviewInfo.isVisible = true + val isCurrentSession = viewState.isCurrentSession + val infoViewState = SessionInfoViewState( + isCurrentSession = isCurrentSession, + deviceFullInfo = viewState.deviceInfo.invoke(), + isVerifyButtonVisible = isCurrentSession || viewState.isCurrentSessionTrusted, + isDetailsButtonVisible = false, + isLearnMoreLinkVisible = true, + isLastSeenDetailsVisible = true, + ) + views.sessionOverviewInfo.render(infoViewState, dateFormatter, drawableProvider, colorProvider) + } else { + hideSessionInfo() + } } private fun hideSessionInfo() { diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewEvent.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewEvent.kt index 83d438ecb4..8508b395ad 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewEvent.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewEvent.kt @@ -19,6 +19,7 @@ package im.vector.app.features.settings.devices.v2.overview import im.vector.app.core.platform.VectorViewEvents sealed class SessionOverviewViewEvent : VectorViewEvents { - object SelfVerification : SessionOverviewViewEvent() + object ShowVerifyCurrentSession : SessionOverviewViewEvent() + data class ShowVerifyOtherSession(val deviceId: String) : SessionOverviewViewEvent() object PromptResetSecrets : SessionOverviewViewEvent() } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt index bcf7542783..69556e039e 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt @@ -21,17 +21,22 @@ import com.airbnb.mvrx.Success import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel import im.vector.app.features.settings.devices.v2.IsCurrentSessionUseCase import im.vector.app.features.settings.devices.v2.verification.CheckIfCurrentSessionCanBeVerifiedUseCase +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel class SessionOverviewViewModel @AssistedInject constructor( @Assisted val initialState: SessionOverviewViewState, + private val activeSessionHolder: ActiveSessionHolder, private val isCurrentSessionUseCase: IsCurrentSessionUseCase, private val getDeviceFullInfoUseCase: GetDeviceFullInfoUseCase, private val checkIfCurrentSessionCanBeVerifiedUseCase: CheckIfCurrentSessionCanBeVerifiedUseCase, @@ -49,6 +54,7 @@ class SessionOverviewViewModel @AssistedInject constructor( copy(isCurrentSession = isCurrentSession(deviceId)) } observeSessionInfo(initialState.deviceId) + observeCurrentSessionInfo() } private fun isCurrentSession(deviceId: String): Boolean { @@ -61,6 +67,19 @@ class SessionOverviewViewModel @AssistedInject constructor( .launchIn(viewModelScope) } + private fun observeCurrentSessionInfo() { + activeSessionHolder.getSafeActiveSession() + ?.sessionParams + ?.deviceId + ?.let { deviceId -> + getDeviceFullInfoUseCase.execute(deviceId) + .map { it.roomEncryptionTrustLevel == RoomEncryptionTrustLevel.Trusted } + .distinctUntilChanged() + .onEach { setState { copy(isCurrentSessionTrusted = it) } } + .launchIn(viewModelScope) + } + } + override fun handle(action: SessionOverviewAction) { when (action) { is SessionOverviewAction.VerifySession -> handleVerifySessionAction() @@ -68,8 +87,10 @@ class SessionOverviewViewModel @AssistedInject constructor( } private fun handleVerifySessionAction() = withState { viewState -> - if (isCurrentSession(viewState.deviceId)) { + if (viewState.isCurrentSession) { handleVerifyCurrentSession() + } else { + handleVerifyOtherSession(viewState.deviceId) } } @@ -77,10 +98,14 @@ class SessionOverviewViewModel @AssistedInject constructor( viewModelScope.launch { val currentSessionCanBeVerified = checkIfCurrentSessionCanBeVerifiedUseCase.execute() if (currentSessionCanBeVerified) { - _viewEvents.post(SessionOverviewViewEvent.SelfVerification) + _viewEvents.post(SessionOverviewViewEvent.ShowVerifyCurrentSession) } else { _viewEvents.post(SessionOverviewViewEvent.PromptResetSecrets) } } } + + private fun handleVerifyOtherSession(deviceId: String) { + _viewEvents.post(SessionOverviewViewEvent.ShowVerifyOtherSession(deviceId)) + } } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewState.kt index a447336c23..1cb455dd5c 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewState.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewState.kt @@ -24,6 +24,7 @@ import im.vector.app.features.settings.devices.v2.DeviceFullInfo data class SessionOverviewViewState( val deviceId: String, val isCurrentSession: Boolean = false, + val isCurrentSessionTrusted: Boolean = false, val deviceInfo: Async = Uninitialized, ) : MavericksState { constructor(args: SessionOverviewArgs) : this( diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/CurrentSessionCrossSigningInfo.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/verification/CurrentSessionCrossSigningInfo.kt similarity index 93% rename from vector/src/main/java/im/vector/app/features/settings/devices/v2/CurrentSessionCrossSigningInfo.kt rename to vector/src/main/java/im/vector/app/features/settings/devices/v2/verification/CurrentSessionCrossSigningInfo.kt index cccdb23d52..1dfab06b1d 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/CurrentSessionCrossSigningInfo.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/verification/CurrentSessionCrossSigningInfo.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package im.vector.app.features.settings.devices.v2 +package im.vector.app.features.settings.devices.v2.verification /** * Used to hold some info about the cross signing of the current Session. diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetCurrentSessionCrossSigningInfoUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/verification/GetCurrentSessionCrossSigningInfoUseCase.kt similarity index 96% rename from vector/src/main/java/im/vector/app/features/settings/devices/v2/GetCurrentSessionCrossSigningInfoUseCase.kt rename to vector/src/main/java/im/vector/app/features/settings/devices/v2/verification/GetCurrentSessionCrossSigningInfoUseCase.kt index cc848342de..182e493213 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetCurrentSessionCrossSigningInfoUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/verification/GetCurrentSessionCrossSigningInfoUseCase.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package im.vector.app.features.settings.devices.v2 +package im.vector.app.features.settings.devices.v2.verification import im.vector.app.core.di.ActiveSessionHolder import kotlinx.coroutines.flow.Flow diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetEncryptionTrustLevelForCurrentDeviceUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForCurrentDeviceUseCase.kt similarity index 95% rename from vector/src/main/java/im/vector/app/features/settings/devices/v2/GetEncryptionTrustLevelForCurrentDeviceUseCase.kt rename to vector/src/main/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForCurrentDeviceUseCase.kt index 7e56d35570..2243471a23 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetEncryptionTrustLevelForCurrentDeviceUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForCurrentDeviceUseCase.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package im.vector.app.features.settings.devices.v2 +package im.vector.app.features.settings.devices.v2.verification import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetEncryptionTrustLevelForDeviceUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForDeviceUseCase.kt similarity index 96% rename from vector/src/main/java/im/vector/app/features/settings/devices/v2/GetEncryptionTrustLevelForDeviceUseCase.kt rename to vector/src/main/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForDeviceUseCase.kt index 6f0dcbface..ba9a380ade 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetEncryptionTrustLevelForDeviceUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForDeviceUseCase.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package im.vector.app.features.settings.devices.v2 +package im.vector.app.features.settings.devices.v2.verification import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetEncryptionTrustLevelForOtherDeviceUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForOtherDeviceUseCase.kt similarity index 96% rename from vector/src/main/java/im/vector/app/features/settings/devices/v2/GetEncryptionTrustLevelForOtherDeviceUseCase.kt rename to vector/src/main/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForOtherDeviceUseCase.kt index 7541b9b1d5..e674ccd8c5 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetEncryptionTrustLevelForOtherDeviceUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForOtherDeviceUseCase.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package im.vector.app.features.settings.devices.v2 +package im.vector.app.features.settings.devices.v2.verification import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/GetCurrentSessionCrossSigningInfoUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/GetCurrentSessionCrossSigningInfoUseCaseTest.kt index 1a805f4c3e..b9ba1b1c0b 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/GetCurrentSessionCrossSigningInfoUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/GetCurrentSessionCrossSigningInfoUseCaseTest.kt @@ -16,13 +16,10 @@ package im.vector.app.features.settings.devices -import im.vector.app.features.settings.devices.v2.CurrentSessionCrossSigningInfo +import im.vector.app.features.settings.devices.v2.verification.CurrentSessionCrossSigningInfo import im.vector.app.test.fakes.FakeActiveSessionHolder -import io.mockk.every -import io.mockk.mockk import org.amshove.kluent.shouldBeEqualTo import org.junit.Test -import org.matrix.android.sdk.api.auth.data.SessionParams private const val A_DEVICE_ID = "device-id" @@ -36,9 +33,7 @@ class GetCurrentSessionCrossSigningInfoUseCaseTest { @Test fun `given the active session when getting cross signing info then the result is correct`() { - val sessionParams = mockk() - every { sessionParams.deviceId } returns A_DEVICE_ID - fakeActiveSessionHolder.fakeSession.givenSessionParams(sessionParams) + fakeActiveSessionHolder.fakeSession.givenSessionId(A_DEVICE_ID) val isCrossSigningInitialized = true fakeActiveSessionHolder.fakeSession .fakeCryptoService diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/DevicesViewModelTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/DevicesViewModelTest.kt index 0e04c2ab51..f4160da9fd 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/DevicesViewModelTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/DevicesViewModelTest.kt @@ -19,6 +19,8 @@ package im.vector.app.features.settings.devices.v2 import com.airbnb.mvrx.Success import com.airbnb.mvrx.test.MvRxTestRule import im.vector.app.features.settings.devices.v2.verification.CheckIfCurrentSessionCanBeVerifiedUseCase +import im.vector.app.features.settings.devices.v2.verification.CurrentSessionCrossSigningInfo +import im.vector.app.features.settings.devices.v2.verification.GetCurrentSessionCrossSigningInfoUseCase import im.vector.app.test.fakes.FakeActiveSessionHolder import im.vector.app.test.fakes.FakeVerificationService import im.vector.app.test.test diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCaseTest.kt index 54b160f196..c9dd9ddea6 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCaseTest.kt @@ -19,6 +19,9 @@ package im.vector.app.features.settings.devices.v2 import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType import im.vector.app.features.settings.devices.v2.filter.FilterDevicesUseCase import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase +import im.vector.app.features.settings.devices.v2.verification.CurrentSessionCrossSigningInfo +import im.vector.app.features.settings.devices.v2.verification.GetCurrentSessionCrossSigningInfoUseCase +import im.vector.app.features.settings.devices.v2.verification.GetEncryptionTrustLevelForDeviceUseCase import im.vector.app.test.fakes.FakeActiveSessionHolder import im.vector.app.test.test import im.vector.app.test.testDispatcher diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/IsCurrentSessionUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/IsCurrentSessionUseCaseTest.kt index 25cd150b21..09a94ac08b 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/IsCurrentSessionUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/IsCurrentSessionUseCaseTest.kt @@ -17,8 +17,6 @@ package im.vector.app.features.settings.devices.v2 import im.vector.app.test.fakes.FakeActiveSessionHolder -import io.mockk.every -import io.mockk.mockk import io.mockk.verify import org.amshove.kluent.shouldBe import org.junit.Test @@ -73,10 +71,7 @@ class IsCurrentSessionUseCaseTest { result shouldBe false } - private fun givenIdForCurrentSession(deviceId: String): SessionParams { - val sessionParams = mockk() - every { sessionParams.deviceId } returns deviceId - fakeActiveSessionHolder.fakeSession.givenSessionParams(sessionParams) - return sessionParams + private fun givenIdForCurrentSession(sessionId: String): SessionParams { + return fakeActiveSessionHolder.fakeSession.givenSessionId(sessionId) } } diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt index 9c7515f2da..3ef1c5a515 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt @@ -18,11 +18,11 @@ package im.vector.app.features.settings.devices.v2.overview import androidx.lifecycle.MutableLiveData import androidx.lifecycle.asFlow -import im.vector.app.features.settings.devices.v2.CurrentSessionCrossSigningInfo import im.vector.app.features.settings.devices.v2.DeviceFullInfo -import im.vector.app.features.settings.devices.v2.GetCurrentSessionCrossSigningInfoUseCase -import im.vector.app.features.settings.devices.v2.GetEncryptionTrustLevelForDeviceUseCase import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase +import im.vector.app.features.settings.devices.v2.verification.CurrentSessionCrossSigningInfo +import im.vector.app.features.settings.devices.v2.verification.GetCurrentSessionCrossSigningInfoUseCase +import im.vector.app.features.settings.devices.v2.verification.GetEncryptionTrustLevelForDeviceUseCase import im.vector.app.test.fakes.FakeActiveSessionHolder import im.vector.app.test.fakes.FakeFlowLiveDataConversions import im.vector.app.test.fakes.givenAsFlow diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt index 71978129d3..857fa94ade 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt @@ -21,6 +21,7 @@ import com.airbnb.mvrx.test.MvRxTestRule import im.vector.app.features.settings.devices.v2.DeviceFullInfo import im.vector.app.features.settings.devices.v2.IsCurrentSessionUseCase import im.vector.app.features.settings.devices.v2.verification.CheckIfCurrentSessionCanBeVerifiedUseCase +import im.vector.app.test.fakes.FakeActiveSessionHolder import im.vector.app.test.test import im.vector.app.test.testDispatcher import io.mockk.coEvery @@ -31,8 +32,10 @@ import io.mockk.verify import kotlinx.coroutines.flow.flowOf import org.junit.Rule import org.junit.Test +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel -private const val A_SESSION_ID = "session-id" +private const val A_SESSION_ID_1 = "session-id-1" +private const val A_SESSION_ID_2 = "session-id-2" class SessionOverviewViewModelTest { @@ -40,30 +43,34 @@ class SessionOverviewViewModelTest { val mvRxTestRule = MvRxTestRule(testDispatcher = testDispatcher) private val args = SessionOverviewArgs( - deviceId = A_SESSION_ID + deviceId = A_SESSION_ID_1 ) + private val fakeActiveSessionHolder = FakeActiveSessionHolder() private val isCurrentSessionUseCase = mockk() private val getDeviceFullInfoUseCase = mockk() private val checkIfCurrentSessionCanBeVerifiedUseCase = mockk() private fun createViewModel() = SessionOverviewViewModel( initialState = SessionOverviewViewState(args), + activeSessionHolder = fakeActiveSessionHolder.instance, isCurrentSessionUseCase = isCurrentSessionUseCase, getDeviceFullInfoUseCase = getDeviceFullInfoUseCase, checkIfCurrentSessionCanBeVerifiedUseCase = checkIfCurrentSessionCanBeVerifiedUseCase, ) @Test - fun `given the viewModel has been initialized then viewState is updated with session info`() { + fun `given the viewModel has been initialized then viewState is updated with session info and current session verification status`() { // Given val deviceFullInfo = mockk() - every { getDeviceFullInfoUseCase.execute(A_SESSION_ID) } returns flowOf(deviceFullInfo) + every { getDeviceFullInfoUseCase.execute(A_SESSION_ID_1) } returns flowOf(deviceFullInfo) val isCurrentSession = true every { isCurrentSessionUseCase.execute(any()) } returns isCurrentSession + givenCurrentSessionIsTrusted() val expectedState = SessionOverviewViewState( - deviceId = A_SESSION_ID, + deviceId = A_SESSION_ID_1, isCurrentSession = isCurrentSession, - deviceInfo = Success(deviceFullInfo) + deviceInfo = Success(deviceFullInfo), + isCurrentSessionTrusted = true, ) // When @@ -74,8 +81,8 @@ class SessionOverviewViewModelTest { .assertLatestState { state -> state == expectedState } .finish() verify { - isCurrentSessionUseCase.execute(A_SESSION_ID) - getDeviceFullInfoUseCase.execute(A_SESSION_ID) + isCurrentSessionUseCase.execute(A_SESSION_ID_1) + getDeviceFullInfoUseCase.execute(A_SESSION_ID_1) } } @@ -83,10 +90,11 @@ class SessionOverviewViewModelTest { fun `given current session can be verified when handling verify current session action then self verification event is posted`() { // Given val deviceFullInfo = mockk() - every { getDeviceFullInfoUseCase.execute(A_SESSION_ID) } returns flowOf(deviceFullInfo) + every { getDeviceFullInfoUseCase.execute(A_SESSION_ID_1) } returns flowOf(deviceFullInfo) every { isCurrentSessionUseCase.execute(any()) } returns true val verifySessionAction = SessionOverviewAction.VerifySession coEvery { checkIfCurrentSessionCanBeVerifiedUseCase.execute() } returns true + givenCurrentSessionIsTrusted() // When val viewModel = createViewModel() @@ -95,7 +103,7 @@ class SessionOverviewViewModelTest { // Then viewModelTest - .assertEvent { it is SessionOverviewViewEvent.SelfVerification } + .assertEvent { it is SessionOverviewViewEvent.ShowVerifyCurrentSession } .finish() coVerify { checkIfCurrentSessionCanBeVerifiedUseCase.execute() @@ -106,10 +114,11 @@ class SessionOverviewViewModelTest { fun `given current session cannot be verified when handling verify current session action then reset secrets event is posted`() { // Given val deviceFullInfo = mockk() - every { getDeviceFullInfoUseCase.execute(A_SESSION_ID) } returns flowOf(deviceFullInfo) + every { getDeviceFullInfoUseCase.execute(A_SESSION_ID_1) } returns flowOf(deviceFullInfo) every { isCurrentSessionUseCase.execute(any()) } returns true val verifySessionAction = SessionOverviewAction.VerifySession coEvery { checkIfCurrentSessionCanBeVerifiedUseCase.execute() } returns false + givenCurrentSessionIsTrusted() // When val viewModel = createViewModel() @@ -124,4 +133,31 @@ class SessionOverviewViewModelTest { checkIfCurrentSessionCanBeVerifiedUseCase.execute() } } + + @Test + fun `given another session when handling verify session action then verify session event is posted`() { + // Given + val deviceFullInfo = mockk() + every { getDeviceFullInfoUseCase.execute(A_SESSION_ID_1) } returns flowOf(deviceFullInfo) + every { isCurrentSessionUseCase.execute(any()) } returns false + val verifySessionAction = SessionOverviewAction.VerifySession + givenCurrentSessionIsTrusted() + + // When + val viewModel = createViewModel() + val viewModelTest = viewModel.test() + viewModel.handle(verifySessionAction) + + // Then + viewModelTest + .assertEvent { it is SessionOverviewViewEvent.ShowVerifyOtherSession } + .finish() + } + + private fun givenCurrentSessionIsTrusted() { + fakeActiveSessionHolder.fakeSession.givenSessionId(A_SESSION_ID_2) + val deviceFullInfo = mockk() + every { deviceFullInfo.roomEncryptionTrustLevel } returns RoomEncryptionTrustLevel.Trusted + every { getDeviceFullInfoUseCase.execute(A_SESSION_ID_2) } returns flowOf(deviceFullInfo) + } } diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetCurrentSessionCrossSigningInfoUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/verification/GetCurrentSessionCrossSigningInfoUseCaseTest.kt similarity index 94% rename from vector/src/test/java/im/vector/app/features/settings/devices/v2/GetCurrentSessionCrossSigningInfoUseCaseTest.kt rename to vector/src/test/java/im/vector/app/features/settings/devices/v2/verification/GetCurrentSessionCrossSigningInfoUseCaseTest.kt index f8ee1231ae..356d771d39 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetCurrentSessionCrossSigningInfoUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/verification/GetCurrentSessionCrossSigningInfoUseCaseTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package im.vector.app.features.settings.devices.v2 +package im.vector.app.features.settings.devices.v2.verification import im.vector.app.test.fakes.FakeActiveSessionHolder import im.vector.app.test.fakes.FakeSession @@ -30,7 +30,6 @@ import kotlinx.coroutines.test.runTest import org.junit.After import org.junit.Before import org.junit.Test -import org.matrix.android.sdk.api.auth.data.SessionParams import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo import org.matrix.android.sdk.api.util.toOptional @@ -107,11 +106,8 @@ class GetCurrentSessionCrossSigningInfoUseCaseTest { } private fun givenSession(deviceId: String): FakeSession { - val sessionParams = mockk() - every { sessionParams.deviceId } returns deviceId - val fakeSession = fakeActiveSessionHolder.fakeSession - fakeSession.givenSessionParams(sessionParams) + fakeSession.givenSessionId(deviceId) return fakeSession } diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetEncryptionTrustLevelForCurrentDeviceUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForCurrentDeviceUseCaseTest.kt similarity index 96% rename from vector/src/test/java/im/vector/app/features/settings/devices/v2/GetEncryptionTrustLevelForCurrentDeviceUseCaseTest.kt rename to vector/src/test/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForCurrentDeviceUseCaseTest.kt index b2ce89df33..3f82cb0dd2 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetEncryptionTrustLevelForCurrentDeviceUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForCurrentDeviceUseCaseTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package im.vector.app.features.settings.devices.v2 +package im.vector.app.features.settings.devices.v2.verification import org.amshove.kluent.shouldBeEqualTo import org.junit.Test diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetEncryptionTrustLevelForDeviceUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForDeviceUseCaseTest.kt similarity index 98% rename from vector/src/test/java/im/vector/app/features/settings/devices/v2/GetEncryptionTrustLevelForDeviceUseCaseTest.kt rename to vector/src/test/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForDeviceUseCaseTest.kt index e43fd49ffc..1b39fe5f73 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetEncryptionTrustLevelForDeviceUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForDeviceUseCaseTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package im.vector.app.features.settings.devices.v2 +package im.vector.app.features.settings.devices.v2.verification import io.mockk.every import io.mockk.mockk diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetEncryptionTrustLevelForOtherDeviceUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForOtherDeviceUseCaseTest.kt similarity index 98% rename from vector/src/test/java/im/vector/app/features/settings/devices/v2/GetEncryptionTrustLevelForOtherDeviceUseCaseTest.kt rename to vector/src/test/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForOtherDeviceUseCaseTest.kt index 2aeffbbb0d..18f998cf97 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetEncryptionTrustLevelForOtherDeviceUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForOtherDeviceUseCaseTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package im.vector.app.features.settings.devices.v2 +package im.vector.app.features.settings.devices.v2.verification import org.amshove.kluent.shouldBeEqualTo import org.junit.Test diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt index 35d23e35e8..4171307922 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt @@ -78,6 +78,13 @@ class FakeSession( every { this@FakeSession.sessionParams } returns sessionParams } + fun givenSessionId(sessionId: String): SessionParams { + val sessionParams = mockk() + every { sessionParams.deviceId } returns sessionId + givenSessionParams(sessionParams) + return sessionParams + } + /** * Do not forget to call mockkStatic("org.matrix.android.sdk.flow.FlowSessionKt") in the setup method of the tests. */