Merge pull request #929 from vector-im/feature/xsigning_fix_4

Feature/xsigning fix 4
This commit is contained in:
Benoit Marty 2020-02-02 03:13:54 +01:00 committed by GitHub
commit bb0fafcb2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 59 additions and 35 deletions

View File

@ -42,7 +42,7 @@ class RxRoom(private val room: Room, private val session: Session) {
val summaryObservable = room.getRoomSummaryLive() val summaryObservable = room.getRoomSummaryLive()
.asObservable() .asObservable()
.startWith(room.roomSummary().toOptional()) .startWith(room.roomSummary().toOptional())
.doOnNext { Timber.d("RX: summary emitted for: ${it.getOrNull()?.roomId}") } .doOnNext { Timber.v("RX: summary emitted for: ${it.getOrNull()?.roomId}") }
val memberIdsChangeObservable = summaryObservable val memberIdsChangeObservable = summaryObservable
.map { .map {
@ -56,7 +56,7 @@ class RxRoom(private val room: Room, private val session: Session) {
} }
}.orEmpty() }.orEmpty()
}.distinctUntilChanged() }.distinctUntilChanged()
.doOnNext { Timber.d("RX: memberIds emitted. Size: ${it.size}") } .doOnNext { Timber.v("RX: memberIds emitted. Size: ${it.size}") }
// Observe the device info of the users in the room // Observe the device info of the users in the room
val cryptoDeviceInfoObservable = memberIdsChangeObservable val cryptoDeviceInfoObservable = memberIdsChangeObservable
@ -68,9 +68,9 @@ class RxRoom(private val room: Room, private val session: Session) {
membersIds membersIds
} }
.startWith(membersIds) .startWith(membersIds)
.doOnNext { Timber.d("RX: CryptoDeviceInfo emitted. Size: ${it.size}") } .doOnNext { Timber.v("RX: CryptoDeviceInfo emitted. Size: ${it.size}") }
} }
.doOnNext { Timber.d("RX: cryptoDeviceInfo emitted 2. Size: ${it.size}") } .doOnNext { Timber.v("RX: cryptoDeviceInfo emitted 2. Size: ${it.size}") }
val roomEncryptionTrustLevelObservable = cryptoDeviceInfoObservable val roomEncryptionTrustLevelObservable = cryptoDeviceInfoObservable
.map { userIds -> .map { userIds ->
@ -80,7 +80,7 @@ class RxRoom(private val room: Room, private val session: Session) {
session.getCrossSigningService().getTrustLevelForUsers(userIds).toOptional() session.getCrossSigningService().getTrustLevelForUsers(userIds).toOptional()
} }
} }
.doOnNext { Timber.d("RX: roomEncryptionTrustLevel emitted: ${it.getOrNull()?.name}") } .doOnNext { Timber.v("RX: roomEncryptionTrustLevel emitted: ${it.getOrNull()?.name}") }
return Observable return Observable
.combineLatest<Optional<RoomSummary>, Optional<RoomEncryptionTrustLevel>, Optional<RoomSummary>>( .combineLatest<Optional<RoomSummary>, Optional<RoomEncryptionTrustLevel>, Optional<RoomSummary>>(
@ -92,18 +92,18 @@ class RxRoom(private val room: Room, private val session: Session) {
).toOptional() ).toOptional()
} }
) )
.doOnNext { Timber.d("RX: final room summary emitted for ${it.getOrNull()?.roomId}") } .doOnNext { Timber.v("RX: final room summary emitted for ${it.getOrNull()?.roomId}") }
} }
fun liveRoomMembers(queryParams: RoomMemberQueryParams): Observable<List<RoomMemberSummary>> { fun liveRoomMembers(queryParams: RoomMemberQueryParams): Observable<List<RoomMemberSummary>> {
val roomMembersObservable = room.getRoomMembersLive(queryParams).asObservable() val roomMembersObservable = room.getRoomMembersLive(queryParams).asObservable()
.startWith(room.getRoomMembers(queryParams)) .startWith(room.getRoomMembers(queryParams))
.doOnNext { Timber.d("RX: room members emitted. Size: ${it.size}") } .doOnNext { Timber.v("RX: room members emitted. Size: ${it.size}") }
// TODO Do it only for room members of the room (switchMap) // TODO Do it only for room members of the room (switchMap)
val cryptoDeviceInfoObservable = session.getLiveCryptoDeviceInfo().asObservable() val cryptoDeviceInfoObservable = session.getLiveCryptoDeviceInfo().asObservable()
.startWith(emptyList<CryptoDeviceInfo>()) .startWith(emptyList<CryptoDeviceInfo>())
.doOnNext { Timber.d("RX: cryptoDeviceInfo emitted. Size: ${it.size}") } .doOnNext { Timber.v("RX: cryptoDeviceInfo emitted. Size: ${it.size}") }
return Observable return Observable
.combineLatest<List<RoomMemberSummary>, List<CryptoDeviceInfo>, List<RoomMemberSummary>>( .combineLatest<List<RoomMemberSummary>, List<CryptoDeviceInfo>, List<RoomMemberSummary>>(
@ -122,7 +122,7 @@ class RxRoom(private val room: Room, private val session: Session) {
} }
} }
) )
.doOnNext { Timber.d("RX: final room members emitted. Size: ${it.size}") } .doOnNext { Timber.v("RX: final room members emitted. Size: ${it.size}") }
} }
fun liveAnnotationSummary(eventId: String): Observable<Optional<EventAnnotationsSummary>> { fun liveAnnotationSummary(eventId: String): Observable<Optional<EventAnnotationsSummary>> {

View File

@ -41,11 +41,11 @@ class RxSession(private val session: Session) {
fun liveRoomSummaries(queryParams: RoomSummaryQueryParams): Observable<List<RoomSummary>> { fun liveRoomSummaries(queryParams: RoomSummaryQueryParams): Observable<List<RoomSummary>> {
val summariesObservable = session.getRoomSummariesLive(queryParams).asObservable() val summariesObservable = session.getRoomSummariesLive(queryParams).asObservable()
.startWith(session.getRoomSummaries(queryParams)) .startWith(session.getRoomSummaries(queryParams))
.doOnNext { Timber.d("RX: summaries emitted: size: ${it.size}") } .doOnNext { Timber.v("RX: summaries emitted: size: ${it.size}") }
val cryptoDeviceInfoObservable = session.getLiveCryptoDeviceInfo().asObservable() val cryptoDeviceInfoObservable = session.getLiveCryptoDeviceInfo().asObservable()
.startWith(emptyList<CryptoDeviceInfo>()) .startWith(emptyList<CryptoDeviceInfo>())
.doOnNext { Timber.d("RX: crypto device info emitted: size: ${it.size}") } .doOnNext { Timber.v("RX: crypto device info emitted: size: ${it.size}") }
return Observable return Observable
.combineLatest<List<RoomSummary>, List<CryptoDeviceInfo>, List<RoomSummary>>( .combineLatest<List<RoomSummary>, List<CryptoDeviceInfo>, List<RoomSummary>>(

View File

@ -57,6 +57,7 @@ internal class MXMegolmDecryption(private val userId: String,
var newSessionListener: NewSessionListener? = null var newSessionListener: NewSessionListener? = null
var hasCheckUserCrossSigning = false
/** /**
* Events which we couldn't decrypt due to unknown sessions / indexes: map from * Events which we couldn't decrypt due to unknown sessions / indexes: map from
* senderKey|sessionId to timelines to list of MatrixEvents. * senderKey|sessionId to timelines to list of MatrixEvents.
@ -65,6 +66,11 @@ internal class MXMegolmDecryption(private val userId: String,
override suspend fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult { override suspend fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult {
// If cross signing is enabled, we don't send request until the keys are trusted // If cross signing is enabled, we don't send request until the keys are trusted
// There could be a race effect here when xsigning is enabled, we should ensure that keys was downloaded once
if (!hasCheckUserCrossSigning) {
deviceListManager.downloadKeys(listOf(userId), true)
hasCheckUserCrossSigning = true
}
val requestOnFail = val requestOnFail =
if (cryptoStore.getMyCrossSigningInfo() != null) { if (cryptoStore.getMyCrossSigningInfo() != null) {
cryptoStore.getMyCrossSigningInfo()?.isTrusted() == true cryptoStore.getMyCrossSigningInfo()?.isTrusted() == true

View File

@ -131,8 +131,7 @@ internal class DefaultEventRelationsAggregationTask @Inject constructor(
EventType.KEY_VERIFICATION_ACCEPT, EventType.KEY_VERIFICATION_ACCEPT,
EventType.KEY_VERIFICATION_START, EventType.KEY_VERIFICATION_START,
EventType.KEY_VERIFICATION_MAC, EventType.KEY_VERIFICATION_MAC,
// TODO Add ? EventType.KEY_VERIFICATION_READY,
// EventType.KEY_VERIFICATION_READY,
EventType.KEY_VERIFICATION_KEY -> { EventType.KEY_VERIFICATION_KEY -> {
Timber.v("## SAS REF in room $roomId for event ${event.eventId}") Timber.v("## SAS REF in room $roomId for event ${event.eventId}")
event.content.toModel<MessageRelationContent>()?.relatesTo?.let { event.content.toModel<MessageRelationContent>()?.relatesTo?.let {
@ -161,8 +160,7 @@ internal class DefaultEventRelationsAggregationTask @Inject constructor(
EventType.KEY_VERIFICATION_ACCEPT, EventType.KEY_VERIFICATION_ACCEPT,
EventType.KEY_VERIFICATION_START, EventType.KEY_VERIFICATION_START,
EventType.KEY_VERIFICATION_MAC, EventType.KEY_VERIFICATION_MAC,
// TODO Add ? EventType.KEY_VERIFICATION_READY,
// EventType.KEY_VERIFICATION_READY,
EventType.KEY_VERIFICATION_KEY -> { EventType.KEY_VERIFICATION_KEY -> {
Timber.v("## SAS REF in room $roomId for event ${event.eventId}") Timber.v("## SAS REF in room $roomId for event ${event.eventId}")
encryptedEventContent.relatesTo.eventId?.let { encryptedEventContent.relatesTo.eventId?.let {
@ -461,6 +459,9 @@ internal class DefaultEventRelationsAggregationTask @Inject constructor(
EventType.KEY_VERIFICATION_ACCEPT -> { EventType.KEY_VERIFICATION_ACCEPT -> {
updateVerificationState(currentState, VerificationState.WAITING) updateVerificationState(currentState, VerificationState.WAITING)
} }
EventType.KEY_VERIFICATION_READY -> {
updateVerificationState(currentState, VerificationState.WAITING)
}
EventType.KEY_VERIFICATION_KEY -> { EventType.KEY_VERIFICATION_KEY -> {
updateVerificationState(currentState, VerificationState.WAITING) updateVerificationState(currentState, VerificationState.WAITING)
} }

View File

@ -16,11 +16,13 @@
package im.vector.riotx.core.epoxy.profiles package im.vector.riotx.core.epoxy.profiles
import android.content.res.ColorStateList
import android.view.View import android.view.View
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.widget.ImageViewCompat
import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.riotx.R import im.vector.riotx.R
@ -68,13 +70,20 @@ abstract class ProfileActionItem : VectorEpoxyModel<ProfileActionItem.Holder>()
holder.subtitle.setTextOrHide(subtitle) holder.subtitle.setTextOrHide(subtitle)
if (iconRes != 0) { if (iconRes != 0) {
holder.icon.setImageResource(iconRes) holder.icon.setImageResource(iconRes)
ImageViewCompat.setImageTintList(holder.icon, ColorStateList.valueOf(tintColor))
holder.icon.isVisible = true holder.icon.isVisible = true
} else { } else {
holder.icon.isVisible = false holder.icon.isVisible = false
} }
if (editableRes != 0) { if (editableRes != 0) {
val tintColorSecondary = if (destructive) {
tintColor
} else {
ThemeUtils.getColor(holder.view.context, R.attr.riotx_text_secondary)
}
holder.editable.setImageResource(editableRes) holder.editable.setImageResource(editableRes)
ImageViewCompat.setImageTintList(holder.editable, ColorStateList.valueOf(tintColorSecondary))
holder.editable.isVisible = true holder.editable.isVisible = true
} else { } else {
holder.editable.isVisible = false holder.editable.isVisible = false

View File

@ -46,9 +46,7 @@ fun EpoxyController.buildProfileAction(
id("action_$id") id("action_$id")
subtitle(subtitle) subtitle(subtitle)
editable(editable) editable(editable)
apply { editableRes?.let { editableRes(editableRes) }
editableRes?.let { editableRes(editableRes) }
}
destructive(destructive) destructive(destructive)
title(title) title(title)
listener { _ -> listener { _ ->

View File

@ -15,8 +15,9 @@
*/ */
package im.vector.riotx.features.settings.crosssigning package im.vector.riotx.features.settings.crosssigning
import android.content.DialogInterface
import android.os.Bundle import android.os.Bundle
import android.text.InputType import android.view.KeyEvent
import android.view.View import android.view.View
import android.widget.EditText import android.widget.EditText
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
@ -31,6 +32,7 @@ import im.vector.riotx.core.extensions.configureWith
import im.vector.riotx.core.extensions.observeEvent import im.vector.riotx.core.extensions.observeEvent
import im.vector.riotx.core.platform.VectorBaseActivity import im.vector.riotx.core.platform.VectorBaseActivity
import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.platform.VectorBaseFragment
import im.vector.riotx.core.utils.toast
import kotlinx.android.synthetic.main.fragment_generic_recycler.* import kotlinx.android.synthetic.main.fragment_generic_recycler.*
import javax.inject.Inject import javax.inject.Inject
@ -91,27 +93,35 @@ class CrossSigningSettingsFragment @Inject constructor(
} }
private fun requestPassword(sessionId: String) { private fun requestPassword(sessionId: String) {
// Ask for password val inflater = requireActivity().layoutInflater
val inflater = this.layoutInflater val layout = inflater.inflate(R.layout.dialog_prompt_password, null)
val layout = inflater.inflate(R.layout.dialog_base_edit_text, null) val passwordEditText = layout.findViewById<EditText>(R.id.prompt_password)
val input = layout.findViewById<EditText>(R.id.edit_text).also { AlertDialog.Builder(requireActivity())
it.inputType = InputType.TYPE_TEXT_VARIATION_PASSWORD .setIcon(android.R.drawable.ic_dialog_alert)
} .setTitle(R.string.devices_delete_dialog_title)
AlertDialog.Builder(requireContext())
.setTitle("Confirm password")
.setView(layout) .setView(layout)
.setPositiveButton(R.string.ok) { _, _ -> .setPositiveButton(R.string.auth_submit, DialogInterface.OnClickListener { _, _ ->
val pass = input.text.toString() if (passwordEditText.toString().isEmpty()) {
requireActivity().toast(R.string.error_empty_field_your_password)
return@OnClickListener
}
val pass = passwordEditText.text.toString()
// TODO sessionId should never get out the ViewModel // TODO sessionId should never get out the ViewModel
viewModel.handle(CrossSigningAction.InitializeCrossSigning(UserPasswordAuth( viewModel.handle(CrossSigningAction.InitializeCrossSigning(UserPasswordAuth(
session = sessionId, session = sessionId,
password = pass password = pass
))) )))
} })
.setNegativeButton(R.string.cancel, null) .setNegativeButton(R.string.cancel, null)
.setOnKeyListener(DialogInterface.OnKeyListener { dialog, keyCode, event ->
if (event.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
dialog.cancel()
return@OnKeyListener true
}
false
})
.show() .show()
} }

View File

@ -168,8 +168,8 @@ class VectorSettingsDevicesFragment @Inject constructor(
viewModel.handle(DevicesAction.Password(mAccountPassword)) viewModel.handle(DevicesAction.Password(mAccountPassword))
} else { } else {
val inflater = requireActivity().layoutInflater val inflater = requireActivity().layoutInflater
val layout = inflater.inflate(R.layout.dialog_device_delete, null) val layout = inflater.inflate(R.layout.dialog_prompt_password, null)
val passwordEditText = layout.findViewById<EditText>(R.id.delete_password) val passwordEditText = layout.findViewById<EditText>(R.id.prompt_password)
AlertDialog.Builder(requireActivity()) AlertDialog.Builder(requireActivity())
.setIcon(android.R.drawable.ic_dialog_alert) .setIcon(android.R.drawable.ic_dialog_alert)

View File

@ -31,7 +31,7 @@
android:textStyle="bold" /> android:textStyle="bold" />
<EditText <EditText
android:id="@+id/delete_password" android:id="@+id/prompt_password"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ems="10" android:ems="10"

View File

@ -20,6 +20,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:scaleType="center" android:scaleType="center"
android:tint="?riotx_text_primary"
android:visibility="gone" android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@ -55,7 +56,6 @@
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:drawablePadding="16dp" android:drawablePadding="16dp"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="2"
android:textColor="?riotx_text_secondary" android:textColor="?riotx_text_secondary"
android:textSize="12sp" android:textSize="12sp"
app:layout_constrainedWidth="true" app:layout_constrainedWidth="true"