Use new error name for expected UTD

This commit is contained in:
Valere 2024-03-27 11:59:21 +01:00
parent 9ebc10f4c2
commit 393f3f3030
2 changed files with 150 additions and 4 deletions

View file

@ -39,7 +39,7 @@ fun DecryptionFailure.toAnalyticsEvent(): Error {
return Error(
context = "mxc_crypto_error_type|${errorMsg}",
domain = Error.Domain.E2EE,
name = this.error.toAnalyticsErrorName(),
name = this.toAnalyticsErrorName(),
// this is deprecated keep for backward compatibility
cryptoModule = Error.CryptoModule.Rust,
cryptoSDK = Error.CryptoSDK.Rust,
@ -52,9 +52,10 @@ fun DecryptionFailure.toAnalyticsEvent(): Error {
)
}
private fun MXCryptoError.toAnalyticsErrorName(): Error.Name {
return if (this is MXCryptoError.Base) {
when (errorType) {
private fun DecryptionFailure.toAnalyticsErrorName(): Error.Name {
val error = this.error
val name = if (error is MXCryptoError.Base) {
when (error.errorType) {
MXCryptoError.ErrorType.UNKNOWN_INBOUND_SESSION_ID,
MXCryptoError.ErrorType.KEYS_WITHHELD -> Error.Name.OlmKeysNotSentError
MXCryptoError.ErrorType.OLM -> Error.Name.OlmUnspecifiedError
@ -64,4 +65,12 @@ private fun MXCryptoError.toAnalyticsErrorName(): Error.Name {
} else {
Error.Name.UnknownError
}
// check if it's an expected UTD!
val localAge = this.eventLocalAgeAtDecryptionFailure
val isHistorical = localAge != null && localAge < 0
if (isHistorical && !this.ownIdentityTrustedAtTimeOfDecryptionFailure) {
return Error.Name.HistoricalMessage
}
return name
}

View file

@ -35,6 +35,7 @@ import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.amshove.kluent.shouldBeEqualTo
import org.amshove.kluent.shouldNotBeEqualTo
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@ -550,6 +551,142 @@ class DecryptionFailureTrackerTest {
decryptionFailureTracker.stop()
}
@Test
fun `should report historical UTDs as an expected UTD if not verified`() = runTest {
val fakeSession = fakeMxOrgTestSession
val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
val historicalEventTimestamp = formatter.parse("2024-03-08 09:24:11")!!.time
val sessionCreationTime = formatter.parse("2024-03-09 10:00:00")!!.time
val eventSlot = slot<VectorAnalyticsEvent>()
every {
fakeAnalyticsTracker.capture(event = capture(eventSlot))
} just runs
fakeSession.fakeCryptoService.cryptoDeviceInfo = CryptoDeviceInfo(
deviceId = "ABCDEFGHT",
userId = "@alice:matrix.org",
firstTimeSeenLocalTs = sessionCreationTime
)
var currentFakeTime = 100_000L
fakeClock.givenEpoch(currentFakeTime)
fakeActiveSessionDataSource.setActiveSession(fakeSession)
decryptionFailureTracker.start(CoroutineScope(coroutineContext))
runCurrent()
// historical event and session not verified
fakeSession.fakeCryptoService.fakeCrossSigningService.givenIsCrossSigningVerifiedReturns(false)
val event = aFakeBobMxOrgEvent.copy(
originServerTs = historicalEventTimestamp
)
decryptionFailureTracker.onEventDecryptionError(event, aUISIError)
runCurrent()
// advance time to be ahead of the permanent UTD period
currentFakeTime += 70_000
fakeClock.givenEpoch(currentFakeTime)
advanceTimeBy(70_000)
runCurrent()
(eventSlot.captured as Error).name shouldBeEqualTo Error.Name.HistoricalMessage
decryptionFailureTracker.stop()
}
@Test
fun `should not report historical UTDs as an expected UTD if verified`() = runTest {
val fakeSession = fakeMxOrgTestSession
val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
val historicalEventTimestamp = formatter.parse("2024-03-08 09:24:11")!!.time
val sessionCreationTime = formatter.parse("2024-03-09 10:00:00")!!.time
val eventSlot = slot<VectorAnalyticsEvent>()
every {
fakeAnalyticsTracker.capture(event = capture(eventSlot))
} just runs
fakeSession.fakeCryptoService.cryptoDeviceInfo = CryptoDeviceInfo(
deviceId = "ABCDEFGHT",
userId = "@alice:matrix.org",
firstTimeSeenLocalTs = sessionCreationTime
)
var currentFakeTime = 100_000L
fakeClock.givenEpoch(currentFakeTime)
fakeActiveSessionDataSource.setActiveSession(fakeSession)
decryptionFailureTracker.start(CoroutineScope(coroutineContext))
runCurrent()
// historical event and session not verified
fakeSession.fakeCryptoService.fakeCrossSigningService.givenIsCrossSigningVerifiedReturns(true)
val event = aFakeBobMxOrgEvent.copy(
originServerTs = historicalEventTimestamp
)
decryptionFailureTracker.onEventDecryptionError(event, aUISIError)
runCurrent()
// advance time to be ahead of the permanent UTD period
currentFakeTime += 70_000
fakeClock.givenEpoch(currentFakeTime)
advanceTimeBy(70_000)
runCurrent()
(eventSlot.captured as Error).name shouldNotBeEqualTo Error.Name.HistoricalMessage
decryptionFailureTracker.stop()
}
@Test
fun `should not report live UTDs as an expected UTD even if not verified`() = runTest {
val fakeSession = fakeMxOrgTestSession
val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
val sessionCreationTime = formatter.parse("2024-03-09 10:00:00")!!.time
// 1mn after creation
val liveEventTimestamp = formatter.parse("2024-03-09 10:01:00")!!.time
val eventSlot = slot<VectorAnalyticsEvent>()
every {
fakeAnalyticsTracker.capture(event = capture(eventSlot))
} just runs
fakeSession.fakeCryptoService.cryptoDeviceInfo = CryptoDeviceInfo(
deviceId = "ABCDEFGHT",
userId = "@alice:matrix.org",
firstTimeSeenLocalTs = sessionCreationTime
)
var currentFakeTime = 100_000L
fakeClock.givenEpoch(currentFakeTime)
fakeActiveSessionDataSource.setActiveSession(fakeSession)
decryptionFailureTracker.start(CoroutineScope(coroutineContext))
runCurrent()
// historical event and session not verified
fakeSession.fakeCryptoService.fakeCrossSigningService.givenIsCrossSigningVerifiedReturns(false)
val event = aFakeBobMxOrgEvent.copy(
originServerTs = liveEventTimestamp
)
decryptionFailureTracker.onEventDecryptionError(event, aUISIError)
runCurrent()
// advance time to be ahead of the permanent UTD period
currentFakeTime += 70_000
fakeClock.givenEpoch(currentFakeTime)
advanceTimeBy(70_000)
runCurrent()
(eventSlot.captured as Error).name shouldNotBeEqualTo Error.Name.HistoricalMessage
decryptionFailureTracker.stop()
}
@Test
fun `should report if permanent UTD`() = runTest {
val fakeSession = fakeMxOrgTestSession