From 31609d62fe524d2082056557267882f6cd8c94e4 Mon Sep 17 00:00:00 2001 From: Till Faelligen <2353100+S7evinK@users.noreply.github.com> Date: Thu, 15 Jun 2023 18:04:31 +0200 Subject: [PATCH] Replace senderID with userID in powerlevel events, workaround invites --- clientapi/routing/membership.go | 24 ++++++-- roomserver/api/api.go | 1 + syncapi/consumers/roomserver.go | 2 + syncapi/storage/postgres/invites_table.go | 2 +- syncapi/storage/sqlite3/invites_table.go | 2 +- syncapi/streams/stream_pdu.go | 73 +++++++++++++++++++++++ 6 files changed, 98 insertions(+), 6 deletions(-) diff --git a/clientapi/routing/membership.go b/clientapi/routing/membership.go index 29ee2b1e5..c0aad9840 100644 --- a/clientapi/routing/membership.go +++ b/clientapi/routing/membership.go @@ -22,10 +22,6 @@ import ( "time" "github.com/getsentry/sentry-go" - "github.com/matrix-org/gomatrixserverlib" - "github.com/matrix-org/gomatrixserverlib/fclient" - "github.com/matrix-org/gomatrixserverlib/spec" - appserviceAPI "github.com/matrix-org/dendrite/appservice/api" "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/httputil" @@ -36,6 +32,9 @@ import ( "github.com/matrix-org/dendrite/roomserver/types" "github.com/matrix-org/dendrite/setup/config" userapi "github.com/matrix-org/dendrite/userapi/api" + "github.com/matrix-org/gomatrixserverlib" + "github.com/matrix-org/gomatrixserverlib/fclient" + "github.com/matrix-org/gomatrixserverlib/spec" "github.com/matrix-org/util" ) @@ -455,6 +454,23 @@ func buildMembershipEvent( return nil, err } + // If we're inviting a local user, we can generate the needed key here. + if targetSenderID == "" && cfg.Matrix.IsLocalServerName(targetID.Domain()) { // todo: remove + roomVersion, err := rsAPI.QueryRoomVersionForRoom(ctx, roomID) + if err != nil { + return nil, err + } + switch roomVersion { + case gomatrixserverlib.RoomVersionPseudoIDs: + key, err := rsAPI.GetOrCreateUserRoomPrivateKey(ctx, *targetID, *validRoomID) + if err != nil { + return nil, err + } + targetSenderID = spec.SenderIDFromPseudoIDKey(key) + } + + } + identity, err := rsAPI.SigningIdentityFor(ctx, *validRoomID, *userID) if err != nil { return nil, err diff --git a/roomserver/api/api.go b/roomserver/api/api.go index ce6594b7d..5d7728bd4 100644 --- a/roomserver/api/api.go +++ b/roomserver/api/api.go @@ -185,6 +185,7 @@ type ClientRoomserverAPI interface { QueryBulkStateContentAPI QueryEventsAPI QuerySenderIDAPI + UserRoomPrivateKeyCreator QueryMembershipForUser(ctx context.Context, req *QueryMembershipForUserRequest, res *QueryMembershipForUserResponse) error QueryMembershipsForRoom(ctx context.Context, req *QueryMembershipsForRoomRequest, res *QueryMembershipsForRoomResponse) error QueryRoomsForUser(ctx context.Context, req *QueryRoomsForUserRequest, res *QueryRoomsForUserResponse) error diff --git a/syncapi/consumers/roomserver.go b/syncapi/consumers/roomserver.go index 6f6cda0aa..fed35b95f 100644 --- a/syncapi/consumers/roomserver.go +++ b/syncapi/consumers/roomserver.go @@ -426,6 +426,8 @@ func (s *OutputRoomEventConsumer) onNewInviteEvent( return } + msg.Event.UserID = *userID + pduPos, err := s.db.AddInviteEvent(ctx, msg.Event) if err != nil { sentry.CaptureException(err) diff --git a/syncapi/storage/postgres/invites_table.go b/syncapi/storage/postgres/invites_table.go index 267209bba..7b8d2d733 100644 --- a/syncapi/storage/postgres/invites_table.go +++ b/syncapi/storage/postgres/invites_table.go @@ -101,7 +101,7 @@ func (s *inviteEventsStatements) InsertInviteEvent( ctx, inviteEvent.RoomID(), inviteEvent.EventID(), - *inviteEvent.StateKey(), + inviteEvent.UserID.String(), headeredJSON, ).Scan(&streamPos) return diff --git a/syncapi/storage/sqlite3/invites_table.go b/syncapi/storage/sqlite3/invites_table.go index 347523cf7..7e0d895f1 100644 --- a/syncapi/storage/sqlite3/invites_table.go +++ b/syncapi/storage/sqlite3/invites_table.go @@ -108,7 +108,7 @@ func (s *inviteEventsStatements) InsertInviteEvent( streamPos, inviteEvent.RoomID(), inviteEvent.EventID(), - *inviteEvent.StateKey(), + inviteEvent.UserID.String(), headeredJSON, ) return diff --git a/syncapi/streams/stream_pdu.go b/syncapi/streams/stream_pdu.go index 7939dd8fa..545cbd963 100644 --- a/syncapi/streams/stream_pdu.go +++ b/syncapi/streams/stream_pdu.go @@ -3,6 +3,7 @@ package streams import ( "context" "database/sql" + "encoding/json" "fmt" "time" @@ -15,6 +16,7 @@ import ( "github.com/matrix-org/dendrite/syncapi/types" userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib/spec" + "github.com/tidwall/sjson" "github.com/matrix-org/dendrite/syncapi/notifier" "github.com/matrix-org/gomatrixserverlib" @@ -346,6 +348,42 @@ func (p *PDUStreamProvider) addRoomDeltaToResponse( // Now that we've filtered the timeline, work out which state events are still // left. Anything that appears in the filtered timeline will be removed from the // "state" section and kept in "timeline". + + for i, ev := range events { + if ev.Version() != gomatrixserverlib.RoomVersionPseudoIDs { + continue + } + if ev.Type() != spec.MRoomPowerLevels || !ev.StateKeyEquals("") { + continue + } + pls, err := gomatrixserverlib.NewPowerLevelContentFromEvent(ev) + if err != nil { + return r.From, err + } + newPls := make(map[string]int64) + for user, level := range pls.Users { + validRoomID, _ := spec.NewRoomID(ev.RoomID()) + userID, err := p.rsAPI.QueryUserIDForSender(ctx, *validRoomID, spec.SenderID(user)) + if err != nil { + return r.From, err + } + newPls[userID.String()] = level + } + newPlBytes, err := json.Marshal(newPls) + if err != nil { + return r.From, err + } + newEv, err := sjson.SetRawBytes(ev.JSON(), "content.users", newPlBytes) + if err != nil { + return r.From, err + } + evNew, err := gomatrixserverlib.MustGetRoomVersion(gomatrixserverlib.RoomVersionPseudoIDs).NewEventFromTrustedJSON(newEv, false) + if err != nil { + return r.From, err + } + events[i] = &rstypes.HeaderedEvent{PDU: evNew} + } + sEvents := gomatrixserverlib.HeaderedReverseTopologicalOrdering( gomatrixserverlib.ToPDUs(removeDuplicates(delta.StateEvents, events)), gomatrixserverlib.TopologicalOrderByAuthEvents, @@ -563,6 +601,41 @@ func (p *PDUStreamProvider) getJoinResponseForCompleteSync( prevBatch.Decrement() } + for i, ev := range events { + if ev.Version() != gomatrixserverlib.RoomVersionPseudoIDs { + continue + } + if ev.Type() != spec.MRoomPowerLevels || !ev.StateKeyEquals("") { + continue + } + pls, err := gomatrixserverlib.NewPowerLevelContentFromEvent(ev) + if err != nil { + return nil, err + } + newPls := make(map[string]int64) + for user, level := range pls.Users { + validRoomID, _ := spec.NewRoomID(ev.RoomID()) + userID, err := p.rsAPI.QueryUserIDForSender(ctx, *validRoomID, spec.SenderID(user)) + if err != nil { + return nil, err + } + newPls[userID.String()] = level + } + newPlBytes, err := json.Marshal(newPls) + if err != nil { + return nil, err + } + newEv, err := sjson.SetRawBytes(ev.JSON(), "content.users", newPlBytes) + if err != nil { + return nil, err + } + evNew, err := gomatrixserverlib.MustGetRoomVersion(gomatrixserverlib.RoomVersionPseudoIDs).NewEventFromTrustedJSON(newEv, false) + if err != nil { + return nil, err + } + events[i] = &rstypes.HeaderedEvent{PDU: evNew} + } + jr.Timeline.PrevBatch = prevBatch jr.Timeline.Events = synctypes.ToClientEvents(gomatrixserverlib.ToPDUs(events), synctypes.FormatSync, func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) { return p.rsAPI.QueryUserIDForSender(ctx, roomID, senderID)