Verification of another session

This commit is contained in:
Maxime NATUREL 2022-09-16 10:10:54 +02:00
parent c16e1ca291
commit a6cb25d0c3
7 changed files with 48 additions and 9 deletions

View File

@ -62,6 +62,7 @@ class SessionInfoView @JvmOverloads constructor(
sessionInfoViewState.deviceFullInfo.roomEncryptionTrustLevel, sessionInfoViewState.deviceFullInfo.roomEncryptionTrustLevel,
sessionInfoViewState.isCurrentSession, sessionInfoViewState.isCurrentSession,
sessionInfoViewState.isLearnMoreLinkVisible, sessionInfoViewState.isLearnMoreLinkVisible,
sessionInfoViewState.isVerifyButtonVisible,
) )
renderDeviceLastSeenDetails( renderDeviceLastSeenDetails(
sessionInfoViewState.deviceFullInfo.isInactive, sessionInfoViewState.deviceFullInfo.isInactive,
@ -78,12 +79,13 @@ class SessionInfoView @JvmOverloads constructor(
encryptionTrustLevel: RoomEncryptionTrustLevel, encryptionTrustLevel: RoomEncryptionTrustLevel,
isCurrentSession: Boolean, isCurrentSession: Boolean,
hasLearnMoreLink: Boolean, hasLearnMoreLink: Boolean,
isVerifyButtonVisible: Boolean,
) { ) {
views.sessionInfoVerificationStatusImageView.render(encryptionTrustLevel) views.sessionInfoVerificationStatusImageView.render(encryptionTrustLevel)
if (encryptionTrustLevel == RoomEncryptionTrustLevel.Trusted) { if (encryptionTrustLevel == RoomEncryptionTrustLevel.Trusted) {
renderCrossSigningVerified(isCurrentSession) renderCrossSigningVerified(isCurrentSession)
} else { } else {
renderCrossSigningUnverified(isCurrentSession) renderCrossSigningUnverified(isCurrentSession, isVerifyButtonVisible)
} }
if (hasLearnMoreLink) { if (hasLearnMoreLink) {
appendLearnMoreToVerificationStatus() appendLearnMoreToVerificationStatus()
@ -120,7 +122,7 @@ class SessionInfoView @JvmOverloads constructor(
views.sessionInfoVerifySessionButton.isVisible = false 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.text = context.getString(R.string.device_manager_verification_status_unverified)
views.sessionInfoVerificationStatusTextView.setTextColor(ThemeUtils.getColor(context, R.attr.colorError)) views.sessionInfoVerificationStatusTextView.setTextColor(ThemeUtils.getColor(context, R.attr.colorError))
val statusResId = if (isCurrentSession) { val statusResId = if (isCurrentSession) {
@ -129,7 +131,7 @@ class SessionInfoView @JvmOverloads constructor(
R.string.device_manager_verification_status_detail_other_session_unverified R.string.device_manager_verification_status_detail_other_session_unverified
} }
views.sessionInfoVerificationStatusDetailTextView.text = context.getString(statusResId) 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. // TODO. We don't have this info yet. Update later accordingly.

View File

@ -21,6 +21,7 @@ import im.vector.app.features.settings.devices.v2.DeviceFullInfo
data class SessionInfoViewState( data class SessionInfoViewState(
val isCurrentSession: Boolean, val isCurrentSession: Boolean,
val deviceFullInfo: DeviceFullInfo, val deviceFullInfo: DeviceFullInfo,
val isVerifyButtonVisible: Boolean = true,
val isDetailsButtonVisible: Boolean = true, val isDetailsButtonVisible: Boolean = true,
val isLearnMoreLinkVisible: Boolean = false, val isLearnMoreLinkVisible: Boolean = false,
val isLastSeenDetailsVisible: Boolean = false, val isLastSeenDetailsVisible: Boolean = false,

View File

@ -82,9 +82,12 @@ class SessionOverviewFragment :
private fun observeViewEvents() { private fun observeViewEvents() {
viewModel.observeViewEvents { viewModel.observeViewEvents {
when (it) { when (it) {
is SessionOverviewViewEvent.SelfVerification -> { is SessionOverviewViewEvent.ShowVerifyCurrentSession -> {
navigator.requestSelfSessionVerification(requireActivity()) navigator.requestSelfSessionVerification(requireActivity())
} }
is SessionOverviewViewEvent.ShowVerifyOtherSession -> {
navigator.requestSessionVerification(requireActivity(), it.deviceId)
}
is SessionOverviewViewEvent.PromptResetSecrets -> { is SessionOverviewViewEvent.PromptResetSecrets -> {
navigator.open4SSetup(requireActivity(), SetupMode.PASSPHRASE_AND_NEEDED_SECRETS_RESET) navigator.open4SSetup(requireActivity(), SetupMode.PASSPHRASE_AND_NEEDED_SECRETS_RESET)
} }
@ -105,7 +108,7 @@ class SessionOverviewFragment :
updateToolbar(state.isCurrentSession) updateToolbar(state.isCurrentSession)
updateEntryDetails(state.deviceId) updateEntryDetails(state.deviceId)
if (state.deviceInfo is Success) { if (state.deviceInfo is Success) {
renderSessionInfo(state.isCurrentSession, state.deviceInfo.invoke()) renderSessionInfo(state.isCurrentSession, state.deviceInfo.invoke(), state.isCurrentSessionTrusted)
} else { } else {
hideSessionInfo() 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 views.sessionOverviewInfo.isVisible = true
val viewState = SessionInfoViewState( val viewState = SessionInfoViewState(
isCurrentSession = isCurrentSession, isCurrentSession = isCurrentSession,
deviceFullInfo = deviceFullInfo, deviceFullInfo = deviceFullInfo,
isVerifyButtonVisible = isCurrentSession || isCurrentSessionTrusted,
isDetailsButtonVisible = false, isDetailsButtonVisible = false,
isLearnMoreLinkVisible = true, isLearnMoreLinkVisible = true,
isLastSeenDetailsVisible = true, isLastSeenDetailsVisible = true,

View File

@ -19,6 +19,7 @@ package im.vector.app.features.settings.devices.v2.overview
import im.vector.app.core.platform.VectorViewEvents import im.vector.app.core.platform.VectorViewEvents
sealed class SessionOverviewViewEvent : VectorViewEvents { sealed class SessionOverviewViewEvent : VectorViewEvents {
object SelfVerification : SessionOverviewViewEvent() object ShowVerifyCurrentSession : SessionOverviewViewEvent()
data class ShowVerifyOtherSession(val deviceId: String) : SessionOverviewViewEvent()
object PromptResetSecrets : SessionOverviewViewEvent() object PromptResetSecrets : SessionOverviewViewEvent()
} }

View File

@ -45,6 +45,7 @@ class SessionOverviewViewModel @AssistedInject constructor(
} }
init { init {
// TODO check if current session is trusted
setState { setState {
copy(isCurrentSession = isCurrentSession(deviceId)) copy(isCurrentSession = isCurrentSession(deviceId))
} }
@ -70,6 +71,8 @@ class SessionOverviewViewModel @AssistedInject constructor(
private fun handleVerifySessionAction() = withState { viewState -> private fun handleVerifySessionAction() = withState { viewState ->
if (isCurrentSession(viewState.deviceId)) { if (isCurrentSession(viewState.deviceId)) {
handleVerifyCurrentSession() handleVerifyCurrentSession()
} else {
handleVerifyOtherSession(verifySession.deviceId)
} }
} }
@ -77,10 +80,14 @@ class SessionOverviewViewModel @AssistedInject constructor(
viewModelScope.launch { viewModelScope.launch {
val currentSessionCanBeVerified = checkIfCurrentSessionCanBeVerifiedUseCase.execute() val currentSessionCanBeVerified = checkIfCurrentSessionCanBeVerifiedUseCase.execute()
if (currentSessionCanBeVerified) { if (currentSessionCanBeVerified) {
_viewEvents.post(SessionOverviewViewEvent.SelfVerification) _viewEvents.post(SessionOverviewViewEvent.ShowVerifyCurrentSession)
} else { } else {
_viewEvents.post(SessionOverviewViewEvent.PromptResetSecrets) _viewEvents.post(SessionOverviewViewEvent.PromptResetSecrets)
} }
} }
} }
private fun handleVerifyOtherSession(deviceId: String) {
_viewEvents.post(SessionOverviewViewEvent.ShowVerifyOtherSession(deviceId))
}
} }

View File

@ -24,6 +24,7 @@ import im.vector.app.features.settings.devices.v2.DeviceFullInfo
data class SessionOverviewViewState( data class SessionOverviewViewState(
val deviceId: String, val deviceId: String,
val isCurrentSession: Boolean = false, val isCurrentSession: Boolean = false,
val isCurrentSessionTrusted: Boolean = false,
val deviceInfo: Async<DeviceFullInfo> = Uninitialized, val deviceInfo: Async<DeviceFullInfo> = Uninitialized,
) : MavericksState { ) : MavericksState {
constructor(args: SessionOverviewArgs) : this( constructor(args: SessionOverviewArgs) : this(

View File

@ -95,7 +95,7 @@ class SessionOverviewViewModelTest {
// Then // Then
viewModelTest viewModelTest
.assertEvent { it is SessionOverviewViewEvent.SelfVerification } .assertEvent { it is SessionOverviewViewEvent.ShowVerifyCurrentSession }
.finish() .finish()
coVerify { coVerify {
checkIfCurrentSessionCanBeVerifiedUseCase.execute() checkIfCurrentSessionCanBeVerifiedUseCase.execute()
@ -124,4 +124,23 @@ class SessionOverviewViewModelTest {
checkIfCurrentSessionCanBeVerifiedUseCase.execute() checkIfCurrentSessionCanBeVerifiedUseCase.execute()
} }
} }
@Test
fun `given another session when handling verify session action then verify session event is posted`() {
// Given
val deviceFullInfo = mockk<DeviceFullInfo>()
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()
}
} }