mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-17 03:43:11 -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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// When sending a v2 invite, the inviting server should try and include
|
// Try to unmarshal the invite room state to pass to the destination queue.
|
||||||
// a "stripped down" version of the room state. This is pretty much just
|
inviteRoomState := []gomatrixserverlib.InviteV2StrippedState{}
|
||||||
// enough information for the remote side to show something useful to the
|
if err := json.Unmarshal(oie.InviteRoomState, &inviteRoomState); err != nil {
|
||||||
// user, like the room name, aliases etc.
|
return fmt.Errorf("json.Unmarshal: %w", err)
|
||||||
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")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the invite request with the info we've got.
|
// 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 {
|
if err != nil {
|
||||||
return fmt.Errorf("gomatrixserverlib.NewInviteV2Request: %w", err)
|
return fmt.Errorf("gomatrixserverlib.NewInviteV2Request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
|
@ -86,9 +87,9 @@ type TransactionID struct {
|
||||||
// the usual context a matrix room event would have. We usually do not have
|
// 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.
|
// access to the events needed to check the event auth rules for the invite.
|
||||||
type InputInviteEvent struct {
|
type InputInviteEvent struct {
|
||||||
RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"`
|
RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"`
|
||||||
Event gomatrixserverlib.HeaderedEvent `json:"event"`
|
Event gomatrixserverlib.HeaderedEvent `json:"event"`
|
||||||
InviteRoomState []gomatrixserverlib.InviteV2StrippedState `json:"invite_room_state"`
|
InviteRoomState json.RawMessage `json:"invite_room_state"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// InputRoomEventsRequest is a request to InputRoomEvents
|
// InputRoomEventsRequest is a request to InputRoomEvents
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -118,6 +120,8 @@ type OutputNewRoomEvent struct {
|
||||||
type OutputNewInviteEvent struct {
|
type OutputNewInviteEvent struct {
|
||||||
// The "m.room.member" invite event.
|
// The "m.room.member" invite event.
|
||||||
Event gomatrixserverlib.HeaderedEvent `json:"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
|
// An OutputRetireInviteEvent is written whenever an existing invite is no longer
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ package input
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/common"
|
"github.com/matrix-org/dendrite/common"
|
||||||
|
|
@ -248,49 +249,16 @@ func processInviteEvent(
|
||||||
}
|
}
|
||||||
|
|
||||||
event := input.Event.Unwrap()
|
event := input.Event.Unwrap()
|
||||||
inviteStrippedState := []gomatrixserverlib.InviteV2StrippedState{}
|
inviteStrippedState := input.InviteRoomState
|
||||||
|
|
||||||
if len(input.InviteRoomState) > 0 {
|
// TODO: replace this with a proper origin check
|
||||||
// If we were supplied with some invite room state then let's use that.
|
if inviteStrippedState == nil {
|
||||||
// This will ordinarily happen over federation.
|
|
||||||
inviteStrippedState = input.InviteRoomState
|
|
||||||
} else {
|
|
||||||
// Otherwise, we should see if we know anything about the room state
|
// 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
|
// locally. If we have local knowledge of the room, use the locally known
|
||||||
// state to build up the invite room state.
|
// state to build up the invite room state.
|
||||||
if roomNID, err := db.RoomNID(ctx, roomID); err == nil && roomNID != 0 {
|
inviteStrippedState, err = buildInviteStrippedState(ctx, db, input)
|
||||||
stateWanted := []gomatrixserverlib.StateKeyTuple{}
|
if err != nil {
|
||||||
for _, t := range []string{
|
return err
|
||||||
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))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -298,7 +266,7 @@ func processInviteEvent(
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
outputUpdates, err := updateToInviteMembership(updater, &event, nil, input.Event.RoomVersion)
|
outputUpdates, err := updateToInviteMembership(updater, event, inviteStrippedState, nil, input.Event.RoomVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -310,3 +278,52 @@ func processInviteEvent(
|
||||||
succeeded = true
|
succeeded = true
|
||||||
return nil
|
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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
|
|
@ -111,8 +112,8 @@ func updateMembership(
|
||||||
}
|
}
|
||||||
|
|
||||||
switch newMembership {
|
switch newMembership {
|
||||||
case gomatrixserverlib.Invite:
|
//case gomatrixserverlib.Invite:
|
||||||
return updateToInviteMembership(mu, add, updates, updater.RoomVersion())
|
// return updateToInviteMembership(mu, add, updates, updater.RoomVersion())
|
||||||
case gomatrixserverlib.Join:
|
case gomatrixserverlib.Join:
|
||||||
return updateToJoinMembership(mu, add, updates)
|
return updateToJoinMembership(mu, add, updates)
|
||||||
case gomatrixserverlib.Leave, gomatrixserverlib.Ban:
|
case gomatrixserverlib.Leave, gomatrixserverlib.Ban:
|
||||||
|
|
@ -125,14 +126,17 @@ func updateMembership(
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateToInviteMembership(
|
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,
|
roomVersion gomatrixserverlib.RoomVersion,
|
||||||
) ([]api.OutputEvent, error) {
|
) ([]api.OutputEvent, error) {
|
||||||
// We may have already sent the invite to the user, either because we are
|
// 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
|
// 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
|
// remote server via the federation invite API. In those cases we don't need
|
||||||
// to send the event.
|
// to send the event.
|
||||||
needsSending, err := mu.SetToInvite(*add)
|
needsSending, err := mu.SetToInvite(add)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -143,7 +147,8 @@ func updateToInviteMembership(
|
||||||
// consider a single stream of events when determining whether a user
|
// consider a single stream of events when determining whether a user
|
||||||
// is invited, rather than having to combine multiple streams themselves.
|
// is invited, rather than having to combine multiple streams themselves.
|
||||||
onie := api.OutputNewInviteEvent{
|
onie := api.OutputNewInviteEvent{
|
||||||
Event: (*add).Headered(roomVersion),
|
Event: add.Headered(roomVersion),
|
||||||
|
InviteRoomState: addState,
|
||||||
}
|
}
|
||||||
updates = append(updates, api.OutputEvent{
|
updates = append(updates, api.OutputEvent{
|
||||||
Type: api.OutputTypeNewInviteEvent,
|
Type: api.OutputTypeNewInviteEvent,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue