Replace senderID with userID in powerlevel events, workaround invites

This commit is contained in:
Till Faelligen 2023-06-15 18:04:31 +02:00
parent b4d5c837dd
commit 31609d62fe
No known key found for this signature in database
GPG key ID: ACCDC9606D472758
6 changed files with 98 additions and 6 deletions

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -101,7 +101,7 @@ func (s *inviteEventsStatements) InsertInviteEvent(
ctx,
inviteEvent.RoomID(),
inviteEvent.EventID(),
*inviteEvent.StateKey(),
inviteEvent.UserID.String(),
headeredJSON,
).Scan(&streamPos)
return

View file

@ -108,7 +108,7 @@ func (s *inviteEventsStatements) InsertInviteEvent(
streamPos,
inviteEvent.RoomID(),
inviteEvent.EventID(),
*inviteEvent.StateKey(),
inviteEvent.UserID.String(),
headeredJSON,
)
return

View file

@ -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)