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" "time"
"github.com/getsentry/sentry-go" "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" appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/httputil"
@ -36,6 +32,9 @@ import (
"github.com/matrix-org/dendrite/roomserver/types" "github.com/matrix-org/dendrite/roomserver/types"
"github.com/matrix-org/dendrite/setup/config" "github.com/matrix-org/dendrite/setup/config"
userapi "github.com/matrix-org/dendrite/userapi/api" 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" "github.com/matrix-org/util"
) )
@ -455,6 +454,23 @@ func buildMembershipEvent(
return nil, err 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) identity, err := rsAPI.SigningIdentityFor(ctx, *validRoomID, *userID)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -185,6 +185,7 @@ type ClientRoomserverAPI interface {
QueryBulkStateContentAPI QueryBulkStateContentAPI
QueryEventsAPI QueryEventsAPI
QuerySenderIDAPI QuerySenderIDAPI
UserRoomPrivateKeyCreator
QueryMembershipForUser(ctx context.Context, req *QueryMembershipForUserRequest, res *QueryMembershipForUserResponse) error QueryMembershipForUser(ctx context.Context, req *QueryMembershipForUserRequest, res *QueryMembershipForUserResponse) error
QueryMembershipsForRoom(ctx context.Context, req *QueryMembershipsForRoomRequest, res *QueryMembershipsForRoomResponse) error QueryMembershipsForRoom(ctx context.Context, req *QueryMembershipsForRoomRequest, res *QueryMembershipsForRoomResponse) error
QueryRoomsForUser(ctx context.Context, req *QueryRoomsForUserRequest, res *QueryRoomsForUserResponse) error QueryRoomsForUser(ctx context.Context, req *QueryRoomsForUserRequest, res *QueryRoomsForUserResponse) error

View file

@ -426,6 +426,8 @@ func (s *OutputRoomEventConsumer) onNewInviteEvent(
return return
} }
msg.Event.UserID = *userID
pduPos, err := s.db.AddInviteEvent(ctx, msg.Event) pduPos, err := s.db.AddInviteEvent(ctx, msg.Event)
if err != nil { if err != nil {
sentry.CaptureException(err) sentry.CaptureException(err)

View file

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

View file

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

View file

@ -3,6 +3,7 @@ package streams
import ( import (
"context" "context"
"database/sql" "database/sql"
"encoding/json"
"fmt" "fmt"
"time" "time"
@ -15,6 +16,7 @@ import (
"github.com/matrix-org/dendrite/syncapi/types" "github.com/matrix-org/dendrite/syncapi/types"
userapi "github.com/matrix-org/dendrite/userapi/api" userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib/spec" "github.com/matrix-org/gomatrixserverlib/spec"
"github.com/tidwall/sjson"
"github.com/matrix-org/dendrite/syncapi/notifier" "github.com/matrix-org/dendrite/syncapi/notifier"
"github.com/matrix-org/gomatrixserverlib" "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 // 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 // left. Anything that appears in the filtered timeline will be removed from the
// "state" section and kept in "timeline". // "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( sEvents := gomatrixserverlib.HeaderedReverseTopologicalOrdering(
gomatrixserverlib.ToPDUs(removeDuplicates(delta.StateEvents, events)), gomatrixserverlib.ToPDUs(removeDuplicates(delta.StateEvents, events)),
gomatrixserverlib.TopologicalOrderByAuthEvents, gomatrixserverlib.TopologicalOrderByAuthEvents,
@ -563,6 +601,41 @@ func (p *PDUStreamProvider) getJoinResponseForCompleteSync(
prevBatch.Decrement() 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.PrevBatch = prevBatch
jr.Timeline.Events = synctypes.ToClientEvents(gomatrixserverlib.ToPDUs(events), synctypes.FormatSync, func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) { 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) return p.rsAPI.QueryUserIDForSender(ctx, roomID, senderID)