diff --git a/go.mod b/go.mod index 0217df2..48709fe 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/gorilla/mux v1.8.0 github.com/jmoiron/sqlx v1.3.3 github.com/lib/pq v1.10.9 - github.com/matrix-org/gomatrixserverlib v0.0.0-20230105074811-965b10ae73ab + github.com/matrix-org/gomatrixserverlib v0.0.0-20230822143230-740f742d6993 github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4 github.com/pressly/goose/v3 v3.14.0 github.com/prometheus/client_golang v1.13.0 diff --git a/go.sum b/go.sum index 8154419..9173ddd 100644 --- a/go.sum +++ b/go.sum @@ -187,6 +187,8 @@ github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16 h1:ZtO5uywdd5d github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s= github.com/matrix-org/gomatrixserverlib v0.0.0-20230105074811-965b10ae73ab h1:ChaQdT2mpxMm3GRXNOZzLDQ/wOnlKZ8o60LmZGOjdj8= github.com/matrix-org/gomatrixserverlib v0.0.0-20230105074811-965b10ae73ab/go.mod h1:Mtifyr8q8htcBeugvlDnkBcNUy5LO8OzUoplAf1+mb4= +github.com/matrix-org/gomatrixserverlib v0.0.0-20230822143230-740f742d6993 h1:88wDfSsqSFyeCnTha8vfK9XJUbNjNXdEZAieOjbBzos= +github.com/matrix-org/gomatrixserverlib v0.0.0-20230822143230-740f742d6993/go.mod h1:H9V9N3Uqn1bBJqYJNGK1noqtgJTaCEhtTdcH/mp50uU= github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4 h1:eCEHXWDv9Rm335MSuB49mFUK44bwZPFSDde3ORE3syk= github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4/go.mod h1:vVQlW/emklohkZnOPwD3LrZUBqdfsbiyO3p1lNV8F6U= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= diff --git a/state/accumulator.go b/state/accumulator.go index 2ced1ca..a5047d2 100644 --- a/state/accumulator.go +++ b/state/accumulator.go @@ -4,6 +4,7 @@ import ( "database/sql" "encoding/json" "fmt" + "github.com/matrix-org/sliding-sync/internal" "github.com/getsentry/sentry-go" @@ -398,11 +399,13 @@ func (a *Accumulator) Accumulate(txn *sqlx.Tx, userID, roomID string, prevBatch var latestNID int64 newEvents := make([]Event, 0, len(eventIDToNID)) + var redactTheseEventIDs []string for _, ev := range dedupedEvents { nid, ok := eventIDToNID[ev.ID] if ok { ev.NID = int64(nid) - if gjson.GetBytes(ev.JSON, "state_key").Exists() { + parsedEv := gjson.ParseBytes(ev.JSON) + if parsedEv.Get("state_key").Exists() { // XXX: reusing this to mean "it's a state event" as well as "it's part of the state v2 response" // its important that we don't insert 'ev' at this point as this should be False in the DB. ev.IsState = true @@ -412,11 +415,40 @@ func (a *Accumulator) Accumulate(txn *sqlx.Tx, userID, roomID string, prevBatch if ev.NID > latestNID { latestNID = ev.NID } + // if this is a redaction, try to redact the referenced event (best effort) + if !ev.IsState && ev.Type == "m.room.redaction" { + // look for top-level redacts then content.redacts (room version 11+) + redactsEventID := parsedEv.Get("redacts").Str + if redactsEventID == "" { + redactsEventID = parsedEv.Get("content.redacts").Str + } + if redactsEventID != "" { + redactTheseEventIDs = append(redactTheseEventIDs, redactsEventID) + } + } newEvents = append(newEvents, ev) timelineNIDs = append(timelineNIDs, ev.NID) } } + // if we are going to redact things, we need the room version to know the redaction algorithm + // so pull it out once now. + var roomVersion string + if len(redactTheseEventIDs) > 0 { + createEventJSON, err := a.eventsTable.SelectCreateEvent(txn, roomID) + if err != nil { + return 0, nil, fmt.Errorf("SelectCreateEvent: %s", err) + } + roomVersion = gjson.GetBytes(createEventJSON, "content.room_version").Str + if roomVersion == "" { + // Defaults to "1" if the key does not exist. + roomVersion = "1" + } + if err = a.eventsTable.Redact(txn, roomVersion, redactTheseEventIDs); err != nil { + return 0, nil, err + } + } + for _, ev := range newEvents { var replacesNID int64 // the snapshot ID we assign to this event is unaffected by whether /this/ event is state or not, diff --git a/state/event_table.go b/state/event_table.go index c6a5a6e..65438b3 100644 --- a/state/event_table.go +++ b/state/event_table.go @@ -2,6 +2,7 @@ package state import ( "database/sql" + "encoding/json" "fmt" "math" @@ -10,6 +11,7 @@ import ( "github.com/tidwall/gjson" "github.com/tidwall/sjson" + "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/sliding-sync/internal" "github.com/matrix-org/sliding-sync/sqlutil" ) @@ -336,6 +338,30 @@ func (t *EventTable) LatestEventNIDInRooms(txn *sqlx.Tx, roomIDs []string, highe return } +func (t *EventTable) Redact(txn *sqlx.Tx, roomVer string, eventIDs []string) error { + // verifyAll=false so if we are asked to redact an event we don't have we don't fall over. + eventsToRedact, err := t.SelectByIDs(txn, false, eventIDs) + if err != nil { + return fmt.Errorf("EventTable.Redact[%v]: %s", eventIDs, err) + } + rv, err := gomatrixserverlib.GetRoomVersion(gomatrixserverlib.RoomVersion(roomVer)) + if err != nil { + // unknown room version... let's just default to "1" + rv = gomatrixserverlib.MustGetRoomVersion(gomatrixserverlib.RoomVersionV1) + } + for i := range eventsToRedact { + eventsToRedact[i].JSON, err = rv.RedactEventJSON(eventsToRedact[i].JSON) + if err != nil { + return fmt.Errorf("RedactEventJSON[%s]: %s", eventsToRedact[i].ID, err) + } + _, err = txn.Exec(`UPDATE syncv3_events SET event=$1 WHERE event_id=$2`, eventsToRedact[i].JSON, eventsToRedact[i].ID) + if err != nil { + return fmt.Errorf("cannot update event %s: %v", eventsToRedact[i].ID, err) + } + } + return nil +} + func (t *EventTable) SelectLatestEventsBetween(txn *sqlx.Tx, roomID string, lowerExclusive, upperInclusive int64, limit int) ([]Event, error) { var events []Event // do not pull in events which were in the v2 state block @@ -440,6 +466,13 @@ func (t *EventTable) SelectClosestPrevBatch(txn *sqlx.Tx, roomID string, eventNI return } +func (t *EventTable) SelectCreateEvent(txn *sqlx.Tx, roomID string) (json.RawMessage, error) { + var evJSON []byte + // there is only 1 create event + err := txn.QueryRow(`SELECT event FROM syncv3_events WHERE room_id=$1 AND event_type='m.room.create' AND state_key=''`, roomID).Scan(&evJSON) + return evJSON, err +} + type EventChunker []Event func (c EventChunker) Len() int { diff --git a/state/event_table_test.go b/state/event_table_test.go index db4bab3..7d6fb2c 100644 --- a/state/event_table_test.go +++ b/state/event_table_test.go @@ -3,6 +3,7 @@ package state import ( "bytes" "database/sql" + "encoding/json" "fmt" "reflect" "testing" @@ -924,3 +925,168 @@ func TestEventTableSelectUnknownEventIDs(t *testing.T) { } } } + +func TestEventTableRedact(t *testing.T) { + db, close := connectToDB(t) + defer close() + table := NewEventTable(db) + txn, err := db.Beginx() + if err != nil { + t.Fatalf("failed to start txn: %s", err) + } + defer txn.Rollback() + + testCases := []struct { + original map[string]interface{} + roomVer string + wantContent map[string]interface{} + }{ + // sanity check + { + original: map[string]interface{}{ + "type": "m.room.message", + "sender": "@nasty-mc-nastyface:localhost", + "content": map[string]interface{}{ + "msgtype": "m.text", + "body": "Something not very nice", + }, + }, + wantContent: map[string]interface{}{}, + roomVer: "10", + }, + // keep membership + { + original: map[string]interface{}{ + "type": "m.room.member", + "state_key": "@nasty-mc-nastyface:localhost", + "sender": "@nasty-mc-nastyface:localhost", + "content": map[string]interface{}{ + "membership": "join", + "displayname": "Something not very nice", + "avatar_url": "mxc://something/not/very/nice", + }, + }, + wantContent: map[string]interface{}{ + "membership": "join", + }, + roomVer: "10", + }, + // keep join rule + { + original: map[string]interface{}{ + "type": "m.room.join_rules", + "state_key": "", + "sender": "@nasty-mc-nastyface:localhost", + "content": map[string]interface{}{ + "join_rule": "invite", + "extra_data": "not very nice", + }, + }, + wantContent: map[string]interface{}{ + "join_rule": "invite", + }, + roomVer: "10", + }, + // keep his vis + { + original: map[string]interface{}{ + "type": "m.room.history_visibility", + "state_key": "", + "sender": "@nasty-mc-nastyface:localhost", + "content": map[string]interface{}{ + "history_visibility": "shared", + "extra_data": "not very nice", + }, + }, + wantContent: map[string]interface{}{ + "history_visibility": "shared", + }, + roomVer: "10", + }, + // keep version specific fields + { + original: map[string]interface{}{ + "type": "m.room.member", + "state_key": "@nasty-mc-nastyface:localhost", + "sender": "@nasty-mc-nastyface:localhost", + "content": map[string]interface{}{ + "membership": "join", + "displayname": "Something not very nice", + "avatar_url": "mxc://something/not/very/nice", + "join_authorised_via_users_server": "@bob:localhost", + }, + }, + wantContent: map[string]interface{}{ + "membership": "join", + "join_authorised_via_users_server": "@bob:localhost", + }, + roomVer: "10", + }, + // remove same field on lower room version + { + original: map[string]interface{}{ + "type": "m.room.member", + "state_key": "@nasty-mc-nastyface:localhost", + "sender": "@nasty-mc-nastyface:localhost", + "content": map[string]interface{}{ + "membership": "join", + "displayname": "Something not very nice", + "avatar_url": "mxc://something/not/very/nice", + "join_authorised_via_users_server": "@bob:localhost", + }, + }, + wantContent: map[string]interface{}{ + "membership": "join", + }, + roomVer: "2", + }, + } + + roomID := "!TestEventTableRedact" + for i, tc := range testCases { + eventID := fmt.Sprintf("$TestEventTableRedact_%d", i) + tc.original["event_id"] = eventID + tc.original["room_id"] = roomID + stateKey := "" + if tc.original["state_key"] != nil { + stateKey = tc.original["state_key"].(string) + } + j, err := json.Marshal(tc.original) + assertNoError(t, err) + table.Insert(txn, []Event{ + { + ID: eventID, + Type: tc.original["type"].(string), + RoomID: roomID, + StateKey: stateKey, + BeforeStateSnapshotID: 22, + JSON: j, + }, + }, false) + assertNoError(t, table.Redact(txn, tc.roomVer, []string{eventID})) + gots, err := table.SelectByIDs(txn, true, []string{eventID}) + assertNoError(t, err) + if len(gots) != 1 { + t.Errorf("SelectByIDs: got %v results, want 1", len(gots)) + continue + } + got := gots[0] + assertVal(t, "event id mismatch", got.ID, eventID) + assertVal(t, "room id mismatch", got.RoomID, roomID) + var gotJSON map[string]interface{} + assertNoError(t, json.Unmarshal(got.JSON, &gotJSON)) + assertVal(t, "content mismatch", gotJSON["content"], tc.wantContent) + } +} + +func TestEventTableRedactMissingOK(t *testing.T) { + db, close := connectToDB(t) + defer close() + table := NewEventTable(db) + txn, err := db.Beginx() + if err != nil { + t.Fatalf("failed to start txn: %s", err) + } + defer txn.Rollback() + assertNoError(t, table.Redact(txn, "2", []string{"$unknown", "$event", "$ids"})) +} diff --git a/state/storage_test.go b/state/storage_test.go index 69c9588..38291b1 100644 --- a/state/storage_test.go +++ b/state/storage_test.go @@ -11,7 +11,7 @@ import ( "time" "github.com/jmoiron/sqlx" - "github.com/matrix-org/gomatrixserverlib" + "github.com/matrix-org/gomatrixserverlib/spec" "github.com/matrix-org/sliding-sync/internal" "github.com/matrix-org/sliding-sync/sqlutil" "github.com/matrix-org/sliding-sync/testutils" @@ -308,7 +308,7 @@ func TestVisibleEventNIDsBetween(t *testing.T) { t.Fatalf("LatestEventNID: %s", err) } - baseTimestamp := gomatrixserverlib.Timestamp(1632131678061).Time() + baseTimestamp := spec.Timestamp(1632131678061).Time() // Test the examples // Stream Positions // 1 2 3 4 5 6 7 8 9 10 diff --git a/sync2/client.go b/sync2/client.go index 9a0a7b3..4d1a90c 100644 --- a/sync2/client.go +++ b/sync2/client.go @@ -9,7 +9,6 @@ import ( "net/url" "time" - "github.com/matrix-org/gomatrixserverlib" "github.com/tidwall/gjson" ) @@ -135,7 +134,7 @@ type SyncResponse struct { NextBatch string `json:"next_batch"` AccountData EventsResponse `json:"account_data"` Presence struct { - Events []gomatrixserverlib.ClientEvent `json:"events,omitempty"` + Events []json.RawMessage `json:"events,omitempty"` } `json:"presence"` Rooms SyncRoomsResponse `json:"rooms"` ToDevice EventsResponse `json:"to_device"` diff --git a/sync3/handler/connstate_test.go b/sync3/handler/connstate_test.go index 46c00d6..edd98ad 100644 --- a/sync3/handler/connstate_test.go +++ b/sync3/handler/connstate_test.go @@ -8,7 +8,7 @@ import ( "testing" "time" - "github.com/matrix-org/gomatrixserverlib" + "github.com/matrix-org/gomatrixserverlib/spec" "github.com/matrix-org/sliding-sync/internal" "github.com/matrix-org/sliding-sync/sync3" "github.com/matrix-org/sliding-sync/sync3/caches" @@ -37,7 +37,7 @@ func (t *NopTransactionFetcher) TransactionIDForEvents(userID, deviceID string, return } -func newRoomMetadata(roomID string, lastMsgTimestamp gomatrixserverlib.Timestamp) internal.RoomMetadata { +func newRoomMetadata(roomID string, lastMsgTimestamp spec.Timestamp) internal.RoomMetadata { m := internal.NewRoomMetadata(roomID) m.NameEvent = "Room " + roomID m.LastMessageTimestamp = uint64(lastMsgTimestamp) @@ -62,11 +62,11 @@ func TestConnStateInitial(t *testing.T) { } userID := "@TestConnStateInitial_alice:localhost" deviceID := "yep" - timestampNow := gomatrixserverlib.Timestamp(1632131678061).Time() + timestampNow := spec.Timestamp(1632131678061).Time() // initial sort order B, C, A - roomA := newRoomMetadata("!a:localhost", gomatrixserverlib.AsTimestamp(timestampNow.Add(-8*time.Second))) - roomB := newRoomMetadata("!b:localhost", gomatrixserverlib.AsTimestamp(timestampNow)) - roomC := newRoomMetadata("!c:localhost", gomatrixserverlib.AsTimestamp(timestampNow.Add(-4*time.Second))) + roomA := newRoomMetadata("!a:localhost", spec.AsTimestamp(timestampNow.Add(-8*time.Second))) + roomB := newRoomMetadata("!b:localhost", spec.AsTimestamp(timestampNow)) + roomC := newRoomMetadata("!c:localhost", spec.AsTimestamp(timestampNow.Add(-4*time.Second))) timeline := map[string]json.RawMessage{ roomA.RoomID: testutils.NewEvent(t, "m.room.message", userID, map[string]interface{}{"body": "a"}), roomB.RoomID: testutils.NewEvent(t, "m.room.message", userID, map[string]interface{}{"body": "b"}), @@ -232,7 +232,7 @@ func TestConnStateMultipleRanges(t *testing.T) { } userID := "@TestConnStateMultipleRanges_alice:localhost" deviceID := "yep" - timestampNow := gomatrixserverlib.Timestamp(1632131678061) + timestampNow := spec.Timestamp(1632131678061) var rooms []*internal.RoomMetadata var roomIDs []string globalCache := caches.NewGlobalCache(nil) @@ -373,7 +373,7 @@ func TestConnStateMultipleRanges(t *testing.T) { // ` ` ` ` // 8,0,1,9,2,3,4,5,6,7 room middleTimestamp := int64((roomIDToRoom[roomIDs[1]].LastMessageTimestamp + roomIDToRoom[roomIDs[2]].LastMessageTimestamp) / 2) - newEvent = testutils.NewEvent(t, "unimportant", "me", struct{}{}, testutils.WithTimestamp(gomatrixserverlib.Timestamp(middleTimestamp).Time())) + newEvent = testutils.NewEvent(t, "unimportant", "me", struct{}{}, testutils.WithTimestamp(spec.Timestamp(middleTimestamp).Time())) dispatcher.OnNewEvent(context.Background(), roomIDs[9], newEvent, 1) t.Logf("new event %s : %s", roomIDs[9], string(newEvent)) res, err = cs.OnIncomingRequest(context.Background(), ConnID, &sync3.Request{ @@ -414,7 +414,7 @@ func TestBumpToOutsideRange(t *testing.T) { } userID := "@TestBumpToOutsideRange_alice:localhost" deviceID := "yep" - timestampNow := gomatrixserverlib.Timestamp(1632131678061) + timestampNow := spec.Timestamp(1632131678061) roomA := newRoomMetadata("!a:localhost", timestampNow) roomB := newRoomMetadata("!b:localhost", timestampNow-1000) roomC := newRoomMetadata("!c:localhost", timestampNow-2000) @@ -482,7 +482,7 @@ func TestBumpToOutsideRange(t *testing.T) { }) // D gets bumped to C's position but it's still outside the range so nothing should happen - newEvent := testutils.NewEvent(t, "unimportant", "me", struct{}{}, testutils.WithTimestamp(gomatrixserverlib.Timestamp(roomC.LastMessageTimestamp+2).Time())) + newEvent := testutils.NewEvent(t, "unimportant", "me", struct{}{}, testutils.WithTimestamp(spec.Timestamp(roomC.LastMessageTimestamp+2).Time())) dispatcher.OnNewEvent(context.Background(), roomD.RoomID, newEvent, 1) // expire the context after 10ms so we don't wait forevar @@ -511,11 +511,11 @@ func TestConnStateRoomSubscriptions(t *testing.T) { } userID := "@TestConnStateRoomSubscriptions_alice:localhost" deviceID := "yep" - timestampNow := gomatrixserverlib.Timestamp(1632131678061) + timestampNow := spec.Timestamp(1632131678061) roomA := newRoomMetadata("!a:localhost", timestampNow) - roomB := newRoomMetadata("!b:localhost", gomatrixserverlib.Timestamp(timestampNow-1000)) - roomC := newRoomMetadata("!c:localhost", gomatrixserverlib.Timestamp(timestampNow-2000)) - roomD := newRoomMetadata("!d:localhost", gomatrixserverlib.Timestamp(timestampNow-3000)) + roomB := newRoomMetadata("!b:localhost", spec.Timestamp(timestampNow-1000)) + roomC := newRoomMetadata("!c:localhost", spec.Timestamp(timestampNow-2000)) + roomD := newRoomMetadata("!d:localhost", spec.Timestamp(timestampNow-3000)) roomIDs := []string{roomA.RoomID, roomB.RoomID, roomC.RoomID, roomD.RoomID} globalCache := caches.NewGlobalCache(nil) globalCache.Startup(map[string]internal.RoomMetadata{ @@ -620,7 +620,7 @@ func TestConnStateRoomSubscriptions(t *testing.T) { }, }) // room D gets a new event but it's so old it doesn't bump to the top of the list - newEvent := testutils.NewEvent(t, "unimportant", "me", struct{}{}, testutils.WithTimestamp(gomatrixserverlib.Timestamp(timestampNow-20000).Time())) + newEvent := testutils.NewEvent(t, "unimportant", "me", struct{}{}, testutils.WithTimestamp(spec.Timestamp(timestampNow-20000).Time())) dispatcher.OnNewEvent(context.Background(), roomD.RoomID, newEvent, 1) // we should get this message even though it's not in the range because we are subscribed to this room. res, err = cs.OnIncomingRequest(context.Background(), ConnID, &sync3.Request{ diff --git a/tests-e2e/client_test.go b/tests-e2e/client_test.go index a698243..dd50cfd 100644 --- a/tests-e2e/client_test.go +++ b/tests-e2e/client_test.go @@ -275,6 +275,15 @@ func (c *CSAPI) SendEventSynced(t *testing.T, roomID string, e Event) string { return eventID } +func (c *CSAPI) RedactEvent(t *testing.T, roomID, eventID string) string { + c.txnID++ + res := c.MustDoFunc(t, "PUT", []string{"_matrix", "client", "v3", "rooms", roomID, "redact", eventID, strconv.Itoa(c.txnID)}, WithJSONBody(t, map[string]interface{}{ + "reason": "who knows", + })) + body := ParseJSON(t, res) + return GetJSONFieldStr(t, body, "event_id") +} + func (c *CSAPI) SendReceipt(t *testing.T, roomID, eventID, receiptType string) *http.Response { return c.MustDoFunc(t, "POST", []string{"_matrix", "client", "v3", "rooms", roomID, "read_markers"}, WithJSONBody(t, map[string]interface{}{ receiptType: eventID, diff --git a/tests-e2e/redaction_test.go b/tests-e2e/redaction_test.go new file mode 100644 index 0000000..090dbf3 --- /dev/null +++ b/tests-e2e/redaction_test.go @@ -0,0 +1,63 @@ +package syncv3_test + +import ( + "testing" + + "github.com/matrix-org/sliding-sync/sync3" + "github.com/matrix-org/sliding-sync/testutils/m" +) + +func TestRedactionsAreRedactedWherePossible(t *testing.T) { + alice := registerNamedUser(t, "alice") + room := alice.CreateRoom(t, map[string]any{"preset": "public_chat"}) + + eventID := alice.SendEventSynced(t, room, Event{ + Type: "m.room.message", + Content: map[string]interface{}{ + "msgtype": "m.text", + "body": "I will be redacted", + }, + }) + + res := alice.SlidingSync(t, sync3.Request{ + Lists: map[string]sync3.RequestList{ + "a": { + Ranges: sync3.SliceRanges{{0, 20}}, + RoomSubscription: sync3.RoomSubscription{ + TimelineLimit: 1, + }, + }, + }, + }) + m.MatchResponse(t, res, m.MatchRoomSubscriptionsStrict(map[string][]m.RoomMatcher{ + room: {MatchRoomTimelineMostRecent(1, []Event{{ID: eventID, Content: map[string]interface{}{ + "msgtype": "m.text", + "body": "I will be redacted", + }}})}, + })) + + // redact the event + redactionEventID := alice.RedactEvent(t, room, eventID) + + // see the redaction + alice.SlidingSyncUntilEventID(t, res.Pos, room, redactionEventID) + + // now resync from scratch, the event should be redacted this time around. + res = alice.SlidingSync(t, sync3.Request{ + Lists: map[string]sync3.RequestList{ + "a": { + Ranges: sync3.SliceRanges{{0, 20}}, + RoomSubscription: sync3.RoomSubscription{ + TimelineLimit: 2, + }, + }, + }, + }) + m.MatchResponse(t, res, m.MatchRoomSubscriptionsStrict(map[string][]m.RoomMatcher{ + room: {MatchRoomTimelineMostRecent(2, []Event{ + {ID: eventID, Content: map[string]interface{}{}}, + {ID: redactionEventID}, + })}, + })) + +} diff --git a/testutils/event.go b/testutils/event.go index 44033e9..2567468 100644 --- a/testutils/event.go +++ b/testutils/event.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "github.com/matrix-org/gomatrixserverlib" + "github.com/matrix-org/gomatrixserverlib/spec" ) // Common functions between testing.T and testing.B @@ -47,7 +47,7 @@ type eventMockModifier func(e *eventMock) func WithTimestamp(ts time.Time) eventMockModifier { return func(e *eventMock) { - e.OriginServerTS = int64(gomatrixserverlib.AsTimestamp(ts)) + e.OriginServerTS = int64(spec.AsTimestamp(ts)) } } @@ -79,7 +79,7 @@ func NewStateEvent(t TestBenchInterface, evType, stateKey, sender string, conten Sender: sender, Content: content, EventID: generateEventID(t), - OriginServerTS: int64(gomatrixserverlib.AsTimestamp(time.Now())), + OriginServerTS: int64(spec.AsTimestamp(time.Now())), } for _, m := range modifiers { m(e) @@ -98,7 +98,7 @@ func NewEvent(t TestBenchInterface, evType, sender string, content interface{}, Sender: sender, Content: content, EventID: generateEventID(t), - OriginServerTS: int64(gomatrixserverlib.AsTimestamp(time.Now())), + OriginServerTS: int64(spec.AsTimestamp(time.Now())), } for _, m := range modifiers { m(e) @@ -132,7 +132,7 @@ func SetTimestamp(t *testing.T, event json.RawMessage, ts time.Time) json.RawMes t.Errorf("Failed to parse eventMock: %s", err) return nil } - parsed.OriginServerTS = int64(gomatrixserverlib.AsTimestamp(ts)) + parsed.OriginServerTS = int64(spec.AsTimestamp(ts)) edited, err := json.Marshal(parsed) if err != nil { t.Errorf("Failed to serialise eventMock: %s", err)