Skip to content

Commit

Permalink
Merge pull request #7776 from element-hq/valere/analytics_posthog_com…
Browse files Browse the repository at this point in the history
…plete

Telemetry | Add additional properties to posthog UTD errors
  • Loading branch information
BillCarsonFr authored Apr 15, 2024
2 parents 24fb540 + afd6dee commit 087f0cc
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 15 deletions.
7 changes: 3 additions & 4 deletions Riot/Modules/Analytics/DecryptionFailure+Analytics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,13 @@ extension DecryptionFailure {
cryptoModule: .Rust,
cryptoSDK: .Rust,
domain: .E2EE,

eventLocalAgeMillis: self.eventLocalAgeMillis,
isFederated: nil,
isMatrixDotOrg: nil,
isFederated: self.isFederated,
isMatrixDotOrg: self.isMatrixOrg,
name: errorName,
timeToDecryptMillis: timeToDecryptMillis,
userTrustsOwnIdentity: self.trustOwnIdentityAtTimeOfFailure,
wasVisibleToUser: nil
wasVisibleToUser: self.wasVisibleToUser
)
}
}
8 changes: 8 additions & 0 deletions Riot/Modules/Analytics/DecryptionFailure.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ import AnalyticsEvents

var eventLocalAgeMillis: Int?

/// Is the current user on matrix org
var isMatrixOrg: Bool?
/// Are the sender and recipient on the same homeserver
var isFederated: Bool?

/// As for now the ios App only reports UTDs visible to user (error are reported from EventFormatter
var wasVisibleToUser: Bool = true

init(failedEventId: String, reason: DecryptionFailureReason, context: String, ts: TimeInterval) {
self.failedEventId = failedEventId
self.reason = reason
Expand Down
11 changes: 11 additions & 0 deletions Riot/Modules/Analytics/DecryptionFailureTracker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,17 @@ class DecryptionFailureTracker: NSObject {
failure.eventLocalAgeMillis = Int(exactly: eventRelativeAgeMillis)
failure.trustOwnIdentityAtTimeOfFailure = isSessionVerified

let myDomain = userId.components(separatedBy: ":").last
failure.isMatrixOrg = myDomain == "matrix.org"

if MXTools.isMatrixUserIdentifier(event.sender) {
let senderDomain = event.sender.components(separatedBy: ":").last
failure.isFederated = senderDomain != nil && senderDomain != myDomain
}

/// XXX for future work, as for now only the event formatter reports UTDs. That means that it's only UTD ~visible to users
failure.wasVisibleToUser = true

reportedFailures[failedEventId] = failure


Expand Down
91 changes: 80 additions & 11 deletions RiotTests/DecryptionFailureTrackerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class DecryptionFailureTrackerTests: XCTestCase {

func test_grace_period() {

let myUser = "test@example.com";
let myUser = "@test:example.com";
fakeSession.mockUserId = myUser;

let decryptionFailureTracker = DecryptionFailureTracker();
Expand Down Expand Up @@ -95,7 +95,7 @@ class DecryptionFailureTrackerTests: XCTestCase {

func test_report_ratcheted_key_utd() {

let myUser = "test@example.com";
let myUser = "@test:example.com";
fakeSession.mockUserId = myUser;

let decryptionFailureTracker = DecryptionFailureTracker();
Expand Down Expand Up @@ -125,7 +125,7 @@ class DecryptionFailureTrackerTests: XCTestCase {

func test_report_unspecified_error() {

let myUser = "test@example.com";
let myUser = "@test:example.com";
fakeSession.mockUserId = myUser;

let decryptionFailureTracker = DecryptionFailureTracker();
Expand Down Expand Up @@ -157,7 +157,7 @@ class DecryptionFailureTrackerTests: XCTestCase {

func test_do_not_double_report() {

let myUser = "test@example.com";
let myUser = "@test:example.com";
fakeSession.mockUserId = myUser;

let decryptionFailureTracker = DecryptionFailureTracker();
Expand Down Expand Up @@ -199,7 +199,7 @@ class DecryptionFailureTrackerTests: XCTestCase {

func test_ignore_not_member() {

let myUser = "test@example.com";
let myUser = "@test:example.com";
fakeSession.mockUserId = myUser;

let decryptionFailureTracker = DecryptionFailureTracker();
Expand Down Expand Up @@ -234,7 +234,7 @@ class DecryptionFailureTrackerTests: XCTestCase {

func test_notification_center() {

let myUser = "test@example.com";
let myUser = "@test:example.com";
fakeSession.mockUserId = myUser;

let decryptionFailureTracker = DecryptionFailureTracker();
Expand Down Expand Up @@ -275,7 +275,7 @@ class DecryptionFailureTrackerTests: XCTestCase {

func test_should_report_late_decrypt() {

let myUser = "test@example.com";
let myUser = "@test:example.com";
fakeSession.mockUserId = myUser;

let decryptionFailureTracker = DecryptionFailureTracker();
Expand Down Expand Up @@ -320,7 +320,7 @@ class DecryptionFailureTrackerTests: XCTestCase {

func test_should_report_permanent_decryption_error() {

let myUser = "test@example.com";
let myUser = "@test:example.com";
fakeSession.mockUserId = myUser;

let decryptionFailureTracker = DecryptionFailureTracker();
Expand Down Expand Up @@ -361,7 +361,7 @@ class DecryptionFailureTrackerTests: XCTestCase {

func test_should_report_trust_status_at_decryption_time() {

let myUser = "test@example.com";
let myUser = "@test:example.com";
fakeSession.mockUserId = myUser;

let decryptionFailureTracker = DecryptionFailureTracker();
Expand Down Expand Up @@ -425,7 +425,7 @@ class DecryptionFailureTrackerTests: XCTestCase {

func test_should_report_event_age() {

let myUser = "test@example.com";
let myUser = "@test:example.com";
fakeSession.mockUserId = myUser;

let format = DateFormatter()
Expand Down Expand Up @@ -477,7 +477,7 @@ class DecryptionFailureTrackerTests: XCTestCase {

func test_should_report_expected_utds() {

let myUser = "test@example.com";
let myUser = "@test:example.com";
fakeSession.mockUserId = myUser;

let format = DateFormatter()
Expand Down Expand Up @@ -529,5 +529,74 @@ class DecryptionFailureTrackerTests: XCTestCase {

}


func test_should_report_is_matrix_org_and_is_federated() {

let myUser = "@test:example.com";
fakeSession.mockUserId = myUser;

let decryptionFailureTracker = DecryptionFailureTracker();
decryptionFailureTracker.timeProvider = timeShifter;

let testDelegate = AnalyticsDelegate();

decryptionFailureTracker.delegate = testDelegate;

timeShifter.timestamp = TimeInterval(0)

let fakeEvent = FakeEvent(id: "$0000");
fakeEvent.sender = "@bob:example.com"
fakeEvent.decryptionError = NSError(domain: MXDecryptingErrorDomain, code: Int(MXDecryptingErrorUnknownInboundSessionIdCode.rawValue))

// set session as not yet verified
fakeCrossSigning.canTrustCrossSigning = false

let fakeRoomState = FakeRoomState();
fakeRoomState.mockMembers = FakeRoomMembers(joined: [myUser])

decryptionFailureTracker.reportUnableToDecryptError(forEvent: fakeEvent, withRoomState: fakeRoomState, mySession: fakeSession);

// Simulate succesful decryption after max wait
timeShifter.timestamp = TimeInterval(70)

decryptionFailureTracker.checkFailures();

XCTAssertEqual(testDelegate.reportedFailure?.isMatrixOrg, false);
XCTAssertEqual(testDelegate.reportedFailure?.isFederated, false);


let analyticsError = testDelegate.reportedFailure!.toAnalyticsEvent()

XCTAssertEqual(analyticsError.isMatrixDotOrg, false)
XCTAssertEqual(analyticsError.isFederated, false)

// Report a new error now that session is verified

let fakeEvent2 = FakeEvent(id: "$0001");
fakeEvent2.sender = "@bob:example.com"
fakeEvent2.decryptionError = NSError(domain: MXDecryptingErrorDomain, code: Int(MXDecryptingErrorUnknownInboundSessionIdCode.rawValue))

fakeSession.mockUserId = "@test:matrix.org";
fakeRoomState.mockMembers = FakeRoomMembers(joined: [fakeSession.mockUserId])

decryptionFailureTracker.reportUnableToDecryptError(forEvent: fakeEvent2, withRoomState: fakeRoomState, mySession: fakeSession);

// Simulate permanent UTD
timeShifter.timestamp = TimeInterval(140)

decryptionFailureTracker.checkFailures();

XCTAssertEqual(testDelegate.reportedFailure?.failedEventId, "$0001");
XCTAssertEqual(testDelegate.reportedFailure?.isMatrixOrg, true);
XCTAssertEqual(testDelegate.reportedFailure?.isFederated, true);

let analyticsError2 = testDelegate.reportedFailure!.toAnalyticsEvent()

XCTAssertEqual(analyticsError2.isMatrixDotOrg, true)
XCTAssertEqual(analyticsError2.isFederated, true)

}


}

0 comments on commit 087f0cc

Please sign in to comment.