mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-23 09:56:00 +03:00
Show untrusted conclusions
This commit is contained in:
parent
0776a301ea
commit
a673bf092d
8 changed files with 104 additions and 13 deletions
|
@ -24,7 +24,7 @@ import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultC
|
|||
import im.vector.matrix.android.internal.crypto.verification.VerificationInfoCancel
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class MessageVerificationCancelContent(
|
||||
data class MessageVerificationCancelContent(
|
||||
@Json(name = "code") override val code: String? = null,
|
||||
@Json(name = "reason") override val reason: String? = null,
|
||||
@Json(name = "m.relates_to") val relatesTo: RelationDefaultContent?
|
||||
|
|
|
@ -18,6 +18,7 @@ package im.vector.matrix.android.internal.session.room
|
|||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.session.crypto.CryptoService
|
||||
import im.vector.matrix.android.api.session.crypto.MXCryptoError
|
||||
import im.vector.matrix.android.api.session.crypto.sas.CancelCode
|
||||
import im.vector.matrix.android.api.session.events.model.*
|
||||
import im.vector.matrix.android.api.session.room.model.ReferencesAggregatedContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
||||
|
@ -52,6 +53,9 @@ enum class VerificationState {
|
|||
DONE
|
||||
}
|
||||
|
||||
fun VerificationState.isCanceled() : Boolean {
|
||||
return this == VerificationState.CANCELED_BY_ME || this == VerificationState.CANCELED_BY_OTHER
|
||||
}
|
||||
/**
|
||||
* Called by EventRelationAggregationUpdater, when new events that can affect relations are inserted in base.
|
||||
*/
|
||||
|
@ -438,26 +442,27 @@ internal class DefaultEventRelationsAggregationTask @Inject constructor(
|
|||
?: ReferencesAggregatedContent(VerificationState.REQUEST.name)
|
||||
// TODO ignore invalid messages? e.g a START after a CANCEL?
|
||||
// i.e. never change state if already canceled/done
|
||||
val currentState = VerificationState.values().firstOrNull { data.verificationSummary == it.name }
|
||||
val newState = when (event.getClearType()) {
|
||||
EventType.KEY_VERIFICATION_START -> {
|
||||
VerificationState.WAITING
|
||||
updateVerificationState(currentState, VerificationState.WAITING)
|
||||
}
|
||||
EventType.KEY_VERIFICATION_ACCEPT -> {
|
||||
VerificationState.WAITING
|
||||
updateVerificationState(currentState, VerificationState.WAITING)
|
||||
}
|
||||
EventType.KEY_VERIFICATION_KEY -> {
|
||||
VerificationState.WAITING
|
||||
updateVerificationState(currentState, VerificationState.WAITING)
|
||||
}
|
||||
EventType.KEY_VERIFICATION_MAC -> {
|
||||
VerificationState.WAITING
|
||||
updateVerificationState(currentState, VerificationState.WAITING)
|
||||
}
|
||||
EventType.KEY_VERIFICATION_CANCEL -> {
|
||||
if (event.senderId == userId) {
|
||||
updateVerificationState(currentState, if (event.senderId == userId) {
|
||||
VerificationState.CANCELED_BY_ME
|
||||
} else VerificationState.CANCELED_BY_OTHER
|
||||
} else VerificationState.CANCELED_BY_OTHER)
|
||||
}
|
||||
EventType.KEY_VERIFICATION_DONE -> {
|
||||
VerificationState.DONE
|
||||
updateVerificationState(currentState, VerificationState.DONE)
|
||||
}
|
||||
else -> VerificationState.REQUEST
|
||||
}
|
||||
|
@ -475,4 +480,18 @@ internal class DefaultEventRelationsAggregationTask @Inject constructor(
|
|||
verifSummary.sourceEvents.add(event.eventId)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateVerificationState(oldState: VerificationState?, newState: VerificationState) : VerificationState{
|
||||
// Cancel is always prioritary ?
|
||||
// Eg id i found that mac or keys mismatch and send a cancel and the other send a done, i have to
|
||||
// consider as canceled
|
||||
if (newState == VerificationState.CANCELED_BY_OTHER || newState == VerificationState.CANCELED_BY_ME) {
|
||||
return newState
|
||||
}
|
||||
//never move out of cancel
|
||||
if (oldState == VerificationState.CANCELED_BY_OTHER || oldState == VerificationState.CANCELED_BY_ME) {
|
||||
return oldState
|
||||
}
|
||||
return newState
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,13 +67,13 @@ class TimelineItemFactory @Inject constructor(private val messageItemFactory: Me
|
|||
}
|
||||
EventType.KEY_VERIFICATION_ACCEPT,
|
||||
EventType.KEY_VERIFICATION_START,
|
||||
EventType.KEY_VERIFICATION_CANCEL,
|
||||
EventType.KEY_VERIFICATION_KEY,
|
||||
EventType.KEY_VERIFICATION_MAC -> {
|
||||
// These events are filtered from timeline in normal case
|
||||
// Only visible in developer mode
|
||||
noticeItemFactory.create(event, highlight, callback)
|
||||
}
|
||||
EventType.KEY_VERIFICATION_CANCEL,
|
||||
EventType.KEY_VERIFICATION_DONE -> {
|
||||
verificationConclusionItemFactory.create(event, highlight, callback)
|
||||
}
|
||||
|
|
|
@ -16,13 +16,17 @@
|
|||
package im.vector.riotx.features.home.room.detail.timeline.factory
|
||||
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.session.crypto.sas.CancelCode
|
||||
import im.vector.matrix.android.api.session.crypto.sas.safeValueOf
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.RelationType
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageRelationContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageVerificationCancelContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageVerificationRequestContent
|
||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||
import im.vector.matrix.android.internal.session.room.VerificationState
|
||||
import im.vector.matrix.android.internal.session.room.isCanceled
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.riotx.core.resources.ColorProvider
|
||||
import im.vector.riotx.core.resources.UserPreferencesProvider
|
||||
|
@ -70,15 +74,52 @@ class VerificationItemFactory @Inject constructor(
|
|||
// If it's not a request ignore this event
|
||||
if (refEvent.root.getClearContent().toModel<MessageVerificationRequestContent>() == null) return ignoredConclusion(event, highlight, callback)
|
||||
|
||||
// Is the request referenced is actually really completed?
|
||||
val referenceInformationData = messageInformationDataFactory.create(refEvent, null)
|
||||
if (referenceInformationData.referencesInfoData?.verificationStatus != VerificationState.DONE) return ignoredConclusion(event, highlight, callback)
|
||||
|
||||
val informationData = messageInformationDataFactory.create(event, null)
|
||||
val attributes = messageItemAttributesFactory.create(null, informationData, callback)
|
||||
|
||||
when (event.root.getClearType()) {
|
||||
EventType.KEY_VERIFICATION_CANCEL -> {
|
||||
// Is the request referenced is actually really cancelled?
|
||||
// if (referenceInformationData.referencesInfoData?.verificationStatus?.isCanceled() == false) return ignoredConclusion(event, highlight, callback)
|
||||
|
||||
val cancelContent = event.root.getClearContent().toModel<MessageVerificationCancelContent>()
|
||||
?: return ignoredConclusion(event, highlight, callback)
|
||||
|
||||
when (safeValueOf(cancelContent.code)) {
|
||||
CancelCode.MismatchedCommitment,
|
||||
CancelCode.MismatchedKeys,
|
||||
CancelCode.MismatchedSas -> {
|
||||
//We should display these bad conclusions
|
||||
return VerificationRequestConclusionItem_()
|
||||
.attributes(
|
||||
VerificationRequestConclusionItem.Attributes(
|
||||
toUserId = informationData.senderId,
|
||||
toUserName = informationData.memberName.toString(),
|
||||
isPositive = false,
|
||||
informationData = informationData,
|
||||
avatarRenderer = attributes.avatarRenderer,
|
||||
colorProvider = colorProvider,
|
||||
emojiTypeFace = attributes.emojiTypeFace,
|
||||
itemClickListener = attributes.itemClickListener,
|
||||
itemLongClickListener = attributes.itemLongClickListener,
|
||||
reactionPillCallback = attributes.reactionPillCallback,
|
||||
readReceiptsCallback = attributes.readReceiptsCallback
|
||||
)
|
||||
)
|
||||
.highlighted(highlight)
|
||||
.leftGuideline(avatarSizeProvider.leftGuideline)
|
||||
}
|
||||
else -> ignoredConclusion(event, highlight, callback)
|
||||
}
|
||||
|
||||
}
|
||||
EventType.KEY_VERIFICATION_DONE -> {
|
||||
|
||||
// Is the request referenced is actually really completed?
|
||||
if (referenceInformationData.referencesInfoData?.verificationStatus != VerificationState.DONE) return ignoredConclusion(event, highlight, callback)
|
||||
|
||||
// We only tale the one sent by me
|
||||
if (informationData.sentByMe) {
|
||||
// We only display the done sent by the other user, the done send by me is ignored
|
||||
|
@ -89,6 +130,7 @@ class VerificationItemFactory @Inject constructor(
|
|||
VerificationRequestConclusionItem.Attributes(
|
||||
toUserId = informationData.senderId,
|
||||
toUserName = informationData.memberName.toString(),
|
||||
isPositive = true,
|
||||
informationData = informationData,
|
||||
avatarRenderer = attributes.avatarRenderer,
|
||||
colorProvider = colorProvider,
|
||||
|
|
|
@ -20,6 +20,7 @@ import android.graphics.Typeface
|
|||
import android.view.View
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.appcompat.widget.AppCompatTextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
|
@ -45,8 +46,15 @@ abstract class VerificationRequestConclusionItem : AbsBaseMessageItem<Verificati
|
|||
holder.endGuideline.updateLayoutParams<RelativeLayout.LayoutParams> {
|
||||
this.marginEnd = leftGuideline
|
||||
}
|
||||
holder.titleView.text = holder.view.context.getString(R.string.sas_verified)
|
||||
val title = if (attributes.isPositive) R.string.sas_verified else R.string.verification_conclusion_warning
|
||||
holder.titleView.text = holder.view.context.getString(title)
|
||||
holder.descriptionView.text = "${attributes.informationData.memberName} (${attributes.informationData.senderId})"
|
||||
|
||||
val startDrawable = if (attributes.isPositive) R.drawable.ic_shield_trusted else R.drawable.ic_shield_warning
|
||||
holder.titleView.setCompoundDrawablesWithIntrinsicBounds(
|
||||
ContextCompat.getDrawable(holder.view.context, startDrawable),
|
||||
null, null, null
|
||||
)
|
||||
}
|
||||
|
||||
class Holder : AbsBaseMessageItem.Holder(STUB_ID) {
|
||||
|
@ -65,6 +73,7 @@ abstract class VerificationRequestConclusionItem : AbsBaseMessageItem<Verificati
|
|||
data class Attributes(
|
||||
val toUserId: String,
|
||||
val toUserName: String,
|
||||
val isPositive: Boolean,
|
||||
override val informationData: MessageInformationData,
|
||||
override val avatarRenderer: AvatarRenderer,
|
||||
override val colorProvider: ColorProvider,
|
||||
|
|
20
vector/src/main/res/drawable/ic_shield_warning.xml
Normal file
20
vector/src/main/res/drawable/ic_shield_warning.xml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:strokeWidth="1"
|
||||
android:pathData="m12,21s9,-3.8 9,-9.5v-6.65l-9,-2.85 -9,2.85v6.65c0,5.7 9,9.5 9,9.5z"
|
||||
android:strokeLineJoin="round"
|
||||
android:fillColor="#ff4b55"
|
||||
android:strokeColor="#fff"
|
||||
android:fillType="evenOdd"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M12.05,5.5L12.05,5.5A1.25,1.25 0,0 1,13.3 6.75L13.3,12.25A1.25,1.25 0,0 1,12.05 13.5L12.05,13.5A1.25,1.25 0,0 1,10.8 12.25L10.8,6.75A1.25,1.25 0,0 1,12.05 5.5z"
|
||||
android:fillColor="#fff"/>
|
||||
<path
|
||||
android:pathData="M12.05,15L12.05,15A1.25,1.25 0,0 1,13.3 16.25L13.3,16.25A1.25,1.25 0,0 1,12.05 17.5L12.05,17.5A1.25,1.25 0,0 1,10.8 16.25L10.8,16.25A1.25,1.25 0,0 1,12.05 15z"
|
||||
android:fillColor="#fff"/>
|
||||
</vector>
|
|
@ -11,7 +11,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:drawableStart="@drawable/ic_shield_trusted"
|
||||
tools:drawableStart="@drawable/ic_shield_trusted"
|
||||
android:drawablePadding="6dp"
|
||||
android:gravity="center"
|
||||
android:textColor="?riotx_text_primary"
|
||||
|
|
|
@ -150,6 +150,7 @@
|
|||
<string name="verification_request_you_cancelled">You cancelled</string>
|
||||
<string name="verification_request_other_cancelled">%s cancelled</string>
|
||||
<string name="verification_request_waiting">Waiting…</string>
|
||||
<string name="verification_conclusion_warning">Untrusted sign in</string>
|
||||
|
||||
|
||||
</resources>
|
||||
|
|
Loading…
Reference in a new issue