Move pseudoID ClientEvent hotswapping to a common location (#3199)

Fixes a variety of issues where clients were receiving pseudoIDs in
places that should be userIDs.
This change makes pseudoIDs work with sliding sync & element x.

---------

Co-authored-by: Till <2353100+S7evinK@users.noreply.github.com>
This commit is contained in:
devonh 2023-09-15 15:25:09 +00:00 committed by GitHub
parent 8245b24100
commit db83789654
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 426 additions and 333 deletions

View file

@ -301,25 +301,14 @@ func (s *OutputRoomEventConsumer) processMessage(ctx context.Context, event *rst
switch {
case event.Type() == spec.MRoomMember:
sender := spec.UserID{}
userID, queryErr := s.rsAPI.QueryUserIDForSender(ctx, event.RoomID(), event.SenderID())
if queryErr == nil && userID != nil {
sender = *userID
cevent, clientEvErr := synctypes.ToClientEvent(event, synctypes.FormatAll, func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) {
return s.rsAPI.QueryUserIDForSender(ctx, roomID, senderID)
})
if clientEvErr != nil {
return clientEvErr
}
sk := event.StateKey()
if sk != nil && *sk != "" {
skUserID, queryErr := s.rsAPI.QueryUserIDForSender(ctx, event.RoomID(), spec.SenderID(*sk))
if queryErr == nil && skUserID != nil {
skString := skUserID.String()
sk = &skString
} else {
return fmt.Errorf("queryUserIDForSender: userID unknown for %s", *sk)
}
}
cevent := synctypes.ToClientEvent(event, synctypes.FormatAll, sender.String(), sk, event.Unsigned())
var member *localMembership
member, err = newLocalMembership(&cevent)
member, err = newLocalMembership(cevent)
if err != nil {
return fmt.Errorf("newLocalMembership: %w", err)
}
@ -538,27 +527,19 @@ func (s *OutputRoomEventConsumer) notifyLocal(ctx context.Context, event *rstype
if err != nil {
return fmt.Errorf("s.localPushDevices: %w", err)
}
sender := spec.UserID{}
userID, err := s.rsAPI.QueryUserIDForSender(ctx, event.RoomID(), event.SenderID())
if err == nil && userID != nil {
sender = *userID
clientEvent, err := synctypes.ToClientEvent(event, synctypes.FormatSync, func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) {
return s.rsAPI.QueryUserIDForSender(ctx, roomID, senderID)
})
if err != nil {
return err
}
sk := event.StateKey()
if sk != nil && *sk != "" {
skUserID, queryErr := s.rsAPI.QueryUserIDForSender(ctx, event.RoomID(), spec.SenderID(*event.StateKey()))
if queryErr == nil && skUserID != nil {
skString := skUserID.String()
sk = &skString
}
}
n := &api.Notification{
Actions: actions,
// UNSPEC: the spec doesn't say this is a ClientEvent, but the
// fields seem to match. room_id should be missing, which
// matches the behaviour of FormatSync.
Event: synctypes.ToClientEvent(event, synctypes.FormatSync, sender.String(), sk, event.Unsigned()),
Event: *clientEvent,
// TODO: this is per-device, but it's not part of the primary
// key. So inserting one notification per profile tag doesn't
// make sense. What is this supposed to be? Sytests require it

View file

@ -23,6 +23,14 @@ import (
userUtil "github.com/matrix-org/dendrite/userapi/util"
)
func queryUserIDForSender(senderID spec.SenderID) (*spec.UserID, error) {
if senderID == "" {
return nil, nil
}
return spec.NewUserID(string(senderID), true)
}
func TestNotifyUserCountsAsync(t *testing.T) {
alice := test.NewUser(t)
aliceLocalpart, serverName, err := gomatrixserverlib.SplitID('@', alice.ID)
@ -100,13 +108,14 @@ func TestNotifyUserCountsAsync(t *testing.T) {
}
// Insert a dummy event
sender, err := spec.NewUserID(alice.ID, true)
ev, err := synctypes.ToClientEvent(dummyEvent, synctypes.FormatAll, func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) {
return queryUserIDForSender(senderID)
})
if err != nil {
t.Error(err)
}
sk := ""
if err := db.InsertNotification(ctx, aliceLocalpart, serverName, dummyEvent.EventID(), 0, nil, &api.Notification{
Event: synctypes.ToClientEvent(dummyEvent, synctypes.FormatAll, sender.String(), &sk, dummyEvent.Unsigned()),
Event: *ev,
}); err != nil {
t.Error(err)
}