mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-16 19:33:09 -06:00
Move responsibility of caring about invite room state
This commit is contained in:
parent
1de1640cc4
commit
48e3088e90
|
|
@ -187,54 +187,14 @@ func (s *OutputRoomEventConsumer) processInvite(oie api.OutputNewInviteEvent) er
|
|||
return nil
|
||||
}
|
||||
|
||||
// When sending a v2 invite, the inviting server should try and include
|
||||
// a "stripped down" version of the room state. This is pretty much just
|
||||
// enough information for the remote side to show something useful to the
|
||||
// user, like the room name, aliases etc.
|
||||
strippedState := []gomatrixserverlib.InviteV2StrippedState{}
|
||||
stateWanted := []string{
|
||||
gomatrixserverlib.MRoomName, gomatrixserverlib.MRoomCanonicalAlias,
|
||||
gomatrixserverlib.MRoomAliases, gomatrixserverlib.MRoomJoinRules,
|
||||
}
|
||||
|
||||
// For each of the state keys that we want to try and send, ask the
|
||||
// roomserver if we have a state event for that room that matches the
|
||||
// state key.
|
||||
for _, wanted := range stateWanted {
|
||||
queryReq := api.QueryLatestEventsAndStateRequest{
|
||||
RoomID: oie.Event.RoomID(),
|
||||
StateToFetch: []gomatrixserverlib.StateKeyTuple{
|
||||
gomatrixserverlib.StateKeyTuple{
|
||||
EventType: wanted,
|
||||
StateKey: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
// If this fails then we just move onto the next event - we don't
|
||||
// actually know at this point whether the room even has that type
|
||||
// of state.
|
||||
queryRes := api.QueryLatestEventsAndStateResponse{}
|
||||
if err := s.query.QueryLatestEventsAndState(context.TODO(), &queryReq, &queryRes); err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"room_id": queryReq.RoomID,
|
||||
"event_type": wanted,
|
||||
}).WithError(err).Info("couldn't find state to strip")
|
||||
continue
|
||||
}
|
||||
// Append the stripped down copy of the state to our list.
|
||||
for _, headeredEvent := range queryRes.StateEvents {
|
||||
event := headeredEvent.Unwrap()
|
||||
strippedState = append(strippedState, gomatrixserverlib.NewInviteV2StrippedState(&event))
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"room_id": queryReq.RoomID,
|
||||
"event_type": event.Type(),
|
||||
}).Info("adding stripped state")
|
||||
}
|
||||
// Try to unmarshal the invite room state to pass to the destination queue.
|
||||
inviteRoomState := []gomatrixserverlib.InviteV2StrippedState{}
|
||||
if err := json.Unmarshal(oie.InviteRoomState, &inviteRoomState); err != nil {
|
||||
return fmt.Errorf("json.Unmarshal: %w", err)
|
||||
}
|
||||
|
||||
// Build the invite request with the info we've got.
|
||||
inviteReq, err := gomatrixserverlib.NewInviteV2Request(&oie.Event, strippedState)
|
||||
inviteReq, err := gomatrixserverlib.NewInviteV2Request(&oie.Event, inviteRoomState)
|
||||
if err != nil {
|
||||
return fmt.Errorf("gomatrixserverlib.NewInviteV2Request: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ package api
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
|
|
@ -86,9 +87,9 @@ type TransactionID struct {
|
|||
// the usual context a matrix room event would have. We usually do not have
|
||||
// access to the events needed to check the event auth rules for the invite.
|
||||
type InputInviteEvent struct {
|
||||
RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"`
|
||||
Event gomatrixserverlib.HeaderedEvent `json:"event"`
|
||||
InviteRoomState []gomatrixserverlib.InviteV2StrippedState `json:"invite_room_state"`
|
||||
RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"`
|
||||
Event gomatrixserverlib.HeaderedEvent `json:"event"`
|
||||
InviteRoomState json.RawMessage `json:"invite_room_state"`
|
||||
}
|
||||
|
||||
// InputRoomEventsRequest is a request to InputRoomEvents
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
)
|
||||
|
||||
|
|
@ -118,6 +120,8 @@ type OutputNewRoomEvent struct {
|
|||
type OutputNewInviteEvent struct {
|
||||
// The "m.room.member" invite event.
|
||||
Event gomatrixserverlib.HeaderedEvent `json:"event"`
|
||||
// The invite stripped event state, if available.
|
||||
InviteRoomState json.RawMessage
|
||||
}
|
||||
|
||||
// An OutputRetireInviteEvent is written whenever an existing invite is no longer
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package input
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/matrix-org/dendrite/common"
|
||||
|
|
@ -248,49 +249,16 @@ func processInviteEvent(
|
|||
}
|
||||
|
||||
event := input.Event.Unwrap()
|
||||
inviteStrippedState := []gomatrixserverlib.InviteV2StrippedState{}
|
||||
inviteStrippedState := input.InviteRoomState
|
||||
|
||||
if len(input.InviteRoomState) > 0 {
|
||||
// If we were supplied with some invite room state then let's use that.
|
||||
// This will ordinarily happen over federation.
|
||||
inviteStrippedState = input.InviteRoomState
|
||||
} else {
|
||||
// TODO: replace this with a proper origin check
|
||||
if inviteStrippedState == nil {
|
||||
// Otherwise, we should see if we know anything about the room state
|
||||
// locally. If we have local knowledge of the room, use the locally known
|
||||
// state to build up the invite room state.
|
||||
if roomNID, err := db.RoomNID(ctx, roomID); err == nil && roomNID != 0 {
|
||||
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 err
|
||||
}
|
||||
roomState := state.NewStateResolution(db)
|
||||
stateEntries, err := roomState.LoadStateAtSnapshotForStringTuples(
|
||||
ctx, currentStateSnapshotNID, stateWanted,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stateNIDs := []types.EventNID{}
|
||||
for _, stateNID := range stateEntries {
|
||||
stateNIDs = append(stateNIDs, stateNID.EventNID)
|
||||
}
|
||||
stateEvents, err := db.Events(ctx, stateNIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, event := range stateEvents {
|
||||
inviteStrippedState = append(inviteStrippedState, gomatrixserverlib.NewInviteV2StrippedState(&event.Event))
|
||||
}
|
||||
inviteStrippedState, err = buildInviteStrippedState(ctx, db, input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -298,7 +266,7 @@ func processInviteEvent(
|
|||
return err
|
||||
}
|
||||
|
||||
outputUpdates, err := updateToInviteMembership(updater, &event, nil, input.Event.RoomVersion)
|
||||
outputUpdates, err := updateToInviteMembership(updater, event, inviteStrippedState, nil, input.Event.RoomVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -310,3 +278,52 @@ func processInviteEvent(
|
|||
succeeded = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildInviteStrippedState(
|
||||
ctx context.Context,
|
||||
db RoomEventDatabase,
|
||||
input api.InputInviteEvent,
|
||||
) (json.RawMessage, error) {
|
||||
roomNID, err := db.RoomNID(ctx, input.Event.RoomID())
|
||||
if err != nil || roomNID == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
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))
|
||||
}
|
||||
inviteStrippedState, err := json.Marshal(inviteState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return inviteStrippedState, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ package input
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
|
|
@ -111,8 +112,8 @@ func updateMembership(
|
|||
}
|
||||
|
||||
switch newMembership {
|
||||
case gomatrixserverlib.Invite:
|
||||
return updateToInviteMembership(mu, add, updates, updater.RoomVersion())
|
||||
//case gomatrixserverlib.Invite:
|
||||
// return updateToInviteMembership(mu, add, updates, updater.RoomVersion())
|
||||
case gomatrixserverlib.Join:
|
||||
return updateToJoinMembership(mu, add, updates)
|
||||
case gomatrixserverlib.Leave, gomatrixserverlib.Ban:
|
||||
|
|
@ -125,14 +126,17 @@ func updateMembership(
|
|||
}
|
||||
|
||||
func updateToInviteMembership(
|
||||
mu types.MembershipUpdater, add *gomatrixserverlib.Event, updates []api.OutputEvent,
|
||||
mu types.MembershipUpdater,
|
||||
add gomatrixserverlib.Event,
|
||||
addState json.RawMessage,
|
||||
updates []api.OutputEvent,
|
||||
roomVersion gomatrixserverlib.RoomVersion,
|
||||
) ([]api.OutputEvent, error) {
|
||||
// We may have already sent the invite to the user, either because we are
|
||||
// reprocessing this event, or because the we received this invite from a
|
||||
// remote server via the federation invite API. In those cases we don't need
|
||||
// to send the event.
|
||||
needsSending, err := mu.SetToInvite(*add)
|
||||
needsSending, err := mu.SetToInvite(add)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -143,7 +147,8 @@ func updateToInviteMembership(
|
|||
// consider a single stream of events when determining whether a user
|
||||
// is invited, rather than having to combine multiple streams themselves.
|
||||
onie := api.OutputNewInviteEvent{
|
||||
Event: (*add).Headered(roomVersion),
|
||||
Event: add.Headered(roomVersion),
|
||||
InviteRoomState: addState,
|
||||
}
|
||||
updates = append(updates, api.OutputEvent{
|
||||
Type: api.OutputTypeNewInviteEvent,
|
||||
|
|
|
|||
Loading…
Reference in a new issue