Try to build invite stripped state if not given to us

This commit is contained in:
Neil Alexander 2020-04-24 09:41:57 +01:00
parent 826688c19f
commit ab8fc3164b

View file

@ -18,6 +18,7 @@ package input
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"github.com/matrix-org/dendrite/common" "github.com/matrix-org/dendrite/common"
@ -78,6 +79,10 @@ type RoomEventDatabase interface {
GetRoomVersionForRoom( GetRoomVersionForRoom(
ctx context.Context, roomID string, ctx context.Context, roomID string,
) (gomatrixserverlib.RoomVersion, error) ) (gomatrixserverlib.RoomVersion, error)
// Get the room NID for a room ID.
RoomNID(ctx context.Context, roomID string) (types.RoomNID, error)
// Get the latest event IDs & state for a given room NID.
LatestEventIDs(ctx context.Context, roomNID types.RoomNID) ([]gomatrixserverlib.EventReference, types.StateSnapshotNID, int64, error)
} }
// OutputRoomEventWriter has the APIs needed to write an event to the output logs. // OutputRoomEventWriter has the APIs needed to write an event to the output logs.
@ -247,9 +252,23 @@ func processInviteEvent(
event := input.Event.Unwrap() event := input.Event.Unwrap()
if len(input.InviteRoomState) > 0 {
// If we were supplied with some invite room state already (which is
// most likely to be if the event came in over federation) then use
// that.
if err = event.SetUnsignedField("invite_room_state", input.InviteRoomState); err != nil { if err = event.SetUnsignedField("invite_room_state", input.InviteRoomState); err != nil {
return err return err
} }
} else {
// There's no invite room state, so let's have a go at building it
// up from local data. If we know about the room then we can insert
// the invite room state, if we don't then we just fail quietly.
if irs, ierr := buildInviteStrippedState(ctx, db, input); ierr == nil {
if err = event.SetUnsignedField("invite_room_state", irs); err != nil {
return err
}
}
}
outputUpdates, err := updateToInviteMembership(updater, &event, nil, input.Event.RoomVersion) outputUpdates, err := updateToInviteMembership(updater, &event, nil, input.Event.RoomVersion)
if err != nil { if err != nil {
@ -263,3 +282,48 @@ func processInviteEvent(
succeeded = true succeeded = true
return nil return nil
} }
func buildInviteStrippedState(
ctx context.Context,
db RoomEventDatabase,
input api.InputInviteEvent,
) ([]gomatrixserverlib.InviteV2StrippedState, error) {
roomNID, err := db.RoomNID(ctx, input.Event.RoomID())
if err != nil || roomNID == 0 {
return nil, errors.New("room unknown")
}
stateWanted := []gomatrixserverlib.StateKeyTuple{}
for _, t := range []string{
gomatrixserverlib.MRoomName, gomatrixserverlib.MRoomCanonicalAlias,
gomatrixserverlib.MRoomAliases, gomatrixserverlib.MRoomJoinRules,
} {
stateWanted = append(stateWanted, gomatrixserverlib.StateKeyTuple{
EventType: t,
StateKey: "",
})
}
_, currentStateSnapshotNID, _, err := db.LatestEventIDs(ctx, roomNID)
if err != nil {
return nil, err
}
roomState := state.NewStateResolution(db)
stateEntries, err := roomState.LoadStateAtSnapshotForStringTuples(
ctx, currentStateSnapshotNID, stateWanted,
)
if err != nil {
return nil, err
}
stateNIDs := []types.EventNID{}
for _, stateNID := range stateEntries {
stateNIDs = append(stateNIDs, stateNID.EventNID)
}
stateEvents, err := db.Events(ctx, stateNIDs)
if err != nil {
return nil, err
}
inviteState := []gomatrixserverlib.InviteV2StrippedState{}
for _, event := range stateEvents {
inviteState = append(inviteState, gomatrixserverlib.NewInviteV2StrippedState(&event.Event))
}
return inviteState, nil
}