mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-17 12:30:07 +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
|
import im.vector.matrix.android.internal.crypto.verification.VerificationInfoCancel
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
internal data class MessageVerificationCancelContent(
|
data class MessageVerificationCancelContent(
|
||||||
@Json(name = "code") override val code: String? = null,
|
@Json(name = "code") override val code: String? = null,
|
||||||
@Json(name = "reason") override val reason: String? = null,
|
@Json(name = "reason") override val reason: String? = null,
|
||||||
@Json(name = "m.relates_to") val relatesTo: RelationDefaultContent?
|
@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 com.zhuinden.monarchy.Monarchy
|
||||||
import im.vector.matrix.android.api.session.crypto.CryptoService
|
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.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.events.model.*
|
||||||
import im.vector.matrix.android.api.session.room.model.ReferencesAggregatedContent
|
import im.vector.matrix.android.api.session.room.model.ReferencesAggregatedContent
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
||||||
|
@ -52,6 +53,9 @@ enum class VerificationState {
|
||||||
DONE
|
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.
|
* 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)
|
?: ReferencesAggregatedContent(VerificationState.REQUEST.name)
|
||||||
// TODO ignore invalid messages? e.g a START after a CANCEL?
|
// TODO ignore invalid messages? e.g a START after a CANCEL?
|
||||||
// i.e. never change state if already canceled/done
|
// i.e. never change state if already canceled/done
|
||||||
|
val currentState = VerificationState.values().firstOrNull { data.verificationSummary == it.name }
|
||||||
val newState = when (event.getClearType()) {
|
val newState = when (event.getClearType()) {
|
||||||
EventType.KEY_VERIFICATION_START -> {
|
EventType.KEY_VERIFICATION_START -> {
|
||||||
VerificationState.WAITING
|
updateVerificationState(currentState, VerificationState.WAITING)
|
||||||
}
|
}
|
||||||
EventType.KEY_VERIFICATION_ACCEPT -> {
|
EventType.KEY_VERIFICATION_ACCEPT -> {
|
||||||
VerificationState.WAITING
|
updateVerificationState(currentState, VerificationState.WAITING)
|
||||||
}
|
}
|
||||||
EventType.KEY_VERIFICATION_KEY -> {
|
EventType.KEY_VERIFICATION_KEY -> {
|
||||||
VerificationState.WAITING
|
updateVerificationState(currentState, VerificationState.WAITING)
|
||||||
}
|
}
|
||||||
EventType.KEY_VERIFICATION_MAC -> {
|
EventType.KEY_VERIFICATION_MAC -> {
|
||||||
VerificationState.WAITING
|
updateVerificationState(currentState, VerificationState.WAITING)
|
||||||
}
|
}
|
||||||
EventType.KEY_VERIFICATION_CANCEL -> {
|
EventType.KEY_VERIFICATION_CANCEL -> {
|
||||||
if (event.senderId == userId) {
|
updateVerificationState(currentState, if (event.senderId == userId) {
|
||||||
VerificationState.CANCELED_BY_ME
|
VerificationState.CANCELED_BY_ME
|
||||||
} else VerificationState.CANCELED_BY_OTHER
|
} else VerificationState.CANCELED_BY_OTHER)
|
||||||
}
|
}
|
||||||
EventType.KEY_VERIFICATION_DONE -> {
|
EventType.KEY_VERIFICATION_DONE -> {
|
||||||
VerificationState.DONE
|
updateVerificationState(currentState, VerificationState.DONE)
|
||||||
}
|
}
|
||||||
else -> VerificationState.REQUEST
|
else -> VerificationState.REQUEST
|
||||||
}
|
}
|
||||||
|
@ -475,4 +480,18 @@ internal class DefaultEventRelationsAggregationTask @Inject constructor(
|
||||||
verifSummary.sourceEvents.add(event.eventId)
|
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_ACCEPT,
|
||||||
EventType.KEY_VERIFICATION_START,
|
EventType.KEY_VERIFICATION_START,
|
||||||
EventType.KEY_VERIFICATION_CANCEL,
|
|
||||||
EventType.KEY_VERIFICATION_KEY,
|
EventType.KEY_VERIFICATION_KEY,
|
||||||
EventType.KEY_VERIFICATION_MAC -> {
|
EventType.KEY_VERIFICATION_MAC -> {
|
||||||
// These events are filtered from timeline in normal case
|
// These events are filtered from timeline in normal case
|
||||||
// Only visible in developer mode
|
// Only visible in developer mode
|
||||||
noticeItemFactory.create(event, highlight, callback)
|
noticeItemFactory.create(event, highlight, callback)
|
||||||
}
|
}
|
||||||
|
EventType.KEY_VERIFICATION_CANCEL,
|
||||||
EventType.KEY_VERIFICATION_DONE -> {
|
EventType.KEY_VERIFICATION_DONE -> {
|
||||||
verificationConclusionItemFactory.create(event, highlight, callback)
|
verificationConclusionItemFactory.create(event, highlight, callback)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,13 +16,17 @@
|
||||||
package im.vector.riotx.features.home.room.detail.timeline.factory
|
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.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.EventType
|
||||||
import im.vector.matrix.android.api.session.events.model.RelationType
|
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.events.model.toModel
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageRelationContent
|
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.model.message.MessageVerificationRequestContent
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
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.VerificationState
|
||||||
|
import im.vector.matrix.android.internal.session.room.isCanceled
|
||||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||||
import im.vector.riotx.core.resources.ColorProvider
|
import im.vector.riotx.core.resources.ColorProvider
|
||||||
import im.vector.riotx.core.resources.UserPreferencesProvider
|
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 it's not a request ignore this event
|
||||||
if (refEvent.root.getClearContent().toModel<MessageVerificationRequestContent>() == null) return ignoredConclusion(event, highlight, callback)
|
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)
|
val referenceInformationData = messageInformationDataFactory.create(refEvent, null)
|
||||||
if (referenceInformationData.referencesInfoData?.verificationStatus != VerificationState.DONE) return ignoredConclusion(event, highlight, callback)
|
|
||||||
|
|
||||||
val informationData = messageInformationDataFactory.create(event, null)
|
val informationData = messageInformationDataFactory.create(event, null)
|
||||||
val attributes = messageItemAttributesFactory.create(null, informationData, callback)
|
val attributes = messageItemAttributesFactory.create(null, informationData, callback)
|
||||||
|
|
||||||
when (event.root.getClearType()) {
|
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 -> {
|
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
|
// We only tale the one sent by me
|
||||||
if (informationData.sentByMe) {
|
if (informationData.sentByMe) {
|
||||||
// We only display the done sent by the other user, the done send by me is ignored
|
// 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(
|
VerificationRequestConclusionItem.Attributes(
|
||||||
toUserId = informationData.senderId,
|
toUserId = informationData.senderId,
|
||||||
toUserName = informationData.memberName.toString(),
|
toUserName = informationData.memberName.toString(),
|
||||||
|
isPositive = true,
|
||||||
informationData = informationData,
|
informationData = informationData,
|
||||||
avatarRenderer = attributes.avatarRenderer,
|
avatarRenderer = attributes.avatarRenderer,
|
||||||
colorProvider = colorProvider,
|
colorProvider = colorProvider,
|
||||||
|
|
|
@ -20,6 +20,7 @@ import android.graphics.Typeface
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.RelativeLayout
|
import android.widget.RelativeLayout
|
||||||
import androidx.appcompat.widget.AppCompatTextView
|
import androidx.appcompat.widget.AppCompatTextView
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.updateLayoutParams
|
import androidx.core.view.updateLayoutParams
|
||||||
import com.airbnb.epoxy.EpoxyAttribute
|
import com.airbnb.epoxy.EpoxyAttribute
|
||||||
import com.airbnb.epoxy.EpoxyModelClass
|
import com.airbnb.epoxy.EpoxyModelClass
|
||||||
|
@ -45,8 +46,15 @@ abstract class VerificationRequestConclusionItem : AbsBaseMessageItem<Verificati
|
||||||
holder.endGuideline.updateLayoutParams<RelativeLayout.LayoutParams> {
|
holder.endGuideline.updateLayoutParams<RelativeLayout.LayoutParams> {
|
||||||
this.marginEnd = leftGuideline
|
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})"
|
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) {
|
class Holder : AbsBaseMessageItem.Holder(STUB_ID) {
|
||||||
|
@ -65,6 +73,7 @@ abstract class VerificationRequestConclusionItem : AbsBaseMessageItem<Verificati
|
||||||
data class Attributes(
|
data class Attributes(
|
||||||
val toUserId: String,
|
val toUserId: String,
|
||||||
val toUserName: String,
|
val toUserName: String,
|
||||||
|
val isPositive: Boolean,
|
||||||
override val informationData: MessageInformationData,
|
override val informationData: MessageInformationData,
|
||||||
override val avatarRenderer: AvatarRenderer,
|
override val avatarRenderer: AvatarRenderer,
|
||||||
override val colorProvider: ColorProvider,
|
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_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
android:drawableStart="@drawable/ic_shield_trusted"
|
tools:drawableStart="@drawable/ic_shield_trusted"
|
||||||
android:drawablePadding="6dp"
|
android:drawablePadding="6dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:textColor="?riotx_text_primary"
|
android:textColor="?riotx_text_primary"
|
||||||
|
|
|
@ -150,6 +150,7 @@
|
||||||
<string name="verification_request_you_cancelled">You cancelled</string>
|
<string name="verification_request_you_cancelled">You cancelled</string>
|
||||||
<string name="verification_request_other_cancelled">%s cancelled</string>
|
<string name="verification_request_other_cancelled">%s cancelled</string>
|
||||||
<string name="verification_request_waiting">Waiting…</string>
|
<string name="verification_request_waiting">Waiting…</string>
|
||||||
|
<string name="verification_conclusion_warning">Untrusted sign in</string>
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Add table
Reference in a new issue