From c16e1ca2916973486f1d787f06cc1fa8630f52ca Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Thu, 15 Sep 2022 16:37:05 +0200 Subject: [PATCH 1/8] Adding changelog entry --- changelog.d/7143.wip | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/7143.wip 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 From a6cb25d0c3bfd18d659dca93f87196dbae3631a7 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Fri, 16 Sep 2022 10:10:54 +0200 Subject: [PATCH 2/8] Verification of another session --- .../devices/v2/list/SessionInfoView.kt | 8 ++++--- .../devices/v2/list/SessionInfoViewState.kt | 1 + .../v2/overview/SessionOverviewFragment.kt | 14 ++++++++++--- .../v2/overview/SessionOverviewViewEvent.kt | 3 ++- .../v2/overview/SessionOverviewViewModel.kt | 9 +++++++- .../v2/overview/SessionOverviewViewState.kt | 1 + .../overview/SessionOverviewViewModelTest.kt | 21 ++++++++++++++++++- 7 files changed, 48 insertions(+), 9 deletions(-) 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/SessionOverviewFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt index 4c83408fe7..db293e88a9 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 @@ -82,9 +82,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) } @@ -105,7 +108,7 @@ class SessionOverviewFragment : updateToolbar(state.isCurrentSession) updateEntryDetails(state.deviceId) if (state.deviceInfo is Success) { - renderSessionInfo(state.isCurrentSession, state.deviceInfo.invoke()) + renderSessionInfo(state.isCurrentSession, state.deviceInfo.invoke(), state.isCurrentSessionTrusted) } else { hideSessionInfo() } @@ -124,11 +127,16 @@ class SessionOverviewFragment : } } - private fun renderSessionInfo(isCurrentSession: Boolean, deviceFullInfo: DeviceFullInfo) { + private fun renderSessionInfo( + isCurrentSession: Boolean, + deviceFullInfo: DeviceFullInfo, + isCurrentSessionTrusted: Boolean, + ) { views.sessionOverviewInfo.isVisible = true val viewState = SessionInfoViewState( isCurrentSession = isCurrentSession, deviceFullInfo = deviceFullInfo, + isVerifyButtonVisible = isCurrentSession || isCurrentSessionTrusted, isDetailsButtonVisible = false, isLearnMoreLinkVisible = true, isLastSeenDetailsVisible = true, 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..183469936f 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 @@ -45,6 +45,7 @@ class SessionOverviewViewModel @AssistedInject constructor( } init { + // TODO check if current session is trusted setState { copy(isCurrentSession = isCurrentSession(deviceId)) } @@ -70,6 +71,8 @@ class SessionOverviewViewModel @AssistedInject constructor( private fun handleVerifySessionAction() = withState { viewState -> if (isCurrentSession(viewState.deviceId)) { handleVerifyCurrentSession() + } else { + handleVerifyOtherSession(verifySession.deviceId) } } @@ -77,10 +80,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/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..ed7fc766c7 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 @@ -95,7 +95,7 @@ class SessionOverviewViewModelTest { // Then viewModelTest - .assertEvent { it is SessionOverviewViewEvent.SelfVerification } + .assertEvent { it is SessionOverviewViewEvent.ShowVerifyCurrentSession } .finish() coVerify { checkIfCurrentSessionCanBeVerifiedUseCase.execute() @@ -124,4 +124,23 @@ 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) } returns flowOf(deviceFullInfo) + every { isCurrentSessionUseCase.execute(any()) } returns false + val verifySessionAction = SessionOverviewAction.VerifySession(A_SESSION_ID) + + // When + val viewModel = createViewModel() + val viewModelTest = viewModel.test() + viewModel.handle(verifySessionAction) + + // Then + viewModelTest + .assertEvent { it is SessionOverviewViewEvent.ShowVerifyOtherSession } + .finish() + } } From 95d133e0e2edbf497060992f69a70ba338d12ebd Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Fri, 16 Sep 2022 14:12:38 +0200 Subject: [PATCH 3/8] Moving some components inside the verification package --- .../app/features/settings/devices/DevicesViewModel.kt | 2 +- .../devices/GetCurrentSessionCrossSigningInfoUseCase.kt | 2 +- .../app/features/settings/devices/v2/DevicesViewModel.kt | 1 + .../app/features/settings/devices/v2/DevicesViewState.kt | 1 + .../settings/devices/v2/GetDeviceFullInfoListUseCase.kt | 3 +++ .../devices/v2/overview/GetDeviceFullInfoUseCase.kt | 4 ++-- .../devices/v2/overview/SessionOverviewViewModel.kt | 1 - .../v2/{ => verification}/CurrentSessionCrossSigningInfo.kt | 2 +- .../GetCurrentSessionCrossSigningInfoUseCase.kt | 2 +- .../GetEncryptionTrustLevelForCurrentDeviceUseCase.kt | 2 +- .../GetEncryptionTrustLevelForDeviceUseCase.kt | 2 +- .../GetEncryptionTrustLevelForOtherDeviceUseCase.kt | 2 +- .../devices/GetCurrentSessionCrossSigningInfoUseCaseTest.kt | 2 +- .../features/settings/devices/v2/DevicesViewModelTest.kt | 2 ++ .../settings/devices/v2/GetDeviceFullInfoListUseCaseTest.kt | 3 +++ .../devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt | 6 +++--- .../GetCurrentSessionCrossSigningInfoUseCaseTest.kt | 2 +- .../GetEncryptionTrustLevelForCurrentDeviceUseCaseTest.kt | 2 +- .../GetEncryptionTrustLevelForDeviceUseCaseTest.kt | 2 +- .../GetEncryptionTrustLevelForOtherDeviceUseCaseTest.kt | 2 +- 20 files changed, 27 insertions(+), 18 deletions(-) rename vector/src/main/java/im/vector/app/features/settings/devices/v2/{ => verification}/CurrentSessionCrossSigningInfo.kt (93%) rename vector/src/main/java/im/vector/app/features/settings/devices/v2/{ => verification}/GetCurrentSessionCrossSigningInfoUseCase.kt (96%) rename vector/src/main/java/im/vector/app/features/settings/devices/v2/{ => verification}/GetEncryptionTrustLevelForCurrentDeviceUseCase.kt (95%) rename vector/src/main/java/im/vector/app/features/settings/devices/v2/{ => verification}/GetEncryptionTrustLevelForDeviceUseCase.kt (96%) rename vector/src/main/java/im/vector/app/features/settings/devices/v2/{ => verification}/GetEncryptionTrustLevelForOtherDeviceUseCase.kt (96%) rename vector/src/test/java/im/vector/app/features/settings/devices/v2/{ => verification}/GetCurrentSessionCrossSigningInfoUseCaseTest.kt (98%) rename vector/src/test/java/im/vector/app/features/settings/devices/v2/{ => verification}/GetEncryptionTrustLevelForCurrentDeviceUseCaseTest.kt (96%) rename vector/src/test/java/im/vector/app/features/settings/devices/v2/{ => verification}/GetEncryptionTrustLevelForDeviceUseCaseTest.kt (98%) rename vector/src/test/java/im/vector/app/features/settings/devices/v2/{ => verification}/GetEncryptionTrustLevelForOtherDeviceUseCaseTest.kt (98%) 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..95b852b809 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,7 +34,7 @@ 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.verification.GetEncryptionTrustLevelForDeviceUseCase import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase import im.vector.lib.core.utils.flow.throttleFirst import kotlinx.coroutines.Dispatchers 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/overview/GetDeviceFullInfoUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt index 5a8106f2fd..bb2c4f4c6a 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,8 +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.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.verification.GetCurrentSessionCrossSigningInfoUseCase +import im.vector.app.features.settings.devices.v2.verification.GetEncryptionTrustLevelForDeviceUseCase import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine 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 183469936f..335341ab07 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 @@ -45,7 +45,6 @@ class SessionOverviewViewModel @AssistedInject constructor( } init { - // TODO check if current session is trusted setState { copy(isCurrentSession = isCurrentSession(deviceId)) } 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..e71a11710b 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,7 +16,7 @@ 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 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/overview/GetDeviceFullInfoUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt index 9c7515f2da..33a83cd590 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,10 +18,10 @@ 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.verification.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.verification.GetCurrentSessionCrossSigningInfoUseCase +import im.vector.app.features.settings.devices.v2.verification.GetEncryptionTrustLevelForDeviceUseCase import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase import im.vector.app.test.fakes.FakeActiveSessionHolder import im.vector.app.test.fakes.FakeFlowLiveDataConversions 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 98% 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..25d5766774 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 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 From 921533e4b291b11a8b2a45c3db285ddebc3a9240 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Fri, 16 Sep 2022 15:03:14 +0200 Subject: [PATCH 4/8] Getting the current session verification status to change verify button visibility --- .../v2/overview/SessionOverviewViewModel.kt | 17 +++++++++ ...rrentSessionCrossSigningInfoUseCaseTest.kt | 7 +--- .../devices/v2/IsCurrentSessionUseCaseTest.kt | 9 +---- .../overview/SessionOverviewViewModelTest.kt | 38 +++++++++++++------ ...rrentSessionCrossSigningInfoUseCaseTest.kt | 5 +-- .../im/vector/app/test/fakes/FakeSession.kt | 7 ++++ 6 files changed, 54 insertions(+), 29 deletions(-) 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 335341ab07..40a78a4fd3 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 @@ -26,9 +26,12 @@ 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, @@ -49,6 +52,7 @@ class SessionOverviewViewModel @AssistedInject constructor( copy(isCurrentSession = isCurrentSession(deviceId)) } observeSessionInfo(initialState.deviceId) + observeCurrentSessionInfo() } private fun isCurrentSession(deviceId: String): Boolean { @@ -61,6 +65,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() 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 e71a11710b..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 @@ -18,11 +18,8 @@ package im.vector.app.features.settings.devices 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/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/SessionOverviewViewModelTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt index ed7fc766c7..3ba3e616df 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 @@ -31,8 +31,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,7 +42,7 @@ class SessionOverviewViewModelTest { val mvRxTestRule = MvRxTestRule(testDispatcher = testDispatcher) private val args = SessionOverviewArgs( - deviceId = A_SESSION_ID + deviceId = A_SESSION_ID_1 ) private val isCurrentSessionUseCase = mockk() private val getDeviceFullInfoUseCase = mockk() @@ -54,16 +56,18 @@ class SessionOverviewViewModelTest { ) @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 +78,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 +87,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() @@ -106,10 +111,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() @@ -129,9 +135,10 @@ class SessionOverviewViewModelTest { 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) } returns flowOf(deviceFullInfo) + every { getDeviceFullInfoUseCase.execute(A_SESSION_ID_1) } returns flowOf(deviceFullInfo) every { isCurrentSessionUseCase.execute(any()) } returns false - val verifySessionAction = SessionOverviewAction.VerifySession(A_SESSION_ID) + val verifySessionAction = SessionOverviewAction.VerifySession + givenCurrentSessionIsTrusted() // When val viewModel = createViewModel() @@ -143,4 +150,11 @@ class SessionOverviewViewModelTest { .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/verification/GetCurrentSessionCrossSigningInfoUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/verification/GetCurrentSessionCrossSigningInfoUseCaseTest.kt index 25d5766774..f566c8f55e 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/verification/GetCurrentSessionCrossSigningInfoUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/verification/GetCurrentSessionCrossSigningInfoUseCaseTest.kt @@ -107,11 +107,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/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. */ From 17bb14c1dc3f25f8aa9c732c06f150fc45be31f9 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Fri, 16 Sep 2022 15:05:55 +0200 Subject: [PATCH 5/8] Fixing coding style issues --- .../vector/app/features/settings/devices/DevicesViewModel.kt | 2 +- .../settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt | 2 +- .../devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt | 4 ++-- .../GetCurrentSessionCrossSigningInfoUseCaseTest.kt | 1 - 4 files changed, 4 insertions(+), 5 deletions(-) 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 95b852b809..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.verification.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/v2/overview/GetDeviceFullInfoUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt index bb2c4f4c6a..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.list.CheckIfSessionIsInactiveUseCase import im.vector.app.features.settings.devices.v2.verification.GetCurrentSessionCrossSigningInfoUseCase import im.vector.app.features.settings.devices.v2.verification.GetEncryptionTrustLevelForDeviceUseCase -import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.emptyFlow 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 33a83cd590..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.verification.CurrentSessionCrossSigningInfo import im.vector.app.features.settings.devices.v2.DeviceFullInfo +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.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase 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/verification/GetCurrentSessionCrossSigningInfoUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/verification/GetCurrentSessionCrossSigningInfoUseCaseTest.kt index f566c8f55e..356d771d39 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/verification/GetCurrentSessionCrossSigningInfoUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/verification/GetCurrentSessionCrossSigningInfoUseCaseTest.kt @@ -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 From aa7f7d7111904bea73df735700ef02d6ae177da3 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 19 Sep 2022 10:00:34 +0200 Subject: [PATCH 6/8] Fix after rebase --- .../devices/v2/overview/SessionOverviewViewModel.kt | 7 +++++-- .../devices/v2/overview/SessionOverviewViewModelTest.kt | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) 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 40a78a4fd3..4756e1e10e 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,6 +21,7 @@ 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 @@ -35,6 +36,7 @@ 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, @@ -85,10 +87,11 @@ class SessionOverviewViewModel @AssistedInject constructor( } private fun handleVerifySessionAction() = withState { viewState -> - if (isCurrentSession(viewState.deviceId)) { + val deviceId = viewState.deviceId + if (isCurrentSession(deviceId)) { handleVerifyCurrentSession() } else { - handleVerifyOtherSession(verifySession.deviceId) + handleVerifyOtherSession(deviceId) } } 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 3ba3e616df..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 @@ -44,12 +45,14 @@ class SessionOverviewViewModelTest { private val args = SessionOverviewArgs( 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, From 72637b465f3dca27bb6801c452a2e26757e3624f Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 19 Sep 2022 11:23:11 +0200 Subject: [PATCH 7/8] Using viewState value to check if it is current session --- .../settings/devices/v2/overview/SessionOverviewViewModel.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) 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 4756e1e10e..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 @@ -87,11 +87,10 @@ class SessionOverviewViewModel @AssistedInject constructor( } private fun handleVerifySessionAction() = withState { viewState -> - val deviceId = viewState.deviceId - if (isCurrentSession(deviceId)) { + if (viewState.isCurrentSession) { handleVerifyCurrentSession() } else { - handleVerifyOtherSession(deviceId) + handleVerifyOtherSession(viewState.deviceId) } } From 943ec7ee7505ee99c96579590923a1474953a97e Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 19 Sep 2022 11:29:39 +0200 Subject: [PATCH 8/8] Reducing argument number in session info view update method --- .../v2/overview/SessionOverviewFragment.kt | 38 +++++++++---------- 1 file changed, 17 insertions(+), 21 deletions(-) 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 db293e88a9..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 @@ -107,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(), state.isCurrentSessionTrusted) - } else { - hideSessionInfo() - } + updateSessionInfo(state) } private fun updateToolbar(isCurrentSession: Boolean) { @@ -127,21 +122,22 @@ class SessionOverviewFragment : } } - private fun renderSessionInfo( - isCurrentSession: Boolean, - deviceFullInfo: DeviceFullInfo, - isCurrentSessionTrusted: Boolean, - ) { - views.sessionOverviewInfo.isVisible = true - val viewState = SessionInfoViewState( - isCurrentSession = isCurrentSession, - deviceFullInfo = deviceFullInfo, - isVerifyButtonVisible = isCurrentSession || isCurrentSessionTrusted, - 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() {