From b935a6557f000264ca19e5fc90abe6fc804bdf34 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 12 Aug 2020 12:20:11 +0200 Subject: [PATCH 1/5] Move state to a dedicated file --- ...iceVerificationInfoBottomSheetViewModel.kt | 16 ++-------- ...iceVerificationInfoBottomSheetViewState.kt | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+), 14 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt index 6f5bd909c7..5746891576 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt @@ -15,31 +15,19 @@ */ package im.vector.app.features.settings.devices -import com.airbnb.mvrx.Async import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.Loading -import com.airbnb.mvrx.MvRxState import com.airbnb.mvrx.MvRxViewModelFactory -import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject -import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import im.vector.app.core.platform.EmptyAction import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel +import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import org.matrix.android.sdk.rx.rx -data class DeviceVerificationInfoBottomSheetViewState( - val cryptoDeviceInfo: Async = Uninitialized, - val deviceInfo: Async = Uninitialized, - val hasAccountCrossSigning: Boolean = false, - val accountCrossSigningIsTrusted: Boolean = false, - val isMine: Boolean = false -) : MvRxState - class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@Assisted initialState: DeviceVerificationInfoBottomSheetViewState, @Assisted val deviceId: String, val session: Session diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt new file mode 100644 index 0000000000..41a33ccfdd --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.settings.devices + +import com.airbnb.mvrx.Async +import com.airbnb.mvrx.MvRxState +import com.airbnb.mvrx.Uninitialized +import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo +import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo + +data class DeviceVerificationInfoBottomSheetViewState( + val cryptoDeviceInfo: Async = Uninitialized, + val deviceInfo: Async = Uninitialized, + val hasAccountCrossSigning: Boolean = false, + val accountCrossSigningIsTrusted: Boolean = false, + val isMine: Boolean = false +) : MvRxState From 6af879fe2a5732522b1f7467174689cd91ac18af Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 12 Aug 2020 12:21:50 +0200 Subject: [PATCH 2/5] Rename class --- .../devices/DeviceVerificationInfoBottomSheet.kt | 10 +++++----- ... => DeviceVerificationInfoBottomSheetController.kt} | 6 +++--- .../DeviceVerificationInfoBottomSheetViewState.kt | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) rename vector/src/main/java/im/vector/app/features/settings/devices/{DeviceVerificationInfoEpoxyController.kt => DeviceVerificationInfoBottomSheetController.kt} (98%) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt index 6a334898c0..c8b12e26a5 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt @@ -39,7 +39,7 @@ data class DeviceVerificationInfoArgs( val deviceId: String ) : Parcelable -class DeviceVerificationInfoBottomSheet : VectorBaseBottomSheetDialogFragment(), DeviceVerificationInfoEpoxyController.Callback { +class DeviceVerificationInfoBottomSheet : VectorBaseBottomSheetDialogFragment(), DeviceVerificationInfoBottomSheetController.Callback { private val viewModel: DeviceVerificationInfoBottomSheetViewModel by fragmentViewModel(DeviceVerificationInfoBottomSheetViewModel::class) @@ -54,17 +54,17 @@ class DeviceVerificationInfoBottomSheet : VectorBaseBottomSheetDialogFragment(), injector.inject(this) } - @Inject lateinit var epoxyController: DeviceVerificationInfoEpoxyController + @Inject lateinit var controller: DeviceVerificationInfoBottomSheetController override fun getLayoutResId() = R.layout.bottom_sheet_generic_list_with_title override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) recyclerView.configureWith( - epoxyController, + controller, showDivider = false, hasFixedSize = false) - epoxyController.callback = this + controller.callback = this bottomSheetTitle.isVisible = false } @@ -74,7 +74,7 @@ class DeviceVerificationInfoBottomSheet : VectorBaseBottomSheetDialogFragment(), } override fun invalidate() = withState(viewModel) { - epoxyController.setData(it) + controller.setData(it) super.invalidate() } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoEpoxyController.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt similarity index 98% rename from vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoEpoxyController.kt rename to vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt index bae31124ed..393bc741fe 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt @@ -31,9 +31,9 @@ import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationA import timber.log.Timber import javax.inject.Inject -class DeviceVerificationInfoEpoxyController @Inject constructor(private val stringProvider: StringProvider, - private val colorProvider: ColorProvider, - private val session: Session) +class DeviceVerificationInfoBottomSheetController @Inject constructor(private val stringProvider: StringProvider, + private val colorProvider: ColorProvider, + private val session: Session) : TypedEpoxyController() { var callback: Callback? = null diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt index 41a33ccfdd..ff7532fdaf 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt @@ -19,8 +19,8 @@ package im.vector.app.features.settings.devices import com.airbnb.mvrx.Async import com.airbnb.mvrx.MvRxState import com.airbnb.mvrx.Uninitialized -import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo -import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo +import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo data class DeviceVerificationInfoBottomSheetViewState( val cryptoDeviceInfo: Async = Uninitialized, From 96c7f57ea0fb543f0852b9f0256184c58df91868 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 12 Aug 2020 12:22:54 +0200 Subject: [PATCH 3/5] Remove useless member --- .../DeviceVerificationInfoBottomSheetController.kt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt index 393bc741fe..5fb6e20a2f 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt @@ -16,9 +16,6 @@ package im.vector.app.features.settings.devices import com.airbnb.epoxy.TypedEpoxyController -import org.matrix.android.sdk.api.extensions.orFalse -import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import im.vector.app.R import im.vector.app.core.epoxy.dividerItem import im.vector.app.core.epoxy.loadingItem @@ -28,12 +25,14 @@ import im.vector.app.core.ui.list.GenericItem import im.vector.app.core.ui.list.genericFooterItem import im.vector.app.core.ui.list.genericItem import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationActionItem +import org.matrix.android.sdk.api.extensions.orFalse +import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import timber.log.Timber import javax.inject.Inject -class DeviceVerificationInfoBottomSheetController @Inject constructor(private val stringProvider: StringProvider, - private val colorProvider: ColorProvider, - private val session: Session) +class DeviceVerificationInfoBottomSheetController @Inject constructor( + private val stringProvider: StringProvider, + private val colorProvider: ColorProvider) : TypedEpoxyController() { var callback: Callback? = null From 2efe5a420cf377041afc51b47134abeacc7ed71b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 12 Aug 2020 12:53:57 +0200 Subject: [PATCH 4/5] Do not propose to verify the current session if there is only one session (#1901) --- CHANGES.md | 1 + ...viceVerificationInfoBottomSheetController.kt | 17 ++++++++++------- ...eviceVerificationInfoBottomSheetViewModel.kt | 8 ++++++++ ...eviceVerificationInfoBottomSheetViewState.kt | 3 ++- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 86b796869e..1ec6d091a9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ Features ✨: Improvements 🙌: - You can now join room through permalink and within room directory search - Add long click gesture to copy userId, user display name, room name, room topic and room alias (#1774) + - Do not propose to verify session if there is only one session (#1901) Bugfix 🐛: - Display name not shown under Settings/General (#1926) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt index 5fb6e20a2f..9c7615c94b 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt @@ -66,16 +66,18 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor( if (data.hasAccountCrossSigning) { // Cross Signing is enabled - handleE2EWithCrossSigning(data.isMine, data.accountCrossSigningIsTrusted, cryptoDeviceInfo, shield) + handleE2EWithCrossSigning(data, cryptoDeviceInfo, shield) } else { - handleE2EInLegacy(data.isMine, cryptoDeviceInfo, shield) + handleE2EInLegacy(data, cryptoDeviceInfo, shield) } // COMMON ACTIONS (Rename / signout) addGenericDeviceManageActions(data, cryptoDeviceInfo.deviceId) } - private fun handleE2EWithCrossSigning(isMine: Boolean, currentSessionIsTrusted: Boolean, cryptoDeviceInfo: CryptoDeviceInfo, shield: Int) { + private fun handleE2EWithCrossSigning(data: DeviceVerificationInfoBottomSheetViewState, cryptoDeviceInfo: CryptoDeviceInfo, shield: Int) { + val isMine = data.isMine + val currentSessionIsTrusted = data.accountCrossSigningIsTrusted Timber.v("handleE2EWithCrossSigning $isMine, $cryptoDeviceInfo, $shield") if (isMine) { @@ -87,8 +89,8 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor( title(stringProvider.getString(R.string.encryption_information_verified)) description(stringProvider.getString(R.string.settings_active_sessions_verified_device_desc)) } - } else { - // You need to complete security + } else if (data.hasOtherSessions) { + // You need to complete security, only if there are other session(s) available genericItem { id("trust${cryptoDeviceInfo.deviceId}") style(GenericItem.STYLE.BIG_TEXT) @@ -131,7 +133,7 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor( description("(${cryptoDeviceInfo.deviceId})") } - if (isMine && !currentSessionIsTrusted) { + if (isMine && !currentSessionIsTrusted && data.hasOtherSessions) { // Add complete security dividerItem { id("completeSecurityDiv") @@ -157,8 +159,9 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor( } } - private fun handleE2EInLegacy(isMine: Boolean, cryptoDeviceInfo: CryptoDeviceInfo, shield: Int) { + private fun handleE2EInLegacy(data: DeviceVerificationInfoBottomSheetViewState, cryptoDeviceInfo: CryptoDeviceInfo, shield: Int) { // ==== Legacy + val isMine = data.isMine // TRUST INFO SECTION if (cryptoDeviceInfo.trustLevel?.isLocallyVerified() == true) { diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt index 5746891576..34e3c566fb 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt @@ -65,6 +65,14 @@ class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@As ) } + session.rx().liveUserCryptoDevices(session.myUserId) + .map { it.size } + .execute { + copy( + hasOtherSessions = it.invoke() ?: 0 > 1 + ) + } + setState { copy(deviceInfo = Loading()) } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt index ff7532fdaf..61e4aa6f4d 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt @@ -27,5 +27,6 @@ data class DeviceVerificationInfoBottomSheetViewState( val deviceInfo: Async = Uninitialized, val hasAccountCrossSigning: Boolean = false, val accountCrossSigningIsTrusted: Boolean = false, - val isMine: Boolean = false + val isMine: Boolean = false, + val hasOtherSessions: Boolean = false ) : MvRxState From 633b12f66d69869d911683aff12886303222a97c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 3 Sep 2020 10:00:01 +0200 Subject: [PATCH 5/5] Propose to verify the current session if the 4S contains secret, even if there is no other sessions --- CHANGES.md | 2 +- .../DeviceVerificationInfoBottomSheetController.kt | 12 ++++++++---- .../DeviceVerificationInfoBottomSheetViewModel.kt | 3 ++- .../DeviceVerificationInfoBottomSheetViewState.kt | 9 +++++++-- vector/src/main/res/values/strings.xml | 1 + 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 1ec6d091a9..e0031644a6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,7 +7,7 @@ Features ✨: Improvements 🙌: - You can now join room through permalink and within room directory search - Add long click gesture to copy userId, user display name, room name, room topic and room alias (#1774) - - Do not propose to verify session if there is only one session (#1901) + - Do not propose to verify session if there is only one session and 4S is not configured (#1901) Bugfix 🐛: - Display name not shown under Settings/General (#1926) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt index 9c7615c94b..25a98bb4b5 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt @@ -89,14 +89,18 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor( title(stringProvider.getString(R.string.encryption_information_verified)) description(stringProvider.getString(R.string.settings_active_sessions_verified_device_desc)) } - } else if (data.hasOtherSessions) { - // You need to complete security, only if there are other session(s) available + } else if (data.canVerifySession) { + // You need to complete security, only if there are other session(s) available, or if 4S contains secrets genericItem { id("trust${cryptoDeviceInfo.deviceId}") style(GenericItem.STYLE.BIG_TEXT) titleIconResourceId(shield) title(stringProvider.getString(R.string.crosssigning_verify_this_session)) - description(stringProvider.getString(R.string.confirm_your_identity)) + if (data.hasOtherSessions) { + description(stringProvider.getString(R.string.confirm_your_identity)) + } else { + description(stringProvider.getString(R.string.confirm_your_identity_quad_s)) + } } } } else { @@ -133,7 +137,7 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor( description("(${cryptoDeviceInfo.deviceId})") } - if (isMine && !currentSessionIsTrusted && data.hasOtherSessions) { + if (isMine && !currentSessionIsTrusted && data.canVerifySession) { // Add complete security dividerItem { id("completeSecurityDiv") diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt index 34e3c566fb..ad840d2efb 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt @@ -43,7 +43,8 @@ class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@As setState { copy( hasAccountCrossSigning = session.cryptoService().crossSigningService().isCrossSigningInitialized(), - accountCrossSigningIsTrusted = session.cryptoService().crossSigningService().isCrossSigningVerified() + accountCrossSigningIsTrusted = session.cryptoService().crossSigningService().isCrossSigningVerified(), + isRecoverySetup = session.sharedSecretStorageService.isRecoverySetup() ) } session.rx().liveCrossSigningInfo(session.myUserId) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt index 61e4aa6f4d..a736b0442c 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt @@ -28,5 +28,10 @@ data class DeviceVerificationInfoBottomSheetViewState( val hasAccountCrossSigning: Boolean = false, val accountCrossSigningIsTrusted: Boolean = false, val isMine: Boolean = false, - val hasOtherSessions: Boolean = false -) : MvRxState + val hasOtherSessions: Boolean = false, + val isRecoverySetup: Boolean = false +) : MvRxState { + + val canVerifySession: Boolean + get() = hasOtherSessions || isRecoverySetup +} diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 7506a4d502..2e031cfd4f 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2413,6 +2413,7 @@ Verify login Interactively Verify by Emoji Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages. + Confirm your identity by verifying this login, granting it access to encrypted messages. Mark as Trusted Please choose a username.